Reputation: 25
I'm trying to create a game of Reversi, and I'm in the beginning stages trying to figure out how to have a square respond to a click event. Here is my code so far.
To be clear, at the moment, I'm just trying to change the background color of a clicked panel in the grid. I'm still learning how ActionListeners work.
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import javax.swing.*;
import java.awt.event.MouseListener;
public class Reversi {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
ReversiFrame frame = new ReversiFrame();
frame.setSize(400,450);
frame.setResizable(false);
frame.setVisible(true);
}
}
/**
*
* Class for the frame
*/
class ReversiFrame extends JFrame{
/**
* Constructor for ReversiFrame
*/
public ReversiFrame(){
super("Reversi");
setDefaultCloseOperation(EXIT_ON_CLOSE);
JMenuBar bar = new JMenuBar();
setJMenuBar(bar);
JMenu gameMenu = new JMenu("Game");
JMenu helpMenu = new JMenu("Help");
bar.add(gameMenu);
bar.add(helpMenu);
final JMenuItem newGame = new JMenuItem("New Game");
final JMenuItem exit = new JMenuItem("Exit");
final JMenuItem help = new JMenuItem("Help");
gameMenu.add(newGame);
gameMenu.add(exit);
helpMenu.add(help);
/**
* Exits program when exit menu item is clicked.
*/
exit.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
dispose();
}
});
ReversiPanel panel = new ReversiPanel();
add(panel);
}
}
class ReversiPanel extends JPanel{
public static final int GRID_ROWS = 8;
public static final int GRID_COLS = 8;
public static final int HEIGHT = 50;
public static final int WIDTH = 50;
private GridPanel [][] panels = new GridPanel[GRID_ROWS][GRID_COLS];
public ReversiPanel(){
setLayout(new GridLayout(GRID_ROWS,GRID_COLS));
setSize(HEIGHT, WIDTH);
for(int row = 0; row < GRID_ROWS; row++){
for(int col = 0; col < GRID_COLS; col++){
panels[row][col] = (new GridPanel(row, col));
setFocusable(true);
panels[row][col].addMouseListener(new MouseAdapter(){
/*public void mouseClicked(MouseEvent e){
((GridPanel)e.getSource()).getParent().setBackground(Color.red);
repaint();
}*/
});
}
}
}
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
for(int row = 0; row < GRID_ROWS; row++){
for(int col = 0; col < GRID_COLS; col++){
panels[row][col].draw(g2);
}
}
}
}
class GridPanel extends JPanel{
public static final int HEIGHT = 50;
public static final int WIDTH = 50;
private boolean filled;
private int numberGridsFilled = 0;
private int x, y;
public GridPanel(int row, int col){
x = row * WIDTH;
y = + col * HEIGHT;
setSize(HEIGHT, WIDTH);
filled = false;
setBorder(BorderFactory.createLineBorder(Color.GRAY));
setBackground(Color.red);
addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent e){
setBackground(Color.RED);
repaint();
}
});
}
public void draw(Graphics2D g2){
g2.setPaint(Color.GRAY);
Rectangle2D r = new Rectangle2D.Double(x, y, WIDTH, HEIGHT);
g2.draw(r);
}
public void changeColor(){
setBackground(Color.BLACK);
}
public void setColor() {
setBackground(Color.BLACK);
}
}
class Tile{
private Color color;
public Tile(Color color){
}
}
Upvotes: 1
Views: 67
Reputation: 347314
To start with, I wouldn't do panels[row][col].draw(g2);
in your paintComponent
, GridPanel
extends from JPanel
and JPanel
is very capable of painting itself.
Start by getting rid the paintComponent
method and add the GridPanel
s to the ReversiPanel
...
public ReversiPanel() {
setLayout(new GridLayout(GRID_ROWS, GRID_COLS));
for (int row = 0; row < GRID_ROWS; row++) {
for (int col = 0; col < GRID_COLS; col++) {
panels[row][col] = (new GridPanel(row, col));
add(panels[row][col]);
setFocusable(true);
panels[row][col].addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e){
((GridPanel)e.getSource()).getParent().setBackground(Color.red);
repaint();
}
});
}
}
}
When a component is added to a container (which is attached to a native peer), it becomes eligible for event notification
Now, in you GridPanel
, replace the draw
method with paintComponent
and override the getPreferredSize
to return the desired size of the component
class GridPanel extends JPanel {
public static final int HEIGHT = 50;
public static final int WIDTH = 50;
private boolean filled;
private int numberGridsFilled = 0;
private int row, col;
public GridPanel(int row, int col) {
row = row;
col = col;
filled = false;
setBorder(BorderFactory.createLineBorder(Color.GRAY));
setBackground(Color.red);
}
public Dimension getPreferredSize() {
return new Dimenions(WIDTH, HEIGHT);
}
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D)g.create();
g2d.setPaint(Color.GRAY);
Rectangle2D r = new Rectangle2D.Double(x, y, WIDTH, HEIGHT);
g2d.draw(r);
g2d.dispose();
}
Upvotes: 4
Reputation: 168825
… trying to figure out how to have a square respond to a click event.
Make the square a (possibly undecorated) JButton
instead of a JPanel
. Give the button an icon, and/or text, then add an ActionListener
.
A button with an action listener will respond to both mouse and keyboard events.
E.G. as seen in this answer to Add a complex image in the panel, with buttons around it in one customized user interface.
Upvotes: 3