为什么在使用repaint()而不是与getParent().repaint()一起使用时会发生此Swing错误? [英] Why does this this Swing bug occur when using repaint() and not with getParent().repaint()?

查看:106
本文介绍了为什么在使用repaint()而不是与getParent().repaint()一起使用时会发生此Swing错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题是基于我前一段时间使用一个简单的Swing骰子程序遇到的一个问题.我发布的原始问题是此处并具有可接受的答案,但是我想确切地了解正在发生的事情,为什么会出现问题以及为什么解决方案会起作用.

This question is based on a problem I had a while back with a simple Swing dice program. The original question I posted is here and has an accepted answer, but I'd like to know exactly what is happening, why the problem occurs, and why the solution works.

我设法缩减了原始代码以找到问题的核心,现在看起来很不一样了:

I managed to whittle down the original code to get to the core of the problem and it now looks very different:

  • 我有两个ColorPanel,每个均绘制一个彩色正方形
  • 单击面板时,框应按以下顺序更改颜色:从黑色开始,然后从> red> green> blue> red> green> blue>等
  • 一旦盒子变了颜色,它就永远不会再变黑
  • I have two ColorPanels that each draw a coloured square
  • when you click on a panel the box should change colour in this order: start at black, then >red>green>blue>red>green>blue> etc
  • once a box has changed colour it should never be black again

但是,当我只是在MouseListener中调用repaint()时,程序的行为却很奇怪:

However when I just call repaint() in the MouseListener, the program behaves very strangely:

  • 我单击一个面板,正方形的颜色就会改变
  • 然后我单击另一个,它的正方形会更改颜色,但第一个正方形也会更改,变回黑色
  • 您可以在下面的gif中看到此行为:

如果使用getParent().repaint(),则此行为消失,程序将按预期方式运行:

If you use getParent().repaint() instead this behaviour goes away and the program behaves as expected:

  • 仅当面板/正方形开始重叠"时,才会出现问题.
  • 如果您使用的布局停止了此操作,或者未将其设置为小尺寸,则问题似乎不会发生.
  • 这个问题并非每次都发生,这最初使我认为可能涉及并发问题.
  • 在最初的问题中遇到问题的代码似乎并没有对每个人造成问题,因此我的IDE,jdk等也可能相关:Windows 7,Eclipse Kepler,jdk1.7.0_03

减去进口等的代码如下:

The code minus imports etc is as follows:

public class ColorPanelsWindow extends JFrame{

    static class ColorPanel extends JPanel {

        //color starts off black
        //once it is changed should never be 
        //black again
        private Color color = Color.BLACK;

        ColorPanel(){
            //add listener
            addMouseListener(new MouseAdapter(){
                @Override
                public void mousePressed(MouseEvent arg0) {
                    color = rotateColor();
                    repaint();
                    //using getParent().repaint() instead of repaint() solves the problem
                    //getParent().repaint();
                }
            });
        }
        //rotates the color black/blue > red > green > blue
        private Color rotateColor(){
            if (color==Color.BLACK || color == Color.BLUE)
                return Color.RED;
            if (color==Color.RED)
                return Color.GREEN;
            else return Color.BLUE;
        }

        @Override
        public void paintComponent(Graphics g){
            g.setColor(color);
            g.fillRect(0, 0, 100, 100);
        }
    }

    ColorPanelsWindow(){
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        setLayout(new GridLayout(1,0));
        add(new ColorPanel());
        add(new ColorPanel());
        //the size must be set so that the window is too small
        // and the two ColorPanels are overlapping
        setSize(40, 40);
//      setSize(300, 200);

        setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable(){

            @Override
            public void run() {
                new ColorPanelsWindow();
            }

        });
    }
}

所以我的问题是,这到底是怎么回事?

So my question is, what on earth is going on here?

推荐答案

但是我想确切地知道正在发生什么,

but I'd like to know exactly what is happening,

在Windows 7上使用JDK7u60时,我也遇到同样的问题.绝对对我来说像是个错误.

I see the same problems using JDK7u60 on Windows 7. Definitely seems like a bug to me.

我最好的猜测是双缓冲存在问题.

My best guess is that it is a problem with the double buffering.

我在paintComponent()方法中添加了调试代码.

I added so debug code to the paintComponent() method.

1)当您单击右侧组件时,仅调用其paintComponent()方法,并且面板将涂上适当的颜色.

1) When you click on the right component only its paintComponent() method is called and the panel is painted the proper color.

2)当您单击左侧组件时,仅调用其paintComponent()方法,并且该面板被涂上适当的颜色,但是右侧的面板将恢复为黑色,而无需在其上调用paintComonent()方法右侧面板.这使我相信以某种方式使用了旧缓冲区(这将是错误,并且我不知道如何解决它).

2) When you click on the left component only its paintComponent() method is called and the panel is painted the proper color, however the panel on the right reverts back to the black color, without invoking the paintComonent() method on the right panel. This leads me to believe that somehow an old buffer is being used (this would be the bug and I have no idea how to fix it).

getParent().repaint()起作用的原因是因为无论您单击哪个面板,这都将强制重涂两个组件.

The reason that getParent().repaint() works is because this forces both components to be repainted no matter which panel you click on.

这篇关于为什么在使用repaint()而不是与getParent().repaint()一起使用时会发生此Swing错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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