I found three ways to fill my JFrame frame = new JFrame("...")
createContentPanel returns a JPanel and createToolBar returns a ToolBar.
frame.add(this.createToolBar(), BorderLayout.PAGE_START); //this works and puts the ToolBar above and the ContentPanel under it<br>
frame.add(this.createContentPanel(), BorderLayout.CENTER);
frame.setContentPane(this.createContentPanel()); //this lets the JToolBar hover over the ContentPanel
frame.getContentPane().add(this.createToolBar());
frame.getContentPane().add(this.createContentPanel()); //this only puts the last one into the JFrame
frame.getContentPane().add(this.createToolBar());
And now I am wondering why should i use the getContentPane()/setContentPane() method if i could just use a simple frame.add(...) to fill my frame.
You are right that it doesn't matter which you use (JFrame#add(...) vs. JFrame#getContentPane().add(...)) since they both essentially call the same code, however there will be times in the future when you'll need access to the contentPane itself, such as if you want to change its border, set its background color or determine its dimensions, and so you'll likely use getContentPane() at some point, and thus getting to know it and be familiar with it would be helpful.
//this only puts the last one into the JFrame
You need to understand how layout managers work. The default content pane is a JPanel that uses a BorderLayout. When you add a component and don't specify a constraint, then it defaults to the CENTER. However you can only has a single component in the center so the layout manager only knows about the last one added. When the layout manager is invoked it sets the size() and location() of that component. The other component has a size of 0, so it is never painted.
In Java 1.6, you can just use the add method of JFrame:
http://download.oracle.com/javase/6/docs/api/javax/swing/JFrame.html
(It will be delegated to the contentPane.)
http://download.oracle.com/javase/1.4.2/docs/api/javax/swing/JFrame.html
Which says:
The JFrame class is slightly
incompatible with Frame. Like all
other JFC/Swing top-level containers,
a JFrame contains a JRootPane as its
only child. The content pane provided
by the root pane should, as a rule,
contain all the non-menu components
displayed by the JFrame. This is
different from the AWT Frame case. For
example, to add a child to an AWT
frame you'd write:
frame.add(child);
However using JFrame you need to add the child
to the JFrame's content pane instead:
frame.getContentPane().add(child);
The same is true for setting layout
managers, removing components, listing
children, and so on. All these methods
should normally be sent to the content
pane instead of the JFrame itself. The
content pane will always be non-null.
Attempting to set it to null will
cause the JFrame to throw an
exception. The default content pane
will have a BorderLayout manager set
on it.
Related
I have a JFrame that uses the BorderLayout. How do I get all the components that are in the left or the right or in any other location of this JFrame?
As #brano suggested, you can access those components via the LayoutManager of your JFrame's contentPane.
For exemple, assuming that you want to get the component that is located on BorderLayout.WEST (and that your JFrame is called frame), you could do:
final BorderLayout layout = (BorderLayout) frame.getContentPane().getLayout();
final Component west = layout.getLayoutComponent(BorderLayout.WEST);
One remark, though: the getLayoutComponent method doesn't belong to LayoutManager: thus, you have to know and be sure that your layout is an actual BorderLayout.
I am adding lots of components (JPanels, JLabels etc.) into a JScrollPane programagically at the start of my program based on some stuff from a database.
It seems that this procedure is too fast for the GUI(?), so the JScrollPane does not always update correctly, i.e the scroll bars are not visible even though the inner JPanel is bigger than the visible area.
Resizing the Window (JFrame) fixes the problem, as I assume Java is re-printing the components when they are resized.
As a test, I have added a debug-button that I can click after the startup of the program has finished. I am trying to force the JScrollPane to "refresh" itself.
I have tried doing:
scrollpane.repaint();
scrollpane.validate();
scrollpane.revalidate();
None of them seems to work. However, if I change the border (or any other layout related to the JScrollPane), it refreshes correctly.
scrollpane.setBorder(new LineBorder(Color.RED));
So I basically have 2 questions.
What is the command for forcing the scrollpane to "refresh"? Obviously it is doing some kind of "repaint" thing when I am adding the border. How can I run that only?
Is there a way of "pausing" the printing of components as they are added and resume it again after I added all the wanted components? As it is now, I basically "see" the components being added on the screen (even though it is really fast). It would be better if I can add all the components I want and THEN tell the program to print it to the screen/JFrame.
The basic code for adding components to a visible panel is:
panel.add(...);
panel.add(...);
panel.revalidate();
panel.repaint();
Adding a component does nothing because the component still has a zero size so there is nothing to paint. When you invoke the revalidate() method the layout manager gets invoked so components will now have a location/size. The repaint() will then paint the components. The revalidate() will also cause the scrollbars to show when required. This of course assumes you are using layout managers.
The components are added to the panel so you invoke the methods on the panel, not the scrollpane.
In my case only
frame.pack();
helped to get the scrollbars on the JScrollPane, when the enclosed JPanel was resized dynamically.
I have an application where I want that the user is able to choose between normal and advanced settings. Now if the user checks a JCheckBox and the advanced settings should disapper the problem starts.
My idea was to set all unnessecary swing components (JScrollPane, JLabel...) invisible and then find a method of JFrame which fits the window to the VISIBLE components.
My question is if there is such a method?
... and then find a method of JFrame which fits the window to the VISIBLE components. My question is if there is such a method?
Yes, there is such a method, and it is called pack().
This will cascade through the layout managers of all the containers held by the top-level window, asking them to re-lay out their visible components, resizing components to their preferred sizes as based on the components and the layout manager requirements, and eventually resizes the top-level window to fit the containers and their components.
1. You can use setVisible(boolean b), to make the component visible and invisible.
2. You can check that if the component is visible or not using isVisible()
3. You can then use the pack() method, pack() method gives sets the frame size as per need
I think you can wrap the advanced content in a panel (if possible) and remove that panel from frame using this.remove(component) then use this.pack()
and you can do the opposite on showing them, this.add(...) then this.pack() again
I'm having this strange issue with Swing. I have a main JPanel to which I am adding a JTabbedPane. Inside of this JTabbedPane I am adding another panel:
myTabbedPane.add(innerPanel, "Title", 0);
outerPanel.add(myTabbedPane);
Now, I no longer want myTabbedPane to be JTabbedPane, I want it to be a JPanel. When I change its type (and remove the extra params from its add() method), nothing within the outerPanel is visible anymore. (I am using setBounds() and I set the layouts to null).
Why does it work when using a tabbed pane but suddenly stop when switching to a JPanel? I know that this can be done differently (such as adding the innerPanel directly to the outerPanel), but please don't just tell me to do it differently. I'd just like to know why it suddenly doesn't work when using a JPanel instead. Is there an issue with adding a JPanel to a JPanel? Thanks!
Stop using null layout. Use BorderLayout and then use add inner panel to the center.
Tabbed pane used it own layered layout - that is why it worked before.
I'm using a JFrame in which the CENTER portion of the BorderLayout is occupied by a JScrollPane that wraps around a JPanel. What I'm finding is that when I initiate the action that actually causes the JPanel to be displayed, the display doesn't change. But when I resize the JFrame, the new JScrollPane has now magically appeared.
So what methods are called when you resize a JFrame? If I know, then I can call it in the code and avoid having to resize the frame just to see the results of the operation.
Its been a little bit since I've done swing, but from memory, calling validate() on the panel should do the trick. This will cause it and its children to have their layout calculated which is when the scrollbars decision is made. If that doesn't work, try calling validate on the frame's content pane. This is a little more costly, but may be needed if other components are being considered.