I'm trying to create a program that will draw an equilateral triangle with an oval at the center point when the mouse is pressed, and while the mouse is being dragged, the triangle will redraw itself so that the triangle remains equilateral regardless of where the mouse is (the mouse acts as one of the corners of the triangle). I have the following code so far.

public class EquilateralRubberBand extends JFrame {
    /**
     *
     */
    public EquilateralRubberBand() {
        super("Equilateral Triangle Rubber Band");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBackground(Color.white);
        setContentPane(new DrawTrianglePanel());
        setSize(400, 400); // you can change this size but don't make it HUGE!
        setVisible(true);
    }

    /**
     *
     */
    private class DrawTrianglePanel extends JPanel implements MouseListener,
      MouseMotionListener {

        final float dash[] = { 5.0f };
        final BasicStroke dashed = new BasicStroke(1.0f,
            BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 3.0f, dash, 0.0f);
        final BasicStroke solid = new BasicStroke(1.0f);
        Graphics2D g2;

        /**
         */
        public DrawTrianglePanel() {
            addMouseListener(this);
            addMouseMotionListener(this);
        }

        /**
         *
         * @param g the graphics context with which we paint into.
         */
        public void paintComponent(Graphics g) {
            super.paintComponent(g);

            g2 = (Graphics2D) g;
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

        }

        public void mousePressed(MouseEvent e) {
            Point pressPoint = e.getPoint();
            g2.setColor(Color.RED);
            g2.fillOval(pressPoint.x, pressPoint.y, 100, 100);
            g2.setColor(Color.BLUE);
            g2.drawRect(pressPoint.x, pressPoint.y, 100, 100);
            g2.drawString(("Dragging: " + pressPoint.x + ", " + pressPoint.y), 
                    50, 25);
            repaint();
        }

        public void mouseReleased(MouseEvent e) {

        }

        public void mouseDragged(MouseEvent e) {

        }

        public void mouseEntered(MouseEvent e) { }
        public void mouseExited(MouseEvent e) { }
        public void mouseClicked(MouseEvent e) { }
        public void mouseMoved(MouseEvent e) { }
    }

    /**
     *
     */
    public static void main(String[] args) {
        new EquilateralRubberBand();
    }

};

Obviously this is nowhere near complete, but I just wanted to be able to test what I had done initially to make sure I was on the right track. So I wrote the code to draw the oval and the corner that the mouse will drag, as well as a string that tracks the coordinates of the mouse. However, when I open the panel and press the mouse to do this initial stuff, nothing happens. I'm sure I've added the mouse listeners correctly, and the frame opens up when I try to run the program. I tried a simple setBackground() in the mouseEntered() portion to make sure I had added the listeners and frame components correctly. It works, so the issue must be with the code I've written in the mousePressed method. I'm not sure where I've gone wrong though. Any help would be appreciated.

All of your drawing code MUST be in the paintComponent method. That's the only place where you have access to the correct Graphics environment, and where Swing will handle the changes to the Graphics properly. All you can do in your mouse listener(s) is to update some variables that keep track of what/where to draw, then call repaint(); which tells Swing that it needs to schedule a call your paintComponent again.

So I've got the code to draw the triangle but when I try to move it, instead of staying equilateral and just spinning around the center , it shifts its shape and is able to move around the screen. I'm assuming there is something wrong with my math but I can't find the problem. Anybody have any ideas?

public class EquilateralRubberBand extends JFrame {

    /**
     *
     */
    public EquilateralRubberBand() {
        super("Equilateral Triangle Rubber Band");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBackground(Color.white);
        setContentPane(new DrawTrianglePanel());
        setSize(400, 400); // you can change this size but don't make it HUGE!
        setVisible(true);
    }

    /**
     *
     */
    private class DrawTrianglePanel extends JPanel implements MouseListener,
      MouseMotionListener {

        final float dash[] = { 5.0f };
        final BasicStroke dashed = new BasicStroke(1.0f,
            BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 3.0f, dash, 0.0f);
        final BasicStroke solid = new BasicStroke(1.0f);
        final int sizeOfCenter = 5;
        final int sizeOfRectangles = 10;

        private String displayString;
        private boolean start;
        private Point centerPoint;
        private Point p1;
        private Point p2;
        private Point p3;



        /**
         */
        public DrawTrianglePanel() {
            addMouseListener(this);
            addMouseMotionListener(this);
        }

        /**
         *
         * @param g the graphics context with which we paint into.
         */
        public void paintComponent(Graphics g) {
            super.paintComponent(g);

            Graphics2D g2;
            g2 = (Graphics2D) g;
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
            if (start) {
                g2.setColor(Color.RED);
                g2.fillOval(centerPoint.x, centerPoint.y, sizeOfCenter, 
                        sizeOfCenter);
                g2.setColor(Color.BLUE);
                g2.drawRect(p1.x, p1.y, sizeOfRectangles, sizeOfRectangles);
                g2.drawRect(p2.x, p2.y, sizeOfRectangles, sizeOfRectangles);
                g2.drawRect(p3.x, p3.y, sizeOfRectangles, sizeOfRectangles);
                g2.drawString(displayString, 50, 25);
                g2.setStroke(dashed);
                g2.drawLine(p1.x, p1.y, p2.x, p2.y);
                g2.drawLine(p1.x, p1.y, p3.x, p3.y);
                g2.drawLine(p2.x, p2.y, p3.x, p3.y);
            }
        }

        public void mousePressed(MouseEvent e) {
            start = true;
            centerPoint = e.getPoint();
            doCoordinateCalculations(e.getPoint());
            displayString = "Pressed: " + centerPoint.x + ", " + centerPoint.y;
            repaint();
        }

        public void mouseReleased(MouseEvent e) {
            Point currentPoint = e.getPoint();
            displayString = "Released: " + currentPoint.x + ", " 
                    + currentPoint.y;
            repaint();
        }

        public void mouseDragged(MouseEvent e) {
            Point currentPoint = e.getPoint();
            displayString = "Dragging: " + currentPoint.x + ", " 
                    + currentPoint.y;
            doCoordinateCalculations(currentPoint);
            repaint();
        }

        public void mouseEntered(MouseEvent e) { }
        public void mouseExited(MouseEvent e) { }
        public void mouseClicked(MouseEvent e) { }
        public void mouseMoved(MouseEvent e) { }

        public void doCoordinateCalculations(Point point) {
            double distanceFromCenter;
            double angleP1;
            double angleP2;
            double angleP3;
            double v2x;
            double v2y;
            double v3x;
            double v3y;
            double p2x;
            double p2y;
            double p3x;
            double p3y;
            p1 = point;
            distanceFromCenter = Math.sqrt((Math.pow((p1.x
                    - centerPoint.x), 2) + Math.pow((p1.y 
                            - centerPoint.y), 2)));
            angleP1 = Math.atan2(p1.y - centerPoint.y,
                    p1.x - centerPoint.x);
            angleP1 = ((2 * Math.PI)/3) - angleP1;

            angleP2 = angleP1 + ((2 * Math.PI)/3);
            v2x = distanceFromCenter * Math.cos(angleP2);
            v2y = distanceFromCenter * Math.sin(angleP2);
            p2x = v2x + centerPoint.x;
            p2y = v2y + centerPoint.y;
            p2 = new Point((int)p2x, (int)p2y);

            angleP3 = angleP1 - ((2 * Math.PI)/3);
            v3x = distanceFromCenter * Math.cos(angleP3);
            v3y = distanceFromCenter * Math.sin(angleP3);
            p3x = v3x + centerPoint.x;
            p3y = v3y + centerPoint.y;
            p3 = new Point((int)p3x, (int)p3y);
        }
    }

    /**
     *
     */
    public static void main(String[] args) {
        new EquilateralRubberBand();
    }

};
This article has been dead for over six months. Start a new discussion instead.