问题
So I add an Ellipse2D.Float to a JPanel (and to an ArrayList) when clicked. I want to know if after this has been done I can then move the shape (say, through shift-click). At the moment it seems to be static and I cannot drag it anywhere.
Furthermore, is it possible to connect two circles with a line in such a fashion that the line connects the two circles permenantly; when a circle is move the line is altered to follow the circles.
I'm just looking to see if this is feasible, I have started coding but can't find out how to do these two things. Any answers, links, code snippets appreciated!
回答1:
You've got the basic idea. Detect mouse click, paint new shape.
The next step is to know when the shift key is pressed and knowing what the last (or selected) shape was and then be able to update it's position.
For me, the easiest solution would be to maintain information about the shape and it's position in some manner. In this example, I've used a simple Drawable
class which not only combines the position and the shape, but also has a simple draw
method to make life easier.
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);
}
}
}
}
来源:https://stackoverflow.com/questions/17395185/moving-an-ellipse-that-has-been-drawn