I added child panel to parent panel by using method 'parent.addTab(child)' and added one JLabel in the child panel but setBounds method is not working in child panel. This JLabel is getting showed at one fix location. setBounds is working fine in parent panel. What to do?
You need to define an appropriate layout manager for your child panel. For example, if you chose to use BorderLayout you could arrange for the label to be shown in the center of the panel as follows:
JTabbedPane parent = new JTabbedPane();
JPanel child = new JPanel(new BorderLayout());
// Create label with centrally aligned text (default is left).
JLabel label = new JLabel("Hello, World", JLabel.CENTER_ALIGNMENT);
// Add label to center of the child panel.
child.add(label, BorderLayout.CENTER);
// Add child panel as a tab within parent JTabbedPane.
// The child panel will expand to fit the size of the tab.
parent.addTab("My Tab", child);
For more a flexible layout consider using GridBagLayout.
setBounds only work for containers that have their layout set to null. (Or for moving frames around on the desktop.)
JPanel's default layout manager is FlowLayout which lays out components in order horizontally, and dropping to a new row when the current is full (like text in a page).
Using a null layout and setBounds isn't a recommended way to lay out GUIs - it's very fragile - too much depends on the size of the container / frame and the size, resolution and font settings of the desktop can easily break the layout.
Read through the Using Layout Managers section of the Swing tutorial to figure out what layout managers can help you accomplish what you want.
Related
I want to have multiple vertical panels in my frame which will start with a button in them. When I push these buttons they will add more buttons to these panels. When new buttons are added, the panels should expand and push all the other panels below them. I added an example image of what I want above.
I am not new with layout managers, are there any layout manager that I can use for this? If not what can I do?
It depends on the layout manager of the child panel and the layout manager of the parent panel. Both layout manager need to be able to grow. Based on the picture you could use a vertical BoxLayout for both parent and child panels.
When you add a component to a visible panel you then need to revalidate() the panel to invoke the layout manager so the basic code would be:
JButton button = new JButton(...);
panel.add( button );
panel.revalidate();
panel.repaint();
Read the section from the Swing tutorial on Layout Managers for more information and working examples to get you started.
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);
I've started doing some experiences with Swing in Netbeans.
I've created two panels and inside each one I've inserted one JLabel.
How can I define the vertical position of my label inside the frame?
Since I'm unable to align the two labels (one on each panel) I would like to set each one to some vertical alignment.
Layouts with layout padding and component borders.
See:
Laying Out Components Within a Container
How to Use Borders
you can use
setBounds(x,y,width,height);
JLabel label = new JLabel();
label.setBounds(10,10,40,20);
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.
BorderLayout does something strange. If I add two panels to a Container with the same constraint (BorderLayout.CENTER for instance), then the first one goes away, even if the second one is deleted or made invisible
It seems as though it would make sense for it to "stack" each element on top of the previous ones.
Is this correct and by design? If so, is there some documentation on it?
Has anyone else been frustrated by it? Have you a solution, such as a custom LayoutManager?
Sample code:
JFrame frame = new JFrame();
frame.setSize(500, 500);
JPanel panel1 = new JPanel();
panel1.setBackground(Color.blue);
frame.getContentPane().add(panel1);
JPanel panel2 = new JPanel();
panel2.setBackground(Color.red);
frame.getContentPane().add(panel2);
panel2.setVisible(false); // Seems like it should allow us to see panel1.
frame.setVisible(true);
This creates and displays a 500x500 blank box.
BorderLayout was simply not designed to do what you want. Separation of responsibility. If you want that behavior you should compose: combine the BorderLayout with a CardLayout. Though for the actual stack behavior, you'll have to code something yourself (or find someone who already has.)
Is this correct and by design?
Yes.
You need to understand the basics of how layout managers work. One of the jobs of the layout manager is to set the "location" and "size" of the components added to the panel. In the case of a BorderLayout it only tracks 5 components so only the last component added to the CENTER is known by the layout manager.
Layout management is not done when components are added to the panel. It is done when the frame is packed, or made visible (or the revalidate() method is invoked) . In this case the blue panel is not part of the components managed by the BorderLayout so its size remains (0, 0), which means there is nothing to paint.
Try changing your code to:
JPanel panel1 = new JPanel();
panel1.setSize(200, 200);
and you will see the blue panel painted at the specified size.
Now try commenting out:
//panel2.setVisible(false);
and you will see both panels. This is because as components are added to the panel they are assigned a ZOrder. Basically the last component added is painted first, which is why the blue panel is painted on top of the red panel. Check out the setComponentZOrder() method of the Container class for more information.
The CardLayout is probably the layout manager you should be using, but you can check out the Overlap Layout as well.