MouseEntered和KeyPressed在同一时间Java Swing

时间:2014-07-27 23:49:58

标签: java swing keylistener mouselistener

使用Java Swing我有20 JLabels。每个JLabel都有MouseListenerKeyListener。我一直试图找到一种方法(没有运气),以便能够知道鼠标输入/悬停在哪个标签上以及何时按下删除键。

例如,当按下删除键并且鼠标位于JLabel时5.我想要对JLabel 5执行操作。

我知道如何独立使用MouseListenerKeyListener,但我不知道如何将它们一起使用。

这是我正在尝试做的事情。

    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

        }
    }

如果重要,我正在使用所有JLabel的列表。

2 个答案:

答案 0 :(得分:6)

可能让您感到惊讶的建议:

  • 第1号惊喜:不要使用MouseListener
  • 第二个惊喜:不要使用MouseMotionListener。
  • 第3号惊喜:不要使用KeyListeners。
  • 而是使用Key Bindings(这里的教程:Key Bindings Tutorial)。我建议您在保存JLabel网格的JPanel上绑定删除键。然后当按下删除键时,通过使用MouseInfo类获取PointerInfo实例,找出光标所在的JLabel(如果有),然后使用它获取光标在屏幕上的位置。有了这些信息和一些琐碎的数学,你应该很容易找出哪个标签有光标(如果有的话),并采取适当的行动。请注意,Key Bindings教程将告诉您为什么更好地使用这些而不是KeyListeners,但最重要的是,您不必为应用程序的重点而付出太多代价。

修改 例如:

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();
         }
      });
   }
}

编辑2
拍摄,只是看到你的问题的评论,是的,JList可能会更好地为你的目的。

答案 1 :(得分:4)

在班级的顶端:

private JLabel hoveredLabel;

添加JLabel时:

final JLabel label = ...

label.addMouseMotionListener(new MouseListener() {
    ...

    public void mouseEntered(MouseEvent me) {
        hoveredLabel = (JLabel)me.getSource();
    }

    public void mouseExited(MouseEvent me) {
        hoveredLabel = null;
    }
}

你的KeyListener:

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
        if (hoveredLabel != null)
            doSomethingWith(hoveredLabel);
    }
}

确保将KeyListener添加到JFrame的contentPane。