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.
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:
JFrame
. Instead, use JPanel
or extension of JComponent
; paintComponent()
rather than paint()
, and don't forget to call super.paintComponent(g)
; 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();
}
});
}
}