【发布时间】:2026-02-01 22:35:01
【问题描述】:
这个问题是基于我不久前在一个简单的 Swing 骰子程序中遇到的一个问题。我发布的原始问题是 here 并且有一个可接受的答案,但我想确切地知道发生了什么,为什么会出现问题,以及为什么解决方案有效。
我设法削减了原始代码以找到问题的核心,现在它看起来非常不同:
- 我有两个
ColorPanels,每个都画一个彩色方块 - 当您单击面板时,框应按以下顺序更改颜色:从黑色开始,然后是 >red>green>blue>red>green>blue> 等
- 一旦盒子改变了颜色,它就不会再变黑了
但是,当我在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, 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();
}
});
}
}
所以我的问题是,这里到底发生了什么?
【问题讨论】:
-
而且不会发生,只有调整大小。
标签: java swing drawing paintcomponent repaint