I have a custom class that extends JPanel called Node that I want to be able to add to panel MainPanel through code, but the Nodes are not appearing. It works fine with drag and drop, but I want to add more Nodes during runtime.
but I want to add more Nodes during runtime.
When adding components to a visible GUI the basic code is:
panel.add(...);
panel.revalidate();
panel.repaint();
You need to invoke the layout manager to the component has a size and location otherwise the size is (0, 0) and there is nothing to paint.
Related
When I provide this code to mouseClicked method in MouseListener interface,
the changeableContentPanel is expanded. Could anyone help me?
if (!changeableContentPanel.isAncestorOf(aMO)) {
aMO = new AccountsManagementOptions();
changeableContentPanel.removeAll();
changeableContentPanel.validate();
changeableContentPanel.repaint();
aMO.setLocation(5, 100);
changeableContentPanel.add(aMO);
changeableContentPanel.validate();
changeableContentPanel.repaint();
}
When you remove/add components to the panel you should be using:
panel.remove(...);
panel.add(...);
panel.revalidate();
panel.repaint();
That is you should be using revalidate() instead of validate() and you only need to invoke the code once after all changes to the panel have been made.
the changeableContentPanel is expanded.
Yes, because the layout manager is invoked and the size of the panel will recalculated based on the size of the component added to the panel.
Could anyone help me?
If you don't want the size to change then you should be using a CardLayout on your panel. The panel size will be fixed to the size of the largest card added to the panel. Then you just swap components.
Read the section from the Swing tutorial on How to Use CardLayout for more information and working examples.
We have some code implemented as follows:
#Override
public void showPanel(CardPanel panel)
{
cardPanel.removeAll();
cardPanel.add((Component) panel);
// Even though you'd think adding a component should automatically repaint,
// it turns out that it doesn't.
cardPanel.repaint();
}
cardPanel is just a JPanel and CardPanel is just one of our own interfaces, but all card panels are just using normal Swing components.
This comment was baffling because, as far as I knew, Container#add was supposed to automatically repaint itself if a child was added. Yet, if I delete the line, indeed I do see that it doesn't repaint its contents when the child is added.
Is there some particular reason why Container behaves this way? To me, it seems to violate the "principle of least surprise"...
Is there some particular reason why Container behaves this way?
By default all Swing components have a default size of (0, 0) so there is nothing to paint.
Components are given a size (and location) when the layout manager is invoked. Since you could be adding multiple components to the panel it doesn't make sense for the layout manager to continually be invoked as each component is added.
So when you finish adding components to the panel you do:
panel.revalidate(); // to invoke the layout manager
panel.repaint(); // not always needed, but will ensure the panel is repainted.
So basically, I am trying to get a JPanel window which will display all components inside dynamically. In other words, which will re-size the window, and display to fit its content.
I have been able to do it with help of JFrame and its pack() method which : "causes this Window to be sized to fit the preferred size and layouts of its subcomponents".
In my situation, I dont want to use JFrame because it will require much effort to make all changes.
Right now, I am able to make it work but only with the help of jscroll inside which wraps the text and or any new lines, so the window size is more static. So my JPanel is extending a TopComponent and am able to display it with:
jpanel.open();
jpanel.requestActive();
So the question is how to resize a window to fit its content upon actions in that window.
The JPanel has to be added to a Window in order to make sense. So I suggest you use layout managers correctly and you will get to a decent user interface.
When you add/remove components from a visible panel you need to use:
panel.revalidate();
panel.repaint();
Then the layout manager will lay out the components again.
I search for a method, which gets called if the jpanel is shown on the display, because i have to fetch the real size of the panel.
Any suggestions?
Have you tried adding a ComponentListener to the JPanel? That would be where I would start with my code in the componentShown(...) method. For this to work, I think that you must call setVisible(true) on the JPanel after adding it to the display.
The other option is to simply query its size after calling pack(), or setVisible(true) on your GUI.
Edit
You state:
I added the panel to the gui designer.. when the window pops up, i wanna now the real size of the jpanel, because it can change it.
If you want to know the size of a component held by a window "when the window pops up", then add a WindowListener to the window and check the size of the component from the windowOpened(...) method.
Edit 2
Then you state:
after i have the real size, i add some subpanels, in relation to the size of this panel. so e.g. size/6 & the subpanel has now the size-height of size/6.
One Solution: Better not to set the sizes of anything but instead to use the right combination of layout managers and then let them set the proper sizes based on their rules.
Set the visibility using function setVisible(true);
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.