您可以扩展SwingWorker类甚至 Thread 来实现您希望复选框控制的功能。创建方法contiueWorking()
并stopWorking()
在运行方法中检查一些布尔标志以查看是执行任务还是休眠。正如 Robin 在下面的帖子中评论的那样,swing 组件只能从事件工作线程访问。我在下面的示例中违反了这条规则,因为我想产生一些简单的东西,并且由于正在运行的线程大部分时间都在休眠,所以它工作正常。
我会使用 SwingWorker 来完成一项更耗时的任务,我希望在执行时更新用户。例如,假设我们有一个线程生成然后发送一组电子邮件消息,并且对于每封电子邮件,在 UI 中显示一些文本,以确认消息已发送或指示无法发送的原因。每条消息都可能将线程锁定一段时间。UI 不会与线程执行电子邮件任务同步更新。SwingWorker 来救援。java2s.com 站点有一个SwingWokerDemo。
import java.awt.BorderLayout;
import javax.swing.*;
import java.awt.event.*;
import java.util.ArrayList;
/**
* The sequence of prime integers is calculated and displayed on the screen.
* This little program demonstrates how a checkbox can be used
* to start and stop a thread.
*/
public class ThreadDemo extends JFrame {
JCheckBox runningCB;
JTextArea displayArea;
JTextField delayField;
PrimeCalcThread workerThread = null;
public ThreadDemo() {
super("Prime Numbers");
runningCB = new JCheckBox("Calculate Primes");
JPanel topPanel = new JPanel();
topPanel.add(runningCB);
topPanel.add(new JLabel("Dealy: "));
delayField = new JTextField(10);
delayField.setText("500");
topPanel.add(delayField);
getContentPane().add(topPanel,BorderLayout.NORTH);
displayArea = new JTextArea(30,80);
displayArea.setText("2, 3, 5, ");
displayArea.setLineWrap(true);
JScrollPane scroller = new JScrollPane(displayArea);
getContentPane().add(scroller,BorderLayout.CENTER);
pack();
runningCB.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(runningCB.isSelected() ) {
if(workerThread != null)
workerThread.contiueWorking();
else {
workerThread = new PrimeCalcThread();
workerThread.start();
}
}
else {
if(workerThread != null)
workerThread.stopWorking();
}
}
});
delayField.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String input = delayField.getText().trim();
try {
int d = Integer.parseInt(input);
workerThread.setDelay(d);
}
catch(NumberFormatException nfe) { }
}
});
setVisible(true);
}
public static void main(String[] arg) {
ThreadDemo window = new ThreadDemo();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
/**
* When this thread is active it calculates prime numbers. The Thread
* continues until it is paused with stopWorking() or until the
* boolean field endThread is set to true.
*/
class PrimeCalcThread extends Thread {
ArrayList<Integer> primeList;
int delay = 500;
boolean active = true;
boolean endThread = false;
private int lastPrime;
public PrimeCalcThread() {
primeList = new ArrayList<> (1024);
primeList.add(2); primeList.add(3); primeList.add(5);
lastPrime=5;
}
public void run() {
while(!endThread) {
if(active) {
calcNextPrime();
displayArea.append(lastPrime + ", ");
}
try { sleep(delay); }
catch(InterruptedException whatever) { }
}
}
private void calcNextPrime() {
int p = lastPrime+2;
while(!isPrime(p))
p+=2;
primeList.add(p);
lastPrime = p;
}
/**
* Checks if p is prime by checking for divisibility by all primes in the
* calculated primeList so far. This method only works if sqrt(p) < lastPrime
*/
private boolean isPrime(int p) {
int maxCheck = (int) Math.sqrt(p) + 1;
for(int prime: primeList) {
if(p % prime == 0)
return false;
if(prime > maxCheck)
break;
}
return true;
}
public int getLastPrime() {
return lastPrime;
}
public ArrayList<Integer> getPrimeList() {
return primeList;
}
public int getDelay() {
return delay;
}
public void setDelay(int waitTime) {
if(waitTime>=0)
delay = waitTime;
}
public void contiueWorking() {
active=true;
}
public void stopWorking() {
active=false;
}
}
}