Java 如何更改1个组件的jtooltip计时器
我有一个组件,我想在其中显示自定义jtooltip。这很简单,只需更改getTooltip方法。位置和文本类似 然而,我也想改变计时器。如果鼠标位于组件的cellrenderer上,则应始终显示工具提示。如果它离开了所有这些,它应该变成隐形的。 我知道我可以使用ToolTimManager来全局控制时间。但最好的解决方案可能是缩短这个时间,自己用鼠标听器显示工具提示。但是,当我尝试这样做时(在ToolTimManager中注销组件,并在鼠标侦听器中将工具提示设置为可见,文本和位置正确),工具提示根本没有显示。我做错了什么 编辑: 现在问题变了!分成两个问题 目前我的解决方案是这样的,但是它会丢失jtooltip有时总是令人沮丧地显示的阴影,并且如果鼠标退出到弹出窗口中,它会被隐藏。如果弹出窗口甚至不是一个组件,如何通过弹出窗口过滤mouseexit事件?我可以根据最后的位置进行一些黑客攻击,但这似乎很愚蠢,因为我不知道它的宽度Java 如何更改1个组件的jtooltip计时器,java,swing,Java,Swing,我有一个组件,我想在其中显示自定义jtooltip。这很简单,只需更改getTooltip方法。位置和文本类似 然而,我也想改变计时器。如果鼠标位于组件的cellrenderer上,则应始终显示工具提示。如果它离开了所有这些,它应该变成隐形的。 我知道我可以使用ToolTimManager来全局控制时间。但最好的解决方案可能是缩短这个时间,自己用鼠标听器显示工具提示。但是,当我尝试这样做时(在ToolTimManager中注销组件,并在鼠标侦听器中将工具提示设置为可见,文本和位置正确),工具提示
private Popup lastPopup;
private final JToolTip tooltip = ...;
private Point lastPoint;
@Override public void mouseMoved(MouseEvent e) {
Point p = privateToolTipLocation(e);
if (p == null || p.equals(lastPoint)) {
return;
}
lastPoint = p;
tooltip.setTipText(privateToolTipText(e));
//copy
p = new Point(p);
SwingUtilities.convertPointToScreen(p, this);
Popup newPopup = PopupFactory.getSharedInstance().getPopup(this, tooltip, p.x, p.y);
if (lastPopup != null) {
lastPopup.hide();
}
lastPopup = newPopup;
newPopup.show();
}
@Override public void mouseExited(MouseEvent e) {
if (lastPopup != null && someUnknownCondiction) {
lastPopup.hide();
lastPopup = null;
}
}
显然,控制工具提示显示的是getToolTiptText是否返回null。如果将其设置为null,则消除一个npe并允许显示内容。然而,仍然有一些人工制品 但最好的解决办法可能是 只需将其短接并显示 用鼠标听器提示我自己 调用组件的默认操作以显示工具提示:
Action toolTipAction = component.getActionMap().get("postTip");
if (toolTipAction != null)
{
ActionEvent postTip = new ActionEvent(component, ActionEvent.ACTION_PERFORMED, "");
toolTipAction.actionPerformed( postTip );
}
编辑:
上述代码似乎不再有效。Ctrl+F1是用于显示零部件工具提示的默认击键。因此,另一种方法是将Ctrl+F1键发送到组件。例如:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class PostTipSSCCE2 extends JPanel
{
public PostTipSSCCE2()
{
FocusAdapter fa = new FocusAdapter()
{
public void focusGained(FocusEvent e)
{
JComponent component = (JComponent)e.getSource();
KeyEvent ke = new KeyEvent(
component,
KeyEvent.KEY_PRESSED,
System.currentTimeMillis(),
KeyEvent.CTRL_MASK,
KeyEvent.VK_F1,
KeyEvent.CHAR_UNDEFINED);
component.dispatchEvent( ke );
}
};
MouseAdapter ma = new MouseAdapter()
{
@Override
public void mouseEntered(MouseEvent e)
{
JComponent component = (JComponent)e.getSource();
KeyEvent ke = new KeyEvent(
component,
KeyEvent.KEY_PRESSED,
System.currentTimeMillis(),
KeyEvent.CTRL_MASK,
KeyEvent.VK_F1,
KeyEvent.CHAR_UNDEFINED);
component.dispatchEvent( ke );
}
};
JButton button = new JButton("Button");
button.setToolTipText("button tool tip");
button.addFocusListener( fa );
button.addMouseListener( ma );
add( button );
JTextField textField = new JTextField(10);
textField.setToolTipText("text field tool tip");
textField.addFocusListener( fa );
textField.addMouseListener( ma );
add( textField );
JCheckBox checkBox = new JCheckBox("CheckBox");
checkBox.setToolTipText("checkbox tool tip");
checkBox.addFocusListener( fa );
checkBox.addMouseListener( ma );
add( checkBox );
}
private static void createAndShowUI()
{
JFrame frame = new JFrame("PostTipSSCCE2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( new JScrollPane(new PostTipSSCCE2()) );
frame.pack();
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
与其尝试重新实现工具提示的显示,不如向组件添加鼠标侦听器,以便在鼠标进入和离开组件上方的区域时更改全局工具提示计时器 下面是一些示例代码:
instantTooltipComponent.addMouseListener(new MouseAdapter()
{
final int defaultTimeout = ToolTipManager.sharedInstance().getInitialDelay();
@Override
public void mouseEntered(MouseEvent e) {
ToolTipManager.sharedInstance().setInitialDelay(0);
}
@Override
public void mouseExited(MouseEvent e) {
ToolTipManager.sharedInstance().setInitialDelay(defaultTimeout);
}
});
这应该会在鼠标移动到组件上时将工具提示延迟更改为零,并在鼠标离开组件时将其更改回默认延迟。我想这是可行的。脏但有效,因为不能有两个鼠标指针。好啊你被标记为正确。编程的一个更深层次的谜团是“什么时候‘脏但能用’才是正确的?”;-)当应用程序小而简单时。对于较大的应用程序,这种黑客行为可能会开始增加,并导致各种问题。此外,对于奇怪的黑客行为(用最好的话说),也可能发生意外情况,在本例中,如果用户将鼠标放在组件上,然后将焦点更改为另一个应用程序(例如通过alt tab)然后,直到应用程序恢复焦点,鼠标退出事件才会发布。可能给你想要的,也可能不给你想要的——谁知道呢?这个解决方案很有道理,但它不起作用。我不明白为什么,行动是调用工具提示之类东西的合乎逻辑的方式。@TomášZato,嗯,你说得对。我确信它曾经起过作用,我不记得编了一个动作名:)添加了另一种方法将Ctrl+F1键发送到组件。但这只适用于可聚焦组件。我想立即显示一些悬停工具提示,我必须使用公认的答案。但我认为,如果存在这样的情况,将来我将不得不切换到更复杂的工具提示类。@TomášZato,
这将只适用于可聚焦组件,尽管
——我认为这是在使用GUI时。Swing需要知道哪个组件具有焦点,以便能够分派事件。在本例中,我们根据MouseEvent指定组件,dispatchEvent(…)
似乎在组件没有焦点时也能工作。我更新了示例,使其也包含一个MouseListener,效果很好。无论如何,你有一个解决方案,不确定哪一个更优雅。