In my code I have a JFrame that opens up a main menu, in that menu you can click options, which will take you to the options menu. On that options menu I want to create a back button that will position itself somewhere in the top left corner of the screen. When I run the program and go to the options menu the JButton does not appear. Something must be wrong with my code. Any help? Below is where I first declare the JButton.
static JButton optionsBackButton = new JButton("<html><font size = 5
color = green>Back</font></html>");
Here is the other part of the code that has to do with the JButton.
//Options Menu
JPanel optionsPanel = new JPanel();
JLabel optionsOptionsTitle = new JLabel("<html><font size = 7 color = blue>Options</font></html>");
JPanel optionsOptionsTitlePanel = new JPanel();
JPanel optionsBackButtonPanel = new JPanel();
optionsPanel.setLayout(null);
optionsBackButton.setBounds(100,100,50,50);
optionsBackButtonPanel.add(optionsBackButton);
optionsOptionsTitlePanel.add(optionsOptionsTitle);
optionsPanel.add(optionsOptionsTitlePanel);
optionsPanel.add(optionsBackButtonPanel);
optionsBackButton.addActionListener(this);
//Add panels to the card
panel.add("Home Screen", homePanel);
panel.add("Options Menu", optionsPanel);
//card.add("Game screen", gamePanel);
cardLayout.show(panel, "HomeScreen");
contentPane.add(panel);
Your problem is stemming from your use of null layouts. Note:
JPanel optionsBackButtonPanel = new JPanel(); // holds the back button
// but never given a size
optionsPanel.setLayout(null); // uh oh,.... bad news
optionsBackButton.setBounds(100,100,50,50); // yes you set the bounds of the button
optionsBackButtonPanel.add(optionsBackButton);
optionsOptionsTitlePanel.add(optionsOptionsTitle);
optionsPanel.add(optionsOptionsTitlePanel);
optionsPanel.add(optionsBackButtonPanel); // again, optionsBackButtonPanel
// has been never given a size or location/bounds
optionsBackButton.addActionListener(this);
So you set the bounds of the button and add it to a JPanel that uses the default FlowLayout, and so the bounds are meaningless. Then you add that JPanel, whose bounds you never set, to a JPanel that uses null layout. So the optionsBackButtonPanel will never show.
Solution: Don't use null layouts, but instead learn and use the layout managers.
While null layouts and setBounds() might seem to Swing newbies like the easiest and best way to create complex GUI's, the more Swing GUI'S you create the more serious difficulties you will run into when using them. They won't resize your components when the GUI resizes, they are a royal witch to enhance or maintain, they fail completely when placed in scrollpanes, they look gawd-awful when viewed on all platforms or screen resolutions that are different from the original one.
Start here: Laying Out Components in a Container Tutorial
Related
I've been fruitlessly searching the internet and nothing that people suggest seems to have any effect for me.
I have a JFrame which I'm trying to put a JPanel in. That JPanel ideally would have a JLabel with an imageicon as the background and a set of buttons in its own Jpanel in the foreground. The issue is every type of layout manager I've seen suggested just does not work as advertised for me. The best I've gotten to work so far is this approach:
public MenuBackgroundPanel(AsteroidsFrame frame)
{
this.gameFrame = frame;
this.setLayout(new OverlayLayout(this));
ImageIcon image = new ImageIcon(getClass().getResource("/resources/background1.gif"));
imageLabel = new JLabel(image, JLabel.CENTER);
mp = new MainMenuPanel(gameFrame);
mp.setMaximumSize(new Dimension(300,200));
this.add(mp);
this.add(imageLabel);
this.setVisible(true);
}
Unfortunately, I'm getting really strange alignments and trying to set location on the background (to actually get it to start at the JFrame's (0,0) or moving the button panel just seems to have no effect. Printing the location of each object says they're both at (0,0) but the image I'll link shows this is just not the case. My point is, I've tried things like JLayeredPane or setting the JLabel as the contentpane of the Jframe and making it transparent but nothing seems to do anything. One or the other of the two objects just covers the other completely.
As you can see the objects are not at all aligned.
Could anyone help me with this?
That JPanel ideally would have a JLabel with an imageicon as the background and a set of buttons in its own Jpanel in the foreground
Easiest way for something like this when the child panel is fully contained in the label image is to just set the layout manager of the JLabel and then add your components to the label.
JLabel background = new JLabel( new ImageIcon(...) );
background.setLayout( new GridBagLayout() );
JPanel buttons = new JPanel();
buttons.setOpaque( false );
buttons.add(...);
background.add(buttons, new GridBagConstraints() );
Now the button panel will be centered on the label.
As you can see the objects are not at all aligned
If you want to use the OverlayLayout then you need to play with the alignmentX/Y properties of each component. You would probably want to set them both to .5. Check out: Java Layout with Component always in Top Right for an example of how changing these values can affect the layout.
Im new in Java Swing, and want to make my layout, but can't do this
Look Now :
Look I want :
Code Now :
JPanel MainPanel = new JPanel(new GridBagLayout());
JLabel MoneyLabel = new JLabel(MoneyIcon);
MoneyLabel.setHorizontalTextPosition(JLabel.CENTER);
MoneyLabel.setVerticalTextPosition(JLabel.BOTTOM);
MoneyLabel.setText("Money:" + CarMain.Money);
JLabel MoneyClicksLabel = new JLabel();
MoneyClicksLabel.setHorizontalTextPosition(JLabel.CENTER);
MoneyClicksLabel.setVerticalTextPosition(JLabel.BOTTOM);
MoneyClicksLabel.setText("Money Clicks: " + CarMain.MoneyClicks);
JLabel BoxesLabel = new JLabel(BoxLv9_10Icon);
BoxesLabel.setHorizontalTextPosition(JLabel.CENTER);
BoxesLabel.setVerticalTextPosition(JLabel.BOTTOM);
BoxesLabel.setText("Boxes: " + CarMain.Boxes);
JLabel BoxesClicksLabel = new JLabel();
BoxesClicksLabel.setHorizontalTextPosition(JLabel.CENTER);
BoxesClicksLabel.setVerticalTextPosition(JLabel.BOTTOM);
BoxesClicksLabel.setText("Boxes Clicks: " + CarMain.BoxesClicks);
MainPanel.add(MoneyLabel);
MainPanel.add(MoneyClicksLabel);
MainPanel.add(jbtnMoney);
MainPanel.add(BoxesLabel);
MainPanel.add(BoxesClicksLabel);
MainPanel.add(jbtnBoxes);
This is simple example of, what i want, becouse i'm building ingame shop, with 13 labels like these, in each tabbedpane window. How can i make it look, like in second picture, what I want?
Im new in Java Swing, and want to make my layout, but can't do this
Probably no single layout can suit everyone's needs. But combining several layouts can usually handle most scenarios.
From the image you showed in the question. There is no need to write your own layout. You can always use sub panels to hold your components and set a specific layout for each sub panel to handle what you need for those individual areas.
The reason for the alignment in your first attached image is because:
JPanel uses FlowLayout as its default layout. Hence all the components added will appear in a linear fashion and tries to fill up the row as much as possible the panel's width can hold. Once exceeded the panel's width, the components will be pushed to the next row.
If you want to achieve the alignment in the second attached image:
You may create a main panel to contain several sub-panels (see image below).
The red box is your main panel and you may continue to use the default FlowLayout.
Then add your components into sub-panels (orange boxes) before adding it to the main. You may then use BoxLayout, FlowLayout or even GridBagLayout for the sub panels (orange boxes).
Artis Uljanovs, at night after work i will give a look at this to help you.
I recommend you already to read the following: https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html
You need some foundations on Java Layouts.
I am trying to build my own "Battleship" game and have problems with swing.
I now read endless docs on oracle tutorials on LayoutManagers, but not any of them works as I understand them. They only add a few buttons, but never two individual panels.
JPanel Background = new JPanel();
Background.setLayout(new BoxLayout(Background, BoxLayout.X_AXIS));
panelPlayer = new JPanel();
panelPlayer.setBorder(BorderFactory.createLineBorder(Color.black));
panelPlayer.setSize(700, 600);
// PC Field
panelPc = new JPanel();
panelPc.setBorder(BorderFactory.createLineBorder(Color.black));
panelPc.setSize(700, 600);
//adding to frame
getContentPane().add(Background);
Background.add(panelPlayer);
Background.add(panelPc);
After that I have a loop thats adds 16x16 buttons in a JButton[] once for every panel.
How to get the two panels to show a table layout?
I used GridLayout before, the grid works, but it always takes up the whole space of the frame, not of the Container or Panel or else. The panels are overlapping then.
GridBagLayout just puts the buttons in a row and beyond the screen.
Don't fix the size of the panel while using any layout. It works only when you use null layout
You can achieve your goal with GridBagLayout. While adding buttons specify gridx, gridy correctly, it will add buttons like table
just keep nesting the layouts.
in your case make a big one with two sides -
then in each side place another panel with your grid.
You can solve this by nesting panels. Each panel has its own layout manager, so it is a matter of breaking up your UI into pieces and choosing the layout manager for each piece.
If you want two panels side-by-side, then the panel that contains them should have a FlowLayout manager with horizontal orientation. Create a panel with FlowLayout and add the panels to it.
If each of the the side-by-side panels needs the grid of buttons, then set the panel layout to GridLayout and put the buttons in the panel. This fits what I remember of Battleship; in a grid layout, all the grid elements remain the same size no matter how the window is resized.
That should get you started. If, as I expect, you will want another panel with some game controls on it, look into BorderLayout; it has a section on each edge of a rectangle and another in the middle. Put the panel containing the two grids in the center of a panel using BorderLayout, and then your game controls can go in a panel to the north, south, east, or west of that.
Good luck. Let us know if you have a specific problem (in another question).
New to Java Swing layouts. After much reading, I think that the best layout for me is the box layout. My JDialogBox has a JTabbedPane on it. On the JTabbedPane, there are four JPanels. I am focusing on laying out one of these panels, called pnlDivision.
What I want to do to this panel is to add a series of scrollable panels. The panels will be vertically stacked upon each other and each will consist of a single row. Included in each panel will be horizontally aligned labels, any of which can be selected for editing by the user.
At the moment, I can't even get anything to appear on my tabbed panel. Focusing on the basics first, I have the following code just to get the idea of a box layout set up, with a single scrollable panel containing and a single label. But my tabbed panel is still blank. Can anyone see what is wrong with this basic code? I've read many resources on this, but I can't get unstuck.
Thanks very much !
JScrollPane myScroller = new JScrollPane();
myScroller.setPreferredSize(new Dimension(250, 80));
myScroller.setAlignmentX(LEFT_ALIGNMENT);
JPanel myPane = new JPanel();
myPane.setLayout(new BoxLayout(myPane, BoxLayout.PAGE_AXIS));
JLabel lbl = new JLabel("label 1");
myPane.add(lbl);
myPane.add(Box.createRigidArea(new Dimension(0,4)));
myPane.add(myScroller);
myPane.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
pnlDivision.add(myPane);
EDIT:
This is the code where I set up the tabbed panel. I used the IDE (NetBeans), so this is generated by NetBeans. I've only pulled out the lines that relate to this issue. If I'm obviously missing any lines, please let me know:
jTabbedPane1 = new javax.swing.JTabbedPane();
pnlDivision = new javax.swing.JPanel();
jTabbedPane1.addTab("division", null, pnlDivision, "Manage Sets for Division Problems");
getContentPane().add(jTabbedPane1);
jTabbedPane1.setBounds(70, 110, 610, 340);
I am trying to create a JScrollPane that contains a JPanel that will be increasing and decreasing in height. When it becomes larger than the size of the JScrollPane, it should create a vertical scroll bar which will allow me to scroll through the entire JPanel. However, I am having difficulty achieving this. Yes, I know I am not using LayoutManagers. No, I will not be using them, and I need a solution that does not involve their usage.
Here are the two button's AbstractActions that add and subtract from the JPanel:
class AddACT extends AbstractAction
{
public void actionPerformed(ActionEvent e)
{
info.setSize(420,info.getHeight() + 40);
info.add(new SubPanel); // Adds another JPanel into the main JPanel (for content input)
gui.repaint();
infoS.validate();
}
}
class RemoveACT extends AbstractAction
{
public void actionPerformed(ActionEvent e)
{
info.remove(subPanel()); // This would remove the last JPanel added to the main JPanel
info.setSize(420,info.getHeight() - 40);
gui.repaint();
infoS.validate();
}
And here is the code for the main JPanel and the JScrollPane:
final JPanel info = new JPanel();
final JScrollPane infoS = new JScrollPane(info, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
info.setLayout(null);
info.setSize(420,600);
infoS.setLocation(10,80);
infoS.setSize(420,490);
gui.add(infoS); // gui is the frame's content pane (the overall JPanel)
This is the second project I've been trying to learn GUI by doing. I am a complete novice in Swing and am only intermediate in Java. Sorry if I am making a blindingly obvious mistake.
1) Use LayoutManagers (+1 to #kleopatra and #GagandeepBali comments)
The absence of LayoutManagers only guarantees your GUI's will look very trashy (especially when run on other OSes/builds) and being a Novice you should rather learn the correct way than learn the wrong way and get into bad habits like calling setSize() etc.
Have a read on these links to get you started:
A Visual Guide to Layout Managers
Concurrency in Swing
2) See this example for how to use a JScrollPane, it simply adds a JPanel with buttons to a JScrollPane which in-turn is added to the JFrame.
3) Also see this example for how to make the JScrollPane vertically scroll-able only.
4) For more on JScrollPanes have a look here: How to Use Scroll Panes.
5) As for how it interacts with LayoutManager, if you do not explicitly set its size via setPreferredSize(Dimension d) the scroll pane computes it based on the preferred size of its nine components (the viewport, and, if present, the two scroll bars, the row and column headers, and the four corners)
6) On your usage of validate():
validate() is used when new JComponents are added to a visible component
revalidate() is used when JComponent is removed/added from a visible component
revalidate() covers validate() too
Thus always use this:
//add or remove component(s)
revalidate();
repaint();
References:
http://www.daniweb.com/software-development/java/threads/405568/validate-vs-revalidate
LayoutManager is not required to solve the problem. The problem in Thrfoot's example is in these lines:
final JScrollPane infoS = new JScrollPane(info, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
info.setLayout(null);
info.setSize(420,600);
The program appears to recognize there is a need for scroll bars (it would show the scroll bar if your setting was VERTICAL_SCROLLBAR_AS_NEEDED), but the actual scrolling does not work (the scroll bar slider is not there).
To fix this, first set the preferred size of info, then construct the infoS.
Example:
info.setPreferredSize(420,600);
final JScrollPane infoS = new JScrollPane(info, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
The idea is to set the preferred size of the info panel before it is used for the scroll pane. This is the same reason to set the size and location of infoS before adding to the gui:
infoS.setLocation(10,80);
infoS.setSize(420,490);
gui.add(infoS); // gui is the frame's content pane (the overall JPanel)