gpt4 book ai didi

java - 用于更新 JLabels 的多个线程

转载 作者:行者123 更新时间:2023-12-01 17:14:32 26 4
gpt4 key购买 nike

下面的代码是一个简单的JFrame,带有一个按钮和两个JLabel,代码的目标是更新“”号JLabel > 通过调用新线程,而不是尝试在 EDT 中执行此操作。

我的问题是,每次按下按钮时,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");
}
});
}
}

最佳答案

Use some flag to stop previous thread as simple as it is.

还有一件事是,下次单击按钮时,您不会更新 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;
}

}

关于java - 用于更新 JLabels 的多个线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22742612/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com