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

标签 java swing crash jframe

我想在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);

        }


    }
}

最佳答案

  • 不要使用Thread.sleep。即使您要使用它,也永远不要在paintComponent方法中使用它。
  • 而是使用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();
    }
    

  • 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());
    
  • 关于java - 使用Thread.Sleep(1000)时,在Jframe中移动像素并使JFrame崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21952448/

    相关文章:

    java - 安装libgdx后拒绝Android Studio Gradle访问

    java - 如何在 Android 运行时 (ART) 上启用语言级断言?

    java - 是否可以将 JFrame 放在前面而不是焦点?

    java - 在 GridLayout 上方添加 JLabel

    c++ - Visual Studio 令人困惑的异常

    java - 如何访问 MS Azure 存储云中的辅助位置

    java - 如何更改 AdListener 的重写方法内的变量值?

    java - 从 xml 模式绘制属性 Pane

    android - Android 上共享库的偏移量

    react-native - React Native 应用程序不会按预期崩溃