动态添加的JPanels没有出现在Swing中

cod*_*er9 2 java user-interface swing jpanel jframe

这是我的代码.显示先前设计的框架(添加了面板)时没有问题.我在动态地向空JFrame添加面板时遇到此问题.

package com.mytunes.controllers;

import com.mytunes.views.*;
import com.mytunes.views.panels.*;
import java.awt.BorderLayout;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.WindowConstants;


public class GUIController {
    ArrayList<JFrame> displayFrames = new ArrayList<JFrame>();

    JPanel displayPanel;
    HeaderPanel headerPanel = new HeaderPanel();
    FooterPanel footerPanel = new FooterPanel();


    public int showFrame(String frameName, Object controller){
        Class c;
        Constructor ctr;
        int lastFrame = -1;

        try {

           // call a class dynamically
           c = Class.forName("com.mytunes.views.frames." + frameName + "Frame");
           // calll a constructor of a class
           ctr = c.getConstructor(SessionController.class);
           // instantiate dynamically created class
           displayFrames.add((JFrame) ctr.newInstance(controller));

           // get the index of frame just added
           lastFrame = displayFrames.size()-1;

           displayFrames.get(lastFrame).setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
           displayFrames.get(lastFrame).pack();
           displayFrames.get(lastFrame).setLocationRelativeTo(null);

           // hide it by default. 
           displayFrames.get(displayFrames.size()-1).setVisible(false);

        } 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) {
            JOptionPane.showMessageDialog(null, "Error while loading class 'com.mytunes.view.frames." + frameName + "'" );
        }

        System.out.println(lastFrame);
        return lastFrame;

    }

    //-------------show panels --------------//
     public void showOperator(String frame, Object controller){

        // this works fine! this frame is already having Panels
        int f = showFrame(frame, controller);
        displayFrames.get(f).setVisible(true);
     }
    public void showEnterPIN(String frame, Object controller){


        int f = showFrame(frame, controller);
        displayFrames.get(f).getContentPane().add(new EnterPINPanel(), BorderLayout.CENTER);
        displayFrames.get(f).setVisible(true);

        //        Try every following ways to show the "Dynamically added" panels
        //        displayFrames.get(f).getContentPane().removeAll();
        //        displayFrames.get(f).getContentPane().invalidate();
        //        displayFrames.get(f).getContentPane().add(new EnterPINPanel(), BorderLayout.PAGE_START);
        //        displayFrames.get(f).getContentPane().validate();
        //        displayFrames.get(f).pack();
        //        displayFrames.get(f).setVisible(true);

    }

}
Run Code Online (Sandbox Code Playgroud)

感谢有人能为我发现这个问题.谢谢.

Hov*_*els 5

如果将组件添加到容器中,则需要告诉容器的布局管理器通过调用revalidate()然后通过调用repaint();容器来布局它们包含的所有组件.所以,像......

JPanel contentPane = (JPanel)displayFrames.get(f).getContentPane();
contentPane.add(new EnterPINPanel(), BorderLayout.CENTER);
contentPane.revalidate();
contentPane.repaint();
Run Code Online (Sandbox Code Playgroud)

话虽如此,您的应用程序设计看起来有点不同.你真的使用JFrames的ArrayList吗?大多数真实世界的应用程序不使用一堆独立的窗口,而是在一个主窗口中交换显示,你可以通过使用一个JFrame和通过CardLayout交换视图来使用Swing做类似的事情.

编辑2
如果您尝试怎么办?

  int f = showFrame(frame, controller);
  JPanel contentPane = (JPanel)displayFrames.get(f).getContentPane();
  contentPane.removeAll();
  contentPane.setLayout(new BorderLayout()); // just to be sure
  contentPane.add(headerPanel, BorderLayout.PAGE_START);
  contentPane.add(new EnterPINPanel(), BorderLayout.CENTER);
  contentPane.add(footerPanel, BorderLayout.PAGE_END);
  contentPane.revalidate(); // *** note that it's **re**validate
  contentPane.repaint();
  displayFrames.get(f).setVisible(true);
Run Code Online (Sandbox Code Playgroud)

再次,如果这没有帮助,那么你应该创建并发布"短,自包含,正确(可编译),示例"或SSCCE

  • 从[如何以聪明的方式提问](http://catb.org/~esr/faqs/smart-questions.html):准确了解代码问题的最有效方法是提供最小的bug演示测试用例.什么是最小的测试用例?这是问题的一个例子; 只需足够的代码来展示不良行为,而不是更多.考虑创建和发布[SSCCE](http://sscce.org). (2认同)