以下代码是一个简单的JFrame
,带有一个按钮和两个JLabels
,代码的目标是通过调用一个新的Thread更新“JLabel
,而不是试图在美国东部时间做到这一点。
我的问题是每次按下按钮时run方法都会调用一个新线程,但是它不会取消旧的线程。因此,如果您按下按钮,并在几秒钟后再次按下它,您将有两个线程更新JLabel
,这看起来很糟糕。
问题声明:每次按下按钮,计数器必须从0开始,并且必须取消正在更新它的旧线程。
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;
gc.weightx = 1;
gc.weighty = 1;
add(statusLabel, gc);
gc.gridx = 0;
gc.gridy = 2;
gc.weightx = 1;
gc.weighty = 1;
add(startButton, gc);
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
start();
}
});
setSize(200, 400);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
private void start()
{
Thread worker = new Thread()
{
public void run()
{
// Simulate doing something useful.
for(int i=0; i<=10; i++) {
final int count = i;
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
countLabel1.setText(Integer.toString(count));
}
});
try
{
Thread.sleep(1000);
} catch (InterruptedException e)
{
}
}
SwingUtilities.invokeLater(new Runnable() {
public void run()
{
statusLabel.setText("Completed.");
}
});
}
};
worker.start();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new MainFrame("SwingWorker Demo");
}
});
}
}
答案 0 :(得分:3)
使用一些标志来停止前一个线程,就像它一样简单。
下次点击按钮时,您还没有更新statusLabel
。
试试这个
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
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");
private MyThread myThread;
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;
gc.weightx = 1;
gc.weighty = 1;
add(statusLabel, gc);
gc.gridx = 0;
gc.gridy = 2;
gc.weightx = 1;
gc.weighty = 1;
add(startButton, gc);
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
start();
}
});
setSize(200, 400);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
private void start() {
if (myThread != null) {
myThread.setRunning(false);
}
SwingUtilities.invokeLater(new Runnable() {
public void run() {
statusLabel.setText("Task not completed.");
}
});
myThread = new MyThread(countLabel1, statusLabel);
Thread thread = new Thread(myThread);
thread.start();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new MainFrame("SwingWorker Demo");
}
});
}
}
class MyThread implements Runnable {
public MyThread(JLabel countLabel1, JLabel statusLabel) {
this.countLabel1 = countLabel1;
this.statusLabel = statusLabel;
}
private boolean running = true;
private JLabel countLabel1, statusLabel;
public void run() {
// Simulate doing something useful.
for (int i = 0; i <= 10; i++) {
if (running) {
final int count = i;
SwingUtilities.invokeLater(new Runnable() {
public void run() {
if (running) {
countLabel1.setText(Integer.toString(count));
if (count == 10) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
statusLabel.setText("Completed.");
}
});
}
}
}
});
} else {
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
}
public boolean isRunning() {
return running;
}
public void setRunning(boolean running) {
this.running = running;
}
}
答案 1 :(得分:2)
检查此版本的代码。主要的新功能是实现Updater
的{{1}}类。看看它是如何在这里使用的。另请参阅Runnable
中的更改。另请参阅private void start()
类中的enabled
标志。
Updater