在JavaSwing中为特定组件设置工具提示延迟时间
我正在尝试在在JavaSwing中为特定组件设置工具提示延迟时间,java,performance,swing,user-interface,tooltip,Java,Performance,Swing,User Interface,Tooltip,我正在尝试在JEditorPane上设置工具提示。我用来确定要显示的工具提示文本的方法相当占用CPU—因此我只想在鼠标停止一小段时间后显示它—比如1秒 我知道我可以使用ToolTipManager.sharedInstance().setInitialDelay(),但是这会同时设置所有swing组件上工具提示的延迟时间,我不希望这样做。好吧,我建议在另一个线程上执行CPU密集型任务,这样它就不会中断正常的GUI任务 这将是一个更好的解决办法。(而不是试图回避问题) *编辑*您可以计算JEdit
JEditorPane
上设置工具提示。我用来确定要显示的工具提示文本的方法相当占用CPU—因此我只想在鼠标停止一小段时间后显示它—比如1秒
我知道我可以使用
ToolTipManager.sharedInstance().setInitialDelay()
,但是这会同时设置所有swing组件上工具提示的延迟时间,我不希望这样做。好吧,我建议在另一个线程上执行CPU密集型任务,这样它就不会中断正常的GUI任务
这将是一个更好的解决办法。(而不是试图回避问题)
*编辑*您可以计算JEditorPane
中每个单词的tootips,并将其存储在地图中。然后,如果tootip发生变化,您只需从映射中访问它
理想情况下,人们不会同时移动鼠标和打字。因此,当文本更改时,您可以计算tootlips,只需从mouseMoved()
上的Map
中拉出它们,您就可以自己显示弹出窗口了。侦听mouseMoved()事件,启动/停止计时器,然后用以下代码显示弹出窗口:
首先,您需要弹出工厂、弹出窗口和工具提示:
private PopupFactory popupFactory = PopupFactory.getSharedInstance();
private Popup popup;
private JToolTip toolTip = jEditorPane.createToolTip();
然后,要显示或隐藏工具提示,请执行以下操作:
private void showToolTip(MouseEvent e) {
toolTip.setTipText(...);
int x = e.getXOnScreen();
int y = e.getYOnScreen();
popup = popupFactory.getPopup(jEditorPane, toolTip, x, y);
popup.show();
}
private void hideToolTip() {
if (popup != null)
popup.hide();
}
这将给您带来可调整的延迟和许多麻烦:)如果您想让工具提示对特定组件的延迟进行更长时间的消除,那么这是一个很好的解决方法:
(技术at的荣誉)
FWIW,这是基于Noel帖子的代码。它采用现有技术,并将其封装在一个新类中,默认值静态存储。以防任何人受益:
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
/**
* Provides customizable tooltip timeouts for a {@link javax.swing.JComponent}.
*
* @see ToolTipManager#setDismissDelay(int).
*/
public final class CustomTooltipDelayer extends MouseAdapter
{
private static final int defaultDismissTimeout = ToolTipManager.sharedInstance().getDismissDelay();
private final int _delay;
/**
* Override the tooltip timeout for the given component in raw millis.
*
* @param component target
* @param delay the timeout duration in milliseconds
*/
public static CustomTooltipDelayer attach(JComponent component, int delay)
{
CustomTooltipDelayer delayer = new CustomTooltipDelayer(delay);
component.addMouseListener( delayer );
return delayer;
}
/**
* Override the tooltip timeout for the given component as a ratio of the JVM-wide default.
*
* @param component target
* @param ratio the timeout duration as a ratio of the default
*/
public static CustomTooltipDelayer attach(JComponent component, float ratio)
{
return attach( component, (int)(defaultDismissTimeout * ratio) );
}
/** Use factory method {@link #attach(JComponent, int)} */
private CustomTooltipDelayer(int delay)
{
_delay = delay;
}
@Override
public void mouseEntered( MouseEvent e )
{
ToolTipManager.sharedInstance().setDismissDelay(_delay);
}
@Override
public void mouseExited( MouseEvent e )
{
ToolTipManager.sharedInstance().setDismissDelay(defaultDismissTimeout);
}
}
你在工具提示中做了什么,而这些不能在后台线程中计算?一些示例代码可能会有所帮助。也许我可以举一个例子来说明我所说的。我想根据用户悬停在哪个单词上来更改工具提示的内容。填充工具提示内容的任务非常昂贵,因此我只想在用户因某个单词而暂停时执行该计算。现在我正在使用MouseMotionListener,并在mouseMoved()处理程序中更改工具提示内容。我想你的建议是,我启动一个线程来计算工具提示的内容,然后显示它,当它就绪时,你的编辑是一个非常好的建议。我不确定它是否会起作用,因为它实际上是我正在处理的一个调试器,因此映射中的值可能会发生变化——尽管这是个好主意。我认为你关于在线程中计算值的建议也很好。是的,我同意——某种形式的在鼠标移动时缓存答案并在用户停止时检索答案可以解决我的问题。我明天会试试——我会把你的答案设为“接受”。感谢您的帮助。在我的例子中,如果您将鼠标悬停在状态栏开始处的图标上方,将弹出一个包含过去“n”条消息的工具提示。只要将鼠标保持在工具提示边界内,它就会保持不变。但我想在不更改全局工具提示计时的情况下控制所有计时方面。在我看来,你的解决方案似乎比公认的答案要好得多,但嘿,这只是我的两分钱?感谢Piligrim提供的此解决方案,我很快就会尝试!我很久没看这篇文章了,但我喜欢你的建议。我从来没有机会完成这个项目,所以我会很快再试一次。我会给你的想法一个机会:)对我来说,它工作得很好。事实上,这应该是首选。+1,但我做了一个改变。我将默认超时设置在mouseenterned()
之外,因为如果多次设置defaultDismissTimeout,可能会把事情搞砸(如果用户有多个组件并排更改超时,会怎么样?从一个组件移动到另一个组件可能会完全丢失默认超时)理想情况下,defaultDismissTimeout应该是全局的,以确保在整个应用程序初始化时只设置一次。@ArtOfWarfare,在链接的博客中,defaultDismissTimeout被标记为final,我想这就是他们绕过多重设置的原因。@BuhBuh-我在这里编辑了答案,将defaultDismissTimeout带到监听器之外,但在我根据这个答案编写的实际代码中,我决定将它作为组件的静态最终变量。如果您想查看默认的实际值,请查看第85-91行:
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
/**
* Provides customizable tooltip timeouts for a {@link javax.swing.JComponent}.
*
* @see ToolTipManager#setDismissDelay(int).
*/
public final class CustomTooltipDelayer extends MouseAdapter
{
private static final int defaultDismissTimeout = ToolTipManager.sharedInstance().getDismissDelay();
private final int _delay;
/**
* Override the tooltip timeout for the given component in raw millis.
*
* @param component target
* @param delay the timeout duration in milliseconds
*/
public static CustomTooltipDelayer attach(JComponent component, int delay)
{
CustomTooltipDelayer delayer = new CustomTooltipDelayer(delay);
component.addMouseListener( delayer );
return delayer;
}
/**
* Override the tooltip timeout for the given component as a ratio of the JVM-wide default.
*
* @param component target
* @param ratio the timeout duration as a ratio of the default
*/
public static CustomTooltipDelayer attach(JComponent component, float ratio)
{
return attach( component, (int)(defaultDismissTimeout * ratio) );
}
/** Use factory method {@link #attach(JComponent, int)} */
private CustomTooltipDelayer(int delay)
{
_delay = delay;
}
@Override
public void mouseEntered( MouseEvent e )
{
ToolTipManager.sharedInstance().setDismissDelay(_delay);
}
@Override
public void mouseExited( MouseEvent e )
{
ToolTipManager.sharedInstance().setDismissDelay(defaultDismissTimeout);
}
}