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

这是我的代码。 显示先前设计的框架(添加了面板)时没有问题。 我在动态地向空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 displayFrames = new ArrayList(); 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); } } 

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

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

 JPanel contentPane = (JPanel)displayFrames.get(f).getContentPane(); contentPane.add(new EnterPINPanel(), BorderLayout.CENTER); contentPane.revalidate(); contentPane.repaint(); 

话虽如此,您的应用程序设计看起来有点不同。 你真的使用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); 

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

这很有效

  JFrame contentPane = new JFrame(); contentPane.getContentPane().add(new EnterPINPanel(), BorderLayout.CENTER); contentPane.setVisible(true); 

但不是这个

 int f =  displayFrames.get(f).getContentPane().add(headerPanel, BorderLayout.PAGE_START); displayFrames.get(f).getContentPane().add(new EnterPINPanel(), BorderLayout.CENTER); displayFrames.get(f).getContentPane().add(footerPanel, BorderLayout.PAGE_END); displayFrames.get(f).getContentPane().validate(); displayFrames.get(f).getContentPane().repaint(); displayFrames.get(f).setVisible(true);