扩展 Swing 的 ToolTipManager 以更改悬停时的行为?
Extending Swing's ToolTipManager to change behaviour on hover?
我想在 Swing 中实现一个具有自定义行为的工具提示:用户悬停在组件上的时间越长,工具提示中应显示的详细信息就越多(即,在几行之后添加几行用户悬停在组件上的秒数)。我只需要检查这是否真的适用于 Swing 而不会变得太乱。我目前的想法可能是:
- 扩展 ToolTipManager
- 覆盖 mouseEntered 以启动计时器(可能使用 javax.swing.Timer?)。定时调用setToolTipText和createToolTip刷新tooltip并添加新信息
- 覆盖 mouseExited 以重置计时器
- 可能使用 setDismissDelay 将关闭延迟设置为更长的时间(或 Integer.MAX_VALUE)
这样的事情可行吗?或者这不是使用 Swing 的好方法(抱歉,我对它还很陌生)?有更好的方法吗?
[edit] 嗯,记得 ToolTipManager 是一个单例,其构造函数仅具有包可见性,因此无法扩展。
[edit 2] 我目前正在尝试一些解决方案。我忘记添加的一件事是我确实需要知道哪个组件正在悬停 - 我想这意味着我需要使用某种带有 mouseEntered() 方法的侦听器(或者能够访问它信息)。并且不需要与 popup/tooltip 的其他交互 - 它只需要显示信息。
(这可能看起来有点令人困惑,所以如果您需要我澄清,请告诉我,我会尽力向您展示我如何描绘代码)我认为如果您扩展它,您的想法可能会奏效,并创建一个扩展 Thread
的私有 class,然后在 run()
方法中执行类似
的操作
while(true)
{
sleep(1);
timeElapsed++;
}
并在扩展 ToolTipManager
的 class 中,为扩展 Thread
的 class 创建一个字段,并在 mouseEntered(MouseEvent e)
中实例化类似:
extendsThreadClass = new ExtendsThreadClass();
extendsThreadClass.start();
然后在mouseExited(MouseEvent e)
方法中做
extendsThreadClass = null;
然后在 mouseEntered(MouseEvent e)
方法中启动 Thread
然后你可以在时间之后做你想做的事情
if(timeElapsed > 3000)
{
//what you want to do here
}
抱歉,这可能令人困惑,如果我可以为您解决问题,请告诉我
我想我应该用我在看到 l1zZY 的回答之前采用的方法更新这个(我认为这是更好的做事方式 - 在我转向其他东西之前我的代码中仍然有错误,但这可能仍然对某人有帮助)。这就是我所做的:
- 扩展 JToolTip
- 使用 Swing Timer 计时
- 向 JTree 添加 MouseMotion 侦听器(在我的例子中,我希望弹出窗口在悬停节点时显示)
有点不雅,像这样检测鼠标何时移过树节点:
public void mouseMoved(MouseEvent e) {
int x = (int) e.getX();
int y = (int) e.getY();
TreePath path = getPathForLocation(x, y);
if (path == null) {
tooltip.hide();
} else {
TreeNode node = (TreeNode) path.getLastPathComponent();
tooltip.setHoveredNode(node);
if (!tooltip.isVisible) {
int absX = e.getXOnScreen();
int absY = e.getYOnScreen();
final Popup tooltipContainer = PopupFactory.getSharedInstance().getPopup(PDTreeView.this,
tooltip, absX, absY);
tooltip.setToolTipContainer(tooltipContainer);
tooltip.show();
}
}
}
tooltip.show()
指的是工具提示是如何包含在 Popup 中的
为了以编程方式显示或隐藏它。 show()
显示
弹出窗口(以及工具提示)并启动 Swing 计时器。
Timer 有一个名为 actionPerformed()
的方法,它会在您设置的任何时间间隔内调用。我刚刚让那个方法调用了将新信息添加到工具提示的代码。在 hide()
中,我重置了工具提示和计时器。
我遇到了弹出窗口或工具提示的问题,无法调整大小以适应内容,但除此之外似乎没问题。
我想在 Swing 中实现一个具有自定义行为的工具提示:用户悬停在组件上的时间越长,工具提示中应显示的详细信息就越多(即,在几行之后添加几行用户悬停在组件上的秒数)。我只需要检查这是否真的适用于 Swing 而不会变得太乱。我目前的想法可能是:
- 扩展 ToolTipManager
- 覆盖 mouseEntered 以启动计时器(可能使用 javax.swing.Timer?)。定时调用setToolTipText和createToolTip刷新tooltip并添加新信息
- 覆盖 mouseExited 以重置计时器
- 可能使用 setDismissDelay 将关闭延迟设置为更长的时间(或 Integer.MAX_VALUE)
这样的事情可行吗?或者这不是使用 Swing 的好方法(抱歉,我对它还很陌生)?有更好的方法吗?
[edit] 嗯,记得 ToolTipManager 是一个单例,其构造函数仅具有包可见性,因此无法扩展。
[edit 2] 我目前正在尝试一些解决方案。我忘记添加的一件事是我确实需要知道哪个组件正在悬停 - 我想这意味着我需要使用某种带有 mouseEntered() 方法的侦听器(或者能够访问它信息)。并且不需要与 popup/tooltip 的其他交互 - 它只需要显示信息。
(这可能看起来有点令人困惑,所以如果您需要我澄清,请告诉我,我会尽力向您展示我如何描绘代码)我认为如果您扩展它,您的想法可能会奏效,并创建一个扩展 Thread
的私有 class,然后在 run()
方法中执行类似
while(true)
{
sleep(1);
timeElapsed++;
}
并在扩展 ToolTipManager
的 class 中,为扩展 Thread
的 class 创建一个字段,并在 mouseEntered(MouseEvent e)
中实例化类似:
extendsThreadClass = new ExtendsThreadClass();
extendsThreadClass.start();
然后在mouseExited(MouseEvent e)
方法中做
extendsThreadClass = null;
然后在 mouseEntered(MouseEvent e)
方法中启动 Thread
然后你可以在时间之后做你想做的事情
if(timeElapsed > 3000)
{
//what you want to do here
}
抱歉,这可能令人困惑,如果我可以为您解决问题,请告诉我
我想我应该用我在看到 l1zZY 的回答之前采用的方法更新这个(我认为这是更好的做事方式 - 在我转向其他东西之前我的代码中仍然有错误,但这可能仍然对某人有帮助)。这就是我所做的:
- 扩展 JToolTip
- 使用 Swing Timer 计时
- 向 JTree 添加 MouseMotion 侦听器(在我的例子中,我希望弹出窗口在悬停节点时显示)
有点不雅,像这样检测鼠标何时移过树节点:
public void mouseMoved(MouseEvent e) { int x = (int) e.getX(); int y = (int) e.getY(); TreePath path = getPathForLocation(x, y); if (path == null) { tooltip.hide(); } else { TreeNode node = (TreeNode) path.getLastPathComponent(); tooltip.setHoveredNode(node); if (!tooltip.isVisible) { int absX = e.getXOnScreen(); int absY = e.getYOnScreen(); final Popup tooltipContainer = PopupFactory.getSharedInstance().getPopup(PDTreeView.this, tooltip, absX, absY); tooltip.setToolTipContainer(tooltipContainer); tooltip.show(); } }
}
tooltip.show()
指的是工具提示是如何包含在 Popup 中的 为了以编程方式显示或隐藏它。show()
显示 弹出窗口(以及工具提示)并启动 Swing 计时器。Timer 有一个名为
actionPerformed()
的方法,它会在您设置的任何时间间隔内调用。我刚刚让那个方法调用了将新信息添加到工具提示的代码。在hide()
中,我重置了工具提示和计时器。
我遇到了弹出窗口或工具提示的问题,无法调整大小以适应内容,但除此之外似乎没问题。