Thread sleep prevents my Swing application from ex

2019-03-04 01:29发布

问题:

What's is happening to my application makes sense but I don't know how to fix it. Here's a brief description of what my application does: A timer window should be display at the bottom right of my screen and show the live time. After an hour, it should do some action (I haven't decided the action yet). The problem I'm facing is that in Timer.java when I am refreshing the seconds for the live timer, I'm using thread sleep and this is preventing all my application to continue executing and therefor no window is showing.

Here's my code with some comments:
TimerFrame.java: The main frame of the application

import java.awt.BorderLayout;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;

import javax.swing.JFrame;

public class TimerFrame extends JFrame{
    public TimerFrame(String title) {
        // TItle and Layout
        super(title);
        setLayout(new BorderLayout());

        // Create the time panel and add it
        final TimerPanel tp = new TimerPanel();
        add(tp, BorderLayout.CENTER);

        // Timer is a class I've created, and it fires an event every second
        Timer time = new Timer();
        time.addTimeListener(new TimeListener() {
            public void refresh(String time) {
                tp.setText(time);
            }
        });

        // Configuration
        setSize(300,300);
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice defaultScreen = ge.getDefaultScreenDevice();
        Rectangle rect = defaultScreen.getDefaultConfiguration().getBounds();
        int x = (int) rect.getMaxX() - getWidth();
        int y = (int) rect.getMaxY() - getHeight();
        this.setLocation(x, y);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
}

TimePanel.java: The panel that should display the live time on the screen

import java.awt.Font;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class TimerPanel extends JPanel{

    private JLabel label;
    public TimerPanel() {
        label = new JLabel("Start Time");
        label.setFont(new Font("Arial",Font.BOLD,40));
        add(label);
    }

    public void setText(String text){
        label.setText(text);
    }
}

TimerListener.java: The Listener interface

public interface TimeListener {
    public void refresh(String time);
}

Timer.java: Gives the live time, and fires an event called refresh every second. In this calss, the thread.sleep() is causing my application to stop executing.

import java.text.SimpleDateFormat;
import java.util.Calendar;

public class Timer {
    private TimeListener sl = null;

    public Timer() {
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
        boolean start = true;
        int StartHour = 0;
        while(true){
            try {
                // Get current time
                Calendar cal = Calendar.getInstance();

                // Initialize Start hour
                if(start){
                    StartHour = getHour(cal, sdf);
                    start = false;
                }

                // Fire event
                if(sl != null)
                    sl.refresh(sdf.format(cal.getTime()));

                // If one hour
                if(getHour(cal, sdf) - StartHour == 1){
                    // Code goes here

                    // Reset start
                    start = true;
                }

                // Delay 1 Sec
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * Get Current Hour
     * @param cal Calentder
     * @param sdf Date format
     * @return Current Hour
     */
    public static int getHour(Calendar cal, SimpleDateFormat sdf){
        sdf.applyPattern("HH");
        int hour = Integer.parseInt(sdf.format(cal.getTime()));
        sdf.applyPattern("HH:mm:ss");
        return hour;
    }

    /**
     * Add Time Listener
     * @param sl TimeListener
     */
    public void addTimeListener(TimeListener sl){
        this.sl = sl;
    }
}

Does anyone know how to make my application execute while having a thread.sleep() that will run infinitely ? Thank you :)

回答1:

Does anyone know how to make my application execute while having a thread.sleep()

Don't use a Thread.sleep().

Instead use a Swing Timer. You set the Timer to fire every second so you components can be updated.



标签: java swing timer