Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MouseEntered and KeyPressed at Same Time Java Swing

Using Java Swing I have 20 JLabels. Each JLabel has a MouseListener and a KeyListener. I'm been trying to come up with a way (with no luck) to be able to know which label the mouse has entered/hovering over and when the delete key is pressed.

For instance, when the delete key is pressed and the mouse is in JLabel 5. I want an action on JLabel 5 to be performed.

I know how to use MouseListener and KeyListener independently, but I don't know how to use them together like that.

Here is what I'm attempting to do.

    public void keyPressed(KeyEvent e) {
        if(e.getKeyCode() == KeyEvent.VK_DELETE){
            //Get the JLabel that the mouse has entered/hovering over
            //Perform action on that JLabel

        }
    }

In case it matters, I'm using a List for all of the JLabel's.

like image 953
Eric Avatar asked Aug 04 '26 23:08

Eric


1 Answers

Suggestions that might surprise you:

  • Surprise number 1: Don't use a MouseListener
  • Surprise number 2: Don't use a MouseMotionListener.
  • Surprise number 3: Don't use KeyListeners.
  • Instead use Key Bindings (tutorial here: Key Bindings Tutorial). I suggest that you bind the delete key press on the JPanel that holds your grid of JLabel. Then when the delete key has been pressed, find out which JLabel the cursor is over (if any) by using the MouseInfo class to get a PointerInfo instance, and with that get the location of the cursor on the screen. With that information and some trivial math, it should be easy for you to figure out which label has the cursor (again, if any), and do your appropriate action. Note that the Key Bindings tutorial will tell you why its better to use these rather than KeyListeners, but most importantly, you don't have to futz so much with the application's focus.

Edit For example:

import java.awt.Component;
import java.awt.GridLayout;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.PointerInfo;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.*;

@SuppressWarnings("serial")
public class BindingExample extends JPanel {
   private static final int ROWS = 10;
   private static final int COLS = 8;
   JLabel[][] labels = new JLabel[ROWS][COLS];

   public BindingExample() {
      setLayout(new GridLayout(ROWS, COLS));
      for (int r = 0; r < labels.length; r++) {
         for (int c = 0; c < labels[r].length; c++) {
            String labelText = String.format("[%d,  %d]", r, c);
            labels[r][c] = new JLabel(labelText, SwingConstants.CENTER);
            int eb = 4;
            labels[r][c].setBorder(BorderFactory.createEmptyBorder(eb, eb, eb, eb));
            add(labels[r][c]);
         }
      }

      int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
      InputMap inputMap = getInputMap(condition);
      ActionMap actionMap = getActionMap();

      KeyStroke delKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0);
      String delete = "delete";

      inputMap.put(delKeyStroke, delete);
      actionMap.put(delete, new DeleteAction());
   }

   private class DeleteAction extends AbstractAction {
      @Override
      public void actionPerformed(ActionEvent evt) {
         PointerInfo pInfo = MouseInfo.getPointerInfo();
         Point ptOnScrn = pInfo.getLocation();
         int xPanel = getLocationOnScreen().x;
         int yPanel = getLocationOnScreen().y;
         int x = ptOnScrn.x - xPanel;
         int y = ptOnScrn.y - yPanel;

         Component component = getComponentAt(x, y);
         if (component != null) {
            JLabel selectedLabel = (JLabel) component;
            System.out.println("Selected Label: " + selectedLabel.getText());
         }
      }
   }

   private static void createAndShowGui() {
      BindingExample mainPanel = new BindingExample();

      JFrame frame = new JFrame("Key Bindings Example");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

Edit 2
Shoot, just saw the comments to your question, and yeah, a JList would probably be much better for your purposes.

like image 125
Hovercraft Full Of Eels Avatar answered Aug 06 '26 11:08

Hovercraft Full Of Eels



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!