【问题标题】:Erasing Must Not Happen [duplicate]擦除不能发生[重复]
【发布时间】:2013-12-01 20:31:47
【问题描述】:

我在这里问了一个类似的问题: Leaving a trace while painting on a transparent JPanel

确实有人试图帮助我,但我认为我无法说清楚,所以他误解了我想要的。

我想知道如何阻止 repaint() 擦除我的面板。如果我删除 setOpaque(false);声明,它似乎停止了擦除-但是,我没有得到背景颜色。

【问题讨论】:

  • 没有。每当绘制面板时,您都需要重新绘制所有内容。您不喜欢它的事实并没有使您之前问题的答案变得不那么真实。
  • -1,不,我理解并告诉过你这不是 Swing 的工作方式。有一些方法可以捏造它,但是一旦 Swing 确定组件需要重新绘制,你就会失去一切。例如,当框架调整大小时。
  • 如果我注释掉 setOpaque(false),它如何停止擦除?
  • @user3015246 不是,这实际上是一个糟糕的油漆副作用
  • 我在 2 分钟前问了一个问题,但在 3 分钟前我得到了答案? SLaks 可以回到过去吗?哦,对不起,我的错!

标签: java swing graphics awt


【解决方案1】:

在 Swing 中绘画是一个破坏性的过程。您的组件用于绘制自身的Graphics 上下文是共享资源,即在您的组件之前和之后绘制的组件将使用相同的图形上下文。

这意味着,如果你不清除它,你会看到你之前画过的东西......

在开始绘画之前清除Graphics 上下文是框架的要求...

为此,预计在调用paintComponent 时,您将完全重绘您需要重绘的内容。

看看Performing Custom PaintingPainting in AWT and Swing

你需要停止与这个过程作斗争,开始学习如何使用它——如果你这样做了,你的生活会简单得多;)

更新了一个可能的基本方法的示例

基本上,这只是在组件范围内的某个位置创建一个随机点,将该点添加到 List 并请求重新绘制组件。 paintComponent 方法简单地循环遍历此列表并绘制点,之后它调用 super.paintComponent 来准备 Graphics 用于绘制的上下文...

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class AutoPaint {

    public static void main(String[] args) {
        new AutoPaint();
    }

    public AutoPaint() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private List<Point> points = new ArrayList<>(25);

        public TestPane() {
            Timer timer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    points.add(new Point(random(getWidth()), random(getHeight())));
                    repaint();
                }
            });
            timer.start();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            for (Point p : points) {
                g2d.drawLine(p.x, p.y, p.x, p.y);
            }
            g2d.dispose();
        }

        protected int random(int range) {
            return (int)Math.round(Math.random() * range);
        }

    }

}

【讨论】:

  • 好的,谢谢。我明白。但是我应该能够保存我每次绘制的内容,例如,使用 ArrayList。我不能吗?
  • 这是一种方法,是的......
  • 谢谢。我会试试的。
猜你喜欢
  • 2021-12-28
  • 2020-07-27
  • 1970-01-01
  • 2014-10-17
  • 2012-03-17
  • 2015-05-26
  • 2020-12-21
  • 2011-04-21
  • 2023-04-07
相关资源
最近更新 更多