开发者

Adding additional panels to a JFrame which lives in a EventDispath thread, from outside that?

开发者 https://www.devze.com 2023-04-11 18:09 出处:网络
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

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(开发者_StackOverflow社区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 this JPanel is placed to the CENTER area and occupated whole JFrame, and in BorderLayout only one JComponent could be placed to the concrete area, then you will call only (no remove, any reason for that)

myFatherPanel.add(myPanel, BorderLayout.PAGE_START);
revalidate();
repaint();

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 remove JComponents from this FatherPanel, because if you calling for JFrame#removeAll(), then you removed RootPane, and from your JFrame stays there only Borders same as you decribed


What else? Also with:

SwingUtilities.invokeLater(new Runnable() {
                public void run() { ... }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消