Recommendation for Layout Manager - java

I am creating a GUI for an arcade game. It consist of a single JFrame with some JPanels and one JMenu as shown in the figure:
I've been trying using BorderLayout but it doesn't show the panels properly. What I get is that the JMenu shows properly. [1] adjusts its width to content the buttons inside it. The JPanel [2] fulfill almost the rest of the screen. And [3] shows just as a thin line at the end.
Here's the fragment of code that I use to put them in position:
add(new TopMenu(), BorderLayout.PAGE_START); // JMenu
add(new LeftPanel(), BorderLayout.WEST); // [1]
add(new StatusPanel(), BorderLayout.CENTER); // [2]
add(new GameUI(), BorderLayout.LINE_END); // [3]
Any suggestions of what could be provoking this behavior are welcome.

You can always nest JPanels/containers, each using its own layout. So the overall layout could be a BorderLayout with the menu at the BorderLayout.NORTH and the JPanel [1] on the BorderLayout.EAST side, then nest a JPanel into the BorderLayout.CENTER position using either another BorderLayout or a BoxLayout and put your other two JPanels into this JPanel. For instance this CENTER JPanel could use BorderLayout and it could hold JPanel [2] in its BorderLayout.NORTH position and JPanel [3] in its BorderLayout.CENTER position.

Your JPanel's have to have Swing components inside, or else they will shrink to the minimum size when you call pack() on the JFrame.
Since you're creating a game, you'll need to set the preferred size on your JPanel's, and set the preferred size on the JFrame. I'm assuming you'll want to paint at least one of the JPanel components directly using the paintComponent method.
You can nest JPanel-2 and JPanel-3 in a rightPanel. You can use FlowLayout for the rightPanel itself, as well as putting JPanel-1 and rightPanel into the JFrame.
If you insist on using a layout manager that will lay out the 3 JPanel's without nesting, you will have to use the GridBagLayout. JPanel-1 will be 1 column wide and 2 rows deep. JPanel-2 will be 1 column wide and 1 column deep. JPanel-3 will be 1 column wide and 1 column deep.
You'll still have to set the preferred size of the 3 JPanel's.

Related

Center Panel's Component Within a java swing BoxLayout

I'm trying to use a BoxLayout to display 2 panels vertically and I searched how to center the components in those panels. At the moment, my components are placed on the top center of each panel, and I want to get them at the center X and Y.
I added the components I want in the 2 panels, then I added the panels in my BoxLayout. This way they're displayed vertically as I want them to be, but as I said I don't want them to be on top center.
I tried to use methods such as setAlignementY and setLocation but any of them actually moves the components. I also saw that a BoxLayout will try to set the components as wide as the widest component, but as I have only 2 panels which have the same size I don't really understand it.
This is basically how I've added my components (without trying to center) :
private void initPanels ()
{
this.titlePanel.add(this.title);
this.bookInputPanel.add(bookTitle);
this.bookInputPanel.add(bookInput);
this.authorInputPanel.add(by);
this.authorInputPanel.add(authorInput);
this.authorInputPanel.add(this.authorsTable);
this.buttonsPanel.add(confirm);
this.contentPanel.setLayout(new BoxLayout(this.contentPanel, BoxLayout.Y_AXIS));
this.contentPanel.add(bookInputPanel);
this.contentPanel.add(authorInputPanel);
this.add(this.titlePanel, BorderLayout.NORTH);
this.add(this.contentPanel, BorderLayout.CENTER);
this.add(this.buttonsPanel, BorderLayout.SOUTH);
}
I made a picture to show you exactly what I want but it seems that I need 10 rep to do it, sorry about that.
This way they're displayed vertically as I want them to be, but as I said I don't want them to be on top center.
One way is to add "glue" to the top/bottom of the panel. This "glue" will expand to fill the extra space available to the panel:
this.contentPane.add(Box.createVerticalGlue());
this.contentPanel.add(bookInputPanel);
this.contentPanel.add(authorInputPanel);
this.contentPane.add(Box.createVerticalGlue());
Read the section from the Swing tutorial on How to Use BoxLayout for more information about the feature of a BoxLayout.
Another option might be to use a "wrapper" panel that uses a different layout manager. For example the GridBagLayout with the default constraints will automatically center the component horizontally/vertically:
//this.add(this.contentPanel, BorderLayout.CENTER);
JPanel wrapper = new JPanel( new GridBagLayout() );
wrapper.add( contentPanel );
this.add(wrapper, BorderLayout.CENTER);

How to put two java swing JPanels next to each other and have a table in it?

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).

How can I split a panel into subpanels?

I already have a panel made (its a row of buttons), and have it located at the bottom of a frame (SOUTH), but I would like to add two rows (panels/ subpanels) beneath it (a text input line and output line if it matters). Right now the only thing I know to do is declare and add more panels, which would be fine, but when I specify .SOUTH they go over top of the previous panel.
EDIT: The solution I used
As suggested by Ted Hopp, I added my original panel (now called subPanel1), as well as the two new panels which were going on top of the original (subPanel2 & subPanel3), to a fourth "container panel" (bottomCotainerPanel). Since I only had three subPanels, this allowed me to specify where in the containerPanel each subPanel would go (using NORTH, CENTER, SOUTH, might have to do something slightly different if you had more than 3...), and then specify where the contianerPanel would go in the frame (SOUTH).
subPanel1.setLayout(new GridLayout(1,6)); //Layout of subPanel1
subPanel1.add(clearButton);
subPanel1.add(customerNameLabel);
subPanel1.add(customerNameTextField);
subPanel1.add(showByNameButton);
subPanel1.add(openNewSavingsButton);
subPanel1.add(openNewCheckingButton);
subPanel2.add(sendChatTextField);
subPanel2.add(sendButton);
subPanel2.add(clearButton2);
subPanel3.add(receiveChatTextField);
subPanel3.add(nextButton);
subPanel3.add(previousButton);
bottomContainerPanel.setLayout(new GridLayout(3,1)); //Layout of Container Panel
bottomContainerPanel.add(subPanel1, BorderLayout.NORTH);
bottomContainerPanel.add(subPanel2, BorderLayout.CENTER);
bottomContainerPanel.add(subPanel3, BorderLayout.SOUTH);
tellerWindow.getContentPane().add(bottomContainerPanel, BorderLayout.SOUTH);
You need to add a single container panel as the SOUTH panel of the frame. The container itself should have the layout that you want for everything that goes at the bottom.
If you just want to split panel onto 2 equal parts at south and north use GridLayout. If you want something in the middle you can use BorderLayout.
If you want to give your user ability to change the sub-panels size use JSplitPane.
I had a similar problem trying to put several rows of buttons into a panel borrowed from the ListDemo example. Well, the first thing to do is to read about BorderLayout: How to Use BorderLayout, or at least see the image shown there:
You cannot have multiple bottom rows in a BorderLayout. But you can use a nested layout. What we need is a BoxLayout, see How to Use BoxLayout:
.
We just have to replace the buttons shown on the above image by rows of buttons.
public class MyStuff extends JPanel {
...
public MyStuff() {
super(new BorderLayout());
...
JPanel buttonArea = new JPanel();
buttonArea.setLayout(new BoxLayout(buttonArea, BoxLayout.PAGE_AXIS));
add(buttonArea, BorderLayout.PAGE_END);
...
//if you dislike the default center alignment:
//panelWithButtons1.setAlignmentX(Component.LEFT_ALIGNMENT);
buttonArea.add(...);// add the 1st panel with buttons
buttonArea.add(...);// add the 2nd panel with buttons
buttonArea.add(...);// add the 3rd panel with buttons

How to vertically center align a JScrollPane in a JPanel?

I have a JPanel with a GridLayout consisting of 1 row and 2 Columns.
Inside the first column, I have a JPanel consisting of a Jpanel and a Jtree.
Inside the second column, I have a JScrollPane consisting of a JTable.
How can I center-align the JscrollPAne to appear vertically center-aligned? currently, It is showing at the top and not at the center.
Here is an image:
You for your JScrollPane in the 2nd column, you will need to wrap it with a JPanel. Then you will need to set a layout manager for the new JPanel. I would probably use GridBagLayout as it gives you more precise control and you can achieve the vertical centering you desire with it.
You will have to add a fake JPanel into the wrapper JPanel to fill in the whitespace you are looking for.
So in short you will have:
JPanel with GridLayout (1 row, 2 columns)
Column 1:
JTree
Column 2:
JPanel with GridBagLayout which then holds:
JPanelwith GridBagConstraints (for whitspace)
JScrollPane with GridBagConstraints
You might need to add another JPanel below the JScrollPane if you want whitespace down there too. I'm not 100% sure what your looking for. With the GridBagConstraints you can precisely control the layout.
There is a Layout manager to save you :) Inside the second column, use a panel with GridBagLayout , and insert the JScrollPane into the panel, you can specify the position of components in panel using GridBagConstraints.
See this for more information : How to Use GridBagLayout

How do I make JScrollPane work properly with nested JPanels?

I'm building a Swing application in Java using NetBeans and I have a problem with layout. My main frame contains a JScrollPane which contains a JPanel called contentPanel which in turn contains a JPanel called listPanel. The listPanel is empty when the program starts, but when the user interacts with the program an unpredictable number of smaller JPanels are added to it. I've used the NetBeans GUI-builder to snap the top edge of listPanel to the top of contentPanel, and the same with the bottom edges.
The problem I have is that when more components are added to listPanel the vertical scrollbar doesen't appear on my scrollpane. The verticalScrollBarPolicy of my scrollpane is set to AS_NEEDED and its viewportView is set to contentPanel. What I think I need to do is to make contentPanel grow when more items are added to listPanel.
The problem I have is that when more components are added to listPanel the vertical scrollbar doesen't appear on my scrollpane.
The scrollbar will appear when the preferred size of the component added to the scrollpane is greater than the size of the scrollpane. When you add components dynamically you need to tell the scrollpane something has changed. So you basic code should be:
panel.add( subPanel );
panel.revalidate();
Or, because you are adding a panel to the sub panel, you may need to revalidate the scrollpane (I don't remember):
panel.add( subPanel );
scrollPane.revalidate();
The key is the revalidate() which tell the layout manager to recalculate its size.
Use a different LayoutManager. One that will allow for vertical growth like BoxLayout. Also remember that you can use multiple layouts and nest them inside of each other for different effects.

Categories

Resources