我正在编写一段代码,我准备了一个简单的示例:
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Example extends JFrame implements ActionListener {
public static void main(String[] args) {
Example e = new Example();
e.setVisible(true);
}
private JButton button;
public Example() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(600, 400);
this.setLayout(null);
button = new JButton("button");
button.setBounds(200, 150, 200, 50);
button.addActionListener(this);
this.add(button);
}
@Override
public void actionPerformed(ActionEvent actionEvent) {
button.setEnabled(false);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
问题是,我们有 actionPerformed
函数,它有两个操作:禁用按钮并运行 sleep
模仿我做的一些工作。
我的问题是那个按钮在 actionPerformed
结束,所以换句话说,在这5秒钟的睡眠之后,我不能更早地禁用它。我试着用它做些什么,但到目前为止改变了 button.setEnabled(false);
至 button.setEnabled(false); this.repaint(); this.validate();
什么都不做。
我的问题是:如何在swing中执行作业,首先需要禁用按钮,然后执行一些耗时的操作(例如睡眠)并在作业完成时启用按钮?
2条答案
按热度按时间lp0sw83n1#
那是因为你不能
Thread.sleep()
在同一个线程上创建ui,否则它将冻结ui直到睡眠结束。你想做的可能是使用一个swing计时器或者swing worker。
其他一些要点:
不要延伸
JFrame
不必要地上课不要使用null/
AbsoluteLayout
而是使用适当的布局管理器不要打电话
setBounds()
或者setSize()
在组件上,如果使用正确的布局管理器,这将为您处理呼叫
JFrame#pack()
在将框架设置为可见之前所有swing组件都应该通过
SwingUtilities.invokeLater
我也从来不喜欢实施ActionListener
在类的基础上,特别是如果您将有一个以上的组件注册ActionListener
.下面是使用
Timer
:6yjfywim2#
@大卫·克鲁坎普非常感谢,这就是我要找的。如果有人需要这里是简单的(但不是完美的,见托达维德的答案)的例子
Worker
```import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Example extends JFrame implements ActionListener {
public static void main(String[] args) {
Example e = new Example();
e.setVisible(true);
}
}