不知何故,javax.swing.RepaintManager
类可以帮助解决工具提示重画问题。扩展的类RepaintManager
下面的例子取自第 11 章,重绘管理器: http://www.java.net/external?url=http://www.curious-creature.org/2007/07/22/repaint-manager-demos-chapter-11/ http://www.java.net/external?url=http://www.curious-creature.org/2007/07/22/repaint-manager-demos-chapter-11/
修改为重画JTooltipFlickerTest
的内容面板...
尝试注释掉installRepaintManager()
调用构造函数,你会看到区别......
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.RepaintManager;
import javax.swing.SwingUtilities;
public class JTooltipFlickerTest extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
JPanel panel;
static public void main (final String[] args) {
new JTooltipFlickerTest ();
}
public JTooltipFlickerTest () {
super ();
panel = new JPanel ();
setTitle (this.getClass().toString());
setSize (1024, 768);
this.getContentPane().setLayout (new BorderLayout());
SwingUtilities.invokeLater (
new Runnable () {
@Override
public void run() {
final MouseAdapter ma = new MouseAdapter () {
public void mouseMoved (final MouseEvent e) {
panel.setToolTipText ("x: "+e.getX()+", y: "+e.getY());
}
};
panel.addMouseMotionListener(ma);
panel.setDoubleBuffered(true);
panel.createToolTip().setDoubleBuffered(true);
JTooltipFlickerTest.this.getContentPane().add (panel, "Center");
JTooltipFlickerTest.this.setVisible (true);
}
}
);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
installRepaintManager();
}
private void installRepaintManager() {
ReflectionRepaintManager manager = new ReflectionRepaintManager();
RepaintManager.setCurrentManager(manager);
}
private class ReflectionRepaintManager extends RepaintManager {
public void addDirtyRegion(JComponent c, int x, int y, int w, int h) {
int lastDeltaX = c.getX();
int lastDeltaY = c.getY();
Container parent = c.getParent();
while (parent instanceof JComponent) {
if (!parent.isVisible()) {
return;
}
if (parent instanceof JTooltipFlickerTest) {
x += lastDeltaX;
y += lastDeltaY;
int gap = getContentPane().getHeight() - h - y;
h += 2 * gap + h;
lastDeltaX = lastDeltaY = 0;
c = (JComponent) parent;
}
lastDeltaX += parent.getX();
lastDeltaY += parent.getY();
parent = parent.getParent();
}
super.addDirtyRegion(c, x, y, w, h);
}
}
}
edited
When installRepaintManager()
禁用后,整个工具提示会在边缘边界的两侧闪烁(与OP原始代码中的效果相同)。
When installRepaintManager()
启用后,工具提示区域的一部分不会在边缘边界内闪烁。相反,它的另一部分在边缘边界之外闪烁。但是,与之前相比,闪烁并没有那么严重installRepaintManager()
被禁用。
我知道,这是一个微妙的差异,我想它没有什么值得期待的。至少,工具提示区域中的文字在以下情况下有点清晰:installRepaintManager()
已启用。
即使双缓冲代码被禁用,installRepaintManager()
按预期工作;也就是说,快速重新绘制重量级组件以减少闪烁。
//panel.setDoubleBuffered(true);
//panel.createToolTip().setDoubleBuffered(true);