从外部向位于 EventDispath 线程中的 JFrame 添加附加面板?
我在 EventDispatch 线程中创建一个新框架,并希望稍后向其中添加新面板。但我得到的只是一个空白框,高度为 0。但会显示从内部类内部添加的面板。如何使用 showFirstFrame() 添加? 遇到此问题后,我必须遵循这样的方法: 当在 Java 中调用 wait() 时,所有 Swing 框架都会“冻结”
我一直在参考本教程:http://leepoint.net/JavaBasics/gui/gui-commentary/ guicom-main-thread.html
提前致谢。
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);
}
}
编辑:
...
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");
}
}
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");
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您只想在两个 JPanel 之间切换,请不要以这种方式重新创建 GUI 里面 JFrame 那么你有两个非常简单的选择
1) JFrame 默认有 BorderLayout,如果你把有
JPanel
(add.myPanel;
) 然后这个JPanel
被放置到CENTER
区域并占据整个JFrame
,并且在BorderLayout
中,只能将一个JComponent
放置到具体区域,那么您将仅调用(不删除,任何原因) )2) 最重要的是使用 CardLayout,然后你就可以忘记了GUI 的所有问题
3) 更安全的方法是放置(到
JFrame
)FatherPanel(从未被删除)并从此FatherPanel< 中删除
JComponents
/code>,因为如果您调用JFrame#removeAll()
,那么您就删除了RootPane
,并且JFrame
中仅保留>边框
和你描述的一样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 thisJPanel
is placed to theCENTER
area and occupated wholeJFrame
, and inBorderLayout
only oneJComponent
could 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 removeJComponents
from thisFatherPanel
, because if you calling forJFrame#removeAll()
, then you removedRootPane
, and from yourJFrame
stays there onlyBorders
same as you decribed还有什么?还带有:
What else? Also with: