1

I'm doing a program in which there are 8 shapes contained in an array that will be displayed when you click the mouse. I am new to Java and not that familiar with event handlers and listeners.

I am trying to make the shapes appear at the location the mouse is clicked at inside the frame yet I am having trouble since the constructor of each shape use 2 Points as its parameter.

Here's an example from the code:

import MyLibs.Circle;
import MyLibs.Rectangle;
import MyLibs.Shape;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Random;

public class DrawInScreenOnClickTest extends javax.swing.JFrame {

    private Image dbImage;

    Shape[] sh = new Shape[] {
        new Circle(new Point(50, 60), new Point(130, 180)),
            new Rectangle(new Point(50, 200), new Point(150, 350)),
            new Circle(new Point(200, 300), new Point(350, 350)),
            new Rectangle(new Point(100, 100), new Point(250, 250)),
            new Circle(new Point(150, 150), new Point(300, 300)),
            new Circle(new Point(200, 200), new Point(450, 500)),
            new Rectangle(new Point(300, 300), new Point(550, 550)),
            new Circle(new Point(150, 150), new Point(320, 320))
    };

    Color[] colors = new Color[] {
        Color.cyan, Color.green, Color.red, Color.blue, Color.magenta, Color.orange
    };

    Random random = new Random();
    int i = 0;
    Shape shape;
    boolean first = true;


    public DrawInScreenOnClickTest() {
        initComponents();
    }


    private void formMouseClicked(java.awt.event.MouseEvent evt) {
        repaint();
    }


    public class Mouse extends MouseAdapter {
        @Override
        public void mousePressed(MouseEvent e) {
            int x = e.getX();
            int y = e.getY();
        }
    }

    public void paint(Graphics g) {

        if (first == true) {
            first = false;
        } else {
            int shapeColor = random.nextInt(6);

            Shape shape = sh[i]; //calls shapes array
            shape.setColor(colors[shapeColor]); //call colors array random
            shape.drawShape(g); //display shape
            if (i == 4) {
                i = 0;
            } else
                i++;
        }
    }


    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new DrawInScreenOnClickTest().setVisible(true);
            }
        });
    }
}
Woodchuck
  • 3,869
  • 2
  • 39
  • 70
hendselp
  • 13
  • 5
  • 1
    What framework are you using? Swing? JavaFx? For better help sooner post a proper [mre] – Frakcool Jul 06 '20 at 18:42
  • I am using javax.swing.JFrame – hendselp Jul 06 '20 at 18:45
  • So you want something like [this](https://stackoverflow.com/questions/41700866/draw-on-one-side-of-a-jpanel/41703107#41703107)? – Frakcool Jul 06 '20 at 18:53
  • yes it is similar to that. i have posted the test part of my code since I am still confused – hendselp Jul 06 '20 at 19:02
  • That's much better but can you please post a proper [mre]? You're lacking a `main` method and we lack the class definition. Also please rename the class from `Test` to something else. There's a lot of people who call their classes `Test`, make it something more meaningful such as `DrawInScreenOnClickTest` – Frakcool Jul 06 '20 at 19:04
  • I have edited the code. I truly sorry for taking up your time and thank you also – hendselp Jul 06 '20 at 19:11
  • That's almost a [mre], we don't have the `initComponents` method and have you tested this code compiles? Actually no need to say sorry, I'm thankful that you're following advises to improve this and future questions you may do on this site :) A MRE is a brand new code that we can copy / paste / compile / run without doing anything else in our side. That way we can provide more help. Also a tip, if you check the code that I shown before in the link, that's a MRE, and there you can see that custom painting is done in the `paintComponent` method not in `paint` – Frakcool Jul 06 '20 at 19:16
  • oh initComponents method is already indicated in netbeans when you choose to do JFrame. So when do you use the paint method? You can just use the paintComponent only without the paint method? – hendselp Jul 06 '20 at 19:20
  • `paintComponent` calls internally `paint`. I don't use NetBeans, also if you were to call `paint` to do your custom painting you forgot to call `super.paint(g);` but again, please try the other code that I provided – Frakcool Jul 06 '20 at 19:28
  • ohh now I understand paint method thank you again for your time I will try what you have advised – hendselp Jul 06 '20 at 19:31

1 Answers1

1

Here's an example that alternates drawing of shapes (rectangle and circle) with randomized lengths and widths.

This example makes use of paintComponent(...) method to draw shapes in the screen.

You shouldn't extend JFrame unless you're changing the behavior of it, instead build your UI towards the use of JPanels which are more flexible and allow you to use paintComponent.

I made use of the Shape API rather than a custom Shape class (which you're using and you didn't post the code for it).

I didn't included the randomized color as that's up to the OP to write it, this is just an example on how to draw components on mouse click.

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class DrawInScreenOnClickTest {
    private JFrame frame;
    private DrawingPane pane;
    private List<Shape> shapes;
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new DrawInScreenOnClickTest()::createAndShowGUI);
    }
    
    private void createAndShowGUI() {
        frame = new JFrame(getClass().getSimpleName());
        
        shapes = new ArrayList<Shape>();
        shapes.add(new Ellipse2D.Double(50, 50, 50, 50));
        shapes.add(new Rectangle.Double(50, 200, 50, 100));
        shapes.add(new Ellipse2D.Double(150, 200, 150, 150));
        
        pane = new DrawingPane();
        
        pane.addMouseListener(new MouseListen());
        
        frame.add(pane);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
    
    @SuppressWarnings("serial")
    class DrawingPane extends JPanel {
        public void addNewShape(Shape s) {
            
        }
        
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            for (Shape s : shapes) {
                g2d.draw(s);
            }
        }
        
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(500, 500);
        }
    }

    class MouseListen extends MouseAdapter {
        int counter = 0;
        
        @Override
        public void mouseClicked(MouseEvent e) {
            super.mouseClicked(e);
            counter++;
            
            if (counter % 2 == 0) {
                shapes.add(new Rectangle.Double(e.getX(), e.getY(), Math.random() * 50, Math.random() * 50));
            } else {
                shapes.add(new Ellipse2D.Double(e.getX(), e.getY(), Math.random() * 50, Math.random() * 50));
            }
            pane.repaint();
        }
    }
}

enter image description here

Additional (recommended) lecture:

Frakcool
  • 10,915
  • 9
  • 50
  • 89