这个问题是基于我前一段时间使用一个简单的Swing骰子程序遇到的一个问题。我最初发布的问题在这里,并且得到了公认的答案,但是我想确切地了解正在发生的事情,为什么会出现问题以及为什么解决方案会起作用。
我设法缩减了原始代码以找到问题的核心,现在看起来很不一样:
ColorPanel
,每个都画一个彩色的正方形但是,当我仅调用repaint()
时MouseListener
,程序的行为非常奇怪:
如果getParent().repaint()
改为使用此行为,则程序将按预期方式运行:
减去导入等的代码如下:
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();
}
});
}
}
所以我的问题是,这到底是怎么回事?
但我想确切地知道正在发生什么,
我在Windows 7上使用JDK7u60时遇到了同样的问题。
我最好的猜测是双缓冲是一个问题。
我在paintComponent()
方法中添加了调试代码。
1)当您单击正确的组件时,只会paintComponent()
调用其方法,并且面板将被涂上适当的颜色。
2)单击左侧组件时,仅paintComponent()
会调用其方法,并且面板将被涂上适当的颜色,但是右侧的面板将恢复为黑色,而不会调用paintComonent()
右侧面板的方法。这使我相信以某种方式使用了旧缓冲区(这将是错误,并且我不知道如何修复它)。
getParent().repaint()
起作用的原因是因为无论您单击哪个面板,这都将强制重涂两个组件。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句