在使用Thread.Sleep(1000)时移动Jframe中的像素并使JFrame崩溃

时间:2014-02-22 09:35:34

标签: java swing crash jframe

我想在JFrame中移动一个像素,但是使用Thread.Sleep(1000)方法eventuate来破坏我的JFrame。为什么会出现这个问题怎么解决呢? 谢谢你

public class Main {
public static void main(String[] args) throws InterruptedException {
    JFrame mainFrame = new JFrame("Sadra Graphics");
    mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    SadraGraphics sadraGraphics = new  SadraGraphics();
    sadraGraphics.setPreferredSize((new Dimension(640,480)));
    mainFrame.getContentPane().add( sadraGraphics );
    mainFrame.pack();
    mainFrame.setVisible(true);    }}


public class SadraGraphics extends JPanel {


public void paintComponent (Graphics g){

    super.paintComponent(g);
    this.setBackground(Color.white);

    for (int i = 0; i <=639; i++) {
        g.setColor(Color.red);
        g.drawLine(i, i * 3 / 4, i, i * 3 / 4);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        g.setColor(Color.white);
        g.drawLine(i,i*3/4,i,i*3/4);

        }


    }
}

1 个答案:

答案 0 :(得分:2)

  1. 请勿使用Thread.sleep。即使您要使用它,永远也不想在paintComponent方法中使用它。
  2. 而是使用javax.swing.Timer,它将更新一些变量并重新粉刷每隔几毫秒

    public SadraGraphics() {
        Timer timer = new Timer(1000, new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                // do something here that will refresh some variables that you
                // are using to paint, then call repaint()
                repaint();
            }
        });
        timer.start();
    }
    
  3. How to use Swing Timers

    了解详情

    这是一个简单的可运行示例

    import java.awt.Dimension;
    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.SwingUtilities;
    import javax.swing.Timer;
    
    public class Main {
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    JFrame mainFrame = new JFrame("Sadra Graphics");
                    mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    SadraGraphics sadraGraphics = new SadraGraphics();
                    sadraGraphics.setPreferredSize((new Dimension(640, 480)));
                    mainFrame.getContentPane().add(sadraGraphics);
                    mainFrame.pack();
                    mainFrame.setVisible(true);
                }
            });
        }
    }
    
    class SadraGraphics extends JPanel {
    
        int x1 = 0;
        int y1 = 50;
        int x2 = 0;
        int y2 = 200;
    
        public SadraGraphics() {
            Timer timer = new Timer(30, new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    x1 += 2;
                    x2 += 2;
                    repaint();
                }
            });
            timer.start();
        }
    
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawLine(x1, y1, x2, y2);
    
        }
    }
    

    旁注

    • 使用SwingUtilities.invokeLater从EDT运行Swing应用程序。
    • paintComponent应为protected而不是public
    • 请勿使用paintComonent方法设置背景。您可以从构造函数中执行此操作,也可以通过执行此操作在paintComponent方法中绘制背景

      g.setColor(Color.WHITE);
      g.fillRect(0, 0, getWidth(), getHeight());