Перемещение нарисованного эллипса

Поэтому я добавляю Ellipse2D.Float в JPanel (и в ArrayList) при нажатии. Я хочу знать, могу ли я после этого переместить фигуру (скажем, с помощью Shift-щелчка). На данный момент он кажется статичным, и я не могу его никуда перетащить.

Кроме того, возможно ли соединить два круга линией таким образом, чтобы линия постоянно соединяла два круга; когда круг перемещается, линия изменяется, чтобы следовать за кругами.

Я просто смотрю, возможно ли это, я начал кодировать, но не могу понять, как сделать эти две вещи. Любые ответы, ссылки, фрагменты кода приветствуются!


person Tim    schedule 30.06.2013    source источник
comment
Стандартный рисунок - это просто рисунок. Он сразу растрирует (т.е. превращает пути, определяемые фигурами, в графический объект). Таким образом, объекты перестают существовать как независимые объекты (и фактически никогда не могут напрямую реагировать на события пользовательского интерфейса). Вам придется обрабатывать макет/график объекта (и соединения) независимо от чертежа, а затем рисовать макет/график по мере необходимости (после обновления указанных объектов). Конечно, для этого есть существующие библиотеки, я уверен.   -  person user2246674    schedule 01.07.2013
comment
Вы можете изучить пример, приведенный здесь.   -  person trashgod    schedule 01.07.2013
comment
вам нужно отслеживать каждый объект, который вы хотите нарисовать в списке С ТОЧКАМИ!, и для любого движения просто очистить (не всю графику) контейнер и перерисовать содержимое с новыми точками, о кругах и линиях вы бы добавили что-то вроде интерфейса движения к объекту src, чтобы переместить связанный объект, который запускается (запускается) перемещением src   -  person    schedule 01.07.2013


Ответы (1)


У вас есть основная идея. Обнаружение щелчка мыши, рисование новой формы.

Следующий шаг — узнать, когда нажата клавиша 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);

            }

        }
    }
}
person MadProgrammer    schedule 01.07.2013