在JPanel和JComponent中绘图

我需要一些帮助来理解为什么绘图在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(); } } 

在上面的例子中,“粒子”从A点移动到B点就好了。

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

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

为什么会这样?

在paintComponent实现中调用super.paintComponent(g)。

 public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g.create(); g2d.setColor(getColor()); g2d.fillRect(x, y, 4, 4); } 

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

JComponentpaintComponent的API文档中

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

JComponent setOpaque

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

添加此代码:

 System.out.println(isOpaque()); 
  • JComponent中,打印false
  • JPanel中,打印出true

就这样。