【问题标题】:Tooltip to show a keystroke in java在java中显示击键的工具提示
【发布时间】:2015-05-22 04:35:50
【问题描述】:

按下 Control 键我想显示一个 Jbutton 的 Jtooltip。

如何显示所需击键的工具提示?

【问题讨论】:

  • 请放一些代码或研究工作
  • 你想为特定按钮还是当前焦点按钮完成它?
  • Key Bindings 会有所帮助
  • 击键理解,不用在物体上抬起鼠标,有没有办法显示tooltip? @MadProgrammer

标签: java swing keystroke


【解决方案1】:

不确定我是否理解这个问题,但您可以使用Control+F1 显示当前焦点组件的工具提示。

【讨论】:

  • 在不移动鼠标的情况下,可以显示带有指定键输入的工具提示吗? @MadProgrammer
  • @Sibal 试试看。一旦控件获得焦点,ctrl+F1 将显示工具提示
【解决方案2】:

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)来调用ToolTipManagerprivateshow方法。

你需要“按下”和“释放”动作,否则你会得到一个重复的按键事件,这会使工具提示“闪烁”

camickr 解决方案是更好(和正确)的选择,这是一个简单的“我想知道如何”破解

【讨论】:

  • 感谢您的努力。有使用Flamingo编程,CTRL F1不灵,我在看别的方法。或许CTRL经常出问题,还是用ALT更好吧?
  • 更多的是组合键,单独使用 ctrl 或 alt 并不是一个好主意,因为它们往往被用来生成其他击键。也许你应该自己绑定ctrl+F1
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多