Reputation: 137
I have a relatively small class called "LoadingWindow" this class has a constructor that calls a Initialize function to setup the frame. Not I was testing some things to try to solve why it would not update. While testing I added "this.removeAll();" to the head of the initialize method. Turns out, I cant add anything after that. Anything I add, simply will not show.
Here is a slightly trimmed down version of the class:
public class LoadingWindow extends JFrame{
public JPanel panel;
public JProgressBar bar;
private JLabel label;
public LoadingWindow()
{
this.Initialize();
}
public void Initialize()
{
this.removeAll();
this.setSize(300, 150);
panel = new JPanel(new BorderLayout());
bar = new JProgressBar(0,100);
label = new JLabel("Please remain calm, we're just loading...");
panel.add(bar,BorderLayout.CENTER);
panel.add(label,BorderLayout.SOUTH);
this.add(panel);
this.validate();
this.repaint();
this.setVisible(true);
}
}
The window itself does pop up properly, with a title. However the window itself is completely blank.
I implement this class statically so that four other objects can access it in the EditorPanel class. Its defined as:
public static LoadingWindow loadingWindow;
and initialized in the constructor with:
loadingWindow = new LoadingWindow();
There is then a double check within the functions that use it to show it if it is hidden.
if(!EditorPanel.loadingWindow.isVisible()){EditorPanel.loadingWindow.Initialize();}
Overall I'm a bit confused as to why no content is showing, and I am very interested in any questions asked, and am willing to provide any info necessary. Google didn't provide a whole lot, and every answer I found I had already implemented "such as repaint and validate".
I look forward to hearing from you!
~Travis
Upvotes: 4
Views: 4163
Reputation: 36423
removeAll()
as said by @TomHawtintackline (+1 to him), is not forwarded to the JFrames
contentPane; like add()
, remove()
or setLayout()
is.
Thus when you do JFrame#removeAll()
it removes the root pane of JFrame
. See How to Use Root Panes for an interesting read and may prove fruitful for future endeavors.
You should do:
getContentPane().removeAll();// will make sure we remove all components from the contentPane
Also dont extend JFrame
unnecessarily (unless adding functionality beyond its current capability) rather just create an instance of JFrame
and use that
Dont call setSize
rather use an appropriate LayoutManager
and/or override getPreferredSize()
of JPanel
and return dimensions which fit drawings, thus you can call pack()
on JFrame
before setting it visible.
I see no need for validate()
and repaint()
these should only be called when a component is added to a visible container. Even than rather do revalidate()
which will work for adding and removing a component (it inturn calls validate()
)
Upvotes: 14
Reputation: 147164
I am guessing removeAll
removes the root pane.
JFrame
is a container and contains a number of components that are part of what we think of as the frame. There was a hack introduced into JFrame
(and JApplet
), so that some methods act on the content pane instead of the frame itself. Use a different method, or one of the special methods when the forwarding is not in force, and it'll screw up.
See the API docs for JFrame.remove
and note that removeAll
is not overridden.
The safest solution is to ignore the "helpful" forwarding, and manipulate the content pane itself (either through getContentPane
, or possible better create your own JPanel
and use setContentPane
). (Also don't extend classes, such as JFrame
or Thread
, unnecessarily and follow standard coding conventions.)
Upvotes: 3