drawPolygon保持从开始(mousePressed)位置到当前(mouseDragged)位置的绘制线

时间:2013-03-13 20:54:17

标签: java awt polygon graphics2d java-2d

所以,我正在尝试从单击鼠标开始直到我停止拖动和释放时动态绘制多边形。而不是为了这个问题的目的,当我点击,向下拖动,然后向右,向上,然后向上,然后向左,绘制方形轮廓,这就是发生的事情:http://imgur.com/t8ZN3Pp

有什么建议吗?

注意:

model.addPolygon()创建一个带起点的Polygon并将其添加到名为'polys'的ArrayList

model.addPolygonPoint()为这个创建的多边形添加点,该多边形存储在'polys'中

我的绘画功能遍历多边形来绘制

public void mousePressed(MouseEvent e) {                
    oldX = e.getX();
    oldY = e.getY();
    model.addPolygon(oldX, oldY);     
}

public void mouseDragged(MouseEvent e) {
    currentX = e.getX();
    currentY = e.getY();
    model.addPolyPoint(currentX, currentY);
    repaint();
}

。 。 。然后在paintComponent中:

   for (ListIterator<Polys> iter = 
                model.polys.listIterator(model.polys.size()); 
                iter.hasPrevious();){
            graphics2D.draw(iter.previous().poly);

Full paintComponent:

public void paintComponent(Graphics g) {
    super.paintComponent(g);
    if (image == null) {
        image = createImage(getSize().width, getSize().height);
        graphics2D = (Graphics2D) image.getGraphics();
        graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
    }
    g.drawImage(image, 0, 0, null);

    for (ListIterator<Polys> iter = 
            model.polys.listIterator(model.polys.size()); 
            iter.hasPrevious();){
        graphics2D.draw(iter.previous().poly);

        }   
    }

2 个答案:

答案 0 :(得分:1)

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;

public class Testing {

    private static int lastX;
    private static int lastY;

    private static int modX;
    private static int modY;

    private static final BasicStroke STROKE = new BasicStroke(2.0F);

    private static final Point[] SHAPE = new Point[]{

            new Point(10, 10),
            new Point(10, 40),
            new Point(60, 90),
            new Point(50, 50)

    };

    public static void main(final String[] args) {

        final JFrame frame = new JFrame("Polygon Movement");
        final JPanel pane = new JPanel() {
            @Override
            public void paintComponent(final Graphics g1) {
            final Graphics2D g = (Graphics2D) g1;
            g.setColor(Color.RED);
            g.translate(modX, modY);
            g.setStroke(STROKE);
            for (int i = 0; i < SHAPE.length; i++) {
                g.drawLine(SHAPE[i].x, SHAPE[i].y, SHAPE[(i + 1) % SHAPE.length].x, SHAPE[(i + 1) % SHAPE.length].y);
            }
        }
    };
    pane.addMouseMotionListener(new MouseMotionAdapter() {
        @Override
        public void mouseDragged(MouseEvent e) {
            modX += e.getX() - lastX;
            modY += e.getY() - lastY;
            lastX = e.getX();
            lastY = e.getY();
            frame.repaint();
        }
    });
    pane.addMouseListener(new MouseAdapter() {
        @Override
        public void mousePressed(MouseEvent e) {
            lastX = e.getX();
            lastY = e.getY();
        }
    });

        pane.setPreferredSize(new Dimension(200, 200));
        frame.add(pane);
        frame.pack();
        frame.setVisible(true);

    }

}

如您所见,我使用定义的点制作基本形状。除非您希望更改基本形状(此处为静态),否则这是最有效的方法。在这种情况下,你会发现鼠标“抓住”并修改那个。无论哪种方式,都不需要添加或删除点。我只是偏好使用lastX而不是oldX这两个词。

BasicStroke是非常可选的,与转换为Graphics2D对象相同。

该行:

g.drawLine(SHAPE[i].x, SHAPE[i].y, SHAPE[(i + 1) % SHAPE.length].x, SHAPE[(i + 1) % SHAPE.length].y);

如果你之前尝试过这个东西,应该有所帮助。它遍历所有点,从当前(SHAPE[i])到下一个(SHAPE[(i + 1) & SHAPE.length)绘制一条线。

这种逻辑背后的原因就是说你有4分,就像我们在这里做的那样。通过它们的最后一次迭代,您将获得i = 3。由于这个和数组只包含4个索引(0-3),我们必须将该值恢复为零。为简单起见,我使用% SHAPE.length,因此不需要特殊情况。

我也选择使用适配器,因为7种可能的方法只需要2种方法。

如果您有任何问题,请随时向我询问此事。

〜图例

答案 1 :(得分:0)

如果您要做的只是绘制多边形。您只需使用Shape API

即可

这将允许您向形状“添加”点并允许形状自行绘制。

这里我使用一个简单的Path2D形状,因为它允许我随着时间的推移附加点。我保留了一个运行的形状列表,这使我可以根据需要生成多个多边形

import java.awt.BorderLayout;
import java.awt.Color;
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.Line2D;
import java.awt.geom.Path2D;
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 DrawPolygon {

    public static void main(String[] args) {
        new DrawPolygon();
    }

    public DrawPolygon() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new PolyPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }

        });
    }

    public static class PolyPane extends JPanel {

        private MouseHandler mouseHandler;
        private Path2D currentShape;
        private List<Path2D> lstPloys;
        private Point lastPoint;
        private Point currentPoint;

        public PolyPane() {
            lstPloys = new ArrayList<>();
        }

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

        @Override
        public void addNotify() {
            super.addNotify();
            addMouseListener(getMouseHandler());
            addMouseMotionListener(getMouseHandler());
        }

        @Override
        public void removeNotify() {
            removeMouseListener(getMouseHandler());
            removeMouseMotionListener(getMouseHandler());
            super.removeNotify();
        }

        public MouseHandler getMouseHandler() {
            if (mouseHandler == null) {
                mouseHandler = new MouseHandler();
            }
            return mouseHandler;
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            if (lastPoint != null) {
                g2d.setColor(Color.RED);
                g2d.fillOval(lastPoint.x - 2, lastPoint.y - 2, 4, 4);
            }
            if (currentShape != null) {
                g2d.setColor(Color.RED);
                g2d.draw(currentShape);
                if (lastPoint != null && currentPoint != null) {
                    System.out.println(lastPoint + " - " + currentPoint);
                    g2d.setColor(new Color(255, 0, 0, 64));
                    g2d.draw(new Line2D.Float(lastPoint, currentPoint));
                }
            }
            g2d.setColor(Color.BLACK);
            for (Shape shape : lstPloys) {
                g2d.draw(shape);
            }
            g2d.dispose();
        }

        public class MouseHandler extends MouseAdapter {

            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getButton() == MouseEvent.BUTTON1) {
                    if (e.getClickCount() == 1) {
                        Point p = e.getPoint();
                        lastPoint = p;
                        if (currentShape == null) {
                            currentShape = new Path2D.Float();
                            currentShape.moveTo(p.x, p.y);
                        } else {
                            currentShape.lineTo(p.x, p.y);
                        }
                        repaint();
                    } else if (e.getClickCount() == 2) {
                        currentShape.closePath();
                        lstPloys.add(currentShape);
                        currentShape = null;
                        lastPoint = null;
                        repaint();
                    }
                }
            }

            @Override
            public void mouseMoved(MouseEvent e) {
                if (currentShape != null) {
                    currentPoint = e.getPoint();
                    repaint();
                } else {
                    currentPoint = null;
                }
            }

        }

    }

}

请查看Working with Geometry了解详情