gpt4 book ai didi

java - 为什么在使用 repaint() 而不是 getParent().repaint() 时会出现此 Swing 错误?

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:26:20 27 4
gpt4 key购买 nike

这个问题是基于我不久前遇到的一个简单的 Swing 骰子程序问题。我发布的原始问题是 here并且有一个可接受的答案,但我想确切地知道发生了什么,为什么会出现问题,以及解决方案为什么有效。

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

  • 我有两个 ColorPanel,每个绘制一个彩色方 block
  • 当你点击一个面板时,盒子应该按以下顺序改变颜色:从黑色开始,然后>红色>绿色>蓝色>红色>绿色>蓝色>等等
  • 一旦盒子改变了颜色,它就永远不会再变黑

然而,当我在 MouseListener 中调用 repaint() 时,程序的行为非常奇怪:

  • 我点击一个面板,正方形的颜色发生变化
  • 然后我点击另一个,它的方 block 变了颜色,但第一个方 block 也变了,变回黑色
  • 您可以在下面的 gif 中看到此行为:

buggy program

如果您改用 getParent().repaint(),此行为就会消失并且程序会按预期运行:

enter image description here

  • 问题似乎只有在面板/正方形开始“重叠”时才会出现。
  • 如果您使用的布局可以阻止这种情况发生,或者没有将尺寸设置得较小,那么问​​题似乎就不会发生。
  • 问题并不是每次都发生,这让我最初认为可能涉及并发问题。
  • 我在最初的问题中遇到问题的代码似乎并没有给每个人带来问题,所以我的 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, 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) 当你点击左边的组件时,只有它的 paintComponent() 方法被调用并且面板被涂上正确的颜色,但是右边的面板恢复为黑色,没有在右侧面板上调用 paintComonent() 方法。这使我相信以某种方式使用了旧缓冲区(这将是错误,我不知道如何修复它)。

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

关于java - 为什么在使用 repaint() 而不是 getParent().repaint() 时会出现此 Swing 错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24222976/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com