绘制一个在下一次绘制中不会消失的矩形 [英] Drawing a rectangle that won't disappear in next paint

查看:29
本文介绍了绘制一个在下一次绘制中不会消失的矩形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创建一个绘制矩形的 JPanel.面板需要绘制很多矩形,但它们不会移动.我的问题的一个解决方案是创建一个包含我已经创建的所有矩形的列表,并在每次Paint"调用中绘制它们.但是有很多矩形会减慢计算机的速度.
我还尝试使用 repaint(x, y, height, width) 来绘制新矩形的空间,但它不起作用.(JPanel 不断擦除之前的矩形.)在排序中,我需要绘制不会在每次绘制时消失的矩形.或者一种不会擦除以前绘制或不会绘制背景的绘画方法.那是我的 JPanel 类的一部分:

I trying to create a JPanel that draws rectangles. The Panel needs to draw alot of rectangles, but they dont move. One solution to my problem was to create an list with all the rectangles i already created and draw they all in every call of "Paint". But there is a lot of rectangles and it slows the computer.
I also tried to use repaint(x, y, height, width) to rapaint just the space of the new rectangle but it did not work. (JPanel keeps erasing previous rectangles.) In sort, i need to draw rectangles that wont disappear every paint. Or a paint method that wont erase previous draws, or wont paint the background. That is part of my JPanel class:

class MyPanel extends JPanel{
  private int x, y, size;
  private Color c;
  public void DrawRect(int x, int y, int size, Color c){
      this.x = x;
      this.y = y;
      this.size = size;
      this.c = c;
      repaint();
  }
  @Override
    public void
    paint(Graphics g) {

        g.setColor(c);
      g.fillRect(x, y, size, size);
    }

}

推荐答案

  1. 不要在没有非常非常好的理由的情况下覆盖 paint...使用 paintComponent 代替
  2. 总是调用super.paintXxx,这些方法在后台做了很多事情,不调用super只会回来困扰你.
  3. 如果您将多个窗格用作矩形,请将 MyPanel 设为透明.
  1. Don't override paint WITHOUT VERY, VERY good reason...use paintComponent instead
  2. Always call super.paintXxx, these methods do a lot in the background, failing to call super is only going to come back and haunt you.
  3. If you're using multiple panes as rectangles, make the MyPanel transparent.

Paint 是无状态的.上一个油漆和下一个油漆之间没有联系.对于每个绘制请求,您都需要更新整个状态.

Paint's are stateless. There is no connection between the last paint and the next. On each paint request you are expected to update the entire state.

Andrew 提出的双缓冲(或后缓冲)建议非常好,我强烈建议您查看并实施它.

Andrew's suggest of double buffering (or back buffering) is and excellent one, and I highly encourage you to have a look an implementing it.

同时,我把这个小例子放在一起......

In the mean time, I put this little example together...

基本上,您按住鼠标按钮,它会每 40 毫秒(大约每秒 25 帧)随机向面板添加另一个矩形.

Basically, you press and hold the mouse button and it will randomly add another rectangle to the panel every 40 milli-seconds (roughly 25 frames a second).

我把它提高到 1000 rects 没有任何问题,能够在没有问题的情况下调整窗口大小或明显减慢...

I got this up to a 1000 rects without any issue, was able to resize the window without and issue or obviously slow down...

public class MyPanel extends JPanel {

    private List<MyRectangle> lstShapes;
    private Timer populate;

    public MyPanel() {

        lstShapes = new ArrayList<MyRectangle>(25);

        populate = new Timer(40, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {

                int x = (int) (Math.random() * getWidth());
                int y = (int) (Math.random() * getHeight());
                int width = (int) (Math.random() * (getWidth() / 4));
                int height = (int) (Math.random() * (getHeight() / 4));

                if (x + width > getWidth()) {
                    x = getWidth() - width;
                }
                if (y + height > getHeight()) {
                    y = getHeight() - height;
                }

                Color color = new Color(
                        (int) (Math.random() * 255),
                        (int) (Math.random() * 255),
                        (int) (Math.random() * 255));

                lstShapes.add(new MyRectangle(x, y, width, height, color));
                repaint();
            }
        });
        populate.setInitialDelay(0);
        populate.setRepeats(true);
        populate.setCoalesce(true);

        addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                populate.restart();
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                populate.stop();
            }
        });

    }

    @Override
    protected void paintComponent(Graphics g) {

        super.paintComponent(g);

        Graphics2D g2d = (Graphics2D) g;
        for (MyRectangle rect : lstShapes) {
            rect.paint(g2d);
        }

        FontMetrics fm = g2d.getFontMetrics();
        String text = Integer.toString(lstShapes.size());

        g2d.setColor(getForeground());
        g2d.drawString(text, getWidth() - fm.stringWidth(text), getHeight() - fm.getHeight() + fm.getAscent());

    }

    public class MyRectangle extends Rectangle {

        private Color color;

        public MyRectangle(int x, int y, int width, int height, Color color) {
            super(x, y, width, height);
            this.color = color;
        }

        public Color getColor() {
            return color;
        }

        public void paint(Graphics2D g2d) {

            g2d.setColor(getColor());
            g2d.fill(this);

        }
    }
}

试一试,很有趣;)

ps- 在我注意到速度变慢之前,我已经达到了超过 5000 个矩形(我将代码修改为 10 毫秒的延迟,并且每个刻度添加了 10 个新矩形)

ps- I got to up to over 5000 rectangles before I noticed a slow down (I modified the code down to a 10 milli second delay and was adding 10 new rectangles per tick)

这篇关于绘制一个在下一次绘制中不会消失的矩形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆