0

因此,我在单击时将 Ellipse2D.Float 添加到 JPanel(和 ArrayList)。我想知道完成此操作后是否可以移动形状(例如,通过 shift-click)。目前它似乎是静态的,我无法将它拖到任何地方。

此外,是否可以用一条线连接两个圆,使线永久连接两个圆?当一个圆圈移动时,这条线会改变为跟随圆圈。

我只是想看看这是否可行,我已经开始编码,但不知道如何做这两件事。任何答案,链接,代码片段表示赞赏!

4

1 回答 1

3

你已经有了基本的想法。检测鼠标点击,绘制新形状。

下一步是知道何时按下 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);

            }

        }
    }
}
于 2013-07-01T00:11:26.403 回答