【问题标题】:Dragging of shapes on Jpanel在 Jpanel 上拖动形状
【发布时间】:2013-05-08 23:04:08
【问题描述】:

我正在使用 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 个按钮

【问题讨论】:

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


    【解决方案1】:

    您需要添加一个 mouselistener 和一个 mousemotionlistener(通常您为两者创建一个实例)并检查您的形状是否包含鼠标按下事件。如果是,您跟踪鼠标拖动的位置以转换您的形状并像往常一样连续调用repaint()

    • 单击即可创建多边形的顶点
    • 双击创建当前绘制的多边形(如果它至少有 3 个顶点),然后我们创建一个新的
    • 右键单击清除当前绘制的多边形并创建一个新多边形
    • Press/Drag/Release 移动位于鼠标下方的多边形(如果有多个,则使用找到的第一个。最好进行反向 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();
                }
            });
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-22
      • 1970-01-01
      • 2020-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多