Thread.sleep()延迟整个程序,而不仅仅是它后面的程序

时间:2015-12-02 00:34:57

标签: java swing paintcomponent thread-sleep

相当多的头衔。代码应该绘制一个框,等待1秒,然后在不同的位置绘制一个新的框并重新绘制。相反,它会等待1秒然后画两个盒子。感谢您的帮助和抱歉,如果我搞砸了格式化。

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

public class GameRunner extends JPanel{
   @Override
   public void paintComponent (Graphics g){
      int x = 0;
      boolean directionRight = true;
      g.setColor(Color.blue);
      g.fillRect(300,400,100,100);
      repaint();
      try{
         Thread.sleep(1000);
      }
      catch (Exception ex){}
      g.fillRect(600,400,100,100);
      repaint();  
   }
   public static void main (String[] args){  
      JFrame frame = new JFrame("Submarine");
      GameRunner gameRunner = new GameRunner();
      frame.add(gameRunner);
      frame.setSize(1200,700);
      frame.setVisible(true);
      frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
   }
}

1 个答案:

答案 0 :(得分:10)

  • Thread.sleep(1000);将阻止当前正在运行的线程
  • 从事件调度线程的上下文中调用
  • paintComponent
  • Swing不会更新UI的状态,直到它完成处理当前(在本例中为“paint”)事件,这意味着当它在Thread.sleep处被阻止时,UI上不会更新任何内容,也不会更新将处理新事件。

Swing是一个单线程框架。您永远不应该在Event Dispatching Thread的上下文中执行任何阻塞或长时间运行的操作。

请查看Concurrency in Swing以获取更多详细信息,并How to use Swing Timers查看可能的解决方案。

作为旁注,如果UI或UI在任何paint方法中依赖的任何变量,都不应该修改状态。绘画应该只绘制组件的当前状态,不要修改它,这包括直接或间接调用repaint

例如......

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class GameRunner extends JPanel {

    private int xPos = 300;

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.blue);
        g.fillRect(xPos, 400, 100, 100);
        repaint();
    }

    public GameRunner() {
        Timer timer = new Timer(1000, new ActionListener() {
            private boolean state = false;
            @Override
            public void actionPerformed(ActionEvent e) {
                if (state) {
                    xPos = 300;
                } else {
                    xPos = 600;
                }
                state = !state;
                repaint();
            }
        });
        timer.start();
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(700, 500);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new GameRunner());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}