尝试做门锁系统的界面开发,第一次接触到java界面,遇到了一些问题。
通常我们打开一个窗口1,点击一个按钮后弹出窗口2(窗口1没有关闭)。当我们把活动窗口再切换成窗口1并再点击之前的按钮时,应当是活动窗口切换成之前弹出的窗口2,而不是再生成一个窗口2。
然而,我在编写程序的时候遇到了该问题:重复点击窗口1中的按钮,生成多个窗口2。
如图所示:
是
public class myFrame extends JFrame{
JLabel label = new JLabel();
JButton button = new JButton("测试");
public myFrame(String title)
{
Container contentPane = this.getContentPane();
contentPane.setLayout(new FlowLayout());
contentPane.add(label);
contentPane.add(button);
buttonlistener btlt = new buttonlistener();
button.addActionListener(btlt);
}
public void showtime()
{
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:SS");
String timestr = sdf.format(new Date());
label.setText(timestr);
}
private class buttonlistener implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
showtime();
}
}
}
想把点击按钮的ActionListener中的myFrame frame = new myFrame()改成static类型的,奈何报错:Illegal modifier for the variable frame; only final is permitted
上网查阅资料后,得出原因:
在方法内部定义的叫“局部变量”,而不是静态变量,局部变量不能加static,以及protected,private,public。而全局变量是可以的。
为了解决这个问题,百度得出了一种解决办法:
singleton模式,即单例模式。通过单例模式的方法创建的类在当前进程中只有一个实例。
改写后的程序:
public class myFrame extends JFrame{
static JLabel label = new JLabel();
static JButton button = new JButton("测试");
private myFrame(String title)
{
buttonlistener btlt = new buttonlistener();
button.addActionListener(btlt);
}
private static volatile myFrame instance = null;
public static myFrame getmyFrame(String title)
{
if(instance == null)
{
synchronized(myFrame.class) {
if (instance == null) {
instance = new myFrame(title);
Container contentPane = instance.getContentPane();
contentPane.setLayout(new FlowLayout());
contentPane.add(label);
contentPane.add(button);
}
}
}
return instance;
}
public void showtime()
{
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:SS");
String timestr = sdf.format(new Date());
label.setText(timestr);
}
private class buttonlistener implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
showtime();
}
}
}
其中getmyFrame方法里的两个if嵌套的作用,我个人猜测可能是为了防止每次检测实例对象是否被创建的时候都要“synchronized”以下。
将构造方法设为私有成员方法,引出一个公有的静态方法getmyFrame(string),检测实例对象是否被创建,如果没被创建则创建一个并返回,如果已被创建,则返回当前实例对象。
结果:
点击大窗口的按钮,只会弹出一个小窗口,再次点击则还显示原来的小窗口,不会创建新的小窗口。