Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/383.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么我的鼠标事件坐标返回错误的值?_Java_Swing_Mouseevent - Fatal编程技术网

Java 为什么我的鼠标事件坐标返回错误的值?

Java 为什么我的鼠标事件坐标返回错误的值?,java,swing,mouseevent,Java,Swing,Mouseevent,我有两个类:connectionextensedjcomponent和PostMachineView extensedjpanel实现MouseListener。 我试图做的是在连接组件中按下鼠标按钮时触发一个方法。 我正在使用SwingUtilities.convertPointToScreen,这样鼠标事件坐标将相对于我正在绘制的位置。问题是它返回的x和y的数字与它应该返回的略有不同。 代码如下: public class PostMachineView extends JPanel imp

我有两个类:
connectionextensedjcomponent
PostMachineView extensedjpanel实现MouseListener
。 我试图做的是在
连接
组件中按下鼠标按钮时触发一个方法。 我正在使用
SwingUtilities.convertPointToScreen
,这样鼠标事件坐标将相对于我正在绘制的位置。问题是它返回的
x
y
的数字与它应该返回的略有不同。 代码如下:

public class PostMachineView extends JPanel implements MouseListener {
    ArrayList<Connection> connections;

    public PostMachineView() {
        connections = new ArrayList<>();
        setSize(new Dimension(800, 800));
        setBackground(Color.white);

        //here i create the points i'll need for the connection and instantiate it
        Point p1 = new Point(100, 100);
        Point p2 = new Point(100, 200);
        Connection conn = new Connection(p1, p2);
        //add the connection component to this panel
        add(conn);
        //set the connection mouse listener
        conn.addMouseListener(this);

        connections.add(conn);
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);

        //this will be done in a different way, just trying to get it to work first
         Point p1 = new Point(100, 100);
         Point p2 = new Point(100, 200);

         ((Connection)getComponent(0)).paintComponent(g, p1, p2);
    }

    @Override
    public void mouseClicked(MouseEvent e) {}

    @Override
    public void mouseEntered(MouseEvent e) {}

    @Override
    public void mouseExited(MouseEvent e) {}

    @Override
    public void mousePressed(MouseEvent e) {
        System.out.println("clicked in the component");
    }

    @Override
    public void mouseReleased(MouseEvent e) {}
}

public class Connection extends JComponent {

    private Rectangle2D.Double curveControl;
    private GeneralPath path;

    public Connection(Point p1, Point p2) {
        path = new GeneralPath();
        path.moveTo(p1.getX(), p1.getY());
        int[] mid = getMidPointCoords(p1, p2);
        curveControl = new Rectangle2D.Double(mid[0] - 5, mid[1] - 5, 10, 10);
        path.curveTo(curveControl.getCenterX(), curveControl.getCenterY(),
                curveControl.getCenterX(), curveControl.getCenterY(),
                p2.getX(), p2.getY());

    }
    public int[] getMidPointCoords(Point p1, Point p2) {
        int[] v = { 0, 0 };
        v[0] = (int) ((p1.getX() + p2.getX()) / 2);
        v[1] = (int) ((p1.getY() + p2.getY()) / 2);
        return v;
    }

    public void paintComponent(Graphics g, Point p1, Point p2) {
        path.moveTo(p1.getX(), p1.getY());
        path.curveTo(curveControl.getCenterX(), curveControl.getCenterY(),
                curveControl.getCenterX(), curveControl.getCenterY(),
                p2.getX(), p2.getY());

        Graphics2D g2d = (Graphics2D) g;

        g2d.draw(path);
        g2d.setColor(Color.red);
        g2d.fill(curveControl);
        g2d.setColor(Color.black);
    }

    @Override
    public boolean contains(int x, int y) {
    //here is where i use swingutilities to convert the coordinates
        Point p = new Point(x, y);
        SwingUtilities.convertPointToScreen(p, this);
        return curveControl.contains(p.getX(), p.getY());
    }
}
这个

public void paint(Graphics g) {
    super.paint(g);

    //this will be done in a different way, just trying to get it to work first
     Point p1 = new Point(100, 100);
     Point p2 = new Point(100, 200);

     ((Connection)getComponent(0)).paintComponent(g, p1, p2);
}
这是一个非常糟糕的主意。
连接
组件已经是
PostMachineView
组件的子组件。您只需更新
连接的状态
(可能通过
mouseClicked
事件)并调用
repaint
进行更新

在连接中,此

public void paintComponent(Graphics g, Point p1, Point p2) {
    path.moveTo(p1.getX(), p1.getY());
    path.curveTo(curveControl.getCenterX(), curveControl.getCenterY(),
            curveControl.getCenterX(), curveControl.getCenterY(),
            p2.getX(), p2.getY());

    Graphics2D g2d = (Graphics2D) g;

    g2d.draw(path);
    g2d.setColor(Color.red);
    g2d.fill(curveControl);
    g2d.setColor(Color.black);
}
应该分为两种方法,一种是添加新点,另一种是绘制新点

public void add(Point p1, Point p2) {
    path.moveTo(p1.getX(), p1.getY());
    path.curveTo(curveControl.getCenterX(), curveControl.getCenterY(),
                    curveControl.getCenterX(), curveControl.getCenterY(),
                    p2.getX(), p2.getY());
}

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D) g.create();
    g2d.draw(path);
    g2d.setColor(Color.red);
    g2d.fill(curveControl);
    g2d.setColor(Color.black);
    g2d.dispose();
}
由于
鼠标侦听器
连接到
组件,因此

@Override
public boolean contains(int x, int y) {
//here is where i use swingutilities to convert the coordinates
    Point p = new Point(x, y);
    SwingUtilities.convertPointToScreen(p, this);
    return curveControl.contains(p.getX(), p.getY());
}
不再有意义了,老实说,我会非常小心地处理这件事

充其量应该更像

public boolean contains(int x, int y) {
    return curveControl.contains(x, y);
}
但是请记住,
MouseListener
将不再生成事件,除非x/y坐标在
curveControl
内,这可能不是您真正想要的


哦,还有这个
ArrayList连接吓到我了…但是,我没有你的问题的上下文来真正知道你的意图是什么…

“我正在使用SwingUtilities.convertPointToScreen,以便鼠标事件坐标与我绘制的位置相对”-这实际上是错误的。坐标将相对于当前屏幕(屏幕的上/左角),其中组件中的
0x0
将是组件的上/左位置。不要从
PostMachineView
绘制
Connection
,这根本没有意义,因为Connection是
PostMachineView
的子级,当你想要更新时,你应该调用
repaint
,当我想要更新连接时,我应该在PostMachineView中调用repaint,是吗?您将
MouseListener
添加到
连接中
,这样所有
MouseEvents
都将被转换到
连接的上下文中,因为
MouseListener
附加到
连接中
,它们已经在
连接的坐标上下文中了,这个项目根本不是个好主意。。。我无法让它工作,因为在改变了你指出的一些事情后,layoutmanager遇到了一些麻烦。我最终放弃了这一切,创建了一个新的项目——它一直运行得很好,让我感到惊讶。我正在使用画布对象绘制扩展Path2D.Double和Polygon的类。谢谢你所做的一切:)
public boolean contains(int x, int y) {
    return curveControl.contains(x, y);
}