未聚焦组件中的KeyPressed和mousePressed事件 [英] KeyPressed and mousePressed Event in an unfocused Component

查看:220
本文介绍了未聚焦组件中的KeyPressed和mousePressed事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


  1. 检测关键笔划有几种方法,而不需要关注事件实现的组件。这是我的想法:

    即使没有关注 myComponent ,按下一个键后,该操作应该参与。
    **同样的问题是 mousePressed 事件。即使未点击组件,也会检测到鼠标点击。**

      myComponent.addKeyListener(new KeyAdapter(){
    @Override
    public void keyPressed(KeyEvent e){
    // My action here
    }

    });


  2. 回答 Question1 即使应用程序在后台运行,也会执行此操作吗?假设我有一个浏览器,每次点击或按下一个键,都会执行给定的操作。

  3. 也接受建议阅读为答案。如果你的答案是KeyBinding相关的,请详细说明。所有的答案和意见将不胜感激。






    我使用 JNativeHooks 这里的例子,它工作得很好。对于第一个问题,关于KeyStroke的事情,我猜你可以使用<一个Java的单独的方法吗?

    解决方案

    href =http://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html =noreferrer> KeyBinding 而不是使用KeyListener,它可以给你想要的结果,没有尽管在Java Dimensions中,焦点相关的问题仍然存在。

    在下面的例子中,重点在于 JTextField ,所以如果你按 CTRL + D ,那么即使焦点在于 JTextField



    虽然如果您将使用 setMnemonic()方法用于 JButton ,然后 JButton 将获得焦点,并执行与之相关的自己的操作,即绘制椭圆。这可以通过按 ALT + C 来查看所需的效果。再次执行绘图相关的事情,这两个组件有问题不需要焦点,但他们仍然响应的KeyStrokes。



    这是示例代码:

      import java.awt。*; 
    import java.awt.event。*;
    import java.util.Random;
    import javax.swing。*;

    公共类SSCCE
    {
    private final int WIDTH = 500;
    private final int HEIGHT = 500;
    私人的CustomPanel customPanel;
    私人JButton circleButton;
    私人JTextField tfield;
    私人随机随机;
    私有int模式;

    私有操作paintAction = new AbstractAction()
    {
    @Override
    public void actionPerformed(ActionEvent ae)
    {
    mode = random .nextInt(3);
    color color = new Color(random.nextFloat(),random.nextFloat()
    ,random.nextFloat(),random.nextFloat());
    customPanel.setValues(random.nextInt(WIDTH),
    random.nextInt(HEIGHT),random.nextInt(WIDTH),
    random.nextInt(HEIGHT),color,mode);
    }
    };
    $ b $ private ActionListener buttonAction = new ActionListener()
    {
    @Override
    public void actionPerformed(ActionEvent ae)
    {
    Color color =新颜色(random.nextFloat(),random.nextFloat()
    ,random.nextFloat(),random.nextFloat());
    customPanel.setValues(random.nextInt(WIDTH),
    random.nextInt(HEIGHT),random.nextInt(WIDTH),
    random.nextInt(HEIGHT),color,2);
    }
    };

    public SSCCE()
    {
    random = new Random();


    private void displayGUI()
    {
    JFrame frame = new JFrame(SSCCE);
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

    JPanel contentPane = new JPanel();
    contentPane.setLayout(new BorderLayout(5,5));

    customPanel = new CustomPanel();
    customPanel.getInputMap(
    JComponent.WHEN_IN_FOCUSED_WINDOW).put(
    KeyStroke.getKeyStroke(KeyEvent.VK_D $ b $,InputEvent.CTRL_DOWN_MASK),paintAction);
    customPanel.getActionMap()。put(paintAction,paintAction);

    JPanel footerPanel = new JPanel();
    circleButton = new JButton(Draw Circle);
    circleButton.setMnemonic(KeyEvent.VK_C);
    circleButton.addActionListener(buttonAction);

    tfield = new JTextField(20);
    tfield.setText(USELESS,只是为了自己的重点);
    tfield.requestFocusInWindow();
    footerPanel.add(tfield);
    footerPanel.add(circleButton);

    contentPane.add(customPanel,BorderLayout.CENTER);
    contentPane.add(footerPanel,BorderLayout.PAGE_END);

    frame.setContentPane(contentPane);
    frame.pack();
    frame.setLocationByPlatform(true);
    frame.setVisible(true);


    public static void main(String ... args)
    {
    EventQueue.invokeLater(new Runnable()
    {
    @Override
    public void run()
    {
    new SSCCE()。displayGUI();
    }
    });



    class CustomPanel扩展JPanel
    {
    private final int WIDTH = 500;
    private final int HEIGHT = 500;
    private int mode = 0;
    私有颜色colorShape;
    private int x = 0;
    private int y = 0;
    private int width = 0;
    private int height = 0;

    public void setValues(int x,int y,int w,int h,Color color,int mode)
    {
    this.x = x;
    this.y = y;
    this.width = w;
    this.height = h;
    this.colorShape = color;
    this.mode = mode;

    repaint();

    $ b @Override
    public Dimension getPreferredSize()
    {
    return(new Dimension(WIDTH,HEIGHT));

    $ b @Override
    保护void paintComponent(Graphics g)
    {
    super.paintComponent(g);
    g.setColor(colorShape);
    if(mode == 1)
    g.fillRect(x,y,width,height);
    else if(mode == 2)
    g.fillOval(x,y,width,height);




    $ p $ mousePressed()

    thingy,@mKorbel,像往常一样以愉快的方式呈现整件事。

    关于你的第二个问题,看起来像你自己做了一些功课。似乎要么使用您在问题中显示的是捕获与操作系统相关的事件的解决方法,并将其转移到您的Java应用程序或 Java Native Interface ,我想也可以为此工作。


    1. What are several ways of detecting a key stroke without the need of focusing on the component that the event was implemented? Here's my idea on this:
      Even without focusing on myComponent, upon pressing a key, the action should take part.
      ** Same question for the mousePressed event. A mouse click will be detected even when not clicking on the component.**

      myComponent.addKeyListener( new KeyAdapter() {
       @Override
       public void keyPressed( KeyEvent e ){
        // My action here         
       }
      
      });
      

    2. Upon answering Question1, can it also be done even if the application is running on background? Say I have a browser, every time I click or press a key, the given action will be executed.

    I also accept suggestions to read as an answer. If your answer would be KeyBinding related, please do elaborate. All answer and comments will be greatly appreciated.


    I used JNativeHooks examples here and it works perfectly fine. Any other method by just Java alone?

    解决方案

    For the first question, regarding the KeyStroke thingy, I guess you can use KeyBinding instead of using KeyListener, that can give you the desired result, without the focus related issues of the component in question, though within the Java Dimensions.

    In the example below, the focus is on the JTextField first, so if you will Press CTRL + D, then the paintAction thingy attached to the CustomPanel will work, even though the focus lies with the JTextField.

    Though if you will use the setMnemonic() method for JButton, then the JButton will gain focus and will perform it's own action associated with it, which is to draw Ovals. This you can see by Pressing ALT + C, to see the desired effect. Again to perform the drawing related thingy, both the components in question don't need the focus, but still they respond to the KeyStrokes.

    Here is the example code :

    import java.awt.*;
    import java.awt.event.*;
    import java.util.Random;
    import javax.swing.*;
    
    public class SSCCE
    {
        private final int WIDTH = 500;
        private final int HEIGHT = 500;
        private CustomPanel customPanel;
        private JButton circleButton;
        private JTextField tfield;
        private Random random;
        private int mode;
    
        private Action paintAction = new AbstractAction()
        {
            @Override
            public void actionPerformed(ActionEvent ae)
            {
                mode = random.nextInt(3);
                Color color = new Color(random.nextFloat(), random.nextFloat()
                                                            , random.nextFloat(), random.nextFloat());
                customPanel.setValues(random.nextInt(WIDTH), 
                                random.nextInt(HEIGHT), random.nextInt(WIDTH), 
                                                                        random.nextInt(HEIGHT), color, mode);
            }
        };
    
        private ActionListener buttonAction = new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent ae)
            {
                Color color = new Color(random.nextFloat(), random.nextFloat()
                                                            , random.nextFloat(), random.nextFloat());
                customPanel.setValues(random.nextInt(WIDTH), 
                                random.nextInt(HEIGHT), random.nextInt(WIDTH), 
                                                                        random.nextInt(HEIGHT), color, 2);
            }
        };
    
        public SSCCE()
        {
            random = new Random();
        }
    
        private void displayGUI()
        {
            JFrame frame = new JFrame("SSCCE");
            frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    
            JPanel contentPane = new JPanel();
            contentPane.setLayout(new BorderLayout(5, 5));
    
            customPanel = new CustomPanel();
            customPanel.getInputMap(
                JComponent.WHEN_IN_FOCUSED_WINDOW).put(
                    KeyStroke.getKeyStroke(KeyEvent.VK_D
                        , InputEvent.CTRL_DOWN_MASK), "paintAction");
            customPanel.getActionMap().put("paintAction", paintAction);
    
            JPanel footerPanel = new JPanel();
            circleButton = new JButton("Draw Circle");
            circleButton.setMnemonic(KeyEvent.VK_C);
            circleButton.addActionListener(buttonAction);
    
            tfield = new JTextField(20);
            tfield.setText("USELESS, just to get the focus for itself.");
            tfield.requestFocusInWindow();
            footerPanel.add(tfield);
            footerPanel.add(circleButton);
    
            contentPane.add(customPanel, BorderLayout.CENTER);
            contentPane.add(footerPanel, BorderLayout.PAGE_END);
    
            frame.setContentPane(contentPane);
            frame.pack();
            frame.setLocationByPlatform(true);
            frame.setVisible(true);
        }
    
        public static void main(String... args)
        {
            EventQueue.invokeLater(new Runnable()
            {
                @Override
                public void run()
                {
                    new SSCCE().displayGUI();
                }
            });
        }
    }
    
    class CustomPanel extends JPanel
    {
        private final int WIDTH = 500;
        private final int HEIGHT = 500;
        private int mode = 0;
        private Color colorShape;
        private int x = 0;
        private int y = 0;
        private int width = 0;
        private int height = 0;
    
        public void setValues(int x, int y, int w, int h, Color color, int mode)
        {
            this.x = x;
            this.y = y;
            this.width = w;
            this.height = h;
            this.colorShape = color;
            this.mode = mode;
    
            repaint();
        }
    
        @Override
        public Dimension getPreferredSize()
        {
            return (new Dimension(WIDTH, HEIGHT));
        }
    
        @Override
        protected void paintComponent(Graphics g)
        {
            super.paintComponent(g);
            g.setColor(colorShape);
            if (mode == 1)
                g.fillRect(x, y, width, height);
            else if (mode == 2)
                g.fillOval(x, y, width, height);
        }
    }
    

    Related to mousePressed() thingy, @mKorbel, had presented the whole thingy as usual in a delightful manner.

    And regarding your second question, seems like you yourself had done some homework on that. Seems like either using what you showed in your question is the workaround for catching Operating System related events and transfer that to your Java Application or Java Native Interface, I guess might also can work for this.

    这篇关于未聚焦组件中的KeyPressed和mousePressed事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆