获取在Jpanel上绘制的Path2D形状的(起始)X和Y坐标 [英] Getting the (starting) X and Y coordinates of a Path2D shape drawn on Jpanel

查看:193
本文介绍了获取在Jpanel上绘制的Path2D形状的(起始)X和Y坐标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我有一个程序,可以使用Path2D对象向JPanel添加形状,然后单击并拖动它们。我想要做的是能够找到药物后形状的最终X和Y坐标。坐标需要是左上角坐标。任何想法?

  // //在屏幕中心添加一个圆圈
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();
}
..................
//绘制所有形状
@Override
保护void paintComponent(图形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);
}
}
..................
//如果鼠标点击在圆圈中,按下= true
@Override
public void mousePressed(MouseEvent e){
if(e.getButton()!= MouseEvent.BUTTON1){
return; (int i = 0; i< shapes.size(); i ++){
if(shapes.get(i)!= null
&& amp; ; shapes.get(i).contains(e.getPoint())){
currentIndex = i;
pressed = true;
this.point = e.getPoint();



$ b // if if pressed = true,用鼠标移动圆圈
@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();
//我需要在这里找到新的坐标!!!!!!!!!!!
repaint();


完整密码

  class Canvas extends JPanel {
private static final long serialVersionUID = 1L;

私人列表< Path2D> shapes = new ArrayList< Path2D>();
private int currentIndex;
private Point lineStartingPoint = new Point();
private point lineEndingPoint = new Point();
私有布尔图;
private boolean lineSelected;
private Path2D.Double linePath;
private Shapes myShapes = new Shapes();
私人列表< Path2D> circles = new ArrayList< Path2D>();
$ b $ public Canvas(){
MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
addMouseListener(myMouseAdapter);
addMouseMotionListener(myMouseAdapter);

$ b public void setList(ArrayList< UMLCircle> shapes){

}

public List< UMLCircle> 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);

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

public void addLine(){
lineSelected = true;
repaint();
}

public void addCircle(int width,int height){
myShapes.addCircle(getWidth()/ 2 - width / 2,getHeight()/ 2 - height
/ 2,宽度,高度);
Path2D circ = new Path2D.Double();
circ.append(new Ellipse2D.Double(getWidth()/ 2 - width / 2,
getHeight()/ 2 - height / 2,width,height),true);
circles.add(circ);
shapes.add(circ);
repaint();


@Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
this.setOpaque(true);
this.setBackground(Color.WHITE);
Graphics2D g2 =(Graphics2D)g;
if(lineSelected){
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setStroke(new BasicStroke(2));
g2.drawLine(lineStartingPoint.x,lineStartingPoint.y,
lineEndingPoint.x,lineEndingPoint.y);
}
g2.setStroke(new BasicStroke(2));
for(Path2D shape:shapes){
g2.draw(shape);
}
}

class MyMouseAdapter extends MouseAdapter {
private boolean pressed = false;
私人点积分;
$ b $ @Override
public void mousePressed(MouseEvent e){
if(e.getButton()!= MouseEvent.BUTTON1){
return; (int i = 0; i< shapes.size(); i ++){
if(shapes.get(i)!= null
&& amp; ; shapes.get(i).contains(e.getPoint())){
currentIndex = i;
pressed = true;
this.point = e.getPoint(); ($)

if(circles.get(i)!= null
&& circles.get(i).contains(e.getPoint())){
currentIndex = i;
pressed = true;
this.point = e.getPoint();
}
}
if(lineSelected){
drawing = true;
lineStartingPoint = e.getPoint();
lineEndingPoint = lineStartingPoint;


$ b @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();
myShapes.updateCircleLocation(currentIndex,point.x,point.y);
System.out.println(point.x ++ point.y);
repaint();
}
if(drawing){
lineEndingPoint = e.getPoint();
repaint();


$ b @Override
public void mouseReleased(MouseEvent e){
if(drawing&& lineSelected){
drawing = false;
lineSelected = false;
lineEndingPoint = e.getPoint();
linePath = new Path2D.Double();
linePath.moveTo(lineStartingPoint.getX(),
lineStartingPoint.getY());
linePath.lineTo(lineEndingPoint.getX(),lineEndingPoint.getY());
shapes.add(linePath);
repaint();
}
pressed =假;
}
}
}

编辑

抵消的计算:

  int deltaX = e。 getX() -  point.x; 
int deltaY = e.getY() - point.y;
shapes.get(currentIndex).transform(
AffineTransform.getTranslateInstance(deltaX,deltaY));
point = e.getPoint();
int newXPos = e.getX() - deltaX; // final X pos
int newXPos = e.getX() - deltaX; // final Y pos


解决方案

在你做任何事情之前,您需要知道从形状的角落点击鼠标的偏移量,这将允许您拖动该对象,以便它不会突然跳到您当前的鼠标位置......

  @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();






$ b

现在,说了这么多,不要做这... ...

pre $ protected void paintComponent(Graphics g){
// ...
this .setOpaque(真);
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;

类Canvas扩展JPanel {

private static final long serialVersionUID = 1L;

私有布尔图;
私人列表<形状> 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);
}
});

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

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

$ b $ 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;
私人点积分;
私人点抵消;
私人形状clickedShape;
$ b $ @Override
public void mousePressed(MouseEvent e){
if(e.getButton()!= MouseEvent.BUTTON1){
return; (形状形状:myShapes){
if(shape!= null
&& shape.contains(e.getPoint())){$ b $(

b 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();
休息;



$ @覆盖
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 =假;
}
}
}


So, I have a program where I can add shapes to JPanel using Path2D objects and then I can click and drag them around. What I want to do is be able to find the final X and Y coordinates of the shape AFTER it has been drug. The coordinates need to be the top-left coordinates. Any ideas?

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

Full Code

class Canvas extends JPanel {
private static final long serialVersionUID = 1L;

private List<Path2D> shapes = new ArrayList<Path2D>();
private int currentIndex;
private Point lineStartingPoint = new Point();
private Point lineEndingPoint = new Point();
private boolean drawing;
private boolean lineSelected;
private Path2D.Double linePath;
private Shapes myShapes = new Shapes();
private List<Path2D> circles = new ArrayList<Path2D>();

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

public void setList(ArrayList<UMLCircle> shapes) {

}

public List<UMLCircle> 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);

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

public void addLine() {
    lineSelected = true;
    repaint();
}

public void addCircle(int width, int height) {
    myShapes.addCircle(getWidth() / 2 - width / 2, getHeight() / 2 - height
            / 2, width, height);
    Path2D circ = new Path2D.Double();
    circ.append(new Ellipse2D.Double(getWidth() / 2 - width / 2,
            getHeight() / 2 - height / 2, width, height), true);
    circles.add(circ);
    shapes.add(circ);
    repaint();
}

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    this.setOpaque(true);
    this.setBackground(Color.WHITE);
    Graphics2D g2 = (Graphics2D) g;
    if (lineSelected) {
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setStroke(new BasicStroke(2));
        g2.drawLine(lineStartingPoint.x, lineStartingPoint.y,
                lineEndingPoint.x, lineEndingPoint.y);
    }
    g2.setStroke(new BasicStroke(2));
    for (Path2D shape : shapes) {
        g2.draw(shape);
    }
}

class MyMouseAdapter extends MouseAdapter {
    private boolean pressed = false;
    private Point point;

    @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 (circles.get(i) != null
                    && circles.get(i).contains(e.getPoint())) {
                currentIndex = i;
                pressed = true;
                this.point = e.getPoint();
            }
        }
        if (lineSelected) {
            drawing = true;
            lineStartingPoint = e.getPoint();
            lineEndingPoint = lineStartingPoint;
        }
    }

    @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();
            myShapes.updateCircleLocation(currentIndex, point.x, point.y);
            System.out.println(point.x + " " + point.y);
            repaint();
        }
        if (drawing) {
            lineEndingPoint = e.getPoint();
            repaint();
        }
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        if (drawing && lineSelected) {
            drawing = false;
            lineSelected = false;
            lineEndingPoint = e.getPoint();
            linePath = new Path2D.Double();
            linePath.moveTo(lineStartingPoint.getX(),
                    lineStartingPoint.getY());
            linePath.lineTo(lineEndingPoint.getX(), lineEndingPoint.getY());
            shapes.add(linePath);
            repaint();
        }
        pressed = false;
    }
}
}

EDIT

Calculation for offset:

            int deltaX = e.getX() - point.x;
            int deltaY = e.getY() - point.y;
            shapes.get(currentIndex).transform(
                    AffineTransform.getTranslateInstance(deltaX, deltaY));
            point = e.getPoint();
            int newXPos = e.getX() - deltaX; // final X pos
            int newXPos = e.getX() - deltaX; // final Y pos

解决方案

Before you can do anything, you need to know the offset of the mouse click from the corner of the shape, this will allow you to drag the object so it doesn't suddenly "jump" to your current mouse position...

@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);
            //...
        }
    }
}

Then, you would calculate the delta of change, between the current mouse position and the offset. Because you're applying a translate, you also need to subtract the shape's current location, as the translation is based on the shape's current location and we only want to apply the amount of change

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

Now, having said all that, don't do this...

protected void paintComponent(Graphics g) {
    //...
    this.setOpaque(true);
    this.setBackground(Color.WHITE);

Changing the state of the component from within the paint method can setup a infinite loop of repaint requests, which can chock your system. Also, the changes you make won't be applied to the current graphics context, as these properties are generally applied by the paint method...

And a working copy....

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

这篇关于获取在Jpanel上绘制的Path2D形状的(起始)X和Y坐标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆