因此,我在单击时将 Ellipse2D.Float 添加到 JPanel(和 ArrayList)。我想知道完成此操作后是否可以移动形状(例如,通过 shift-click)。目前它似乎是静态的,我无法将它拖到任何地方。
此外,是否可以用一条线连接两个圆,使线永久连接两个圆?当一个圆圈移动时,这条线会改变为跟随圆圈。
我只是想看看这是否可行,我已经开始编码,但不知道如何做这两件事。任何答案,链接,代码片段表示赞赏!
因此,我在单击时将 Ellipse2D.Float 添加到 JPanel(和 ArrayList)。我想知道完成此操作后是否可以移动形状(例如,通过 shift-click)。目前它似乎是静态的,我无法将它拖到任何地方。
此外,是否可以用一条线连接两个圆,使线永久连接两个圆?当一个圆圈移动时,这条线会改变为跟随圆圈。
我只是想看看这是否可行,我已经开始编码,但不知道如何做这两件事。任何答案,链接,代码片段表示赞赏!
你已经有了基本的想法。检测鼠标点击,绘制新形状。
下一步是知道何时按下 shift 键并知道最后一个(或选择的)形状是什么,然后能够更新它的位置。
对我来说,最简单的解决方案是以某种方式维护有关形状及其位置的信息。在这个例子中,我使用了一个简单的Drawable
类,它不仅结合了位置和形状,而且有一个简单的draw
方法让生活更轻松。
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ShiftShape {
public static void main(String[] args) {
new ShiftShape();
}
public ShiftShape() {
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 List<Drawable> drawables;
public TestPane() {
drawables = new ArrayList<Drawable>(25);
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
Drawable drawable = null;
if ((e.getModifiersEx() & MouseEvent.SHIFT_DOWN_MASK) == MouseEvent.SHIFT_DOWN_MASK) {
if (!drawables.isEmpty()) {
drawable = drawables.get(drawables.size() - 1);
}
} else {
drawable = new Drawable();
drawables.add(drawable);
}
if (drawable != null) {
drawable.setLocation(e.getPoint());
repaint();
}
}
});
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
for (Drawable drawable : drawables) {
drawable.draw(g2d);
}
g2d.dispose();
}
public class Drawable {
private Point location;
private Shape shape;
public Drawable() {
shape = new Ellipse2D.Float(0, 0, 20, 20);
}
public void setLocation(Point location) {
this.location = location;
}
public Point getLocation() {
return location;
}
public void draw(Graphics2D g2d) {
Point p = getLocation();
int x = p.x - 10;
int y = p.y - 10;
g2d.translate(x, y);
g2d.draw(shape);
g2d.translate(-x, -y);
}
}
}
}