Java- 如何从 JPanel 中清除图形

Java- how to clear graphics from a JPanel

我正在创建一个简单的程序,我在其中用鼠标单击绘制了一个黑色椭圆。但是,我希望出现一个新的椭圆形,而旧的椭圆形消失。我该怎么做呢?我搞砸了插入到我的 mousePressed 方法中的 removeAll() 方法,但它对我不起作用。 removeAll() 方法是否适用于此?还是我应该使用其他东西?很抱歉,如果答案很明显,但我对此仍然很陌生并且正在努力学习。任何建议将不胜感激。谢谢。

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class PaintPractice extends JPanel implements MouseListener {

    Random rand = new Random(); 
    int x = rand.nextInt(450);
    int y = rand.nextInt(450);

    public PaintPractice(){
        super();
        addMouseListener(this);
    }

    public static void main(String[] args){

        JFrame frame = new JFrame();
        PaintPractice panel = new PaintPractice();

        frame.setSize(500, 500);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setContentPane(panel);        
    }

    public void paint(Graphics g){
        g.setColor(Color.BLACK);
        g.fillOval(x, y, 50, 50);
    }

    @Override
    public void mousePressed(MouseEvent e) {
        x = e.getX();
        y = e.getY();
        removeAll();
        repaint();      
    }

    @Override
    public void mouseClicked(MouseEvent e) {        
    }

    @Override
    public void mouseEntered(MouseEvent e) {        
    }

    @Override
    public void mouseExited(MouseEvent e) {     
    }

    @Override
    public void mouseReleased(MouseEvent e) {       
    }
}

只用当前绘图表面的背景色填充椭圆

 {
        g.setColor(...);//setColor to  surface background 
        g.fillOval(x, y, 50, 50);
    }

如果你愿意,你可以清除该区域: 更多内容在 OracleDoc

如果您只想显示新创建的椭圆,一种可能的解决方法。使您的框架和面板静态,然后在 mousePressed.

中调用 frame.setContentPane(panel)

另一种工作方法是在paint中调用g.clearRect(0, 0, getWidth(), getHeight()),但这会使整个背景变成白色。

立即解决它只需在 paint(Graphics g) 方法中调用 super.paint(g)

public void paint(Graphics g){
        super.paint(g);
        g.setColor(Color.BLACK);
        g.fillOval(x, y, 50, 50);
    }

Paint 机制以及为什么我应该覆盖 paintComponent() 而不是覆盖 paint():

Javadoc 解释 the Paint Mechanism:

By now you know that the paintComponent method is where all of your painting code should be placed. It is true that this method will be invoked when it is time to paint, but painting actually begins higher up the class heirarchy, with the paint method (defined by java.awt.Component.) This method will be executed by the painting subsystem whenever you component needs to be rendered. Its signature is:

  • public void paint(Graphics g)

javax.swing.JComponent extends this class and further factors the paint method into three separate methods, which are invoked in the following order:

  • protected void paintComponent(Graphics g)
  • protected void paintBorder(Graphics g)
  • protected void paintChildren(Graphics g)

The API does nothing to prevent your code from overriding paintBorder and paintChildren, but generally speaking, there is no reason for you to do so. For all practical purposes paintComponent will be the only method that you will ever need to override.

这就是为什么您的 PaintPractice 代码应该调用 super.paintComponent(g)

public void paintComponent(Graphics g) {    
    super.paintComponent(g);       
     g.setColor(Color.BLACK);
     g.fillOval(x, y, 50, 50);
}  

此外,您不需要在 mousePressed(MouseEvent e) 方法中调用 removeAll()

    @Override
    public void mousePressed(MouseEvent e) {
        x = e.getX();
        y = e.getY();
        repaint();     
    }
  1. 由于 JPanel 是 JComponent 的子类,因此您应该重写 paintComponent 而不是 paint 并且 paintComponent 方法中的

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
    
  2. 当您使用 removeAll 时,JPanel 中的所有组件(按钮、文本字段、标签等)都将被删除(如果有的话)。但是,您似乎没有向JPanel 添加任何组件,因此没有必要调用此方法。

使用

g.clearRect(pos, pos, size, size);

遇到同样的问题并找到了这个解决方案