当前位置: 首页 > 知识库问答 >
问题:

Java:将MouseListener添加到自定义JComponent

鲜于凯歌
2023-03-14

如果我创建一个继承JComponent的新类,我重写了JComponent的绘图Component(Graphics g)方法,通过使用g绘制一个圆圈,我应该修改什么才能使MouseListener仅在我单击组件的边界内时触发?

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

我不想检查在mouseClick()方法是否事件发生在我的组件内或没有,我希望它被调用只有当点击是在里面。

这是我的代码:

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

共有1个答案

松秦斩
2023-03-14

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

public Node(int xx, int yy, int r) {
   //. ....
   setBorder(BorderFactory.createTitledBorder("Node"));
}

请理解,您的组件正在使用默认(BorderLayout.CENTER)位置的容器添加到BorderLayout,因此它会填充容器。设置组件的边界(您不应该做的事情)或设置其首选大小(通常应该避免的事情)并不重要。

对我来说,我会让我的节点成为一个逻辑类,一个实现形状接口的类,而不是一个扩展JComponent的类,然后每当我需要知道我的节点是否被点击时,我可以使用形状的包含(Point p)方法。

 类似资料:
  • 问题内容: 我已经构建了自己的自定义react-bootstrap Popover组件: 该组件的呈现方式如下: 现在,我想向组件中添加自定义道具,例如:我的文字,并使用新道具在弹出框中设置一些内容,例如- 但随后我在浏览器中收到此警告: 警告:标签上的未知道具。从元素中删除这些道具。 现在,我想我可以删除零件并逐个插入所有原始道具,而无需自定义道具,但是这样我就失去了“淡入淡出”效果,这也是处理

  • 问题内容: 我正在研究启用AJAX的asp.net应用程序。我刚刚向Array.prototype添加了一些方法,例如 该解决方案对我有用,可以以“漂亮”的方式重用代码。 但是,当我测试了它与整个页面一起使用时,我遇到了问题。我们有了一些自定义的Ajax扩展程序,它们开始表现出意想不到的效果:某些控件在其内容或值上显示为“未定义”。 这可能是什么原因?我是否缺少修改标准对象原型的东西? 注意:我很

  • 我一直在尝试向<code>PYTHONPATH</code>添加一个自定义目录。我在Mac上使用bash,如果相关的话。这就是我所做的: < li> < li> 并保存 < li> 有两个问题: < li >当我在Python IDE中运行< code>sys.path时,目标目录仍然没有出现。 < li >当我在终端中启动Python并在那里运行< code>sys.path时,确实显示了目录,

  • 我已经搜索了又搜索,除了我称之为“hack方法”的方法之外,找不到其他方法将自定义分类添加到自定义管理菜单中。 然后我注册我的帖子类型并确保它们使用 这可以工作,自定义帖子类型显示在我的自定义菜单中。 但是自定义分类法不接受同一属性的字符串,只接受true或false。 因此,要添加它,您必须创建一个子菜单页 这是一种“黑客”方式。 还有别的办法吗?如果不修改WordPress核心,我可以覆盖re

  • 问题内容: 我正在尝试通过向其传递自定义数据源来填充表。我创建了一个带有表的简单报告。它自己的报告从ms sql数据库获取数据。我已经编写了一个与本示例类似的java类。但是我在表中没有任何价值。在该示例中,没有脚本。我已经检查了 代码行。它从现场获取数据并可以在报告中显示。因此,我猜想bean数据源未填充。我在中调用fill Table方法。如何在Jasper中使用来自Java的数据收集?我也尝