动态添加的 JPanel 未显示在 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<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);
}
}
如果有人能为我解决这个问题,我将不胜感激。谢谢。
Here's my code. I have no problem when showing up the previously designed frames (with panels added). I get this issue when adding panels to an empty JFrame dynamically.
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);
}
}
Appreciate if someone can spot this issue out for me. Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果将组件添加到容器中,则需要告诉容器的布局管理器通过调用
revalidate()
以及有时调用repaint();
来布局它们包含的所有组件> 在容器上。所以,就像...话虽如此,您的应用程序设计看起来有点不同。您真的使用 JFrame 的 ArrayList 吗?大多数现实世界的应用程序不使用一堆单独的窗口,而是在一个主窗口中交换显示,您可以通过仅使用一个 JFrame 并通过 CardLayout 交换视图来使用 Swing 执行类似的操作。
编辑2
如果您尝试怎么办:
同样,如果这没有帮助,那么您应该创建并发布“简短、独立、正确(可编译) ),示例”或 SSCCE
If you add a component to a container you need to tell the container's layout managers to layout all the components they contain by calling
revalidate()
and then by sometimes callingrepaint();
on the container. So, something like...Having said this, your application design looks a bit different. Do you really use an ArrayList of JFrames? Most real-world applications don't use a bunch of separate windows but rather swap displays in one main window, and you can do a similar thing with Swing by using just one JFrame and swap views via a CardLayout.
Edit 2
What if you try:
Again, if this doesn't help, then you should create and post a "Short, Self Contained, Correct (Compilable), Example" or SSCCE
这可行
但不是这个
This works
But not this