我们遇到了 Java 6 应用程序在切换虚拟桌面时无法正确刷新的问题。到目前为止,该问题已在带有 GNOME 的 Fedora 11 和 13 以及带有 KDE 的 Suse SLES 10 上重现。我使用以下测试用例来重现问题:
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.Timer;
public class RepaintTest {
private JLabel label;
private void createAndShowGUI() {
final JFrame frame = new JFrame("RepaintTest");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
label = new JLabel("Repaint Test");
label.setOpaque(true);
frame.getContentPane().add(label);
frame.pack();
frame.setSize(200, 100);
frame.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
final RepaintTest repaintTest = new RepaintTest();
repaintTest.createAndShowGUI();
new Timer(5000, new ActionListener() {
boolean flip;
@Override
public void actionPerformed(ActionEvent e) {
repaintTest.label.setBackground(flip ? Color.GREEN : Color.RED);
flip = !flip;
}
}).start();
}
});
}
}
启动此程序并移动另一个窗口,例如终端窗口,部分位于其前面。等待窗口背景变为红色,切换到另一个虚拟桌面并等待五秒钟,然后切换回原来的屏幕。现在背景应该是完全绿色的。相反,我得到的是一个仅在其他窗口未覆盖的可见部分中部分更新的窗口。
Java 5 不会出现此问题,并且在启动时使用以下属性之一时不会出现此问题:
-Dswing.handleTopLevelPaint=false
或者
-Dswing.bufferPerWindow=false
但是,关闭 Swing 的双缓冲似乎不是一个很好的选择。这是 Linux 上的一个 JDK 错误,还是我们可以在我们的应用程序中做任何事情来解决这个重绘问题?