I am trying to write a program in Java Swing that outputs a 10 x 10 grid of geometric rectangles filled with randoms colors. However, when the user clicks on one of the rectangles within the display window the rectangle should repaint() and change to another color.
Thus far I have the rudimentary program running, but I can't figure out how to implement a mouseListener to it in order to have the rectangles' color change when a user clicks inside. At this point, the rectangles only repaint when the display window is expanded and minimized. Any advice/help would be greatly appreciated! Thanks!
Here is what I have so far...
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.geom.*;
public class ColorGrid extends JPanel {
int w, x, y, z;
Color c = new Color((int)(Math.random() * 0xFFFFFF));
public void paint(Graphics g){
Graphics2D g2 = (Graphics2D) g;
setLayout(new GridLayout(10,10));
int w = x = y = z = 0;
for(int i=0;i<100;i++){
Color c = new Color((int)(Math.random() * 0xFFFFFF));
w+=10;
x+=10;
y+=50;
z+=15;
g2.drawRect(w+10,x+30,y,z);
g2.drawRect(w+10,x+30,y,z);
g2.fillRect(w+10,x+30,y,z);
g2.setPaint(c);
}
}
public static void main(String[] args) {
JFrame f= new JFrame();
f.setTitle("ColorGrid Display Window");
f.setSize(200,200);
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
Container contentPane = f.getContentPane();
contentPane.add(new ColorGrid());
f.show();
}
}
Any Component
can have a MouseListener
. JLabel
is nice for a colored rectangle, as long as you make it opaque.
Addendum: Having recommended MouseAdapter
elsewhere, I should mention that one instance is enough.
Addendum: This update adds the mouse listener in the ColorLabel
constructor.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JLabel;
/** @see http://stackoverflow.com/questions/5136859 */
public class ColorLabel extends JLabel {
private static final int N = 10;
private static final Random random = new Random();
private static final MouseAdapter listener = new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
ColorLabel label = (ColorLabel) e.getSource();
label.setBackground(new Color(random.nextInt()));
}
};
public ColorLabel() {
this.setOpaque(true);
this.setBackground(new Color(random.nextInt()));
this.setPreferredSize(new Dimension(32, 32));
this.addMouseListener(listener);
}
private void displayGrid() {
JFrame f = new JFrame("ColorGrid");
f.setLayout(new GridLayout(N, N));
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
for (int i = 0; i < N * N; i++) {
final ColorLabel label = new ColorLabel();
f.add(label);
}
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new ColorLabel().displayGrid();
}
});
}
}
Instead of having a JPanel
that you draw your grid of colors on, how about you have a grid of buttons. You override the drawing mechanism for the button so that it just renders as it's current color. Then you have functionality built in to listen for clicks to occur in a specific section of your grid.
This is what I came up with.
Note: I'm still studying Java in University, so this might not be the exact way to do this but it worked when I did it.
public class ColorGrid extends JPanel implements MouseListener {
this.addMouseListener(this);
addMouseListener(this);
That's the first part, the second part is to have these methods in your code.
public void mouseClicked(MouseEvent arg0) {
}
public void mouseEntered(MouseEvent arg0) {
}
public void mouseExited(MouseEvent arg0) {
}
public void mousePressed(MouseEvent arg0) {
}
public void mouseReleased(MouseEvent arg0) {
}
Then, depending on what you want, (i.e. Mouse clicked or pressed), just type in:
repaint();
Hope this helped.
Assuming you have a 2d array of colors, you can simply use the x and y the mouselistener gives you when you click to calculate the indices of that rectangle. Just divide the x and y by the size of the rectangle using integer division. After changing the color use repaint() to show it.