加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 为什么在使用repaint()而不是getParent()时会出现这个Sw

发布时间:2020-12-15 04:20:48 所属栏目:Java 来源:网络整理
导读:这个问题是基于我用一个简单的Swing骰子程序回来的问题.我发布的原始问题是 here,并且已经接受了答案,但我想确切地知道发生了什么,问题发生的原因以及解决方案的工作原理. 我设法削减原始代码以找到问题的核心,现在看起来非常不同: 我有两个ColorPanel,每个
这个问题是基于我用一个简单的Swing骰子程序回来的问题.我发布的原始问题是 here,并且已经接受了答案,但我想确切地知道发生了什么,问题发生的原因以及解决方案的工作原理.

我设法削减原始代码以找到问题的核心,现在看起来非常不同:

>我有两个ColorPanel,每个都绘制一个彩色方块
>当您单击面板时,框应按此顺序更改颜色:从黑色开始,然后是>红色>绿色>蓝色>红色>绿色>蓝色>等等
>一旦盒子改变颜色,它就不应该再变黑了

但是,当我在MouseListener中调用repaint()时,程序表现得非常奇怪:

>我点击一个面板,方块的颜色会发生变化
>然后我点击另一个,它的方块改变颜色,但第一个方块也改变,回到黑色
>你可以在下面的gif中看到这种行为:

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

>如果面板/正方形开始“重叠”,似乎只会出现问题.
>如果使用停止此布局或不将尺寸设置得小的布局,则似乎不会出现问题.
>问题不会每次都发生,最初让我觉得可能涉及并发问题.
>我在原始问题中遇到问题的代码似乎并没有给每个人带来问题,所以我的IDE,jdk等也可能是相关的:Windows 7,Eclipse Kepler,jdk1.7.0_03

代码减去进口等如下:

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,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();
            }

        });
    }
}

所以我的问题是,到底发生了什么?

解决方法

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

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

我最好的猜测是双缓冲是一个问题.

我将这样的调试代码添加到paintComponent()方法中.

1)当您单击右侧组件时,仅调用其paintComponent()方法,并且该面板被绘制为正确的颜色.

2)单击左侧组件时,并且面板绘制正确的颜色,但右侧面板将恢复为黑色,而不调用右侧面板上的paintComonent()方法.这让我相信不知何故使用旧缓冲区(这将是错误,我不知道如何解决它).

getParent().repaint()工作的原因是因为无论您单击哪个面板,都会强制重新绘制两个组件.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读