【问题标题】:Multithreading program not working多线程程序不工作
【发布时间】:2013-04-14 11:25:09
【问题描述】:

我正在努力完成这项工作。我创建了一个带有一个文本字段和按钮的窗口,然后运行 ​​run() 方法,该方法应该刷新文本字段中的文本,当我单击按钮时,它应该将数字迭代 1。我想同时进行这项工作,但我被卡住了。它只是迭代数字但不刷新文本字段中的值。你能帮我吗?我认为它很容易学习线程,但是......没有:-D 这是代码。

窗口类

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton; 
import javax.swing.JFrame;
import javax.swing.JTextField;

@SuppressWarnings("serial") 
public class Okno extends JFrame implements ActionListener,Runnable {

    private JFrame o = new JFrame();
private static JTextField t = new JTextField();
private JTextField t2 = new JTextField();
private static int x = 0;
protected JButton b = new JButton("KLIK");


Okno() {

    o.setVisible(true);
    o.setBounds(0, 0, 300, 200);
    o.setLayout(null);
    o.setDefaultCloseOperation(EXIT_ON_CLOSE);

    t.setBounds(10, 10, 60, 20);
    t2.setBounds(80, 10, 60, 20);
    b.setBounds(50, 80, 60, 30);
    b.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            while (true) {
                Okno.work();
                System.out.println("Klik");
            }

        }
    });
    o.add(t);
    o.add(b);
    o.add(t2);
}
public static int iter(){

    x++;
    return x;
}

public static void work(){
    try {
        iter();
        System.out.println(x);
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
@Override
public void actionPerformed(ActionEvent e) {

}
@Override
public void run() {
    while(true){
        try {
            Thread.sleep(1200);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    t.setText(Integer.toString(x));
    System.out.println("RUN");
    }
}
    }

主类

public class ThreadDemo {
public static void main(String args[]) {
 Okno o = new Okno();

 while(true){
 o.run();
 }
 }
 }

【问题讨论】:

  • 您的代码通过尝试在后台线程上进行 Swing 调用并在 Swing 事件线程上调用 Thread.sleep(...) 来忽略 Swing 线程规则。使用 Swing 计时器(根据答案)或使用 SwingWorker 以确保 Swing 方法调用仅在 Swing 事件线程上进行。您应该能够找到涵盖此内容的教程。
  • 感谢D先生的建议!我坚持了几个小时,这可能会解决问题。

标签: java multithreading swing


【解决方案1】:

Swing 是单线程的。调用 Thread.sleep 会阻止 UI 更新。请改用Swing Timer

来自 GETah 对java stopwatch that updates gui every second 的回复:

应该这样做:

import java.awt.EventQueue;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JFrame;
import javax.swing.JLabel;

/** @see https://stackoverflow.com/a/11058263/230513 */
public class Clock {

    private Timer timer = new Timer();
    private JLabel timeLabel = new JLabel(" ", JLabel.CENTER);

    public Clock() {
        JFrame f = new JFrame("Seconds");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(timeLabel);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
        timer.schedule(new UpdateUITask(), 0, 1000);
    }

    private class UpdateUITask extends TimerTask {

        int nSeconds = 0;

        @Override
        public void run() {
            EventQueue.invokeLater(new Runnable() {

                @Override
                public void run() {
                    timeLabel.setText(String.valueOf(nSeconds++));
                }
            });
        }
    }

    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                final Clock clock = new Clock();
            }
        });
    }
}

timeLabel 将始终显示计时器的秒数 一直在运行。

  1. 您需要正确格式化它以显示“hh:mm:ss”;显示了一种方法here

  2. 创建一个容器并为其添加标签,以便您可以将其显示为 GUI 的一部分。

  3. 使用javax.swing.Timer将结果与alternate进行比较。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-30
    • 2011-04-04
    • 2021-05-21
    • 2014-04-04
    • 1970-01-01
    • 1970-01-01
    • 2020-10-06
    • 1970-01-01
    相关资源
    最近更新 更多