Java:将MouseListener添加到自定义JComponent

Java:将MouseListener添加到自定义JComponent,java,swing,mouselistener,jcomponent,Java,Swing,Mouselistener,Jcomponent,如果我创建了一个从JComponent继承的新类,通过使用g绘制一个圆,我覆盖了它的paintComponent(Graphics g)方法,那么我应该修改什么才能使鼠标侦听器仅在我在组件的边界内单击时触发 因为在我的组件的构造函数中,我添加了setBounds(…),然后添加了一个MouseListener,但它会在我每次单击自定义组件所在的容器中的任何位置时激发,而不仅仅是在我单击它的内部时激发 我不想在mouseClicked()方法中检查事件是否发生在我的组件内部,我只想在单击发生在组件

如果我创建了一个从JComponent继承的新类,通过使用g绘制一个圆,我覆盖了它的paintComponent(Graphics g)方法,那么我应该修改什么才能使鼠标侦听器仅在我在组件的边界内单击时触发

因为在我的组件的构造函数中,我添加了setBounds(…),然后添加了一个MouseListener,但它会在我每次单击自定义组件所在的容器中的任何位置时激发,而不仅仅是在我单击它的内部时激发

我不想在mouseClicked()方法中检查事件是否发生在我的组件内部,我只想在单击发生在组件内部时调用它

这是我的密码:

public class Node extends JComponent {
    private int x, y, radius;

    public Node(int xx, int yy, int r) {
        x = xx;
        y = yy;
        radius = r;
        this.setBounds(new Rectangle(x - r, y - r, 2 * r, 2 * r));
        setPreferredSize(new Dimension(2 * r, 2 * r));
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D gr = (Graphics2D) g;
        gr.setColor(Color.BLACK);
        gr.drawOval(x - radius, y - radius, 2 * radius, 2 * radius);
    }

    public static void main(String[] args) {
        final JFrame f = new JFrame();
        f.setSize(new Dimension(500, 500));
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        final JPanel p = new JPanel();
        p.setLayout(new BorderLayout());
        Node n = new Node(100, 100, 25);
        n.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                super.mouseClicked(e);
                System.out.println("clicked");
            }
        });
        p.add(n);
        f.add(p);
        f.setVisible(true);
    }
}

您的鼠标侦听器工作正常,因为它只在JComponent的范围内工作。为了向自己证明这一点,在组件周围画一个边框,看看它实际上覆盖了什么:

public Node(int xx, int yy, int r) {
   //. ....
   setBorder(BorderFactory.createTitledBorder("Node"));
}
请理解,您的组件正在使用默认(BorderLayout.CENTER)位置的容器添加到BorderLayout,因此它将填充容器。设置组件的边界(您不应该做的事情)或设置其首选大小(通常应该避免的事情)并不重要


为了我的钱,我会让我的节点成为一个逻辑类,一个实现Shape接口的类,而不是一个扩展JComponent的类,然后我可以在需要知道我的节点是否被单击时使用Shape的
contains(Point p)
方法。

code请?我希望您的意思是您正在重写
paintComponent(Graphics g)
,因为没有
paintMethod(Graphics g)
。我为我的错误道歉,我已经更正并添加了代码。我看到了问题。如果我重写getPreferredSize()方法,并使用FlowLayout,一切都会正常工作。如果我想动态修改组件的大小,正确的布局是什么?非常感谢。