我有一个组件,我想显示自定义jtooltip。这很简单,只需更改getTooltip方法即可。类似于位置和文字。
但是我也想改变计时器。如果鼠标位于组件的cellrenderer上,则应始终显示工具提示。如果它离开了所有这些,它应该变得不可见。 我知道我可以使用TooltipManager来控制全局时间。但最好的解决方案可能只是短截线,并用鼠标滑块显示工具提示。但是,当我尝试这样做时(取消注册TooltipManager中的组件并设置工具提示可见,文本和位置正确,在鼠标监听器中)工具提示根本没有显示。我做错了什么?
编辑: 现在问题已经改变了!分为2个问题。
我的解决方案现在就是这样,但是它会丢失jtooltip总是显示有时令人沮丧的阴影,并且如果鼠标退出进入弹出窗口本身就会隐藏它。如果弹出窗口甚至不是组件,如何通过弹出窗口过滤mouseexit事件?我可以根据lastPosition做一些黑客攻击,但这看起来很愚蠢,因为我真的不知道它的宽度。
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;
}
}
答案 0 :(得分:6)
您可以在组件中添加鼠标侦听器,以便在鼠标进入并离开组件上方的区域时更改全局工具提示计时器,而不是尝试重新实现工具提示的显示。
以下是一些示例代码:
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);
}
});
每当鼠标移动到组件上时,这应该将工具提示延迟更改为零,并在鼠标离开组件时将其更改回默认延迟。
答案 1 :(得分:3)
但最好的解决方案可能是 只是短路并显示 使用mouselistener工具提示自己
调用组件的默认操作以显示工具提示:
Action toolTipAction = component.getActionMap().get("postTip");
if (toolTipAction != null)
{
ActionEvent postTip = new ActionEvent(component, ActionEvent.ACTION_PERFORMED, "");
toolTipAction.actionPerformed( postTip );
}
编辑:
上面的代码似乎不再起作用了。 Ctrl + F1是用于显示组件工具提示的默认KeyStroke。因此,另一种方法是将Ctrl + F1 KeyStroke分派给组件。例如:
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();
}
});
}
}
答案 2 :(得分:0)
显然,如果getTooltipText返回null,则控制Tooltip显示的是什么。让它为null,消除一个npe并允许显示的东西。但是仍有一些文物......