【问题标题】:drawPolygon keeps drawing lines from starting (mousePressed) location to current (mouseDragged) locationdrawPolygon 保持从起始(mousePressed)位置到当前(mouseDragged)位置绘制线
【发布时间】:2013-03-02 00:48:44
【问题描述】:

所以,我试图从单击鼠标开始动态绘制多边形,直到我停止拖动和释放。而不是,为了这个问题,当我单击时绘制一个方形轮廓,向下拖动,然后向右,然后向上,然后向左,这就是发生的事情: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);

完整的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);

        }   
    }

【问题讨论】:

  • 显示您的paintComponent 代码..
  • @VishalK 我会编辑完整的代码,但我认为这并不重要
  • 你必须在 mouseDragged 方法中用它们平移鼠标拖动点后设置 oldX 和 oldY。
  • @Legend 在 repaint() 之后添加下面的内容会产生与提供的图片相同的结果。或者这就是你的意思? (对不起,不知道如何格式化) oldX = currentX; oldY = currentY;
  • @Rima 你不能添加新点。您只需翻译已经存在的。我会尝试快速制作一些东西给你看。

标签: java awt polygon graphics2d java-2d


【解决方案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) &amp; SHAPE.length) 绘制一条线。

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

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

如果您对此有任何疑问,请随时问我。

~传说

【讨论】:

  • 谢谢,这应该可以帮助我做我想做的事。这只是我使用 Java 编码的第三周,所以我仍在努力学习。
  • 这是“需要知道”之一。有几个。它们只是完成工作的基本方法。
【解决方案2】:

如果你只想画一个多边形。你可以简单地使用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了解更多详情

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-04
    • 2011-09-19
    相关资源
    最近更新 更多