【问题标题】:Trouble using mouse to click on JComponent使用鼠标单击 JComponent 时出现问题
【发布时间】:2013-11-25 21:39:02
【问题描述】:

大家好,我正在尝试创建一个有点动态的程序,您可以在其中向 JPanel 添加形状或图像,然后在添加后选择并移动这些形状。问题是当我单击特定的 JComponent 时,什么也没有发生。事实上,单击我为测试项目而创建的任何组件都会为所有 JComponent 返回 false。但是,如果我在左上角的 JComponent 范围内单击,似乎所有 JComponent 都将返回 true,即单击 (0,0,50,68) 界定的区域。

这个想法是,如果我单击其中一个 JComponent,它将将该特定 JComponent 设置为可移动,但是我无法超越实际选择特定 JComponent 的部分。

这是我为重现问题而构建的基本 SSCE:

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;

public class SSCE1 extends JPanel {
private ArrayList<Shape> shapeList = new ArrayList<Shape>();

SSCE1() {
    setLayout(null);
    /* Debug Stuff */
    System.out.println("Debug:");
    /* Add The First Shape To The List */
    shapeList.add(0, new Shape(100, 100));
    add(shapeList.get(0));
    shapeList.add(1, new Shape(610, 0));
    add(shapeList.get(1));
    shapeList.add(2, new Shape(500, 900));
    add(shapeList.get(2));

    addMouseListener(new MouseAdapter() {
        public void mouseClicked(MouseEvent e) {
            for (Shape shape : shapeList) {
                if (shape.contains(e.getPoint())) {
                    System.out.println("Hello");
                } else {
                    System.out.println("Goodbye");
                }
            }

        }
    });
}
}

class Shape extends JComponent {
int xLocation, yLocation, xBounds1, yBounds1;

Shape(int xLocation, int yLocation) {
    this.xLocation = xLocation;
    this.yLocation = yLocation;
    this.xBounds1 = 50;
    this.yBounds1 = 68;
    setBounds(xLocation, yLocation, xBounds1, yBounds1);
    setLocation(xLocation, yLocation);
}

public void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.setColor(Color.blue);
    g.fillRect(0, 0, 100, 100);

}
}

class Run {

public static void main(String[] args) {
    JFrame main = new JFrame();
    SSCE1 p1 = new SSCE1();
    main.setSize(new Dimension(1000, 1000));
    main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    main.setLocation(new Point(0, 0));
    main.setVisible(true);
    main.add(p1);
}

}

【问题讨论】:

  • 什么是形状,怎么定义的?
  • 对不起,什么意思?
  • @MadProgrammer 它是 JComponent,下面确定
  • 抱歉,缺少滚动条:P

标签: java swing user-interface paintcomponent mouselistener


【解决方案1】:

基本上,问题在于,Shape 期望您传递给它的任何鼠标坐标都在Shape 的上下文中定义。也就是说,Shape 的左上角总是0x0

您正在处理的鼠标点位于父容器的上下文中,因此,除非Shape 位于父容器中的0x0,否则Shape 将永远不会包含鼠标点。

在检查之前,您需要将鼠标指向Shape 的上下文

例如...

addMouseListener(new MouseAdapter() {
    public void mouseClicked(MouseEvent e) {
        for (Shape shape : shapeList) {
            Point shapePoint = SwingUtilities.convertPoint(e.getComponent(), e.getPoint(), shape);
            if (shape.contains(shapePoint) {
                System.out.println("Hello");
            } else {
                System.out.println("Goodbye");
            }
        }

    }
});

【讨论】:

    【解决方案2】:

    使用下一个 mouseListener 就可以了:

    addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent e) {
                for (Shape shape : shapeList) {
                    Point convertPoint = SwingUtilities.convertPoint(SSCE1.this, e.getPoint(), shape);
                    if (shape.contains(convertPoint)) {
                        System.out.println("Hello");
                    } else {
                        System.out.println("Goodbye");
                    }
                }
    
            }
        });
    

    原因是下一个根据docscontains 方法the point's x and y coordinates are defined to be relative to the coordinate system of this component. 因为它适用于(0,0,50,68)。在SwingUtilities.convertPoint(...) 的帮助下,您需要将点从JPanel 转换为Shape

    【讨论】:

    • 谢谢,我没想到
    • 我现在在工作,我回家试试这个,但如果你不介意它是如何工作的?我想我不明白从源坐标系到目标坐标系的转换是如何工作的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-24
    • 2014-05-29
    • 2022-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多