Using Timer To Pause Program Execution [duplicate]

2019-02-20 14:34发布

This question already has an answer here:

I want to pause the execution of a Swing Program for a specified amount of time. Naturally the first thing that I used was Thread.sleep(100) (since, I am a noob). Then I got to know that my program is not thread safe so I decided to use Timer with some suggestions from fellow programmers. The problem is I am unable to get any sources from where I can learn how to delay the thread, using Timer. Most of them use Timer for delaying execution. Please help me solve this problem. I have provided a compileable code snippet below.

import javax.swing.*;
import java.awt.*;

public class MatrixBoard_swing extends JFrame{

    public static void main(String[] args){
        SwingUtilities.invokeLater(new Runnable() {
          public void run() {
            MatrixBoard_swing b = new MatrixBoard_swing();      
          }
       });
    }

    MatrixBoard_swing(){
        this.setSize(640, 480);
        this.setVisible(true);
        while(rad < 200){
            repaint();
            rad++;
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
    }

    int rad = 10;

    public void paint(Graphics g){
        super.paint(g);
        g.drawOval(400-rad, 400-rad, rad, rad); 
    }

}

EDIT: My trial for a Timer implementation(please tell me if it is wrong):

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class MatrixBoard_swing extends JFrame implements ActionListener{

    Timer timer;

    public static void main(String[] args){
        SwingUtilities.invokeLater(new Runnable() {
          public void run() {
            MatrixBoard_swing b = new MatrixBoard_swing();      
          }
       });
    }

    MatrixBoard_swing(){
        this.setSize(640, 480);
        this.setVisible(true);
        timer = new Timer(100, this);
        timer.start();
    }

    int rad = 10;

    public void paint(Graphics g){
        super.paint(g);
        g.drawOval(400-rad, 400-rad, rad, rad); 
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
        repaint();
        rad++;
        if(rad >= 200){
            timer.stop();
        }
    }

1条回答
Bombasti
2楼-- · 2019-02-20 15:14

So instead of...

while(rad < 200){
    repaint();
    rad++;
    try {
        Thread.sleep(100);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

You simply need to turn the logic around a little...

Timer timer = new Timer(1000, new ActionListener() {
    public void actionPerformed(ActionEvent evt) {
        rad++;
        if (rad < 200) {
            repaint();
        } else {
            ((Timer)evt.getSource()).stop();
        }
    }
});
timer.start();

Basically, the Timer will act as the Thread.sleep(), but in a nice way that doesn't break the UI, but will allow you to inject a delay between execution. Each time it executes, you need to increment your value, test for the "stop" condition and update otherwise...

Take a look at How to Use Swing Timers and the other 3, 800 questions on the subject on SO...

查看更多
登录 后发表回答