简体   繁体   中英

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 .
It's quite a time since I last used Threads and now i searched for a long time and nothing worked for me...
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. Instead you call run() which runs it on the current thread and not in a background thread. To solve this, call start() on your Thread object, not run() .

so not:

tr.run();

but rather:

tr.start();

Other issues:

  • You're generally better off having classes implement Runnable rather than extend Thread.
  • You're trying to make Swing calls from a background thread which shouldn't be done. Almost all Swing method calls should be done on the Swing event thread or EDT. For more on this, please see: Concurrency in Swing .
  • One of your class names, Timer, is the same as a critical Swing class, the javax.swing.Timer class. I'd rename your class to avoid confusion, especially if you would want to use a 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. 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. Please check the Swing Timer tutorial .
  • 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. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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