我的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();
完成后运行,并且我可以安全地调用MyFrame.getInstance()
。把它们加起来:
1)所有这些方法正确吗?
2)是否将其中任何一种(或我可能未提及的其他可能方法)视为最佳实践?
3)Singleton JFrame的最佳做法是哪一种?
4)为什么当我
synchronized
我的getInstance()
方法时我仍然得到java.lang.ExceptionInInitializerError
? 最佳答案
我认为,如果您的初始化逻辑不是特定于ui的,那么它应该是主要的。从myinit中提取一个单独的类,然后在main中调用它。
您也可以使用枚举使它成为单例,然后使用它,以便在首次使用/应用程序加载时对其进行初始化。