简体   繁体   English

Java JFrame卡在运行线程上

[英]Java JFrame gets stuck on running a thread

I have a maybe simple question. 我有一个简单的问题。 Obviously because my program does not do what it is supposed to... 显然是因为我的程序没有执行应有的功能...

First of all my code: 首先我的代码:

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();
        }
    }
}

So back to my problem: 回到我的问题:
If I run the program and hit the 'Go'-Button after entering some numbers the program gets stuck. 如果我运行该程序并在输入一些数字后按“开始”按钮,则程序将卡住。 I think the issue is caused by the while-loop in TThread . 我认为问题是由TThread的while循环引起的。
It's quite a time since I last used Threads and now i searched for a long time and nothing worked for me... 自从我上次使用Threads以来已经有一段时间了,现在我搜索了很长时间,没有任何结果适合我...
Hopefully someone can tell me what the issue is and can give a solution or some hints how to solve the problem. 希望有人可以告诉我问题所在,并且可以给出解决方案或一些提示来解决问题。

Greetings 问候
max. 最高

You never run the thread in a background thread by calling start() on it. 您永远不会通过在其上调用start()在后台线程中运行该线程。 Instead you call run() which runs it on the current thread and not in a background thread. 而是调用run()在当前线程而不是在后台线程中运行它。 To solve this, call start() on your Thread object, not run() . 要解决此问题,请在您的Thread对象上调用start() ,而不是run()

so not: 所以不是:

tr.run();

but rather: 反而:

tr.start();

Other issues: 其他事宜:

  • You're generally better off having classes implement Runnable rather than extend Thread. 通常最好让类实现Runnable,而不是扩展Thread。
  • You're trying to make Swing calls from a background thread which shouldn't be done. 您正在尝试从后台线程进行Swing调用,这不应该完成。 Almost all Swing method calls should be done on the Swing event thread or EDT. 几乎所有的Swing方法调用都应在Swing事件线程或EDT上完成。 For more on this, please see: Concurrency in Swing . 有关更多信息,请参见: Swing中的并发
  • One of your class names, Timer, is the same as a critical Swing class, the javax.swing.Timer class. 您的类名称之一Timer与关键的Swing类javax.swing.Timer类相同。 I'd rename your class to avoid confusion, especially if you would want to use a Swing Timer. 我将重命名您的班级以避免混淆,特别是如果您想使用Swing Timer。
  • And in fact on view of your code, I think that you would be much better off using a Swing Timer instead of a background Thread for your application. 而且实际上,从您的代码来看,我认为您最好为应用程序使用Swing计时器而不是后台线程。 This is a much easier way to do your timer animation and makes it much easier to ensure that Swing calls are made on the Swing event thread. 这是制作计时器动画的一种简单得多的方法,并且可以更轻松地确保在Swing事件线程上进行Swing调用。 Please check the Swing Timer tutorial . 请查看Swing Timer教程
  • You are using null layout. 您正在使用空布局。 While to a newbie a null layout often appears to be the best way to easily create complex GUI's, as you gain more Swing GUI experience you will find that actually the opposite is true. 尽管对于新手来说,空布局通常是轻松创建复杂GUI的最佳方法,但是随着您获得更多的Swing GUI经验,您会发现事实恰恰相反。 If you use layout managers, often nesting JPanels, each with its own layout manager, you can more easily create complex, beautiful GUI's, that easily resize, that look good on all platforms, and that are much easier to maintain, debug and enhance. 如果使用布局管理器(通常嵌套JPanels),每个布局管理器都有自己的布局管理器,则可以更轻松地创建复杂,漂亮的GUI,易于调整大小,在所有平台上看起来都很好,并且更易于维护,调试和增强。

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

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