如果要使用Swing用Java编写桌面或Java Web Start程序,您可能会觉得需要通过创建自己的线程在后台运行某些东西。
没有什么可以阻止您在Swing中使用标准的多线程技术,并且需要遵循通常的注意事项。 如果您有多个线程访问相同的变量,则需要使用同步方法或代码块(或诸如AtomicInteger或ArrayBlockingQueue之类的线程安全类)。
但是,对于那些粗心的人来说是一个陷阱。 与大多数用户界面API一样,您无法从自己创建的线程更新用户界面。 好吧,正如每个Java本科生都知道的那样,您通常可以 ,但是您不应该。 如果这样做,有时您的程序会运行,而其他时候则无法。
您可以通过使用专门的SwingWorker类来解决此问题。 在本文中,我将向您展示即使您正在使用Thread类,如何使程序正常运行,然后我们将继续研究SwingWorker解决方案。
为了演示,我创建了一个Swing程序。
如您所见,它由两个标签和一个开始按钮组成。 此刻,单击开始按钮将调用一个不执行任何操作的处理程序方法。 这是Java代码:
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import java.util.concurrent.ExecutionException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
public class MainFrame extends JFrame {
private JLabel countLabel1 = new JLabel('0');
private JLabel statusLabel = new JLabel('Task not completed.');
private JButton startButton = new JButton('Start');
public MainFrame(String title) {
super(title);
setLayout(new GridBagLayout());
countLabel1.setFont(new Font('serif', Font.BOLD, 28));
GridBagConstraints gc = new GridBagConstraints();
gc.fill = GridBagConstraints.NONE;
gc.gridx = 0;
gc.gridy = 0;
gc.weightx = 1;
gc.weighty = 1;
add(countLabel1, gc);
gc.gridx = 0;
gc.gridy = 1