【问题标题】:Java- how to clear graphics from a JPanelJava-如何从 JPanel 中清除图形
【发布时间】:2015-07-12 08:59:56
【问题描述】:

我正在创建一个简单的程序,在该程序中我用鼠标单击的地方画了一个黑色椭圆。但是,我希望出现一个新的椭圆形而旧的椭圆形消失。我该怎么做呢?我已经搞砸了插入到我的 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) {       
    }
}

【问题讨论】:

  • 记得阅读文档中对你不知道的方法的描述。这就是你错误使用 removeAll() 方法的原因。

标签: java swing jpanel java-2d


【解决方案1】:

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

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

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

Javadoc 解释the Paint Mechanism

现在你知道paintComponent方法是你所有的 应该放置绘画代码。确实,这种方法将是 在绘画的时候调用,但绘画实际上开始得更高 使用paint方法(定义为 java.awt.Component.) 这个方法会被画图执行 每当您的组件需要渲染时,子系统。它的签名 是:

  • 公共 void 油漆(图形 g)

javax.swing.JComponent 扩展了这个类并进一步考虑了 paint 方法分为三个单独的方法,它们在 以下顺序:

  • 受保护的 void 油漆组件(图形 g)
  • 受保护的 void paintBorder(Graphics g)
  • protected void paintChildren(Graphics g)

API 不会阻止您的代码覆盖paintBorder 和paintChildren,但一般来说,你没有理由 这样做。出于所有实际目的,paintComponent 将是唯一的 您将需要覆盖的方法

这就是为什么您的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();     
    }

【讨论】:

  • 等等...我之前没有看到在JPanel 中覆盖mousePressed 方法。和addMouseListener()一样吗?
  • @JamesSmith 检查this.
  • 感谢您的意见,我最喜欢您的回答。它究竟是如何工作的?首先,我猜测该方法是从 JComponent 的超类 Container 类中调用的?其次,方法解释中究竟有什么告诉你它会取代旧油漆?docs.oracle.com/javase/7/docs/api/java/awt/…
  • @anonymousnoob 我已经在我的答案中添加了绘画机制;)不要忘记一个赞成票;)
【解决方案2】:

如果您只想显示新创建的椭圆形,一种可能的解决方法。将你的框架和面板设为静态,然后在 mousePressed 中调用 frame.setContentPane(panel)。

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

【讨论】:

    【解决方案3】:
    1. 由于 JPanel 是 JComponent 的子类,您应该在 paintComponent 方法中覆盖 paintComponent 而不是 paintuse super.paintComponent(g)

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

    【讨论】:

    • 不考虑,直接去做,因为自定义绘制是通过在 Swing 中覆盖 paintComponent() 来完成的。 (+1)。您在使用 AWT 时覆盖了 paint(),您不应该再使用它了。
    【解决方案4】:

    只需用当前绘图表面的背景颜色填充Oval

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

    如果您愿意,可以清除该区域: 更多OracleDoc

    【讨论】:

      【解决方案5】:

      使用

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

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

      【讨论】:

        猜你喜欢
        • 2011-10-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-01
        • 2015-06-27
        • 2020-09-14
        • 2012-05-13
        相关资源
        最近更新 更多