KeyPressed and mousePressed event in an unfocused component

  • What are several ways to detect a key stroke without having to focus on the component that was implemented in this event? Here is my idea: Without even focusing on myComponent , when the key is pressed, the action should take part.
    ** Same question for mousePressed event. A mouse click will be detected even if you do not click on the component. **

     myComponent.addKeyListener( new KeyAdapter() { @Override public void keyPressed( KeyEvent e ){ // My action here } }); 
  • Answering Question1 , can this be done even if the application is running in the background? Say I have a browser, every time I press or press a key, this action will be performed.

I also accept reading suggestions as an answer. If your answer will be related to KeyBinding, consult with him. All answers and comments will be highly appreciated.


I used the JNativeHooks examples here and it works fine. Any other method of only one Java?

+7
source share
2 answers

For the first question regarding KeyStroke thingy, I think you can use KeyBinding instead of using KeyListener, which can give you the desired result, without the problems associated with focusing the component in question, albeit in Java dimensions.

In the example below, the focus is on the JTextField first, so if you press CTRL + D , then the paintAction property attached to the CustomPanel will work, although the focus is on the JTextField .

Although if you use the setMnemonic () method for JButton , JButton will receive focus and will perform its associated action, which should draw the Ovals. This can be seen by pressing ALT + C to see the desired effect. Again, in order to accomplish things related to the drawing, both components in question do not need focus, but they still respond to KeyStrokes.

Here is a sample 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); } } 

Regarding mousePressed() thingy, @mKorbel, presented all this, as usual, deliciously.

And regarding your second question, it looks like you yourself did some homework. It seems that either using what you showed in your question is a workaround for catching events related to the operating system and passing them to your Java application or Java Native Interface , I think it might work for that as well.

+6
source
  • all JComponent has a dispatchEvent method,

  • you can redirect the mouse and key event from one JComponent to another

  • for JButton instead of doClick()

eg

 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); } } } 
+4
source

All Articles