在JPanel和JComponent中绘图

Spa*_*ost 1 java graphics swing jcomponent jpanel

我需要一些帮助来理解为什么绘图在JComponent和JPanel中的工作方式不同.

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Particle extends JComponent implements Runnable{
    private int x = 45;
    private int y = 45;
    private int cx;
    private int cy;
    private int size;
    private Color color;
    private JFrame frame;

    public Color getColor(){
        return color = new Color(100,0,190);
    }

    public Particle(){
        frame = new JFrame();
        frame.setSize(400, 400);
        frame.setResizable(false);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(this);
        frame.setVisible(true);
    }

    public void update(){
        x+=1;
        y+=1;
    }

    public void paintComponent(Graphics g){
        Graphics2D g2d = (Graphics2D) g.create();
        g2d.setColor(getColor());

        g2d.fillRect(x, y, 4, 4);
    }

    public void startThread(){
        Thread thread = new Thread(this);
        thread.start();
    }

    @Override
    public void run() {
        for(int i = 0; i <= 200; i++){
            try{
                update();
                repaint();
                Thread.sleep(4);    
            }catch(Exception e){
                System.out.print("Exception at thread.start()");
            }
        }
    }

    public static void main(String[] args) {
        Particle particle = new Particle();
        particle.startThread();
    }
}
Run Code Online (Sandbox Code Playgroud)

在上面这个例子中,"粒子"从A点移动到B点就好了.

但是当我将粒子从JComponent子类化为JPanel时...

图形形成一条线..即矩形永远不会从它开始的地方消失.

为什么会这样?

joh*_*902 5

Toilal发布了一个解决方案.我想解释一下原因:

API的文档paintComponentJComponent

此外,如果您没有调用super的实现,则必须遵守opaque属性,即如果此组件是不透明的,则必须以非不透明的颜色完全填充背景.如果您不遵守opaque属性,您可能会看到视觉伪影.

setOpaqueJComponent

此属性的默认值为false JComponent.但是,大多数标准JComponent子类(例如JButtonJTree)上此属性的默认值依赖于外观.

添加此代码:

System.out.println(isOpaque());
Run Code Online (Sandbox Code Playgroud)
  • JComponent的情况下false被打印出来.
  • JPanel的情况下true被打印出来.

就这样.