Question

Ok so basically I'm trying to write a GUI application which draws 2 circles and 2 rectangles in its main window. I'm trying to get it so that whenever the user clicks within the circles or rectangles, that particular circle or rectangle changes to another random colour.

Currently I've got it so that the MouseClick event (anywhere on screen) causes all of the circles or rectangles to change colour, to the same colour. This is what I've got so far:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Random;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;


public class Question2 {
    public static void main(String[] args) {
        SecondFrame f = new SecondFrame("Draw and Fill");
        f.init();
    }
}   

class SecondFrame extends JFrame{
    SecondFrame(String title) {
        super(title);
    }   

    private JPanel mainPanel;
    private GridBagConstraints gbc = new GridBagConstraints();
    private GridBagLayout gbLayout = new GridBagLayout();

    void init() {
        mainPanel = new JPanel();
        mainPanel.setLayout(gbLayout);
        this.setExtendedState(JFrame.MAXIMIZED_BOTH);
        this.setContentPane(mainPanel);
        gbc.gridheight = 1;

        mainPanel.addMouseListener(new MouseListener(){

            @Override
            public void mouseClicked(MouseEvent e) {
                Point mousePosition;
                mousePosition = mainPanel.getMousePosition();
                repaint();
            }

            @Override
            public void mouseEntered(MouseEvent e) {

            }

            @Override
            public void mouseExited(MouseEvent arg0) {
                // TODO Auto-generated method stub

            }

            @Override
            public void mousePressed(MouseEvent arg0) {
                // TODO Auto-generated method stub

            }

            @Override
            public void mouseReleased(MouseEvent arg0) {
                // TODO Auto-generated method stub

            }

        });

        this.pack();
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
    }

    public void paint(Graphics g){
     super.paint(g);
     Random ran = new Random();
     // Assumes max and min are non-negative.
     int red = 0 + ran.nextInt(255 - 0 + 1);
     int green = 0 + ran.nextInt(255 - 0 + 1);
     int blue = 0 + ran.nextInt(255 - 0 + 1);

     Color myColor = new Color(red,green,blue);
     g.setColor(myColor);
     g.fillOval(50,50,200,200);
     g.fillOval(50, 255, 200, 200);
     g.fillRect(255,50,200,200);
     g.fillRect(255, 255, 200, 200);
    }

}

If you could point me in the right direction that would be much appreciated. Thanks.

Was it helpful?

Solution

You would keep a track of drawn object. Then check if click occurred within any of these objects. If yes, change its color. For example, you can use Shape to represent simple forms. Its contains() method can be useful to determine if a clicked point is inside the boundary of the shape. Below is an example that introduces ShapeItem that has two properties Shape and Color. And, a panel that uses a list of ShapeItem to paint the actual shapes.

Also consider some minor side notes:

  • Don't paint directly on top level container such as JFrame. Instead, use JPanel or extension of JComponent;
  • For painting override paintComponent() rather than paint(), and don't forget to call super.paintComponent(g);
  • Usually there is no need to extend JFrame unless new functionality is added;

Take a look at Performing Custom Painting tutorial, and Closer Look at the Paint Mechanism section in particular, for more details.

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

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

public class DemoShapes {
    public static final Color DEFAULT_COLOR = Color.BLUE;

    public DemoShapes() {
        List<ShapeItem> shapes = new ArrayList<ShapeItem>();
        shapes.add(new ShapeItem(new Rectangle2D.Double(110, 1, 100, 100),
                DEFAULT_COLOR));
        shapes.add(new ShapeItem(new Rectangle2D.Double(110, 110, 100, 100),
                DEFAULT_COLOR));
        shapes.add(new ShapeItem(new Ellipse2D.Double(1, 1, 100, 100),
                DEFAULT_COLOR));
        shapes.add(new ShapeItem(new Ellipse2D.Double(1, 110, 100, 100),
                DEFAULT_COLOR));

        JFrame frame = new JFrame("Shapes");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        ShapesPanel panel = new ShapesPanel(shapes);
        frame.add(panel);

        frame.setLocationByPlatform(true);
        frame.pack();
        frame.setVisible(true);
    }

    class ShapeItem {
        private Shape shape;
        private Color color;

        public ShapeItem(Shape shape, Color color) {
            super();
            this.shape = shape;
            this.color = color;
        }

        public Shape getShape() {
            return shape;
        }

        public void setShape(Shape shape) {
            this.shape = shape;
        }

        public Color getColor() {
            return color;
        }

        public void setColor(Color color) {
            this.color = color;
        }
    }

    class ShapesPanel extends JPanel {
        private List<ShapeItem> shapes;
        private Random rand = new Random();

        public ShapesPanel(List<ShapeItem> shapesList) {
            this.shapes = shapesList;

            addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {

                    Color color = getRandomColor();
                    for (ShapeItem item : shapes) {
                        if (item.getShape().contains(e.getPoint())) {
                            item.setColor(color);
                        }
                    }
                    repaint();
                }
            });
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            Graphics2D g2 = (Graphics2D) g.create();

            for (ShapeItem item : shapes) {
                g2.setColor(item.getColor());
                g2.fill(item.getShape());
            }

            g2.dispose();
        }

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

        private Color getRandomColor() {
            return new Color(rand.nextFloat(), rand.nextFloat(),
                rand.nextFloat());
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new DemoShapes();
            }
        });
    }
}

enter image description here

OTHER TIPS

You should use mousePosition to determine if that point is within the bounds of any ovals or rectangles. If it is, perform g.setColor(myColor) and fill that shape. Then change g to a normal, non-randomized color, and fill the rest of the shapes.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top