I create a new frame in EventDispatch thread and want to add new Panels to that later on. But all i get is a blank frame, with 0 height. But panels added from inside the inner class are displayed. How to add using showFirstFrame()?
I had to follow such an approach after getting this issue: All the Swing frames get "frozen" when wait() is called in Java
I’ve been referring to this tutorial: http://leepoint.net/JavaBasics/gui/gui-commentary/guicom-main-thread.html
Thanks in advance.
public class GUIController {
JFrame bf;
JFrame tempFrame;
public JFrame showFrame(){
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
Class c;
Constructor ctr;
c = Class.forName("SomeJFrame");
ctr = c.getConstructor();
GUIController.this.bf.removeAll();
GUIController.this.bf = (BaseFrame) ctr.newInstance();
GUIController.this.bf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
GUIController.this.bf.pack();
GUIController.this.bf.setVisible(true);
} catch (InstantiationException ex) {
Logger.getLogger(GUIController.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
Logger.getLogger(GUIController.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalArgumentException ex) {
Logger.getLogger(GUIController.class.getName()).log(Level.SEVERE, null, ex);
} catch (InvocationTargetException ex) {
Logger.getLogger(GUIController.class.getName()).log(Level.SEVERE, null, ex);
} catch (NoSuchMethodException ex) {
Logger.getLogger(GUIController.class.getName()).log(Level.SEVERE, null, ex);
} catch (SecurityException ex) {
Logger.getLogger(GUIController.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(GUIController.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
return GUIController.this.bf;
}
public void showFirstFrame(){
tempFrame = showFrame();
tempFrame .getContentPane().add(headerPanel, BorderLayout.PAGE_START);
tempFrame .getContentPane().add(new EnterSomePanel(), BorderLayout.CENTER);
tempFrame .getContentPane().add(footerPanel, BorderLayout.PAGE_END);
tempFrame .setVisible(true);
}
}
EDIT:
...
class GUIController {
HeaderPanel headerPanel = new HeaderPanel(); // extends JPanel
FooterPanel footerPanel = new FooterPanel();
BaseFrame bf = new BaseFrame(); // extends JFrame
public BaseFrame showFrame(String frameName){
try {
Class c;
Constructor ctr;
c = Class.forName("some.dynamically.loaded.JFrame" + frameName);
ctr = c.getConstructor();
bf = (BaseFrame) ctr.newInstance();
bf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
bf.pack();
bf.setVisible(true);
} catch (InstantiationException ex) {
Logger.getLogger(GUIController.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
Logger.getLogger(GUIController.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalArgumentException ex) {
Logger.getLogger(GUIController.class.getName()).log(Level.SEVERE, null, ex);
} catch (InvocationTargetException ex) {
Logger.getLogger(GUIController.class.getName()).log(Level.SEVERE, null, ex);
} catch (NoSuchMethodException ex) {
Logger.getLogger(GUIController.class.getName()).log(Level.SEVERE, null, ex);
} catch (SecurityException ex) {
Logger.getLogger(GUIController.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(GUIController.class.getName()).log(Level.SEVERE, null, ex);
}
return bf;
}
public void showFirstFrame(final String frame){ //some controller will pass a frame name to this
bf = showFrame(frame);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
bf.getContentPane().add(headerPanel, BorderLayout.PAGE_START);
bf.invalidate();
bf.validate();
System.out.println("test");
}
});
}
}
class Main{
public static void main(String args[]){
GUIController c = new GUIController();
c.showFirstFrame("FirstFrame");
}
}
don’t recreate GUI this way, if you want ot only switch betweens two JPanels inside JFrame then you have two very simple choises
1) JFrame has by defalut BorderLayout, and if you put there
JPanel(add.myPanel;) then thisJPanelis placed to theCENTERarea and occupated wholeJFrame, and inBorderLayoutonly oneJComponentcould be placed to the concrete area, then you will call only (no remove, any reason for that)2) and best of all would be lay your GUI by using CardLayout, then you can pretty to forgot about all problems with your GUI
3) more safer would be to place (to the
JFrame) FatherPanel (that never has been removed) and removeJComponentsfrom thisFatherPanel, because if you calling forJFrame#removeAll(), then you removedRootPane, and from yourJFramestays there onlyBorderssame as you decribed