简体   繁体   English

当我拖动鼠标以绘制圆时,形状在某些情况下会移动

[英]When I mouse drag to draw a Circle, the shape moves in certain situations

 @Override
    public Shape getShape() {
        final Ellipse2D.Double result = new Ellipse2D.Double();
        final double px = Math.min(getStart().getX(), getEnd().getX());
        final double py = Math.min(getStart().getY(), getEnd().getY());
        final double pw = Math.abs(getStart().getX() - getEnd().getX());
        result.setFrame(px, py, pw, pw);
        return result;
    }

So this getShape() is returning the shape to a class that draws the shape. 因此,此getShape()将形状返回到绘制形状的类。 getStart() gets the starting Point of the mouse on click, and getEnd() gets the Point at mouse release. getStart()获取单击时鼠标的起点,而getEnd()获取释放鼠标时的指针。 Now, when I drag to draw a circle, if i drag to the right or down the circle works as intended and expands to the mouse, if I drag up or left of the cursor the circle expands as it should BUT the circle shape moves up and down with the cursor and I am not sure why. 现在,当我拖动以绘制一个圆时,如果我向右或向下拖动,圆会按预期工作并扩展到鼠标,如果我向上或向左拖动光标,则圆会扩展, 圆形应该向上移动并向下移动光标,我不确定为什么。

Shapes in Java are based on the top/left corner as the anchor and the width/height been drawn down/right. Java中的形状基于上/左角作为锚点,而宽度/高度则向下/向右绘制。

You need to calculate the bounding box between the click point and the drag point 您需要计算单击点和拖动点之间的边界框

public Shape getShape() {
    final Ellipse2D.Double result = new Ellipse2D.Double();
    final double px = Math.min(getStart().getX(), getEnd().getX());
    final double py = Math.min(getStart().getY(), getEnd().getY());
    final double pw = Math.abs(getStart().getX() - getEnd().getX());
    result.setFrame(px, py, pw, pw);
    return result;
}

The problem is, you're still using the difference between the click point and the drag point to calculate the width, pw should be the difference between the maxX and minX values 问题是,您仍在使用点击点和拖动点之间的差来计算宽度, pw应该是maxXminX值之间的差

So this example shows you how to calculate the anchor and size properties 因此, 此示例向您展示了如何计算锚点和尺寸属性

I read through that post, but it doesn't solve the dragging expansion of the circle, and how it moves up and down. 我通读了该帖子,但它并不能解决圆的拖动扩展以及它如何上下移动。

Then you're doing something wrong 那你做错了

I am trying to get a circle drawn not a circle without the same width and height(ellipse). 我正在尝试绘制一个不具有相同宽度和高度(椭圆)的圆,而不是一个圆。

Okay, so it should always appear that the circle is been draw from the anchor point, so when the minX or minY is less than the clickPoint 's x / y points, then you need to adjust them as a difference of the clickPoint and the size 好的,因此总会出现从锚点开始画圆的情况,因此,当minXminY小于clickPointx / y点时,您需要将其调整为clickPoint与尺寸

例

So, this will make it "appear" as if the circle is always been drawn from the intial click point 因此,这将使其“出现”,好像总是从初始点击点绘制了圆圈

import java.awt.BorderLayout;
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.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class SelectionExample {

    public static void main(String[] args) {
        new SelectionExample();
    }

    public SelectionExample() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

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

    public class TestPane extends JPanel {

        private Point clickPoint;

        private Shape shape;
        private Rectangle box;

        public TestPane() {
            MouseAdapter ma = new MouseAdapter() {

                @Override
                public void mouseDragged(MouseEvent e) {
                    int minX = Math.min(e.getX(), clickPoint.x);
                    int minY = Math.min(e.getY(), clickPoint.y);
                    int maxX = Math.max(e.getX(), clickPoint.x);
                    int maxY = Math.max(e.getY(), clickPoint.y);

                    box = new Rectangle(minX, minY, maxX - minX, maxY - minY);
                    int size = Math.min(maxX - minX, maxY - minY);
                    if (minX < clickPoint.x) {
                        minX = clickPoint.x - size;
                    }
                    if (minY < clickPoint.y) {
                        minY = clickPoint.y - size;
                    }

                    shape = new Ellipse2D.Double(minX, minY, size, size);
                    repaint();
                }

                @Override
                public void mousePressed(MouseEvent e) {
                    clickPoint = new Point(e.getPoint());
                }

            };

            addMouseListener(ma);
            addMouseMotionListener(ma);
        }

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

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (shape != null) {
                Graphics2D g2d = (Graphics2D) g.create();
                g2d.setColor(new Color(0, 0, 255, 64));
                g2d.fill(shape);
                g2d.setColor(Color.BLUE);
                g2d.draw(shape);
                g2d.draw(box);
                g2d.dispose();
            }
        }
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM