未聚焦组件中的KeyPressed和mousePressed事件

Mic*_*dan 7 java swing key-events focus mouseevent

  1. 有哪些方法可以检测关键笔划而无需关注事件实施的组件?这是我的想法:
    即使没有关注myComponent,按下一个键,动作也应该参与其中.
    **同样的问题mousePressed.即使未单击组件,也会检测到鼠标单击.**

    myComponent.addKeyListener( new KeyAdapter() {
     @Override
     public void keyPressed( KeyEvent e ){
      // My action here         
     }
    
    });
    
    Run Code Online (Sandbox Code Playgroud)
  2. 在回答时Question1,即使应用程序在后台运行,它也可以完成吗?假设我有一个浏览器,每次单击或按键时,都会执行给定的操作.

我也接受建议作为答案阅读.如果您的答案与KeyBinding相关,请详细说明.所有答案和评论将不胜感激.


在这里使用了JNativeHooks的 例子,它的工作原理非常好.仅Java的任何其他方法?

nIc*_*cOw 6

对于第一个问题,关于KeyStroke的问题,我猜你可以使用KeyBinding而不是使用KeyListener,它可以提供所需的结果,而不会引起相关组件的焦点相关问题,尽管在Java Dimensions中.

在下面的例子中,重点是第JTextField一个,所以如果你按下CTRL + D,那么附加到的paintAction东西CustomPanel将起作用,即使重点在于JTextField.

虽然如果你将使用setMnemonic()方法JButton,那么JButton它将获得焦点并将执行它自己的与之关联的动作,即绘制椭圆.您可以通过按下来查看ALT + C,以查看所需的效果.再次执行绘图相关的东西,有问题的组件都不需要焦点,但它们仍然响应KeyStrokes.

这是示例代码:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

mousePressed()thingy 相关的@mKorbel以愉快的方式像往常一样呈现了整个东西.

关于你的第二个问题,看起来你自己已经完成了一些功课.似乎使用您在问题中显示的内容是捕获与操作系统相关的事件并将其传输到Java应用程序或Java Native Interface的解决方法,我想也可能适用于此.