可以在重量级模式下停止闪烁的java工具提示吗?
类似于 不断更新的轻量级工具提示工作正常,但一旦它移出窗口边界或变为重量级(通过禁用轻量级弹出窗口),它就是闪烁城市 尝试了“-Dsun.awt.noerasebackground=true”提示,该提示在窗口内工作,但代价是在其他组件上绘制一些人工制品(此示例只是一个空白面板)。在一扇窗户外,它没有帮助,仍然有可怕的闪烁量 有人知道怎么解决这个问题吗?还是目前还不可能 示例如下代码-->可以在重量级模式下停止闪烁的java工具提示吗?,java,tooltip,flicker,Java,Tooltip,Flicker,类似于 不断更新的轻量级工具提示工作正常,但一旦它移出窗口边界或变为重量级(通过禁用轻量级弹出窗口),它就是闪烁城市 尝试了“-Dsun.awt.noerasebackground=true”提示,该提示在窗口内工作,但代价是在其他组件上绘制一些人工制品(此示例只是一个空白面板)。在一扇窗户外,它没有帮助,仍然有可怕的闪烁量 有人知道怎么解决这个问题吗?还是目前还不可能 示例如下代码--> 不知何故,javax.swing.repaitmanager类可以帮助解决工具提示重绘问题。下面扩展重新绘
不知何故,
javax.swing.repaitmanager
类可以帮助解决工具提示重绘问题。下面扩展重新绘制管理器的类取自第11章“重新绘制管理器”中的示例:
它被修改为重新绘制JTooltipFlickerTest
的内容窗格
尝试注释掉构造函数中的installRepaitManager()
调用,您将看到不同之处
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);
}
}
}
已编辑
禁用installRepaitManager()
时,整个工具提示在边缘边界的两侧闪烁(其效果和OP的原始代码中的效果相同)
启用installRepaitManager()
时,工具提示区域的一部分不会在边缘边界内闪烁。相反,它的另一部分在边缘边界外闪烁。但是,与禁用installrepaitmanager()
时相比,闪烁情况并不严重
我知道,这是一个微妙的区别,我想它没有留下什么不想要的。至少,启用installrepaitmanager()
时,工具提示区域中的文字有点清晰
即使禁用了双缓冲代码,installrepaitmanager()
也能正常工作;也就是说,重量级组件将快速重新绘制以减少闪烁
//panel.setDoubleBuffered(true);
//panel.createToolTip().setDoubleBuffered(true);
嗯。。。我看不出有什么不同。我发现工具提示和弹出窗口并不是真正的双缓冲,即硬件双缓冲,而类的设置方式意味着不能通过子类化来改变etc@mgraham:启用installRepaitManager()
时,与面板重叠的工具提示区域部分不会闪烁;另一部分闪烁。禁用installRepaitManager()
时,整个工具提示将闪烁。这是一个微妙的差别,我想它没有留下任何不想要的东西。至少,当启用installrepaitmanager()
时,工具提示区域中的文字有点清晰。是的,我现在可以看到了。我可以用一个未修饰的JFrame制作一个虚假的工具提示,其中包含一个JTooltip,我可以在屏幕上移动它,闪烁可以忽略不计,因此它似乎是工具提示所使用的重量级Opup类所特有的。。。对真正的双缓冲警告的怀疑。。。这对我来说更糟糕,因为我使用多行HTML工具提示,所以闪烁非常糟糕…+我想在工具提示中使用半透明的重量级窗口,这样即使在组件中也会出现闪烁。我会给你一个向上的投票或者其他任何尝试,但我不允许因为之前没有帖子…@mgraham:我已经测试了它的半透明重量级假工具提示。结果如何?它的行为仍然与我所描述的一模一样。但是,如果我希望它位于任何窗口的顶部,我就无法获得令人满意的结果。我会更新我的帖子,如果我有时间。。。别担心:我真的不在乎投票系统。重要的是我们可以学习和分享我们的知识;)@mgraham:对不起,这是另一种方式。它适用于setAlwaysOnTop(true)
通过PopupFactory
。但是,当setOpaque(false)
//panel.setDoubleBuffered(true);
//panel.createToolTip().setDoubleBuffered(true);