我有一些代码可以在用户操作后在屏幕上生成JToolTip。我希望用户能够通过单击提示或单击某个键(例如ESC)来消除提示。我可以使鼠标部分正常工作,但无法弄清楚如何/在何处捕获按键事件。我怀疑这与专注有关,但是我所有的随机刺刺都是徒劳的。这是一个简短的代码示例,显示了我的尝试:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.*;

public class HelloSwing extends JFrame {

  HelloSwing() {
    JPanel panel = new JPanel();
    JButton button = new JButton("Hello!");

    button.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        final JWindow window = new JWindow();
        JToolTip tip = new JToolTip();
        tip.setTipText("Here's a tip...");
        tip.setVisible(true);
        window.getContentPane().add(tip);
        window.pack();
        window.setLocation(50, 50);
        window.setAlwaysOnTop(true);
        window.setVisible(true);

        // This works:
        window.getRootPane().addMouseListener(new MouseAdapter() {
          @Override
          public void mouseClicked(MouseEvent e) {
            window.setVisible(false);
          }
        });

        // This does not work:
        window.getRootPane().addKeyListener(new KeyAdapter() {
          @Override
          public void keyPressed(KeyEvent e) {
            System.out.println("key pressed!");
            window.setVisible(false);
          }
        });
      }
  });

    panel.add(button);
    add(panel);
  }

  public static void main(String[] args) {
    HelloSwing hello = new HelloSwing();
    hello.setTitle("Title!");
    hello.setSize(300, 200);
    hello.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    hello.setVisible(true);
  }
}

最佳答案

为了使关键侦听器正常工作,组件必须具有焦点并具有焦点。关键侦听器是较低级别的接口。最好改用键绑定。有关详细信息和示例,请参见How to Use Key Bindings。例如,尝试以下操作:

getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, false), "ESCAPE");
getRootPane().getActionMap().put("ESCAPE", new AbstractAction() {
    public void actionPerformed(ActionEvent e) {
        window.setVisible(false);
    }
});


请注意,ToolTipManager已经注册了VK_ESCAPE以隐藏工具提示,通常情况下,转义可以按预期进行。

另请注意,在这种情况下无需使用JToolTip,因为您正在使用JWindow手动显示它。它可以只是一个JLabel

有关常见工具提示用法的一些示例,请参见How to Use Tool Tips

07-28 06:07