gpt4 book ai didi

java - 多线程计时器无法正常工作

转载 作者:行者123 更新时间:2023-12-02 02:31:06 24 4
gpt4 key购买 nike

再次请大家帮帮我!在下面的代码中,我想通过按下按钮插入计时器线程并将其输入到标签中来开始。每次按下按钮都会启动一个新线程并将其标记在每个标签上。但不幸的是,每个标签都写了相同的计时器。你能帮助我们把事情做好吗?如果你能告诉我错误是什么意思?

public class TimerThreads implements ActionListener{

JFrame jFrame = new JFrame();
JLabel[] labels;
int second = 0;
int minute = 0;
String s = "";
String m = "";
int l = 0;


public TimerThreads(){
JLabel one = new JLabel();
JLabel two = new JLabel();
JLabel three = new JLabel();
JLabel four = new JLabel();
labels = new JLabel[]{one, two, three, four};

jFrame.setLayout(new GridLayout(0, 2, 5, 5));
jFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

JButton start = new JButton("Start");
start.addActionListener(this);

JButton stop = new JButton("Stop");
stop.addActionListener(this);

jFrame.add(start);
jFrame.add(stop);
jFrame.setVisible(true);
jFrame.pack();
}

public static void main(String[] args) {
new TimerThreads();
}

@Override
public void actionPerformed(ActionEvent e) {
String select = e.getActionCommand();
switch(select){
case "Start":
jFrame.add(labels[l]);
jFrame.revalidate();
jFrame.repaint();
TimerThread t = new TimerThread(labels[l]);
t.start();
l++;
break;
case "Stop":
//
break;
}
}

class TimerThread extends Thread{
JLabel jLabel;

public TimerThread(JLabel jLabel) {
this.jLabel = jLabel;
}

@Override
public void run() {
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
second++;
if(String.valueOf(second).length() == 1){
s = "0";
}
else{
s = "";
}
if(second == 60){
second = 0;
s = "0";
minute++;
}

if(String.valueOf(minute).length() == 1){
m = "0";
}
jLabel.setText(m + String.valueOf(minute) + ":" + s + String.valueOf(second));
}
},0, 1000);
}
}
}

最佳答案

您的错误原因如下:

public class TimerThreads implements ActionListener {

JFrame jFrame = new JFrame();
JLabel[] labels;

// ***** these fields below
int second = 0;
int minute = 0;
String s = "";
String m = "";
// ***** these fields above

int l = 0;

这四个字段是该类的实例字段,由您创建的每个 TimerTask 实例共享,因此所有字段都将显示相同的确切时间。

解决方案是使这些字段成为嵌套类的本地字段:

public class TimerThreads implements ActionListener {

JFrame jFrame = new JFrame();
JLabel[] labels;
// int second = 0;
// int minute = 0;
// String s = "";
// String m = "";
int l = 0;

public TimerThreads() {
//.....
}

// ....


class TimerThread extends Thread {
JLabel jLabel;

public TimerThread(JLabel jLabel) {
this.jLabel = jLabel;
}

@Override
public void run() {
java.util.Timer timer = new java.util.Timer();
timer.scheduleAtFixedRate(new TimerTask() {

// ***** add these fields here
int second = 0;
int minute = 0;
String s = "";
String m = "";
<小时/>

话虽如此,您已经得到了有风险的代码,因为您在应该使用 Swing Timer 或 javax.swing.Timer 时使用了错误的 Timer(java.util.Timer)。这非常重要,因为后一个 Timer 可以很好地与 Swing 事件模型配合使用并防止线程冲突。请查看Swing Timer Tutorial

其他问题:使用固定大小的数组,如果用户希望运行 4 个以上的线程,则可能会出现索引越界异常的风险。请改用 ArrayList。

关于java - 多线程计时器无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47098829/

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