java - 在 Jpanel 上拖动形状

标签 java swing event-handling mouseevent java-2d

我正在使用 JButton 的 Action 监听器来绘制不同的形状。为了始终在面板上保留以前绘制的形状,我使用了一个数组列表,其中添加了所有绘制的形状并重新绘制了整个列表。我如何拖动任何形状而其他形状一直显示在Jpanel上?

protected void paintComponent(Graphics g) {
        super.paintComponent(g);


        System.out.println("====>>> " + s);
        switch (s) {

          case "Button1":
                Activity act = new Activity();
                act.setArcH(15);
                act.setArcW(15);
                act.setBreadth(40);
                act.setLength(50);
                act.setXpoint(x);
                act.setYpoint(y);

                //==========================================================

                obj = new ShapePoints();
                obj.setShapeId(ShapesID.ROUND_RECTANGLE_ID);
                obj.setxPoint(act.getXpoint());
                obj.setyPoint(act.getYpoint());
                obj.setLength(act.getLength());
                obj.setBreadth(act.getBreadth());
                obj.setArcW(act.getArcW());
                obj.setArcH(act.getArcH());
                shapePoints.add(obj);

                Iterator itr = shapePoints.iterator();
                while (itr.hasNext()) {
                    ShapePoints sp = (ShapePoints) itr.next();

                    switch (sp.getShapeId()) {

                        case ShapesID.ARROW_ID:

                            break;
                        case ShapesID.CIRCLE_ID:

                            g.drawOval(obj.getxPoint(), obj.getyPoint(), obj.getLength(), obj.getBreadth());

                            break;


                        case ShapesID.CON_CIRCLE_ID:
                            g.drawOval(sp.getxPoint(), sp.getyPoint(), sp.getLength(), sp.getLength());
                            g.fillOval(sp.getxPoint() + 10, sp.getyPoint() + 10, sp.getBreadth() / 2, sp.getBreadth() / 2);
                            break;
                        case ShapesID.RECTANGLE_ID:

                            break;
                        case ShapesID.ROUND_RECTANGLE_ID:

                            g.drawRoundRect(obj.getxPoint(), obj.getyPoint(), obj.getLength(), obj.getBreadth(),
                                    obj.getArcW(), obj.getArcH());
                            break;
                    }
                }
                break;

这是1个按钮

最佳答案

您需要添加一个 mouselistener 和一个 mousemotionlistener(通常您为两者创建一个实例)并检查您的形状是否包含鼠标按下事件。如果是,您将跟踪鼠标拖动到哪里以平移您的形状,并像往常一样不断调用 repaint()

  • 单击创建多边形的顶点
  • 双击创建当前绘制的多边形(如果它至少有 3 个顶点),然后我们创建一个新的
  • 右键单击清除当前绘制的多边形并创建一个新多边形
  • 按下/拖动/释放移动位于鼠标下方的多边形(如果有多个多边形,则取第一个找到的多边形。最好进行反向 for 循环)

这是一个例子:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.event.MouseAdapter;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class TestNaming {

    private static final int PANEL_WIDTH = 600;
    private static final int PANEL_HEIGHT = 600;

    public static class Drawing extends JPanel {

        private static final Font FONT = new Font("Arial", Font.PLAIN, 12);

        private List<Polygon> polygons = new ArrayList<Polygon>();

        private Polygon currentPolygon = new Polygon();

        private MouseAdapter mouseListener = new MouseAdapter() {

            private Polygon dragged;
            private Point lastLocation;

            @Override
            public void mousePressed(java.awt.event.MouseEvent e) {
                for (Polygon p : polygons) {
                    if (p.contains(e.getPoint())) {
                        dragged = p;
                        lastLocation = e.getPoint();
                        break;
                    }
                }
            }

            @Override
            public void mouseDragged(java.awt.event.MouseEvent e) {
                if (dragged != null) {
                    dragged.translate(e.getX() - lastLocation.x, e.getY() - lastLocation.y);
                    lastLocation = e.getPoint();
                    repaint();
                }
            }

            @Override
            public void mouseReleased(java.awt.event.MouseEvent e) {
                dragged = null;
                lastLocation = null;
            }

            @Override
            public void mouseClicked(java.awt.event.MouseEvent e) {
                if (SwingUtilities.isLeftMouseButton(e)) {
                    if (e.getClickCount() == 1) {
                        addPoint(e.getX(), e.getY());
                    } else if (e.getClickCount() == 2) {
                        createPolygon();
                    }
                } else if (SwingUtilities.isRightMouseButton(e)) {
                    clearCurrentPolygon();
                }
            }

        };

        public Drawing() {
            addMouseListener(mouseListener);
            addMouseMotionListener(mouseListener);
        }

        protected void addPoint(int x, int y) {
            currentPolygon.addPoint(x, y);
            repaint();
        }

        protected void clearCurrentPolygon() {
            currentPolygon = new Polygon();
            repaint();
        }

        protected void createPolygon() {
            if (currentPolygon.npoints > 2) {
                polygons.add(currentPolygon);
            }
            clearCurrentPolygon();
            repaint();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(PANEL_WIDTH, PANEL_HEIGHT);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.RED);
            g.setFont(FONT);
            for (Polygon polygon : polygons) {
                drawPolygon(g, polygon);
            }
            g.setColor(Color.GREEN);
            drawPolygon(g, currentPolygon);
        }

        private void drawPolygon(Graphics g, Polygon polygon) {
            if (polygon.npoints < 3) {
                if (polygon.npoints == 1) {
                    g.fillOval(polygon.xpoints[0] - 2, polygon.ypoints[0] - 2, 4, 4);
                    drawNthPoint(g, polygon, 0);
                } else if (polygon.npoints == 2) {
                    g.drawLine(polygon.xpoints[0], polygon.ypoints[0], polygon.xpoints[1], polygon.ypoints[1]);
                    drawNthPoint(g, polygon, 0);
                    drawNthPoint(g, polygon, 1);
                }
            } else {
                g.drawPolygon(polygon);
                for (int i = 0; i < polygon.npoints; i++) {
                    drawNthPoint(g, polygon, i);
                }
            }
        }

        private void drawNthPoint(Graphics g, Polygon polygon, int nth) {
            // Only works 26 times!
            String name = Character.toString((char) ('A' + nth));
            int x = polygon.xpoints[nth];
            int height = g.getFontMetrics().getHeight();
            int y = polygon.ypoints[nth] < height ? polygon.ypoints[nth] + height : polygon.ypoints[nth];
            Rectangle2D stringBounds = g.getFontMetrics().getStringBounds(name, g);
            g.drawString(name, x, y);
        }

    }

    protected static void initUI() {
        JFrame frame = new JFrame("test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new Drawing());
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                initUI();
            }
        });
    }
}

关于java - 在 Jpanel 上拖动形状,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16440159/

相关文章:

java - 如何 move 棋盘?

java - 如何制作一个文本字段来从数据库中搜索数据?

Python (2.*) Tkinter - 高级事件处理格式

java - 如何在需要时而不是在启动时初始化单例 spring bean?

java - 当 Java 中两个值相等时,为什么会出现交换错误?

java - 有关通过 PropertyChangeSupport 更新 Swing GUI 的设计问题

python - wxPython WebView : how to reload on error?

java - Android 套接字连接被拒绝

java - Spring Security 自定义 RememberMeAuthenticationFilter 没有被解雇

javascript - 如何为一个元素禁用 JQuery 按键事件?