Java 中的形状基于左上角作为锚点,宽度/高度向下/向右绘制。
你需要计算点击点和拖动点之间的边界框
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;
}
问题是,你还是用点击点和拖动点的差来计算宽度,pw应该是maxX和minX值的差
所以this example 向您展示了如何计算锚点和大小属性
我阅读了那个帖子,但它没有解决圆圈的拖动扩展,以及它如何上下移动。
那你做错了
我正在尝试绘制一个圆,而不是一个没有相同宽度和高度(椭圆)的圆。
好的,所以应该总是显示圆是从锚点绘制的,所以当minX 或minY 小于clickPoint 的x/y 点时,那么您需要将它们调整为 clickPoint 和大小的差异
因此,这将使它“出现”,就好像圆始终是从初始点击点绘制的一样
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();
}
}
}
}