JFrame 图形忽略前几个渲染

Вдо*_*вые 1 java graphics swing jframe

这是查看错误的最小代码:

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

public class Main1 extends JFrame {
    static Main1 main;
    public Main1() {
        super("app");
    }

    public static void main(String[] args) {
        main = new Main1();
        main.setBounds(300, 300, 800, 500);
        main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        main.setVisible(true);
        Graphics g = main.getGraphics();
        for(int i = 0; i < 100; i++){
            g.setColor(new Color(255, 0, 0));
            g.fillRect(0, 0, 800, 500);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我在“for”循环中使用 100,则框架似乎没有着色,但 200 个循环足以为它着色。

我想制作一个框架很少变化的应用程序,但是这个功能破坏了代码的质量,因为我必须制作一些虚拟框架。

Don*_*ter 5

public static void main(String[] args) {
    main = new Main1();
    main.setBounds(300, 300, 800, 500);
    main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    main.setVisible(true);
    Graphics g = main.getGraphics();
    for(int i = 0; i < 100; i++){
        g.setColor(new Color(255, 0, 0));
        g.fillRect(0, 0, 800, 500);
    }
}
Run Code Online (Sandbox Code Playgroud)

这不是您制作 Swing 图形的方式。通过在组件上调用 .getGraphics() 来获取 Graphics 对象会为您提供一个短期不稳定且有时为 null 的对象。比如,创建的JFrame渲染需要一些时间,如果你getGraphics()在渲染之前调用并尝试使用它,对象可能为null,当然不会wokr。

而是按照教程使用 JVM 提供的 Graphics 对象在 JPanel 的paintComponent 方法中进行绘制:

public class MainPanel extends JPanel {

    public MainPanel {
        setPreferredSize(new Dimension(800, 500)));
        setBackground(new Color(255, 0, 0)); // if you just want to set background
    }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        
        // use g here do do your drawing
    }

}
Run Code Online (Sandbox Code Playgroud)

然后像这样使用它:

public static void main(String[] args) {
    SwingUtilities.invokeLater(() -> {
        JFrame frame = new JFrame("GUI");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new MainPanel());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    });
}  
Run Code Online (Sandbox Code Playgroud)

教程:课程:执行自定义绘画

是的,如果您想驱动一个简单的动画,请使用Swing Timer来帮助驱动它,如下所示:

public class MainPanel extends JPanel {
    private int x = 0;
    private int y = 0;

    public MainPanel {
        setPreferredSize(new Dimension(800, 500)));
        setBackground(new Color(255, 0, 0)); // if you just want to set background
        
        // timer code:
        int timerDelay = 15;
        new Timer(timerDelay, ()-> {
            x += 4;
            y += 4;
            repaint();
        }).start();
    }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        
        // use g here do do your drawing
        g.setColor(Color.BLUE);
        g.drawRect(x, y, 20, 20);
    }

}
Run Code Online (Sandbox Code Playgroud)