TooltipManager 中有一个private 方法叫做show,它以JComponent 为参数,用于显示工具提示。这实际上是由 TooltipManager 在按下 CTRL+F1 时使用的...
所以,我的第一个建议是使用 CTRL+F1,因为它是内置的。我的第二个建议是使用 CTRL+F1 因为人们按下 CTRL 的原因有很多(例如复制/粘贴、菜单快捷方式等),如果您一直弹出所有工具提示,这可能会很烦人时间。我的第三个建议是使用 CTRL+F1 因为show 方法是private
但是,因为我只是好奇(而且完全疯了),你“可以”(但我不推荐)使用肮脏、肮脏的 hack(我像 Phillip Fry 一样堕落),这很可能解决问题时在你的脸上炸毁(但我很好奇如何将动作绑定到 CTRL 键)
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.KeyboardFocusManager;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JComponent;
import static javax.swing.JComponent.WHEN_IN_FOCUSED_WINDOW;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.ToolTipManager;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
JButton btn = new JButton("Banana");
btn.setToolTipText("Hello");
add(btn);
TooltipPopup.register(this);
}
}
public static class TooltipPopup {
public static void register(JComponent comp) {
new TooltipPopup(comp);
}
private JComponent parent;
private boolean showing = false;
private TooltipPopup(JComponent parent) {
this.parent = parent;
bindKeyStrokeTo(parent,
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,
"help.press",
KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL, InputEvent.CTRL_DOWN_MASK),
new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
if (!showing) {
Component comp = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
if (comp != null && comp instanceof JComponent) {
JComponent focused = (JComponent) comp;
try {
Class clazz = ToolTipManager.sharedInstance().getClass();
Method method = clazz.getDeclaredMethod("show", JComponent.class);
method.setAccessible(true);
method.invoke(ToolTipManager.sharedInstance(), focused);
showing = true;
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
ex.printStackTrace();
}
}
}
}
});
bindKeyStrokeTo(parent,
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,
"help.release",
KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL, 0, true),
new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
showing = false;
}
});
}
public void bindKeyStrokeTo(JComponent parent, int condition, String name, KeyStroke keyStroke, Action action) {
InputMap im = parent.getInputMap(condition);
ActionMap am = parent.getActionMap();
im.put(keyStroke, name);
am.put(name, action);
}
}
}
所有这一切都是将按下和释放Action 绑定到给定组件(父容器)的 CTRL,它将找到当前聚焦的组件并显示它的工具提示。
它使用反射“tick”(hack)来调用ToolTipManager的privateshow方法。
你需要“按下”和“释放”动作,否则你会得到一个重复的按键事件,这会使工具提示“闪烁”
camickr 解决方案是更好(和正确)的选择,这是一个简单的“我想知道如何”破解