首页 文章

在java awt或swing中,我如何安排键盘输入去鼠标的哪里?

提问于
浏览
6

在帮助系统上工作,我希望每个组件在鼠标悬停时提供一些帮助并且“?”按下键 . 有点像工具提示,除了更广泛的帮助 - 基本上一个小的Web浏览器旨在弹出和显示文本,图像或更多 .

我发现无论鼠标在哪里,输入总是转到同一个KeyListener . 是否应该一次只有一个活跃?

对于它的 Value ,这是现在正在运行的版本 - 感谢您的建议!

/**
     * Main class JavaHelp wants to support a help function so that when
     * the user types F1 above a component, it creates a popup explaining
     * the component.
     * The full version is intended to be a big brother to tooltips, invoking
     * an HTML display with clickable links, embedded images, and the like.
     */


    import javax.swing.*;
    import javax.swing.border.Border;
    import java.awt.*;
    import java.awt.event.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;

    class Respond2Key extends AbstractAction
    {
    Component jrp;

    // Contract consructor
    public Respond2Key( String text)
    {
      super( text );
    }

    // Constructor that makes sure it gets done right
    public Respond2Key( String text, Component jrpIn)
    {
      super( text );
      System.out.println( "creating Respond2Key with component " + jrpIn
                                       .toString
                                        () );
      jrp = jrpIn;
    }

    public void setJrp( Component j) {
        jrp = j;
    }


    // Functionality: what is the response to a key
    public void actionPerformed(ActionEvent e)
    {
      // use MouseInfo to get position, convert to pane coords, lookup component
      Point sloc = MouseInfo.getPointerInfo().getLocation();

      SwingUtilities.convertPointFromScreen( sloc, (Component) jrp );

      Component c = jrp.getComponentAt( sloc );
      System.out.printf( "Mouse at %5.2f,%5.2f Component under mouse is %s\n",
                 sloc.getX(), sloc.getY(), c.toString() );
    }
    }


    //---------------------------------------------------------------- 
    // The main class
    //---------------------------------------------------------------- 
    public class JavaHelp extends JFrame
    {
    // The object constructor
    public JavaHelp()
    {
        // Start construction
        super( "Help System" );
        this.setSize( 640, 480 );
        Container contents = getContentPane();
        contents.setLayout( new FlowLayout() );


        JButton b1 = butt(  "button1", 64, 48 );
        JButton b2 = butt(  "button2", 96, 48 );
        JButton b3 = butt(  "button3", 128, 48 );
        JPanel p1 = pane( "hello", 100, 100 );
        JPanel p2 = pane( "world", 200, 100 );

        contents.add( b1 );
        contents.add( p1 );
        contents.add( b2 );
        contents.add( p2 );
        contents.add( b3 );

        JRootPane jrp = this.getRootPane();
        jrp.getInputMap( jrp.WHEN_IN_FOCUSED_WINDOW)
        .put( KeyStroke.getKeyStroke( "F1" ), "helpAction" );
        jrp.getActionMap().put( "helpAction",
                    new Respond2Key("frame",(Component)contents)
                    );
        this.setVisible( true );
        this.requestFocus();
        this.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );

    }

    // Inner classes for instantiating and listening to button, and panel.
    class ButtonListener implements ActionListener
    {
      private String label = null;

      public void setLabel(String s) {label = s;}

      public void actionPerformed(ActionEvent e)
      {
        System.out.printf( "Dealing with event labeled %s source %s\n\n",
                   label,
                   e.getSource().toString() );
      }

    }

    // def butt( from, name, w, h) = new Jbutton (...)
    protected JButton butt( String s, int w, int h)
    {
      JButton b = new JButton( s );
      b.setSize( w, h );
      ButtonListener oj = new ButtonListener();
      oj.setLabel( s );
      b.addActionListener( oj );
      return (b);
    }

    // def pane = new Jpanel(...)
    protected JPanel pane(String name, int w, int h)
    {
      JPanel p = new JPanel();
      p.setMinimumSize( new Dimension( w, h ) );
      p.add( new Label( name ) );
      p.setBackground( Color.black );
      p.setForeground( Color.red );
      return (p);
    }

    //--------------------------------
    public static void main(String[] args)
    {
      JavaHelp jh = new JavaHelp();
    }



    }

2 回答

  • 3

    输入始终转到相同的KeyListener .

    始终将KeyEvent调度到具有焦点的组件,鼠标位置与生成键事件的方式无关 .

    您应该使用 Key Bindings 而不是使用KeyListener . 使用键绑定时,只要通过将绑定添加到JFrame的根窗格生成KeyStroke,就可以调用Action . 有关详细信息,请阅读Key Bindings上Swing教程中的部分 .

    现在在你创建的Action中听取“?” KeyStroke然后你可以:

    • 使用 MouseInfo 类获取当前鼠标位置 .

    • 使用 SwingUtilities.convertPointFromScreen(...) 将鼠标点转换为相对于根窗格

    • 然后您可以使用 Conatiner.getComponentAt(...) 获取鼠标结束的实际组件

    • 一旦您知道该组件,您就可以显示您的帮助信息 .

  • 3

    我确信有更好的方法,但一个快速而肮脏的解决方案:

    private final class HoverFocusListener extends MouseInputAdapter {  
      public void mouseEntered(MouseEvent e) {
        e.getComponent().requestFocusInWindow();   
      }
    }
    

    或者,如有必要:

    public void mouseEntered(MouseEvent e) {
      e.getSource().setFocusable(true);
      for (Component c : refToParent.getComponents()) c.setFocusable(false);
      e.getComponent().requestFocusInWindow();   
     }
    

    然后只需 .addMouseListener(new HoverFocusListener()) 到所有受影响的组件 .

相关问题