我的Java Swing应用程序启动时需要运行一些初始化代码,而不会触发任何事件。
我的初始化代码在myInits()
函数中。 myInits()
做了各种各样的事情:从文件中读取配置,设置背景和一些标签,生成网络线程,初始化变量。
从谷歌搜索和我自己的知识,我已经找到了不同的方法来实现这一点(如果下面的任何假设是错误的,请纠正我):
myInits()
事件时运行Window_Opened
。 这可确保GUI已绘制,myInits()
可以访问任何组件并进行更改。很遗憾,我无法使用此方法,因为我的应用程序开始隐藏,Window_Opened
没有被触发。
将myInits()
放在JFrame
构造函数中:
public class MyFrame extends javax.swing.JFrame {
private MyFrame(){
initComponents(); // <= Auto generated by NetBeans GUI Builder
myInits();
}
}
我认为这个方法没有错,因为initComponents()
本身会进行各种GUI操作。我使用这种方法,它工作得很好。
但是今天我将MyFrame
改为了Singleton,我得到了java.lang.ExceptionInInitializerError
。由于myInits()
调用MyFrame.getInstance()
并将其置于构造函数中,因此我在另一个getInstance()
内调用getInstance()
。我尝试制作getInstance()
synchronized
,但它没有成功。
制作myInits()
public
并从main()
拨打电话:
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new ChatFrame().myInits();
}
});
}
我个人不喜欢这种方法,因为我不希望myInits()
成为public
。还因为我更喜欢4号。
invokeLater
myInits()
。
private myFrame(){
initComponents();
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run(){
myInits();
}
});
}
这就是我自己想出来的。因为实例化本身是用invokeLater()
方法完成的(见第3号),我想我可以肯定myInits()
将在new myFrame();
完成之后运行,我可以安全地调用{{ 1}}。
总结一下:
1)所有这些方法都正确吗?
2)这些(或其他可能未提及的方法)中的任何一种是否被认为是最佳做法?
3)哪一个是Singleton JFrame的最佳实践?
4)为什么当我MyFrame.getInstance()
我的synchronized
方法时,我仍然得到getInstance()
?
答案 0 :(得分:0)
在我看来,如果你的初始化逻辑不是ui特定的,那么它应该在main中。从myinit中提取一个单独的类,并在main中调用它。
您也可以使用枚举使其成为单例,并使用它,以便在首次使用/应用程序加载时初始化。