0

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!

Tim
  • 1,056
  • 4
  • 17
  • 34
  • The standard drawing is just that - drawing. It immediately rasters (i.e. turns the paths defined by the shapes to the graphic object). As such, the objects "cease to exist" as independent entities (and are actually never able to directly respond to UI events). You'll have to handle the object layout/graph (and connections) independent of the drawing - and then draw the layout/graph as required (after updating said objects). Of course, there are existing libraries for this, I'm sure. – user2246674 Jun 30 '13 at 21:52
  • You might examine the example cited [here](http://stackoverflow.com/a/11944233/230513). – trashgod Jun 30 '13 at 21:55
  • you need to track every object you want to draw in a List WITH POINTS!, and for any movement just clear(not whole the graphic) the container and redraw contents with new points, about the circles and lines you would add something like movement interface to the src object to move the associated object to, which is triggered(fired) by the src move –  Jun 30 '13 at 22:01

1 Answers1

3

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

            }

        }
    }
}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366