代码之家  ›  专栏  ›  技术社区  ›  Eric

鼠标输入并同时按下Java Swing

  •  2
  • Eric  · 技术社区  · 10 年前

    使用Java Swing我有20 JLabels 每个 JLabel 有一个 MouseListener 和一个 KeyListener 。我一直在尝试想出一种方法(运气不好),可以知道鼠标已输入/悬停在哪个标签上,以及何时按下删除键。

    例如,当按下删除键且鼠标处于 标签类 5.我希望对JLabel 5执行操作。

    我知道如何使用 鼠标收听器 密钥侦听器 但我不知道如何这样一起使用它们。

    这是我想做的。

        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 回复  |  直到 10 年前
        1
  •  6
  •   Hovercraft Full Of Eels    10 年前

    可能会让您惊讶的建议:

    • 惊喜1:不要使用MouseListener
    • 惊喜之二:不要使用MouseMotionListener。
    • 惊喜之三:不要使用KeyListeners。
    • 而是使用密钥绑定(此处的教程: Key Bindings Tutorial ). 我建议您在保存JLabel网格的JPanel上绑定delete键。然后,当按下删除键时,通过使用MouseInfo类获取PointerInfo实例,找出光标在哪个JLabel上(如果有的话),然后获取光标在屏幕上的位置。有了这些信息和一些简单的数学运算,您应该可以很容易地找出哪个标签有光标(如果有光标的话),并执行适当的操作。请注意,KeyBindings教程将告诉您为什么使用这些而不是KeyListener更好,但最重要的是,您不必对应用程序的焦点进行过多的讨论。

    编辑 例如:

    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可能会更好地满足你的目的。

        2
  •  4
  •   David Xu    10 年前

    在班上排名靠前的位置:

    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中。