当前位置: 首页 > 知识库问答 >
问题:

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

顾俊誉
2023-03-14

在一个帮助系统中工作,我希望每个组件都能提供一些帮助,当鼠标在它上面和“?”键被按下。有点像工具提示,除了更广泛的帮助--本质上,一个小小的web浏览器是用来弹出并显示文本、图像或更多。

我发现的是,无论鼠标在哪里,输入总是进入同一个KeyListener。一次只能有一个活动的吗?

值得的是,这是现在正在工作的版本--谢谢你的建议!

    /**
     * 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个答案

葛骏
2023-03-14

我肯定有更好的办法,但有一个快速而肮脏的解决办法:

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())访问所有受影响的组件。

武晨
2023-03-14

输入总是进入同一个KeyListener。

键事件总是被调度到有焦点的组件,鼠标位置与键事件的生成方式无关。

您应该使用键绑定而不是使用KeyListener。当您使用键绑定时,只要通过将绑定添加到JFrame的根窗格生成击键,就可以调用一个操作。有关更多信息,请阅读Swing教程中关于键绑定的部分。

现在,在您创建的监听“?”的操作中然后击键您可以:

  1. 使用MouseInfo类获取当前鼠标位置。
  2. 使用SwingUtilites.ConvertPointFromScreen(...)将鼠标点转换为相对于根窗格
  3. 然后您可以使用conatiner.getComponentat(...)获取鼠标所在的实际组件
  4. 一旦了解组件,就可以显示帮助信息。
 类似资料:
  • 按照惯例,用户接口的ActionListener应该去哪里?我有几个选择,但似乎没有一个是对的。 速记: null 我可以在GUI中内联声明一个新的ActionListener,存储它,然后它/将其指针传递到需要它的地方。 我可以让GUI本身实现ActionListener,并将对自身的引用传递到需要它的地方。 我可以在主逻辑中内联声明一个新的ActionListener(这是有意义的,因为按钮执

  • 问题内容: 在下面的代码(从键盘检索字符并打印到命令行)中,我在概念上无法理解我指定输入必须来自键盘的地方? 问题答案: 不是方法,而是默认情况下绑定到键盘的字段。 “标准”输入流。该流已经打开,可以提供输入数据了。通常,此流对应于键盘输入或主机环境或用户指定的另一个输入源。 您可以调用该方法以将其更改为其他输入流。 参考:命令行中的I / O

  • 问题内容: 我正在使用SphinxSearch查询某些内容,并具有要使用MySQL查询的对象的ID。我的ID数组根据Sphinx给出的排名进行排序。因此,我想制作一个像这样的MySQL: 我知道我可以做: 但是我无法获得订单。 我如何与Laravel以适当的方式做到这一点? 问题答案: 使用http://laravelsnippets.com/snippets/get-all-items-at-o

  • 用于创建自己的令牌和字符过滤器的Solr文档说明如下。 http://wiki.apache.org/solr/AnalyzersTokenizersTokenFilters#Specifying_an_Analyzer_in_the_schema 如果您想使用定制的CharFilters、Tokenizer或TokenFilters,您需要编写一个非常简单的工厂,将BaseTokenizerFa

  • 我想写一个很小的“Hello World”J2ME MIDlet。在这样的示例中,中的类用于显示输出。当我尝试在Eclipse中编译它时,我得到错误, 无法解析导入javax.microedition.lcdui 我已经安装了JME SDK3.4,并且能够运行不导入javax.microedition.lcdui.*的MIDlet。我在某处读到lcdui可以从无线工具包中获得;Oracle表示,从

  • 在javax中输入if条件的位置。swing我正在创建一个注册表格,希望在表格中添加以下条件:•姓名:不能少于3个字母。•地址1和地址2:两个地址不应该相同年龄:不少于18岁身高:不低于130重量:不少于30,但我不知道在哪里进入if状态