Java 未聚焦组件中的按键和鼠标按下事件

Java 未聚焦组件中的按键和鼠标按下事件,java,swing,focus,mouseevent,key-events,Java,Swing,Focus,Mouseevent,Key Events,有哪些方法可以检测关键中风,而无需关注事件实施的组件?以下是我的想法: 即使不关注myComponent,按下一个键,操作也应该参与**鼠标按下事件的问题相同。即使未单击组件,也会检测到鼠标单击** myComponent.addKeyListener( new KeyAdapter() { @Override public void keyPressed( KeyEvent e ){ // My action here } }); 回答问题1时,即使应用程序在

有哪些方法可以检测关键中风,而无需关注事件实施的组件?以下是我的想法:
即使不关注myComponent,按下一个键,操作也应该参与
**鼠标按下事件的问题相同。即使未单击组件,也会检测到鼠标单击**

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

});
  • 回答
    问题1
    时,即使应用程序在后台运行,也可以这样做吗?假设我有一个浏览器,每次我点击或按键时,给定的动作都会被执行

  • 我也接受阅读的建议作为答案。如果您的答案与密钥绑定相关,请详细说明。所有的回答和评论将不胜感激


    我用过,效果很好。只有Java才能使用其他方法吗?

    • 所有
      JComponent
      都有方法

    • 您可以将
      鼠标
      事件从一个
      j组件
      重定向到另一个组件

    • 对于
      JButton
      使用
      doClick()

    比如说

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Point;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseListener;
    import javax.swing.BorderFactory;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.SwingUtilities;
    
    public class LostMouseEvent {
    
        private JPanel panel1;
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    new LostMouseEvent();
                }
            });
        }
    
        public LostMouseEvent() {
            EventQueue.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    JFrame frame = new JFrame();
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new BorderLayout());
                    panel1 = new JPanel() {
                        private static final long serialVersionUID = 1L;
    
                        @Override
                        public Dimension getPreferredSize() {
                            return new Dimension(600, 400);
                        }
                    };
                    JPanel panel2 = new JPanel() {
                        private static final long serialVersionUID = 1L;
    
                        @Override
                        public Dimension getPreferredSize() {
                            return new Dimension(500, 300);
                        }
                    };
                    JScrollPane pane = new JScrollPane(panel2);
                    panel1.setBorder(BorderFactory.createLineBorder(Color.blue));
                    panel2.setBorder(BorderFactory.createLineBorder(Color.green));
                    panel1.setLayout(new CircleLayout());
                    panel1.add(pane);
                    frame.add(panel1);
                    MouseListener rml = new RealMouseListener();
                    panel1.addMouseListener(rml);
                    MouseListener fml = new FakeMouseListener();
                    panel2.addMouseListener(fml);
                    frame.pack();
                    frame.setVisible(true);
    
                }
            });
        }
    
        private class RealMouseListener extends MouseAdapter {
    
            @Override
            public void mousePressed(MouseEvent me) {
                System.out.println(me);
                Point point = me.getPoint();
                System.out.println(me.getX());
                System.out.println(me.getXOnScreen());
                System.out.println(me.getY());
                System.out.println(me.getYOnScreen());
            }
        }
    
        private class FakeMouseListener extends MouseAdapter {
    
            @Override
            public void mousePressed(MouseEvent me) {
                JPanel panel2 = (JPanel) me.getSource();
                MouseEvent newMe = SwingUtilities.convertMouseEvent(panel2, me, panel1);
                System.out.println(newMe.getX());
                System.out.println(newMe.getXOnScreen());
                System.out.println(newMe.getY());
                System.out.println(newMe.getYOnScreen());
                panel1.dispatchEvent(me);
            }
        }
    }
    

    对于第一个问题,关于击键的问题,我想您可以使用而不是使用KeyListener,这可以为您提供所需的结果,而不存在所讨论组件的焦点相关问题,尽管在Java维度内

    在下面的示例中,焦点首先放在
    JTextField
    上,因此如果按CTRL+D,则附加到
    CustomPanel
    上的paintAction将起作用,即使焦点在
    JTextField

    虽然如果您将使用
    JButton
    的方法,那么
    JButton
    将获得焦点,并将执行与其相关联的自身操作,即绘制椭圆。按ALT+C可以看到这一点,以查看所需的效果。同样,要执行与绘图相关的操作,这两个组件都不需要焦点,但它们仍然会响应击键

    下面是示例代码:

    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);
        }
    }
    
    mousePressed()
    thingy相关,@mKorbel像往常一样以令人愉快的方式展示了整个东西


    关于你的第二个问题,看起来你自己也做了一些家庭作业。似乎使用您在问题中展示的内容是捕获操作系统相关事件并将其传输到Java应用程序的变通方法,或者,我想可能也适用于此。

    为什么您想知道???我目前正在开发一个记录输入的应用程序。有点监视应用程序。然后你应该试试VB.NET或者C++,因为你需要它来为你的机器。它实际出现在我的脑海中。但不幸的是,我目前正在学习Java。这就是为什么我必须使用这种语言来开发应用程序。@Michael Ardan我的重要问题,这个问题是否与
    AWT
    /
    Swing
    有关?它不会处理java面板之外的任何单击。是的,Arpit是正确的。我试过这门课。它打印事件和帧内事件发生的坐标。不管怎样,谢谢你把这个放在mKorbel上。这是非常有用的。