繁体   English   中英

Java JFrame卡在运行线程上

[英]Java JFrame gets stuck on running a thread

我有一个简单的问题。 显然是因为我的程序没有执行应有的功能...

首先我的代码:

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
import javax.swing.plaf.nimbus.NimbusLookAndFeel;

public class Timer 
        extends JFrame
        implements ActionListener
{

    protected class TThread extends Thread{
        private boolean running = false;
        @Override
        public void run() {
            int timer = 10,
                index = 0;
            running = true;
            while(running){
                try {
                    out.setText(timer + " Secs");
                    timer--;
                    if(timer == 0){
                        if(index % 2 == 0){
                            timer = ti1;
                            out.setBackground(Color.red);
                        }else{
                            timer = ti2;
                            out.setBackground(Color.green);
                        }
                        index++;
                    }
                    sleep(1000L);
                } catch (InterruptedException e) {
                }
            }
        }
        @Override
        public void interrupt() {
            running = false;
        }
    }

    private static final long serialVersionUID = 1L;
    private JTextField t1 = new JTextField(),
                       t2 = new JTextField();
    private int ti1 = 0, ti2 = 0;
    private JLabel l1 = new JLabel("Zeit 1"),
                   l2 = new JLabel("Zeit 2"),
                   out = new JLabel("00 Secs", SwingConstants.CENTER);
    private JButton go = new JButton("Go"),
                    stop = new JButton("Stop");
    private JPanel cont = new JPanel();
    private TThread tr = new TThread();

    public Timer() {
        super("Timer");
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setSize(800, 600);
        setLayout(null);
        add(cont);
            cont.setBounds(0, 0, getWidth(), 200);
            cont.setLayout(new GridLayout(3, 2));
            cont.add(l1);
            cont.add(t1);
            cont.add(l2);
            cont.add(t2);
            cont.add(go);
                go.addActionListener(this);
            cont.add(stop);
                stop.addActionListener(this);
        add(out);
            out.setBounds(0, 200, getWidth(), getHeight()-200);
            out.setFont(new Font("Arial", Font.BOLD, 72));

        try {
            UIManager.setLookAndFeel(new NimbusLookAndFeel());
            SwingUtilities.updateComponentTreeUI(this);
        } catch (UnsupportedLookAndFeelException e) {
        }
    }

    public static void main(String[] args) {
        Timer t = new Timer();
        t.setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource().equals(go)){
            ti1 = Integer.parseInt(t1.getText());
            ti2 = Integer.parseInt(t2.getText());
            tr.run();
        }else if(e.getSource().equals(stop)){
            tr.interrupt();
        }
    }
}

回到我的问题:
如果我运行该程序并在输入一些数字后按“开始”按钮,则程序将卡住。 我认为问题是由TThread的while循环引起的。
自从我上次使用Threads以来已经有一段时间了,现在我搜索了很长时间,没有任何结果适合我...
希望有人可以告诉我问题所在,并且可以给出解决方案或一些提示来解决问题。

问候
最高

您永远不会通过在其上调用start()在后台线程中运行该线程。 而是调用run()在当前线程而不是在后台线程中运行它。 要解决此问题,请在您的Thread对象上调用start() ,而不是run()

所以不是:

tr.run();

反而:

tr.start();

其他事宜:

  • 通常最好让类实现Runnable,而不是扩展Thread。
  • 您正在尝试从后台线程进行Swing调用,这不应该完成。 几乎所有的Swing方法调用都应在Swing事件线程或EDT上完成。 有关更多信息,请参见: Swing中的并发
  • 您的类名称之一Timer与关键的Swing类javax.swing.Timer类相同。 我将重命名您的班级以避免混淆,特别是如果您想使用Swing Timer。
  • 而且实际上,从您的代码来看,我认为您最好为应用程序使用Swing计时器而不是后台线程。 这是制作计时器动画的一种简单得多的方法,并且可以更轻松地确保在Swing事件线程上进行Swing调用。 请查看Swing Timer教程
  • 您正在使用空布局。 尽管对于新手来说,空布局通常是轻松创建复杂GUI的最佳方法,但是随着您获得更多的Swing GUI经验,您会发现事实恰恰相反。 如果使用布局管理器(通常嵌套JPanels),每个布局管理器都有自己的布局管理器,则可以更轻松地创建复杂,漂亮的GUI,易于调整大小,在所有平台上看起来都很好,并且更易于维护,调试和增强。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM