GridLayout + 鼠标监听器

5

大家好,我有一个问题,我不知道如何知道在网格布局中点击了哪个单元格,有没有相关函数?

我在容器中有一个包含10行10列的网格布局,我想监听所有单元格的鼠标事件,这样当我点击(2,1)处的单元格时,会因为鼠标监听器而告诉我我点击了哪个单元格。

有什么提示吗?非常感谢。

3个回答

9

在使用网格布局并且容器中包含组件的情况下,向容器添加一个MouseListener。然后在mousePressed事件中,使用MouseEvent对象(例如myMouseEvent)获取点击位置并调用getComponentAt(myMouseEvent.getPoint)方法以获取被点击的组件。简单易行。

例如:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.*;

public class TestComponentAt extends JPanel {
   private static final int ROW_COUNT = 10;
   private static final int W = 60;
   private static final int H = W;
   private static final Dimension PREF_SIZE = new Dimension(W, H);
   protected static final Color SELECTION_COLOR = Color.pink;
   private JPanel selectedPanel = null;
   private Color originalColor = null;

   public TestComponentAt() {
      setLayout(new GridLayout(ROW_COUNT, ROW_COUNT, 1, 1));
      setBackground(Color.black);
      for (int i = 0; i < ROW_COUNT * ROW_COUNT; i++) {
         JPanel panel = new JPanel();
         String name = String.format("[%d, %d]", 
               i / ROW_COUNT, i % ROW_COUNT);
         panel.setName(name);
         if (i == 0) {
            originalColor = panel.getBackground();
         }
         panel.setPreferredSize(PREF_SIZE);
         add(panel);
      }
      addMouseListener(new MouseAdapter() {
         @Override
         public void mousePressed(MouseEvent e) {
            JPanel panel = (JPanel) getComponentAt(e.getPoint());
            if (panel == null || panel == TestComponentAt.this) {
               return;
            }
            if (selectedPanel != null) {
               selectedPanel.setBackground(originalColor);
               selectedPanel.removeAll();
               selectedPanel.revalidate();
               selectedPanel.repaint();
            }
            selectedPanel = panel;
            selectedPanel.setBackground(SELECTION_COLOR);
            selectedPanel.add(new JLabel(selectedPanel.getName()));
            selectedPanel.revalidate();
            selectedPanel.repaint();
         }
      });
   }

   private static void createAndShowGui() {
      JFrame frame = new JFrame("TestComponentAt");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(new TestComponentAt());
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

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

非常感谢你的答案,这就是我想要的!谢谢,伙计,现在我知道该怎么做了:D 你能否解释一下你做的一些事情吗? 像这样: SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGui(); } });我只测试了在main方法中使用createAndShowGui();,也运行良好:s还有为什么呢? if (panel == null || panel == TestComponentAt.this) { return; }当你使用TestComponentAt.this时,我不明白,为什么? panel不会总是为空吗?为什么要用 if(panel == null || ...)?非常感谢,伙计! - TiagoM
面板可能为空,如果您单击组件之外的区域,但更有可能是容器本身,这就是为什么我有第二个检查的原因 - 如果它是容器,我不想使用面板。关于invokeLater,最好在Swing教程中搜索一下,因为需要一些解释,但要点是您只想在EDT或事件分派线程上进行Swing调用。 - Hovercraft Full Of Eels

0

您可以使用容器的宽度和高度,获取容器的宽度和高度并将其分成单元格数,并找到单元格(2,1)的范围。例如,如果容器的宽度和高度等于100,行数和列数为10*10,则单元格(2,1)的左坐标为x=10,y=0。通过mouseListener类的getX()和getY()方法,您可以找到鼠标点击的位置,然后如果鼠标位置的x和y在单元格(2,1)的范围内,您就可以知道它单击了单元格(2,1)。 enter image description here


谢谢,伙计;) 我正在走向解决方案 :) - TiagoM

-1

递归地向您的UI中的所有组件添加鼠标监听器并进行调试...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接