Java-如何从JPanel清除图形。

时间:2023-02-04 17:29:12

I'm creating a simple program where I draw a black oval where I click with my mouse. However I want a new oval to appear and the old one to disappear. How would I go about doing this? I've messed around with the removeAll() method inserted into my mousePressed method, however it isn't working for me. Is the removeAll() method even suitable for this? Or should I use something else? Sorry if the answer is obvious, but I am still new to this and trying to learn. Any advice would be immensely appreciated. Thanks.

我正在创建一个简单的程序,在这个程序中,我用鼠标点击一个黑色的椭圆。但是我想要一个新的椭圆出现,旧的椭圆消失。我该怎么做呢?我将removeAll()方法插入到我的mousePressed方法中,但它对我不起作用。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) {       
    }
}

4 个解决方案

#1


1  

Immediate solution it to Just call super.paint(g) in the paint(Graphics g) method.

立即解决它,只需在paint(图形g)方法中调用super.paint(g)。

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

The Paint Mechanism and why Should i override paintComponent() instead of overriding paint():

Javadoc explains the Paint Mechanism:

Javadoc解释了绘制机制:

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:

现在您已经知道,应该将所有的绘图代码放在paintComponent方法中。确实,在绘制的时候会调用这个方法,但是绘制实际上是从类的继承关系开始的,使用paint方法(由java.awt.Component定义)。当需要呈现组件时,这个方法将由绘图子系统执行。它的签名是:

  • public void paint(Graphics g)
  • 公共空间油漆(图形g)

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

javax.swing。JComponent扩展了这个类,并将paint方法进一步分解为三个独立的方法,按以下顺序调用:

  • protected void paintComponent(Graphics g)
  • 保护无效paintComponent(图形g)
  • protected void paintBorder(Graphics g)
  • 保护无效paintBorder(图形g)
  • protected void paintChildren(Graphics g)
  • 保护无效paintChildren(图形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.

API没有阻止您的代码覆盖paintBorder和paintChildren,但是一般来说,您没有理由这样做。实际上,paintComponent是惟一需要重写的方法。

This is why your PaintPractice code should invoke super.paintComponent(g) instead.

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

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

Also you don't need to call removeAll() in the mousePressed(MouseEvent e) method.

同样,不需要在mousePressed(MouseEvent e)方法中调用removeAll()。

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

#2


3  

  1. Since JPanel is a subclass of JComponent, you should override paintComponent instead of paint and also use super.paintComponent(g) in the paintComponent method.

    由于JPanel是JComponent的子类,所以您应该在paintComponent方法中重写paintComponent而不是paint,并使用super.paintComponent(g)。

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
    
  2. When you use removeAll, all components (buttons, text fields, labels, etc) in the JPanel are removed, if any. However, you don't seem to add any components to the JPanel, so it is not necessary to call this method.

    使用removeAll时,JPanel中的所有组件(按钮、文本字段、标签等)都将被删除(如果有的话)。但是,您似乎没有向JPanel添加任何组件,因此没有必要调用这个方法。

#3


2  

One possible workaround if u just want to show the newly created oval. Make your frame and panel static, then call frame.setContentPane(panel) in mousePressed.

如果你只是想要显示新创建的椭圆,一个可能的解决方案。将框架和面板设置为静态,然后在mousePressed中调用frame. setcontentpane (panel)。

Another working method is call g.clearRect(0, 0, getWidth(), getHeight()) in paint, but this will make the whole background whitecolor.

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

#4


1  

just fillOval with the background color of the current drawing surface

只需用当前绘图表面的背景色进行丝状处理

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

if you want you can clear the area: more at OracleDoc

如果你愿意,你可以清理这个区域:更多在OracleDoc

#1


1  

Immediate solution it to Just call super.paint(g) in the paint(Graphics g) method.

立即解决它,只需在paint(图形g)方法中调用super.paint(g)。

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

The Paint Mechanism and why Should i override paintComponent() instead of overriding paint():

Javadoc explains the Paint Mechanism:

Javadoc解释了绘制机制:

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:

现在您已经知道,应该将所有的绘图代码放在paintComponent方法中。确实,在绘制的时候会调用这个方法,但是绘制实际上是从类的继承关系开始的,使用paint方法(由java.awt.Component定义)。当需要呈现组件时,这个方法将由绘图子系统执行。它的签名是:

  • public void paint(Graphics g)
  • 公共空间油漆(图形g)

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

javax.swing。JComponent扩展了这个类,并将paint方法进一步分解为三个独立的方法,按以下顺序调用:

  • protected void paintComponent(Graphics g)
  • 保护无效paintComponent(图形g)
  • protected void paintBorder(Graphics g)
  • 保护无效paintBorder(图形g)
  • protected void paintChildren(Graphics g)
  • 保护无效paintChildren(图形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.

API没有阻止您的代码覆盖paintBorder和paintChildren,但是一般来说,您没有理由这样做。实际上,paintComponent是惟一需要重写的方法。

This is why your PaintPractice code should invoke super.paintComponent(g) instead.

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

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

Also you don't need to call removeAll() in the mousePressed(MouseEvent e) method.

同样,不需要在mousePressed(MouseEvent e)方法中调用removeAll()。

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

#2


3  

  1. Since JPanel is a subclass of JComponent, you should override paintComponent instead of paint and also use super.paintComponent(g) in the paintComponent method.

    由于JPanel是JComponent的子类,所以您应该在paintComponent方法中重写paintComponent而不是paint,并使用super.paintComponent(g)。

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
    
  2. When you use removeAll, all components (buttons, text fields, labels, etc) in the JPanel are removed, if any. However, you don't seem to add any components to the JPanel, so it is not necessary to call this method.

    使用removeAll时,JPanel中的所有组件(按钮、文本字段、标签等)都将被删除(如果有的话)。但是,您似乎没有向JPanel添加任何组件,因此没有必要调用这个方法。

#3


2  

One possible workaround if u just want to show the newly created oval. Make your frame and panel static, then call frame.setContentPane(panel) in mousePressed.

如果你只是想要显示新创建的椭圆,一个可能的解决方案。将框架和面板设置为静态,然后在mousePressed中调用frame. setcontentpane (panel)。

Another working method is call g.clearRect(0, 0, getWidth(), getHeight()) in paint, but this will make the whole background whitecolor.

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

#4


1  

just fillOval with the background color of the current drawing surface

只需用当前绘图表面的背景色进行丝状处理

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

if you want you can clear the area: more at OracleDoc

如果你愿意,你可以清理这个区域:更多在OracleDoc