Java 获取在Jpanel上绘制的Path2D形状的(起始)X和Y坐标

Java 获取在Jpanel上绘制的Path2D形状的(起始)X和Y坐标,java,swing,graphics,jpanel,Java,Swing,Graphics,Jpanel,因此,我有一个程序,可以使用Path2D对象向JPanel添加形状,然后单击并拖动它们。我想做的是,在形状被修改后,能够找到它的最终X和Y坐标。坐标必须是左上角的坐标。有什么想法吗 // add a circle to center of the screen public void addCircle(int width, int height) { Path2D circ = new Path2D.Double(); circ.append(new Ellipse2D.Dou

因此,我有一个程序,可以使用Path2D对象向JPanel添加形状,然后单击并拖动它们。我想做的是,在形状被修改后,能够找到它的最终X和Y坐标。坐标必须是左上角的坐标。有什么想法吗

// add a circle to center of the screen
public void addCircle(int width, int height) {
    Path2D circ = new Path2D.Double();
    circ.append(new Ellipse2D.Double(getWidth() / 2 - width / 2,
            getHeight() / 2 - height / 2, width, height), true);
    shapes.add(circ);
    repaint();
}
            ..................
//paint all shapes
@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    this.setOpaque(true);
    this.setBackground(Color.WHITE);
    Graphics2D g2 = (Graphics2D) g;
    g2.setStroke(new BasicStroke(2));
    for (Path2D shape : shapes) {
        g2.draw(shape);
    }
}
            ..................
    // if the mouse click is in the circle, set pressed=true
    @Override
    public void mousePressed(MouseEvent e) {
        if (e.getButton() != MouseEvent.BUTTON1) {
            return;
        }
        for (int i = 0; i < shapes.size(); i++) {
            if (shapes.get(i) != null
                    && shapes.get(i).contains(e.getPoint())) {
                currentIndex = i;
                pressed = true;
                this.point = e.getPoint();
            }
        }
    }

    //if pressed=true, move circle with mouse
    @Override
    public void mouseDragged(MouseEvent e) {
        if (pressed && !lineSelected) {
            int deltaX = e.getX() - point.x;
            int deltaY = e.getY() - point.y;
            shapes.get(currentIndex).transform(
                    AffineTransform.getTranslateInstance(deltaX, deltaY));
            point = e.getPoint();
            //I need to find the new coordinates here!!!!!!!!!!!
            repaint();
        }
    }

在您可以做任何事情之前,您需要知道鼠标单击从形状角的偏移量,这将允许您拖动对象,使其不会突然“跳”到您当前的鼠标位置

@Override
public void mousePressed(MouseEvent e) {
    //...
    for (Shape shape : myShapes) {
            //...
            this.point = e.getPoint();
            int deltaX = point.x - shape.getBounds().x;
            int deltaY = point.y - shape.getBounds().y;
            offset = new Point(deltaX, deltaY);
            //...
        }
    }
}
然后,计算当前鼠标位置和偏移之间的变化增量。因为要应用平移,还需要减去形状的当前位置,因为平移基于形状的当前位置,我们只希望应用更改量

@Override
public void mouseDragged(MouseEvent e) {
    if (pressed) {
        int index = myShapes.indexOf(clickedShape);
        myShapes.remove(index);

        int deltaX = e.getPoint().x - offset.x;
        int deltaY = e.getPoint().y - offset.y;

        clickedShape = new Path2D.Double(clickedShape,
                        AffineTransform.getTranslateInstance(
                                        deltaX - clickedShape.getBounds().x,
                                        deltaY - clickedShape.getBounds().y));
        myShapes.add(index, clickedShape);
        point = e.getPoint();
        repaint();
    }
}
现在,说了这么多,不要这样做

protected void paintComponent(Graphics g) {
    //...
    this.setOpaque(true);
    this.setBackground(Color.WHITE);
在paint方法中更改组件的状态可以设置无限重绘请求循环,这会阻塞系统。此外,您所做的更改不会应用于当前图形上下文,因为这些属性通常由
paint
方法应用

还有一份工作副本

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Path2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

class Canvas extends JPanel {

    private static final long serialVersionUID = 1L;

    private boolean drawing;
    private List<Shape> myShapes = new ArrayList<Shape>();

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new Canvas());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public Canvas() {
        MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
        addMouseListener(myMouseAdapter);
        addMouseMotionListener(myMouseAdapter);
        addSquare(100, 100);
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(400, 400);
    }

    public void setList(ArrayList<Shape> shapes) {

    }

    public List<Shape> getList() {
        return null;
    }

    public void addSquare(int width, int height) {
        Path2D rect2 = new Path2D.Double();
        rect2.append(new Rectangle(getWidth() / 2 - width / 2, getHeight() / 2
                        - height / 2, width, height), true);

        myShapes.add(rect2);
        repaint();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setStroke(new BasicStroke(2));
        for (Shape shape : myShapes) {
            g2.draw(shape);
        }
    }

    class MyMouseAdapter extends MouseAdapter {

        private boolean pressed = false;
        private Point point;
        private Point offset;
        private Shape clickedShape;

        @Override
        public void mousePressed(MouseEvent e) {
            if (e.getButton() != MouseEvent.BUTTON1) {
                return;
            }
            for (Shape shape : myShapes) {
                if (shape != null
                                && shape.contains(e.getPoint())) {
                    System.out.println("Clicked");
                    pressed = true;
                    clickedShape = shape;
                    this.point = e.getPoint();
                    int deltaX = point.x - shape.getBounds().x;
                    int deltaY = point.y - shape.getBounds().y;
                    offset = new Point(deltaX, deltaY);
                    System.out.println(point + "x" + offset);
                    repaint();
                    break;
                }
            }
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            if (pressed) {
                int index = myShapes.indexOf(clickedShape);
                myShapes.remove(index);

                int deltaX = e.getPoint().x - offset.x;
                int deltaY = e.getPoint().y - offset.y;

                clickedShape = new Path2D.Double(clickedShape,
                                AffineTransform.getTranslateInstance(
                                                deltaX - clickedShape.getBounds().x,
                                                deltaY - clickedShape.getBounds().y));
                myShapes.add(index, clickedShape);
                point = e.getPoint();
                repaint();
            }
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            offset = null;
            pressed = false;
        }
    }
}
import java.awt.BasicStroke;
导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.EventQueue;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.Point;
导入java.awt.Rectangle;
导入java.awt.RenderingHints;
导入java.awt.Shape;
导入java.awt.event.MouseAdapter;
导入java.awt.event.MouseEvent;
导入java.awt.geom.AffineTransform;
导入java.awt.geom.Ellipse2D;
导入java.awt.geom.Path2D;
导入java.util.ArrayList;
导入java.util.List;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.UIManager;
导入javax.swing.UnsupportedLookAndFeelException;
类Canvas扩展了JPanel{
私有静态最终长serialVersionUID=1L;
私有布尔图;
private List myShapes=new ArrayList();
公共静态void main(字符串[]args){
invokeLater(新的Runnable(){
@凌驾
公开募捐{
试一试{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}catch(ClassNotFoundException |实例化Exception | IllegalacessException |不支持ookandfeelException ex){
例如printStackTrace();
}
JFrame=新JFrame(“测试”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(新画布());
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
});
}
公共画布(){
MyMouseAdapter MyMouseAdapter=新的MyMouseAdapter();
addMouseListener(myMouseAdapter);
addMouseMotionListener(myMouseAdapter);
addSquare(100100);
}
@凌驾
公共维度getPreferredSize(){
返回新维度(400400);
}
公共void集合列表(ArrayList形状){
}
公共列表getList(){
返回null;
}
公共空心正方形(整数宽度、整数高度){
Path2D rect2=新的Path2D.Double();
rect2.append(新矩形(getWidth()/2-width/2,getHeight()/2
-高度/2,宽度,高度),真实);
myShapes.add(rect2);
重新油漆();
}
@凌驾
受保护组件(图形g){
超级组件(g);
图形2d g2=(图形2d)g;
g2.设定行程(新基本行程(2));
用于(形状:myShapes){
g2.绘制(形状);
}
}
类MyMouseAdapter扩展了MouseAdapter{
私有布尔值=false;
专用点;
专用点偏移;
私有形状点击形状;
@凌驾
公共无效鼠标按下(MouseEvent e){
如果(例如getButton()!=MouseEvent.BUTTON1){
返回;
}
用于(形状:myShapes){
if(shape!=null
&&shape.contains(例如getPoint()){
System.out.println(“单击”);
按下=真;
单击形状=形状;
this.point=e.getPoint();
int deltaX=point.x-shape.getBounds().x;
int deltaY=point.y-shape.getBounds().y;
抵销=新点(deltaX、deltaY);
系统输出打印项次(点+“x”+偏移量);
重新油漆();
打破
}
}
}
@凌驾
公共无效鼠标标记(鼠标事件e){
如果(按下){
int index=myShapes.indexOf(单击形状);
myShapes.remove(索引);
int deltaX=e.getPoint().x-offset.x;
int deltaY=e.getPoint().y-offset.y;
clickedShape=新路径2D.Double(clickedShape,
AffineTransform.getTranslateInstance(
deltaX-clickedShape.getBounds().x,
deltaY-clickedShape.getBounds().y));
添加(索引,点击形状);
point=e.getPoint();
重新油漆();
}
}
@凌驾
公共无效MouseEvent(MouseEvent e){
偏移量=空;
按下=假;
}
}
}

在执行任何操作之前,您需要知道鼠标单击与形状角的偏移量,这将允许您拖动对象,使其不会突然“跳”到您当前的鼠标位置

@Override
public void mousePressed(MouseEvent e) {
    //...
    for (Shape shape : myShapes) {
            //...
            this.point = e.getPoint();
            int deltaX = point.x - shape.getBounds().x;
            int deltaY = point.y - shape.getBounds().y;
            offset = new Point(deltaX, deltaY);
            //...
        }
    }
}
然后,你会计算变化的增量,在
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Path2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

class Canvas extends JPanel {

    private static final long serialVersionUID = 1L;

    private boolean drawing;
    private List<Shape> myShapes = new ArrayList<Shape>();

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new Canvas());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public Canvas() {
        MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
        addMouseListener(myMouseAdapter);
        addMouseMotionListener(myMouseAdapter);
        addSquare(100, 100);
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(400, 400);
    }

    public void setList(ArrayList<Shape> shapes) {

    }

    public List<Shape> getList() {
        return null;
    }

    public void addSquare(int width, int height) {
        Path2D rect2 = new Path2D.Double();
        rect2.append(new Rectangle(getWidth() / 2 - width / 2, getHeight() / 2
                        - height / 2, width, height), true);

        myShapes.add(rect2);
        repaint();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setStroke(new BasicStroke(2));
        for (Shape shape : myShapes) {
            g2.draw(shape);
        }
    }

    class MyMouseAdapter extends MouseAdapter {

        private boolean pressed = false;
        private Point point;
        private Point offset;
        private Shape clickedShape;

        @Override
        public void mousePressed(MouseEvent e) {
            if (e.getButton() != MouseEvent.BUTTON1) {
                return;
            }
            for (Shape shape : myShapes) {
                if (shape != null
                                && shape.contains(e.getPoint())) {
                    System.out.println("Clicked");
                    pressed = true;
                    clickedShape = shape;
                    this.point = e.getPoint();
                    int deltaX = point.x - shape.getBounds().x;
                    int deltaY = point.y - shape.getBounds().y;
                    offset = new Point(deltaX, deltaY);
                    System.out.println(point + "x" + offset);
                    repaint();
                    break;
                }
            }
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            if (pressed) {
                int index = myShapes.indexOf(clickedShape);
                myShapes.remove(index);

                int deltaX = e.getPoint().x - offset.x;
                int deltaY = e.getPoint().y - offset.y;

                clickedShape = new Path2D.Double(clickedShape,
                                AffineTransform.getTranslateInstance(
                                                deltaX - clickedShape.getBounds().x,
                                                deltaY - clickedShape.getBounds().y));
                myShapes.add(index, clickedShape);
                point = e.getPoint();
                repaint();
            }
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            offset = null;
            pressed = false;
        }
    }
}