Java 没有检测到鼠标侦听器

Java 没有检测到鼠标侦听器,java,swing,awt,mouselistener,Java,Swing,Awt,Mouselistener,我在网格中有一个JPanel,嵌套在主JFrame中。我试图在网格上设置一个鼠标侦听器,并将事件报告给主框架 App.java入口点 java主容器,控制器 HeaderPanel.java包含两行文本的标题 public class HeaderPanel extends JPanel { public static final String HEADER_TEXT = "Pure Tic Tac Toe Java - AI"; public static final Str

我在网格中有一个JPanel,嵌套在主JFrame中。我试图在网格上设置一个鼠标侦听器,并将事件报告给主框架

App.java入口点

java主容器,控制器

HeaderPanel.java包含两行文本的标题

public class HeaderPanel extends JPanel {

    public static final String HEADER_TEXT = "Pure Tic Tac Toe Java - AI";
    public static final String SMALL_HEADER_TEXT =
            "The only game where you are the champion if it's a draw";

    // TODO: figure out a way to fill the whole header dynamically
    public static final int HEADER_WIDTH = 1366; // temporary solution
    public static final int HEADER_HEIGHT = 100;

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        // Draw the dark blue rectangle
        g.drawRect(0, 0, HEADER_WIDTH, HEADER_HEIGHT);
        g.setColor(new Color(33, 33, 33, 240)); // Dark blue
        g.fillRect(0, 0, HEADER_WIDTH, HEADER_HEIGHT);

        // Draw the first line of text
        g.setColor(Color.WHITE);
        FontMetrics fm = g.getFontMetrics();
        Rectangle2D header = fm.getStringBounds(HEADER_TEXT, g);
        int x = (this.getWidth() - (int) header.getWidth()) / 2;
        int y = (this.getHeight() - (int) header.getHeight()) / 4 + fm.getAscent();
        g.drawString(HEADER_TEXT, x, y);

        // Draw the second line of text
        fm = g.getFontMetrics();
        Rectangle2D miniHeader = fm.getStringBounds(SMALL_HEADER_TEXT, g);
        x = (this.getWidth() - (int) miniHeader.getWidth()) / 2;
        y = (this.getHeight() - (int) miniHeader.getHeight()) * 3 / 4 + fm.getAscent();
        g.setColor(new Color(44, 170, 231, 250));
        g.drawString(SMALL_HEADER_TEXT, x, y);
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(HEADER_WIDTH, HEADER_HEIGHT);
    }
}
CellHoverListener.java

最终结果: 问题 就是根本没有检测到悬停事件。我试着直接在黑板上放一个鼠标听筒,但还是老样子

在这种情况下,如何正确设置鼠标事件的侦听器?

首先,从paintComponent中删除addMouseListener。请注意,paintComponent是反复调用的,我相信您不会一直在每次重新绘制时添加新的鼠标侦听器

在构造函数或某种initGUI调用中添加侦听器:

在此处添加调试语句。你会看到它确实被称为

public void mouseEntered(final MouseEvent e) {
    System.out.println(e);
    if (mHoverListener != null) {
        mHoverListener.onCellHover(e.getX(), e.getY());
    }
}
检测移动事件的主要问题是您没有分配MouseMotionListener:

例如,使用以下选项为面板创建构造函数:

public BoardPanel() {

    BoardMouseListener bml = new BoardMouseListener();
    addMouseListener(bml);
    addMouseMotionListener(bml);
}
如果不需要构造函数,也可以在任何地方设置组件。然后@Override方法用于您想要检测的任何事件:

class BoardMouseListener extends MouseAdapter {

    @Override
    public void mouseEntered(MouseEvent e) {

        System.out.println(e.getX() + " - " + e.getY());
    }

    @Override
    public void mouseMoved(MouseEvent e) {

        System.out.println(e.getX() + " - " + e.getY());
    }
}
你的其他问题是:

在paintComponent内调用addMouseListener。每次绘制组件时,您都在创建和注册一个新的侦听器。这很糟糕。 只有在完成所有组件的设置后,才应调用setVisible。 如果不需要重写其所有方法,请使用extends mouseadapternstant代替implements MouseListener。如果您在移动过程中按下按钮,它将不会被记录,因为这现在是一个拖动事件-使用适当的方法。
你有没有为JPanel申请焦点?补充说,没有任何区别。我不知道何时何地调用它。为什么要在paintComponent中添加鼠标侦听器?该方法应该只包含绘制计算,并且返回速度很快。这还意味着您每次绘制时都要添加一个新组件。@user1803551我应该在哪里调用它?在哪里设置组件。我还在看代码,但这让我感到很不舒服:谢谢你的回复。我试过了,但它并没有记录里面的每一个动作。我需要将鼠标移出网格并再次移入以触发侦听器。@Sparta这是因为它只被鼠标覆盖。对MouseMotionListener和mouseMoved执行相同的操作。您将获得每一次鼠标移动。由于您的答案已被接受,您可能实际上希望在答案的注释中包含您提示的带有MouseMotionListener的解决方案。现在你的答案只是关于OP代码的一些注释,没有修改。我真的很感激。如果你在@Whisky之前回答,我会接受你的回答,因为他的回答让我意识到我没有设置一个我所需要的动作监听器。@Sparta没问题,但他的回答实际上没有包含解决方案,这有点可笑:@Sparta是的,我只是让他在他的回答中添加解决方案。人们期望解决方案出现在那里,而不是出现在评论中。请将您的答案标记为最正确和更好的答案,因为您提供了更多的细节和信息,不仅帮助我解决了这个问题所涉及的问题,而且在许多其他方面也有所帮助。
public interface CellHoverListener {
    void onCellHover(int x, int y);
}
protected void paintComponent(final Graphics g) {
    super.paintComponent(g);
}
public BoardPanel() {
    addMouseListener(new BoardMouseListener());
}
public void mouseEntered(final MouseEvent e) {
    System.out.println(e);
    if (mHoverListener != null) {
        mHoverListener.onCellHover(e.getX(), e.getY());
    }
}
public BoardPanel() {

    BoardMouseListener bml = new BoardMouseListener();
    addMouseListener(bml);
    addMouseMotionListener(bml);
}
class BoardMouseListener extends MouseAdapter {

    @Override
    public void mouseEntered(MouseEvent e) {

        System.out.println(e.getX() + " - " + e.getY());
    }

    @Override
    public void mouseMoved(MouseEvent e) {

        System.out.println(e.getX() + " - " + e.getY());
    }
}