繁体   English   中英

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

[英]move a pixel in Jframe and crash JFrame when use Thread.Sleep(1000)

我想在JFrame中移动像素,但是使用Thread.Sleep(1000)方法最终会导致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. 不要使用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(); } 

如何使用Swing计时器中查看更多信息

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

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()); 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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