Home > Enterprise >  Create Polygon that update after the insertion of every point
Create Polygon that update after the insertion of every point

Time:04-14

I am having a problem with a school project in Which I create a Polygon that when I insert points the polygon update after the insertion of every point.

For example

My program:

The result I want:

What I understood is that to make it look like the result, remove the link between Point3 and Point1 and the new one will be between Point4 and Point1. If this is the solution I don't know what to add to my code to fix it.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.geom.*;
import java.util.*;

public class ShapesByMouseDrag3 extends JFrame {

    private static final int FW = 800;
    private static final int FH = 600;

    private Point p1;
    private Point p2;

    private int x;
    private int y;

    ArrayList<Integer> alX = new ArrayList<>();
    ArrayList<Integer> alY = new ArrayList<>();

    JRadioButton lineRB = new JRadioButton("Line");
    JRadioButton rectRB = new JRadioButton("Rectangle");
    JRadioButton Ellipse = new JRadioButton("Ellipse");
    JRadioButton PolygonRB = new JRadioButton("Polygon");

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

    public ShapesByMouseDrag3() {
        setSize(FW, FH);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setTitle("Draw Graphics Objects by Mouse Drag");
        setLocationRelativeTo(null);

        setLayout(new BorderLayout());

        PaintPanel paintPanelObj = new PaintPanel(FW, FH);

        JPanel chooseShapePanel = new JPanel();
        chooseShapePanel.setBackground(Color.WHITE);
        chooseShapePanel.setLayout(new GridLayout(4, 1));

        chooseShapePanel.setBorder(BorderFactory.createTitledBorder(
                BorderFactory.createEtchedBorder(), "Shapes"));

        //Create the radio buttons.
        //Create a button group and add buttons
        ButtonGroup bgroup = new ButtonGroup();
        bgroup.add(lineRB);
        bgroup.add(rectRB);
        bgroup.add(Ellipse);
        bgroup.add(PolygonRB);

        // add buttons to chooseShapePanel panel
        chooseShapePanel.add(lineRB);
        chooseShapePanel.add(rectRB);
        chooseShapePanel.add(Ellipse);
        chooseShapePanel.add(PolygonRB);
        add(paintPanelObj, BorderLayout.CENTER);
        add(chooseShapePanel, BorderLayout.WEST);
        setVisible(true);
        pack();
    }

    private class PaintPanel extends JPanel {

        private int PW; // panel-width
        private int PH; // panel-height

        Collection<Shape> shapeList = new ArrayList<Shape>();
        Collection<Shape> shapeListR = new ArrayList<Shape>();

        public PaintPanel(int W, int H) {
            PW = W;
            PH = H;
            setPreferredSize(new Dimension(PW, PH)); // set width & height of panel 
            setBorder(BorderFactory.createTitledBorder(
                    BorderFactory.createEtchedBorder(), "Canvas"));

            addMouseListener(new MouseClickListener());
        }

        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D) g;

            g2.setStroke(new BasicStroke(2f));
            g2.setColor(Color.blue);

            if (lineRB.isSelected()) {
                makeLine();
            } else if (rectRB.isSelected()) {
                makeRectangle();
            } else if (Ellipse.isSelected()) {
                makeEllipse();
            } else if (PolygonRB.isSelected()) {
                makePolygon();
            }

            // draw all the shapes stored in the collection
            Iterator itr = shapeList.iterator();
            while (itr.hasNext()) {
                g2.draw((Shape) itr.next());
            }

            // reset
            p1 = null;
            p2 = null;

        }

        public void makeLine() {
            if (p1 != null && p2 != null) {
                shapeList.add(new Line2D.Double(p1.x, p1.y, p2.x, p2.y));
            }
        }

        public void makeRectangle() {
            double RectangleX = Math.min(p1.x, p2.x);
            double RectangleY = Math.min(p1.y, p2.y);
            double RectangleW = Math.abs(p1.x - p2.x);
            double RectangleH = Math.abs(p1.y - p2.y);
            if (p1 != null && p2 != null) {
                shapeList.add(new Rectangle2D.Double(RectangleX, RectangleY, RectangleW, RectangleH));
            }
        }

        public void makeEllipse() {
            double EllipseX = Math.min(p1.x, p2.x);
            double EllipseY = Math.min(p1.y, p2.y);
            double EllipseW = Math.abs(p1.x - p2.x);
            double EllipseH = Math.abs(p1.y - p2.y);
            if (p1 != null && p2 != null) {
                shapeList.add(new Ellipse2D.Double(EllipseX, EllipseY, EllipseW, EllipseH));
            }
        }

        public void makePolygon() {

            int[] xArray = new int[alX.size()];
            int[] yArray = new int[alY.size()];
            for (int i = 0; i < alX.size(); i  ) {
                xArray[i] = alX.get(i);
                yArray[i] = alY.get(i);

            }
            if (p1 != null && p2 != null) {
                shapeList.add(new Polygon(xArray, yArray, xArray.length));
            }

        }

        private class MouseClickListener extends MouseAdapter {

            public void mousePressed(MouseEvent event) {
                p1 = new Point(event.getX(), event.getY());
                alX.add(p1.x);
                alY.add(p1.y);
            }

            public void mouseEntered(MouseEvent event) {
                alX.clear();
                alY.clear();
            }

            public void mouseReleased(MouseEvent event) {
                p2 = new Point(event.getX(), event.getY());
                alX.add(p2.x);
                alY.add(p2.y);
                repaint();
            }
        }
    }
}

CodePudding user response:

Don't use paintComponent to build the shapes, this is not what paintComponent is for.

I would use Path2D (over Polygon) as you add new points to Path2D in a much easier way.

The following is a simple example, it uses two Path2D instances to track the shape. The first is an "open" path, which we keep adding points to, the second is a "closed" copy of the first. This is intentional, as if you close the shape after each click, it will just draw lines extending from the first click point.

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.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Line2D;
import java.awt.geom.Path2D;
import javax.swing.JFrame;
import javax.swing.JPanel;

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

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private Path2D polygon = null;
        // Give some guidence
        private Point lastClickPoint = null;
        private Point currentMousePoint = null;

        public TestPane() {
            MouseAdapter ma = new MouseAdapter() {
                // This is the "acutal" shape been draw
                // This allows us to "close" the polygon
                // without it breaking the underlying shape
                private Path2D mouseShape = null;

                @Override
                public void mouseClicked(MouseEvent e) {
                    if (mouseShape == null) {
                        mouseShape = new Path2D.Double();
                        mouseShape.moveTo(e.getX(), e.getY());
                    } else {
                        mouseShape.lineTo(e.getX(), e.getY());
                    }
                    polygon = new Path2D.Double();
                    polygon.append(mouseShape, true);
                    polygon.closePath();
                    lastClickPoint = e.getPoint();
                    repaint();
                }

                @Override
                public void mouseMoved(MouseEvent e) {
                    currentMousePoint = e.getPoint();
                    repaint();
                }
            };

            addMouseListener(ma);
            addMouseMotionListener(ma);
        }

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

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setColor(Color.BLACK);
            if (polygon != null) {
                g2d.draw(polygon);
            }
            if (lastClickPoint != null && currentMousePoint != null) {
                g2d.setColor(Color.GRAY);
                g2d.draw(new Line2D.Double(lastClickPoint, currentMousePoint));
            }
            g2d.dispose();
        }

    }
}

This is focused example, solving just the one problem and you're going to need to modify you code to fit it. I would, on each mouse click, be making determinations about what type of shape you are trying to create and create a "intermediate", which can be painted, until the user "commits" the changes, at which time the shape would be added to the List, but that's me

  • Related