How can I set this program to match the MVC design pattern - java
I believe I have got most of the MVC part down for this program - Game Of Life. However I can't get the MouseListener to work properly. How can I change this match the MVC design pattern?
View
package lifepreparation;
import java.awt.Color;
import java.awt.*;
import java.awt.event.*;
import java.util.Hashtable;
import javax.swing.*;
import java.awt.event.MouseListener;
public class LifeView extends JFrame {
//Label used to house cells
private LifeModel[][] cellHouse;
private LifeModel model;
//Timer used to fire the next generation
private Timer timer;
//Generation counter - used to count the number of generations
private int generationCount = 0;
private JLabel generationLabel = new JLabel("Generation: 0");
//Declare action buttons
private JButton startB = new JButton("Start");
private JButton pauseB = new JButton("Pause");
private JButton clearB = new JButton("Clear");
//Slider to adjust the time interval between generations
private static final int minSpeed = 0;
private static final int maxSpeed = 1000;
private static final int speedMajorTicks = (maxSpeed-minSpeed)/5;
private static final int speedMinorTicks = (maxSpeed-minSpeed)/20;
JSlider generationS = new JSlider(minSpeed,maxSpeed);
//Identifies game status: false=pause, true=running
private boolean runStatus = false;
//Panel for the city
private JPanel panel;
public LifeView(int boardRow, int boardCol, LifeModel model) {
super("Game Of Life");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//**START Create labels to house cells, +2 more
cellHouse = new LifeModel[boardRow+2][boardCol+2];
for(int r = 0; r < boardRow+2; r++) {
for(int c = 0; c < boardCol+2; c++) {
cellHouse[r][c] = new LifeModel();
}
}
//--END Create Labels
//Panel to hold cell houses
panel = new JPanel(new GridLayout(boardRow, boardCol, 1, 1));
panel.setBackground(Color.BLACK);
panel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
//Add cellHouses to the panel
for(int r = 1; r < boardRow+1; r++) {
for(int c = 1; c < boardCol+1; c++) {
panel.add(cellHouse[r][c]);
cellHouse[r][c].addNeighbor(cellHouse[r-1][c]); //Add to TOP ^
cellHouse[r][c].addNeighbor(cellHouse[r+1][c]); //Add to BOTTOM _
cellHouse[r][c].addNeighbor(cellHouse[r][c-1]); //Add to left <-
cellHouse[r][c].addNeighbor(cellHouse[r][c+1]); //Add to right ->
cellHouse[r][c].addNeighbor(cellHouse[r-1][c-1]); //Add to top left ^<-
cellHouse[r][c].addNeighbor(cellHouse[r-1][c+1]); //Add to top right ^->
cellHouse[r][c].addNeighbor(cellHouse[r+1][c-1]); //Add to bottom left _<-
cellHouse[r][c].addNeighbor(cellHouse[r+1][c+1]); //Add to bottom right _->
}
}
//Panel with cellHouses added to the container
add(panel, BorderLayout.CENTER);
//South Panel to hold buttons and widgets with extra features
JPanel panelBottom = new JPanel();
//buttonPanel to hold start, pause, clear features
JPanel buttonPanel = new JPanel();
buttonPanel.add(clearB);
pauseB.setEnabled(false);
buttonPanel.add(pauseB);
buttonPanel.add(startB);
//speedPanel to hold slider to adjust the time interval
JPanel speedPanel = new JPanel();
JLabel speedText = new JLabel("Set Speed:");
generationS.setMajorTickSpacing(speedMajorTicks);
generationS.setMinorTickSpacing(speedMinorTicks);
generationS.setPaintTicks(true);
// the labels for the Slider
Hashtable<Integer, JLabel> speedLabel = new Hashtable<Integer, JLabel>();
for(int i = 0; i <= maxSpeed; i++) {
speedLabel.put( new Integer( i * speedMajorTicks ), new JLabel("" + i) );
}
generationS.setLabelTable(speedLabel);
generationS.setPaintLabels(true);
generationLabel.setHorizontalAlignment(SwingConstants.CENTER);
speedPanel.add(speedText);
speedPanel.add(generationS);
panelBottom.add(buttonPanel);
panelBottom.add(speedPanel);
panelBottom.add(generationLabel);
// add bottom panel to the JFrame
add(panelBottom, BorderLayout.SOUTH);
// put the frame on
setLocation(20, 20);
pack();
setVisible(true);
}
//Action to take dependent on the action referenced by the JButton and Timer
public void startPauseClear(ActionEvent e) {
//Get action reference
Object o = e.getSource();
//Action reference is to clear
if(o == clearB) {
timer.stop(); //Stop the timer
runStatus = false; //Set game as not running
pauseB.setEnabled(false); //Disable the pause button
startB.setEnabled(true); //Enable the start button
//Remove/Clear all cells from the cellHouse
for(int r = 1; r < cellHouse.length -1; r++) {
for(int c = 1; c < cellHouse[r].length -1; c++) {
cellHouse[r][c].clear();
}
}
//Reset the generation count
generationCount = 0;
generationLabel.setText("Generation: 0");
return;
}
//Action reference is to pause
if(o == pauseB) {
timer.stop(); //Stop the timer
runStatus = false; //Set game as not running
pauseB.setEnabled(false); //Disable the pause button
startB.setEnabled(true); //Enable the start button
return;
}
//Action reference is to start
if(o == startB) {
pauseB.setEnabled(true); //Enable the pause button
startB.setEnabled(false); //Disable the start button
runStatus = true; //Set game as running
timer.setDelay(maxSpeed - generationS.getValue()); //Adjust the speed
timer.start();
return;
}
//If the action is set by timer, set speed
timer.setDelay(maxSpeed - generationS.getValue());
//If the game is not running, exit and do nothing more
if(!runStatus) return;
//Update generation count and display
++generationCount;
generationLabel.setText("Generation: " + generationCount);
//Check to see if the cell should be buried
for(int r = 0; r < cellHouse.length; r++) {
for(int c = 0; c < cellHouse[r].length; c++) {
cellHouse[r][c].checkGeneration();
}
}
//Update to the next generation
for(int r = 0; r < cellHouse.length; r++) {
for(int c = 0; c < cellHouse[r].length; c++) {
cellHouse[r][c].updateGeneration();
}
}
}
public void addActionListener(ActionListener e) {
clearB.addActionListener(e);
pauseB.addActionListener(e);
startB.addActionListener(e);
timer = new Timer(maxSpeed - generationS.getValue(), e);
}
}
Controller
package lifepreparation;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class LifeController {
//Run App
LifeModel model;
LifeView view;
//Constructor
public LifeController(LifeModel model, LifeView view) {
this.model = model;
this.view = view;
//Add Listeners
view.addActionListener(new LifeActionListener());
view.addMouseListener(new LifeMouseListener());
}
class LifeActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
view.startPauseClear(e);
}
}
class LifeMouseListener implements MouseListener {
public void mouseClicked(MouseEvent arg0) {
model.unselectCell();
}
//If the mouse is in a cellHouse while being pressed, cell becomes alive
public void mouseEntered(MouseEvent arg0) {
model.selectCells();
}
public void mouseExited(MouseEvent arg0) {
}
//If the mouse is clicked on a cellHouse, cell comes to life
public void mousePressed(MouseEvent arg0) {
model.selectACell();
}
//Set mouse as not being held anymore
public void mouseReleased(MouseEvent arg0) {
model.setMouseHold();
}
}
}
Model
package lifepreparation;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
//LifeModel to handle cell life and death algorithm
public class LifeModel extends JLabel {
//Cell Color: cell[0] = dead cell, cell[1] = live cell.
private static final Color[] color = {Color.LIGHT_GRAY, Color.GREEN};
//Size of cells
private static final int cellSize = 15;
private static final Dimension citySize = new Dimension(cellSize, cellSize);
//checks if the mouse is still pressed or not
private boolean mouseHold = false;
private int currentStatus, newStatus;
private int nbNeighbor;
private LifeModel[] Neighbor = new LifeModel[8];
LifeModel() {
currentStatus = newStatus = 0; //Currently Dead
setOpaque(true); //Show color
setBackground(color[0]); //Light Gray color
this.setPreferredSize(citySize); //Set the dimension of the board
}
//Add a neighbor
void addNeighbor(LifeModel n) {
Neighbor[nbNeighbor++] = n;
}
//Check to see if a cell should live or not
void checkGeneration() {
//Number of neighbors that are alive
int nbAlive = 0;
//Check the status of the neighbors
for(int i = 0; i < nbNeighbor; i++)
nbAlive += Neighbor[i].currentStatus;
//If status of cell is alive
if(currentStatus == 1) {
//Bury cell if it has less than two neighbors
if(nbAlive < 2)
newStatus = 0;
//Bury cell if it has more than three live neighbors
if(nbAlive > 3)
newStatus = 0;
}
else {
//Dead cells with three live neighbors get reborn
if(nbAlive == 3)
newStatus = 1;
}
}
//Switch to next generation
void updateGeneration() {
if(currentStatus != newStatus) { //Adjust color for the new generation
currentStatus = newStatus;
setBackground(color[currentStatus]);
}
}
//Bury all cells in the city
void clear() {
if(currentStatus == 1 || newStatus == 1) {
currentStatus = newStatus = 0;
setBackground(color[currentStatus]);
}
}
public void unselectCell() {
if(currentStatus == 1 || newStatus == 1) {
currentStatus = newStatus = 0;
setBackground(color[currentStatus]);
}
}
//If the mouse is in a cellHouse while being pressed, cell becomes alive
public void selectCells() {
if(mouseHold) {
currentStatus = newStatus = 1;
setBackground(color[1]);
}
}
//If the mouse is clicked on a cellHouse, cell comes to life
public void selectACell() {
mouseHold = true;
currentStatus = newStatus = 1;
setBackground(color[1]);
}
//Set mouse as not being held anymore
public void setMouseHold() {
mouseHold = false;
}
}
Program without MVC implementation
package lifepreparation;
import java.awt.Color;
import java.awt.*;
import java.awt.event.*;
import java.util.Hashtable;
import javax.swing.*;
public class LifeView extends JFrame implements ActionListener {
//Cell Color: cell[0] = dead cell, cell[1] = live cell.
private static final Color[] color = {Color.LIGHT_GRAY, Color.GREEN};
//Size of cells
private static final int cellSize = 15;
private static final Dimension citySize = new Dimension(cellSize, cellSize);
//Label used to house cells
private LifeLabel[][] cellHouse;
//Timer used to fire the next generation
private Timer timer;
//Generation counter - used to count the number of generations
private int generationCount = 0;
private JLabel generationLabel = new JLabel("Generation: 0");
//Declare default buttons
private JButton startB = new JButton("Start");
private JButton pauseB = new JButton("Pause");
private JButton clearB = new JButton("Clear");
//Slider to adjust the time interval between generations
private static final int minSpeed = 0;
private static final int maxSpeed = 1000;
private static final int speedMajorTicks = (maxSpeed-minSpeed)/5;
private static final int speedMinorTicks = (maxSpeed-minSpeed)/20;
JSlider generationS = new JSlider(minSpeed,maxSpeed);
//Identifies game status: false=pause, true=running
private boolean runStatus = false;
// if the mouse is down or not
private boolean mouseHold = false;
public LifeView(int boardRow, int boardCol) {
super("Game Of Life");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//**START Create labels to house cells, +2 more to calculate cells that are out of bounds
cellHouse = new LifeLabel[boardRow+2][boardCol+2];
for(int r = 0; r < boardRow+2; r++) {
for(int c = 0; c < boardCol+2; c++) {
cellHouse[r][c] = new LifeLabel();
}
}
//--END Create Labels
//Panel to hold cell houses
JPanel panel = new JPanel(new GridLayout(boardRow, boardCol, 1, 1));
panel.setBackground(Color.BLACK);
panel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
//Add cellHouses to the panel
for(int r = 1; r < boardRow+1; r++) {
for(int c = 1; c < boardCol+1; c++) {
panel.add(cellHouse[r][c]);
cellHouse[r][c].addNeighbor(cellHouse[r-1][c]); //Add to TOP ^
cellHouse[r][c].addNeighbor(cellHouse[r+1][c]); //Add to BOTTOM _
cellHouse[r][c].addNeighbor(cellHouse[r][c-1]); //Add to left <-
cellHouse[r][c].addNeighbor(cellHouse[r][c+1]); //Add to right ->
cellHouse[r][c].addNeighbor(cellHouse[r-1][c-1]); //Add to top left ^<-
cellHouse[r][c].addNeighbor(cellHouse[r-1][c+1]); //Add to top right ^->
cellHouse[r][c].addNeighbor(cellHouse[r+1][c-1]); //Add to bottom left _<-
cellHouse[r][c].addNeighbor(cellHouse[r+1][c+1]); //Add to bottom right _->
}
}
//Panel with cellHouses added to the container
add(panel, BorderLayout.CENTER);
//South Panel to hold buttons and widgets with extra features
JPanel panelBottom = new JPanel();
//buttonPanel to hold start, pause, clear features
JPanel buttonPanel = new JPanel();
clearB.addActionListener(this);
buttonPanel.add(clearB);
pauseB.addActionListener(this);
pauseB.setEnabled(false);
buttonPanel.add(pauseB);
startB.addActionListener(this);
buttonPanel.add(startB);
//speedPanel to hold slider to adjust the time interval
JPanel speedPanel = new JPanel();
JLabel speedText = new JLabel("Set Speed:");
generationS.setMajorTickSpacing(speedMajorTicks);
generationS.setMinorTickSpacing(speedMinorTicks);
generationS.setPaintTicks(true);
// the labels for the Slider
Hashtable<Integer, JLabel> speedLabel = new Hashtable<Integer, JLabel>();
for(int i = 0; i <= maxSpeed; i++) {
speedLabel.put( new Integer( i * speedMajorTicks ), new JLabel("" + i) );
}
generationS.setLabelTable(speedLabel);
generationS.setPaintLabels(true);
generationLabel.setHorizontalAlignment(SwingConstants.CENTER);
speedPanel.add(speedText);
speedPanel.add(generationS);
panelBottom.add(buttonPanel);
panelBottom.add(speedPanel);
panelBottom.add(generationLabel);
// add bottom panel to the JFrame
add(panelBottom, BorderLayout.SOUTH);
// put the frame on
setLocation(20, 20);
pack();
setVisible(true);
// start the thread that run the cycles of life
timer = new Timer(maxSpeed - generationS.getValue(), this);
}
//Action to take dependent on the action referenced by the JButton and Timer
public void actionPerformed(ActionEvent e) {
//Get action reference
Object o = e.getSource();
//Action reference is to clear
if(o == clearB) {
timer.stop(); //Stop the timer
runStatus = false; //Set game as not running
pauseB.setEnabled(false); //Disable the pause button
startB.setEnabled(true); //Enable the start button
//Remove/Clear all cells from the cellHouse
for(int r = 1; r < cellHouse.length -1; r++) {
for(int c = 1; c < cellHouse[r].length -1; c++) {
cellHouse[r][c].clear();
}
}
//Reset the generation count
generationCount = 0;
generationLabel.setText("Generation: 0");
return;
}
//Action reference is to pause
if(o == pauseB) {
timer.stop(); //Stop the timer
runStatus = false; //Set game as not running
pauseB.setEnabled(false); //Disable the pause button
startB.setEnabled(true); //Enable the start button
return;
}
//Action reference is to start
if(o == startB) {
pauseB.setEnabled(true); //Enable the pause button
startB.setEnabled(false); //Disable the start button
runStatus = true; //Set game as running
timer.setDelay(maxSpeed - generationS.getValue()); //Adjust the speed
timer.start();
return;
}
//If the action is set by timer, set speed
timer.setDelay(maxSpeed - generationS.getValue());
//If the game is not running, exit and do nothing more
if(!runStatus) return;
//Update generation count and display
++generationCount;
generationLabel.setText("Generation: " + generationCount);
//Check to see if the cell should be buried
for(int r = 0; r < cellHouse.length; r++) {
for(int c = 0; c < cellHouse[r].length; c++) {
cellHouse[r][c].checkGeneration();
}
}
//Update to the next generation
for(int r = 0; r < cellHouse.length; r++) {
for(int c = 0; c < cellHouse[r].length; c++) {
cellHouse[r][c].updateGeneration();
}
}
}
//Run App
public static void main(String[] arg) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new LifeView(30, 50);
}
});
}
//LifeModel to handle cell life and death algorithm
class LifeLabel extends JLabel implements MouseListener {
private int currentGen, newGen;
private int nbNeighbor;
private LifeLabel[] Neighbor = new LifeLabel[8];
LifeLabel() {
currentGen = newGen = 0; //Currently Dead
setOpaque(true); //Show color
setBackground(color[0]); //Light Gray color
addMouseListener(this); //Add mouseListener
this.setPreferredSize(citySize); //Set the dimension of the board
}
//Add a neighbor
void addNeighbor(LifeLabel n) {
Neighbor[nbNeighbor++] = n;
}
//Check to see if a cell should live or not
void checkGeneration() {
//Number of neighbors that are alive
int nbAlive = 0;
//Check the status of the neighbors
for(int i = 0; i < nbNeighbor; i++)
nbAlive += Neighbor[i].currentGen;
//If status of cell is alive
if(currentGen == 1) {
//Bury cell if it has less than two neighbors
if(nbAlive < 2)
newGen = 0;
//Bury cell if it has more than three live neighbors
if(nbAlive > 3)
newGen = 0;
}
else {
//Dead cells with three live neighbors get reborn
if(nbAlive == 3)
newGen = 1;
}
}
//Switch to next generation
void updateGeneration() {
if(currentGen != newGen) { //Adjust color for the new generation
currentGen = newGen;
setBackground(color[currentGen]);
}
}
//Bury all cells in the city
void clear() {
if(currentGen == 1 || newGen == 1) {
currentGen = newGen = 0;
setBackground(color[currentGen]);
}
}
public void mouseClicked(MouseEvent arg0) {
if(currentGen == 1 || newGen == 1) {
currentGen = newGen = 0;
setBackground(color[currentGen]);
}
}
//If the mouse is in a cellHouse while being pressed, cell becomes alive
public void mouseEntered(MouseEvent arg0) {
if(mouseHold) {
currentGen = newGen = 1;
setBackground(color[1]);
}
}
public void mouseExited(MouseEvent arg0) {
}
//If the mouse is clicked on a cellHouse, cell comes to life
public void mousePressed(MouseEvent arg0) {
mouseHold = true;
currentGen = newGen = 1;
setBackground(color[1]);
}
//Set mouse as not being held anymore
public void mouseReleased(MouseEvent arg0) {
mouseHold = false;
}
}
}
Your code it too hard to follow, but I have done an application using mvc in swing.
My advice is to have something like this in a Main class:
MainModel model = new MainModel();
MainView view = new MainView(model);
MainController controller = new MainController(model, view);
Your controller is ok.
The view looks ok, but you should have separate addActionListener methods for clearB, startB, pauseB (perhaps that's the problem).
The model is where the brain should be. Do not extend JLabel, doesn't make sense at all.
Hope this helps.
Related
need help solving errors while creating a memory game in java
I am new to java and am very confused about errors in my code. I have the error at line 48 "local variables referenced from an inner class must be final or effectively final". here is my code: import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class MemoryGame extends JFrame { private JButton[][] buttons = new JButton[4][4]; private Color[] colors = {Color.RED, Color.BLUE, Color.GREEN, Color.YELLOW}; private List<Color> colorList = new ArrayList<>(); private int score = 0; public MemoryGame() { setTitle("Memory Game"); setSize(400, 400); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLayout(new GridLayout(4, 4)); // populate colorList with two copies of each color for (int i = 0; i < 2; i++) { for (Color color : colors) { colorList.add(color); } } // shuffle colorList Collections.shuffle(colorList); int index = 0; for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { JButton button = new JButton(); button.setBackground(Color.GRAY); buttons[i][j] = button; add(button); button.addActionListener(new ActionListener() { #Override public void actionPerformed(ActionEvent e) { final int currentIndex = index; JButton clickedButton = (JButton) e.getSource(); Color color = colorList.get(currentIndex); clickedButton.setBackground(color); clickedButton.setEnabled(false); for (int x = 0; x < 4; x++) { for (int y = 0; y < 4; y++) { if (buttons[x][y].getBackground() == color && buttons[x][y] != clickedButton) { buttons[x][y].setEnabled(false); score++; if (score == 8) { JOptionPane.showMessageDialog(MemoryGame.this, "You won!"); System.exit(0); } } } } } }); index++; } } setVisible(true); } public static void main(String[] args) { new MemoryGame(); } } I've tried different things to solve the error and they just result in more errors. the program is meant to have a grid of different squares that can be clicked on to display their colors and matched by the user. when the user matches all of the colors on the grid they win.
The problem is with final int currentIndex = index; as the compiler was telling you in the error message. actionPerformed will run at some unspecified future time and the compiler has no idea what value of index you expect to find there at that time. What do you want to do? Assign colors to buttons. You can do that more directly with JButton button = new JButton(); button.setBackground(Color.GRAY); buttons[i][j] = button; // let's store the color for later button.putClientProperty("color", colorList.get(index)); add(button); outside the handler. And then retrieving it inside: public void actionPerformed(ActionEvent e) { JButton clickedButton = (JButton) e.getSource(); Color color = (Color)clickedButton.getClientProperty("color");
The Tic Tac Toe game does not show the winner at the right time
my code is tic tac toe and i have problem with show winner. i get winner but not when X or O in correct direction. and show winner after click on button. code : import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.UIManager; import javax.swing.border.EtchedBorder; public class TicTocToe extends JFrame implements ActionListener { private static final long serialVersionUID = -7730552764304282715L; private static final Font BT_FONT = new Font("Segoe UI", 0, 30); private static final Font LB_FONT = new Font("Consolas", 0, 20); private JButton[][] board; private JLabel statusBar; private JPanel centerPanel, southPanel; private int turn = 0, count = 0; private String name; public static void main(String[] args) { EventQueue.invokeLater(() -> new TicTocToe().setVisible(true)); } public TicTocToe() { super("Tic Toc Toe"); try { UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); initUI(); } catch (Exception e) { e.printStackTrace(); } } private void initUI() { initCenterPanel(); initSouthPanel(); add(centerPanel); add(southPanel, BorderLayout.SOUTH); pack(); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setResizable(false); setLocationRelativeTo(null); } private void initCenterPanel() { centerPanel = new JPanel(); board = new JButton[3][3]; for (int i = 0; i < board[0].length; i++) { for (int j = 0; j < board[i].length; j++) { board[i][j] = new JButton("-"); board[i][j].setFont(BT_FONT); board[i][j].setFocusPainted(false); board[i][j].setPreferredSize(new Dimension(80, 80)); board[i][j].addActionListener(this); centerPanel.add(board[i][j]); } } } private void initSouthPanel() { southPanel = new JPanel(); southPanel.setLayout(new BorderLayout()); statusBar = new JLabel(); statusBar.setFont(LB_FONT); statusBar.setText("Click On Button To Start"); statusBar.setHorizontalAlignment(JLabel.CENTER); statusBar.setBorder(new EtchedBorder()); southPanel.add(statusBar); } private void play(JButton button) { for (int i = 0; i < board.length; i++) { for (int j = 0; j < board[i].length; j++) { if (button.equals(board[i][j])) { count++; if (turn < 1) { statusBar.setText("Player " + "O" + " Turn"); button.setText("X"); button.setEnabled(false); turn++; } else { statusBar.setText("Player " + "X" + " Turn"); button.setText("O"); button.setEnabled(false); turn--; } } } } } private String getPlayerName() { return (turn < 1) ? "X" : "O"; } private boolean findWinner() { name = getPlayerName(); for (int i = 0; i < board.length; i++) { if (board[i][0].getText().equals(name) && board[i][1].getText().equals(name) && board[i][2].getText().equals(name)) return true; for (int j = 0; j < board[i].length; j++) { if (board[0][j].getText().equals(name) && board[1][j].getText().equals(name) && board[2][j].getText().equals(name)) return true; if (board[0][0].getText().equals(name) && board[1][1].getText().equals(name) && board[2][2].getText().equals(name)) return true; if (board[0][2].getText().equals(name) && board[1][1].getText().equals(name) && board[2][0].getText().equals(name)) return true; } } return false; } private void showWinner() { for (int i = 0; i < board.length; i++) { for (int j = 0; j < board.length; j++) { if (findWinner()) { if (getPlayerName().equalsIgnoreCase("x")) { statusBar.setText("Winner is Player X"); board[i][j].removeActionListener(this); } else if (getPlayerName().equalsIgnoreCase("o")) { statusBar.setText("Winner is Player O"); board[i][j].removeActionListener(this); } } else if (!findWinner() && count == 9) { statusBar.setText("It was a draw, no wone."); board[i][j].removeActionListener(this); } } } } public void actionPerformed(ActionEvent event) { JButton button = (JButton) event.getSource(); play(button); showWinner(); } public Dimension getPreferredSize() { return new Dimension(300, 320); } public Dimension getMinimumSize() { return getPreferredSize(); } } in this image Winner is X but wait for Player O and after click on other button show Winner. i need show winner when X or O in correct Direction and no wait for click on other button
I think I see it. When a button is pressed, you do stuff in this order: change the status bar to say it's the next player's turn set the relevant button text to show the player who just picked that button disable the button change the turn value to reflect the next player check for a winner, based on the current player's name but you have already changed this to the next player, not the player who just made the move. When X makes a winning move, the current player name is changed to O before the game checks for a winner, so it checks to see if O has won. You need to reorder stuff: change the button text disable the button check for a winner based on the current player name, end the game if the current player has won or if there is a draw if the game is still going, now is the time to change the turn value and update the status bar to show that it's the next player's turn.
Mouse Drag stops working after adding to drag layer
I'm trying to build a Scrabble game to help get more familiar with building GUIs and practice java skills in general. The board is mainly composed of a JLayeredPane with JPanels to include the board image and board spaces. I'm trying to be able to drag and drop the Tile objects (extends JLabel) around the board by adding the tile to the drag_layer and then moving it from there, similar to the following example: dragging a jlabel around the screen. The mouse press is working and correctly adding the tile to the drag layer, but after that, it seems like the mouse stops listening completely. I tried just printing "Dragging" in the mouseDragged override method, but it won't even print that. There are two relevant classes - Console and MouseInput, which I'll show below, but I'll also add the link to the GitHub repo at the end if you want to pull the whole project. Console: public Console () throws IOException{ // Create gameConsole gameConsole = new JFrame(); final int frameWidth = 850; final int frameHeight = 950; gameConsole.setPreferredSize(new Dimension(frameWidth, frameHeight)); gameConsole.setTitle("Scrabble"); gameConsole.setLayout(new GridBagLayout()); gameConsole.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); GridBagConstraints c = new GridBagConstraints(); c.fill = GridBagConstraints.BOTH; c.ipadx = 810; c.ipady = 950; // Create center console panel and add to gameConsole centerConsole = new JPanel(); centerConsole.setLayout(new BorderLayout()); gameConsole.add(centerConsole,c); // Create layered pane that holds the board and playerbox gameContainer = new JLayeredPane(); gameContainer.setBounds(0,0,810,950); gameContainer.addMouseListener(new MouseInput(gameContainer)); gameContainer.addMouseMotionListener(new MouseInput(gameContainer)); centerConsole.add(gameContainer, BorderLayout.CENTER); // Create board image label and add to JPanel BufferedImage scrabbleImage = ImageIO.read(Console.class.getResource("/board.jpg")); JLabel background = new JLabel(new ImageIcon(scrabbleImage)); boardImage = new JPanel(); boardImage.setBounds(0, 0, 810, 810); boardImage.add(background); boardImage.setOpaque(true); // create JPanel with gridBagLayout boardGrid = new JPanel(); boardGrid.setBounds(0, 3, 810, 810); boardGrid.setLayout(new GridBagLayout()); boardGrid.setOpaque(false); // Create panels to add to boardGrid spaces = new BoardSpace [15][15]; BoardSpace.setBoardSpaces(spaces); // Set grid constraints GridBagConstraints cGrid = new GridBagConstraints(); for (int i = 0; i < 15; i++) { for (int j = 0; j < 15; j++) { // panel constraints cGrid.gridx = i; // grid x location cGrid.gridy = j; // grid y location cGrid.gridheight = 1; // spans 1 row cGrid.gridwidth = 1; // spans 1 column cGrid.weightx = 0.0; cGrid.weighty = 0.0; cGrid.fill = GridBagConstraints.BOTH; // Resize veritically & horizontally // Set size of board space and add to grid spaces[i][j].setOpaque(false); spaces[i][j].setPreferredSize(new Dimension((int) Info.GRIDSIZE,(int) Info.GRIDSIZE)); boardGrid.add(spaces[i][j], cGrid); } } // Add to layeredPane gameContainer.add(boardImage, new Integer(0),0); gameContainer.add(boardGrid, new Integer(1),0); // Create player box panel playerPanel = new JPanel(); playerPanel.setLayout(new GridBagLayout()); playerBox = new JPanel(); playerBox.setLayout(new GridLayout(1,7, 10, 0)); // Create player box constraints GridBagConstraints cp = new GridBagConstraints(); cp.ipadx = 50; cp.ipady = 50; // Create playerBox spaces playerSpaces = new BoardSpace [1][7]; BoardSpace.setPlayerSpaces(playerSpaces); // Add playerSpaces to playerBox for (int j = 0; j < 7; j++) { // panel constraints cGrid.gridx = 0; // grid x location cGrid.gridy = j; // grid y location cGrid.gridheight = 1; // spans 1 row cGrid.gridwidth = 1; // spans 1 column cGrid.weightx = 0.0; cGrid.weighty = 0.0; cGrid.fill = GridBagConstraints.BOTH; // Resize veritically & horizontally // Set size of board space and add to grid playerSpaces[0][j].setOpaque(false); playerSpaces[0][j].setPreferredSize(new Dimension((int) Info.GRIDSIZE,(int) Info.GRIDSIZE)); playerBox.add(playerSpaces[0][j], cGrid); } // Add player box to south panel playerPanel.add(playerBox, cp); // Add player box to bottom of layeredPane playerPanel.setBounds(0,825,810,75); gameContainer.add(playerPanel, new Integer(0),0); gameConsole.pack(); // Make gameConsole visible gameConsole.setVisible(true); } Mouse Adapter: public class MouseInput extends MouseAdapter { /** * */ private Component mouseArea; private boolean dragging; private Tile draggingTile; private BoardSpace currentSpace; private BoardSpace startingSpace; private Component selectedObject; Component [] panelObjects; private JLayeredPane dragLayer; private Point dragPoint; private int dragWidth; private int dragHeight; public MouseInput(Component mouseArea) { // TODO Auto-generated constructor stub super(); mouseArea = this.mouseArea; } void eventOutput(String eventDescription, MouseEvent e) { Point p = e.getPoint(); System.out.println(eventDescription + " (" + p.getX() + "," + p.getY() + ")" + " detected on " + e.getComponent().getClass().getName() + "\n"); } public void mouseMoved(MouseEvent e) { //eventOutput("Mouse moved", e); } public void mouseDragged(MouseEvent e) { if (dragging) { System.out.println("Dragging"); } if (!dragging) { return; } else { System.out.println("Dragging " + Tile.getLetter(draggingTile)); int x = e.getPoint().x - dragWidth; int y = e.getPoint().y - dragHeight; draggingTile.setLocation(x, y); draggingTile.repaint(); } } #Override public void mouseClicked(MouseEvent e) { // TODO Auto-generated method stub //eventOutput("Mouse Clicked", e); } #Override public void mouseEntered(MouseEvent e) { /* dragPoint = e.getPoint(); selectedObject = e.getComponent().getComponentAt(dragPoint); // Get the current space while (!selectedObject.getClass().getSimpleName().equals("BoardSpace")) { try { dragPoint = selectedObject.getMousePosition(); selectedObject = selectedObject.getComponentAt(dragPoint); } catch (NullPointerException illegalSpace){ currentSpace = startingSpace; break; } } if (selectedObject.getClass().getSimpleName().equals("BoardSpace")) { currentSpace = (BoardSpace) selectedObject; System.out.println(BoardSpace.getID(currentSpace)); } */ } #Override public void mouseExited(MouseEvent e) { // TODO Auto-generated method stub //eventOutput("Mouse Exited", e); } #Override public void mousePressed(MouseEvent e) { dragLayer = (JLayeredPane) e.getSource(); dragPoint = e.getPoint(); selectedObject = e.getComponent().getComponentAt(dragPoint); // Get the current space while (!selectedObject.getClass().getSimpleName().equals("BoardSpace")) { try { dragPoint = selectedObject.getMousePosition(); selectedObject = selectedObject.getComponentAt(dragPoint); } catch (NullPointerException illegalSpace){ return; } } currentSpace = (BoardSpace) selectedObject; startingSpace = currentSpace; // If the boardspace has a tile, remove Tile from boardspace and add to dragging layer if (BoardSpace.Taken(currentSpace)) { // get dragging tile draggingTile = BoardSpace.getTile(currentSpace); dragging = true; // remove tile and repaint space BoardSpace.removeTile(currentSpace, draggingTile); currentSpace.revalidate(); currentSpace.repaint(); // Add tile to dragging layer dragWidth = draggingTile.getWidth() / 2; dragHeight = draggingTile.getHeight() / 2; int x = e.getPoint().x - dragWidth; int y = e.getPoint().y - dragHeight; draggingTile.setLocation(x, y); dragLayer.add(draggingTile, JLayeredPane.DRAG_LAYER); draggingTile.revalidate(); draggingTile.repaint(); System.out.println("Selected Tile " + Tile.getLetter(draggingTile)); } else { return; } } #Override public void mouseReleased(MouseEvent e) { /* // TODO Auto-generated method stub if (!BoardSpace.Taken(currentSpace)) { return; } else { dragging = false; BoardSpace.setTile(currentSpace, draggingTile); draggingTile = null; currentSpace.repaint(); currentSpace.revalidate(); } */ } } Full code can be pulled from: https://github.com/jowarren13/scrabble.git
So after playing around some more, I figured out that every time a new mouse operation is called (mouse pressed, mouse dragged, etc.), it was instantiating new instances of the private class variables, so the variables weren't holding their set values. To work around this, I created a new class as an extension of JLayeredPane with these additional variables and used my new class as the layered game console. Still working out some error handling for when a tile is released outside of bounds or in an invalid space, but the code below at least lets me move the tiles around in valid spaces. The following post was helpful in figuring this out: MouseListener in separate class not working. Again, full code can be pulled from the git repo listed above. BoardPane class: package objects; import java.awt.Component; import java.awt.Point; import javax.swing.JLayeredPane; public class BoardPane extends JLayeredPane { /** * */ private static final long serialVersionUID = 1L; private boolean dragging; private Tile draggingTile; private BoardSpace currentSpace; private BoardSpace startingSpace; private Component selectedObject; Component [] panelObjects; private BoardPane dragLayer; private Point dragPoint; private int dragWidth; private int dragHeight; public BoardPane() { this.dragging = false; this.draggingTile = null; this.currentSpace = null; this.startingSpace = null; this.selectedObject = null; this.panelObjects = null; this.dragLayer = null; this.dragPoint = null; this.dragWidth = 51/2; this.dragHeight = 51/2; } public static void resetPane(BoardPane board) { board.dragging = false; board.draggingTile = null; board.currentSpace = null; board.startingSpace = null; board.selectedObject = null; board.panelObjects = null; board.dragLayer = null; board.dragPoint = null; } public static Boolean getDragStatus(BoardPane board) { return board.dragging; } public static void setDragStatus(BoardPane board, Boolean status) { board.dragging = status; } public static Tile getDragTile(BoardPane board) { return board.draggingTile; } public static void setDragTile(BoardPane board, Tile t) { board.draggingTile = t; } public static BoardSpace getCurrentSpace(BoardPane board) { return board.currentSpace; } public static void setCurrentSpace(BoardPane board, BoardSpace bs) { board.currentSpace = bs; } public static BoardSpace getStartingSpace(BoardPane board) { return board.startingSpace; } public static void setStartingSpace(BoardPane board, BoardSpace bs) { board.startingSpace = bs; } public static Component getSelectedObj(BoardPane board) { return board.selectedObject; } public static void setSelectedObj(BoardPane board, Component obj) { board.selectedObject = obj; } public static Component [] getPanelObjects(BoardPane board) { return board.panelObjects; } public static BoardPane getDragLayer(BoardPane board) { return board.dragLayer; } public static void setDragLayer(BoardPane board) { board.dragLayer = board; } public static void setPanelObjects(BoardPane board, Component [] obj) { board.panelObjects = obj; } public static Point getDragPoint (BoardPane board) { return board.dragPoint; } public static void setDragPoint(BoardPane board, Point p) { board.dragPoint = p; } public static int getDragWidth(BoardPane board) { return board.dragWidth; } public static int getDragHeight(BoardPane board) { return board.dragHeight; } } Console: package Main; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.GridLayout; import java.awt.event.ActionListener; import java.awt.image.BufferedImage; import java.io.IOException; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JLayeredPane; import javax.swing.JPanel; import objects.BoardPane; import objects.BoardSpace; import javax.imageio.ImageIO; public class Console { private JFrame gameConsole; private JPanel centerConsole; private BoardPane gameContainer; private JPanel playerPanel; private JPanel gamePanel; private JPanel north; private JPanel south; private JPanel east; private JPanel west; private JLayeredPane center; private JPanel splash; private JPanel playerBox; private JPanel boardGrid; private JPanel boardImage; private JButton start; private BoardSpace [][] spaces; private BoardSpace [][] playerSpaces; public Console () throws IOException{ // Create gameConsole gameConsole = new JFrame(); final int frameWidth = 850; final int frameHeight = 950; gameConsole.setPreferredSize(new Dimension(frameWidth, frameHeight)); gameConsole.setTitle("Scrabble"); gameConsole.setLayout(new GridBagLayout()); gameConsole.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); GridBagConstraints c = new GridBagConstraints(); c.fill = GridBagConstraints.BOTH; c.ipadx = 810; c.ipady = 950; // Create center console panel and add to gameConsole centerConsole = new JPanel(); centerConsole.setLayout(new BorderLayout()); gameConsole.add(centerConsole,c); // Create layered pane that holds the board and playerbox gameContainer = new BoardPane(); gameContainer.setBounds(0,0,810,950); MouseInput mouseActions = new MouseInput(); gameContainer.addMouseMotionListener(mouseActions); gameContainer.addMouseListener(mouseActions); centerConsole.add(gameContainer, BorderLayout.CENTER); // Create board image label and add to JPanel BufferedImage scrabbleImage = ImageIO.read(Console.class.getResource("/board.jpg")); JLabel background = new JLabel(new ImageIcon(scrabbleImage)); boardImage = new JPanel(); boardImage.setBounds(0, 0, 810, 815); boardImage.add(background); boardImage.setOpaque(true); // create JPanel with gridBagLayout boardGrid = new JPanel(); boardGrid.setBounds(0, 3, 810, 810); boardGrid.setLayout(new GridBagLayout()); boardGrid.setOpaque(false); // Create panels to add to boardGrid spaces = new BoardSpace [15][15]; BoardSpace.setBoardSpaces(spaces); // Set grid constraints GridBagConstraints cGrid = new GridBagConstraints(); for (int i = 0; i < 15; i++) { for (int j = 0; j < 15; j++) { // panel constraints cGrid.gridx = i; // grid x location cGrid.gridy = j; // grid y location cGrid.gridheight = 1; // spans 1 row cGrid.gridwidth = 1; // spans 1 column cGrid.weightx = 0.0; cGrid.weighty = 0.0; cGrid.fill = GridBagConstraints.BOTH; // Resize veritically & horizontally // Set size of board space and add to grid spaces[i][j].setOpaque(false); spaces[i][j].setPreferredSize(new Dimension((int) Info.GRIDSIZE,(int) Info.GRIDSIZE)); boardGrid.add(spaces[i][j], cGrid); } } // Add to layeredPane gameContainer.add(boardImage, new Integer(0),0); gameContainer.add(boardGrid, new Integer(1),0); // Create player box panel playerPanel = new JPanel(); playerPanel.setLayout(new GridBagLayout()); playerBox = new JPanel(); playerBox.setLayout(new GridLayout(1,7, 10, 0)); // Create player box constraints GridBagConstraints cp = new GridBagConstraints(); cp.ipadx = 50; cp.ipady = 50; // Create playerBox spaces playerSpaces = new BoardSpace [1][7]; BoardSpace.setPlayerSpaces(playerSpaces); // Add playerSpaces to playerBox for (int j = 0; j < 7; j++) { // panel constraints cGrid.gridx = 0; // grid x location cGrid.gridy = j; // grid y location cGrid.gridheight = 1; // spans 1 row cGrid.gridwidth = 1; // spans 1 column cGrid.weightx = 0.0; cGrid.weighty = 0.0; cGrid.fill = GridBagConstraints.BOTH; // Resize veritically & horizontally // Set size of board space and add to grid playerSpaces[0][j].setOpaque(false); playerSpaces[0][j].setPreferredSize(new Dimension((int) Info.GRIDSIZE,(int) Info.GRIDSIZE)); playerBox.add(playerSpaces[0][j], cGrid); } // Add player box to south panel playerPanel.add(playerBox, cp); // Add player box to bottom of layeredPane playerPanel.setBounds(0,825,810,75); gameContainer.add(playerPanel, new Integer(0),0); gameConsole.pack(); // Make gameConsole visible gameConsole.setVisible(true); } } Mouse Listener: package Main; import java.awt.Point; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import javax.swing.JLayeredPane; import objects.BoardSpace; import objects.Tile; import objects.BoardPane; public class MouseInput implements MouseMotionListener, MouseListener { /** * */ private BoardPane dragLayer; void eventOutput(String eventDescription, MouseEvent e) { Point p = e.getPoint(); System.out.println(eventDescription + " (" + p.getX() + "," + p.getY() + ")" + " detected on " + e.getComponent().getClass().getName() + "\n"); } #Override public void mouseMoved(MouseEvent e) { //eventOutput("Mouse moved", e); } #Override public void mouseDragged(MouseEvent e) { // Set dragLayer dragLayer = BoardPane.getDragLayer((BoardPane) e.getSource()); // Drag tile across board if (BoardPane.getDragStatus(dragLayer)) { int x = e.getPoint().x - BoardPane.getDragWidth(dragLayer); int y = e.getPoint().y - BoardPane.getDragHeight(dragLayer); BoardPane.getDragTile(dragLayer).setLocation(x, y); BoardPane.getDragTile(dragLayer).repaint(); System.out.println("Dragging Tile " + Tile.getLetter(BoardPane.getDragTile(dragLayer))); } } #Override public void mouseClicked(MouseEvent e) { //eventOutput("Mouse Clicked", e); } #Override public void mouseEntered(MouseEvent e) { eventOutput("Mouse entered", e); } #Override public void mouseExited(MouseEvent e) { eventOutput("Mouse Exited", e); } #Override public void mousePressed(MouseEvent e) { eventOutput("Mouse Pressed", e); // Set dragLayer, dragPoint, and selectedObject BoardPane.setDragLayer((BoardPane) e.getSource()); dragLayer = (BoardPane) e.getSource(); BoardPane.setDragPoint(dragLayer, e.getPoint()); BoardPane.setSelectedObj(dragLayer, e.getComponent().getComponentAt(BoardPane.getDragPoint(dragLayer))); // Find the current board space try { while (!BoardPane.getSelectedObj(dragLayer).getClass().getSimpleName().equals("BoardSpace")) { BoardPane.setDragPoint(dragLayer, BoardPane.getSelectedObj(dragLayer).getMousePosition()); BoardPane.setSelectedObj(dragLayer, BoardPane.getSelectedObj(dragLayer).getComponentAt(BoardPane.getDragPoint(dragLayer))); } } catch (NullPointerException illegalSpace) { return; } // Set the current board space & starting space BoardPane.setCurrentSpace(dragLayer, (BoardSpace) BoardPane.getSelectedObj(dragLayer)); BoardPane.setStartingSpace(dragLayer, BoardPane.getCurrentSpace(dragLayer)); // If the board space has a tile, remove Tile from board space then add to dragging layer if (BoardSpace.Taken(BoardPane.getCurrentSpace(dragLayer))) { // get dragging tile BoardPane.setDragTile(dragLayer, BoardSpace.getTile(BoardPane.getCurrentSpace(dragLayer))); BoardPane.setDragStatus(dragLayer, true); // remove tile and repaint space BoardSpace.removeTile(BoardPane.getCurrentSpace(dragLayer), BoardPane.getDragTile(dragLayer)); BoardPane.getCurrentSpace(dragLayer).revalidate(); BoardPane.getCurrentSpace(dragLayer).repaint(); // Add tile to dragging layer at specified location int x = e.getPoint().x - BoardPane.getDragWidth(dragLayer); int y = e.getPoint().y - BoardPane.getDragHeight(dragLayer); BoardPane.getDragTile(dragLayer).setLocation(x, y); dragLayer.add(BoardPane.getDragTile(dragLayer), JLayeredPane.DRAG_LAYER); BoardPane.getDragTile(dragLayer).revalidate(); BoardPane.getDragTile(dragLayer).repaint(); System.out.println("Selected Tile " + Tile.getLetter(BoardPane.getDragTile(dragLayer))); } else { return; } } #Override public void mouseReleased(MouseEvent e) { if (BoardPane.getDragStatus(dragLayer) == true) { // Change drag status to false BoardPane.setDragStatus(dragLayer, false); // Set dragLayer & remove tile dragLayer = BoardPane.getDragLayer((BoardPane) e.getSource()); dragLayer.remove(BoardPane.getDragTile(dragLayer)); dragLayer.revalidate(); dragLayer.repaint(); //get selected object at given point BoardPane.setDragPoint(dragLayer, e.getPoint()); BoardPane.setSelectedObj(dragLayer, e.getComponent().getComponentAt(BoardPane.getDragPoint(dragLayer))); // Find the current board space try { while(!BoardPane.getSelectedObj(dragLayer).getClass().getSimpleName().equals("BoardSpace")) { BoardPane.setDragPoint(dragLayer, BoardPane.getSelectedObj(dragLayer).getMousePosition()); BoardPane.setSelectedObj(dragLayer, BoardPane.getSelectedObj(dragLayer).getComponentAt(BoardPane.getDragPoint(dragLayer))); } } catch (NullPointerException illegalSpace) { // if released on an invalid space, put tile back in starting space BoardPane.getStartingSpace(dragLayer).add(BoardPane.getDragTile(dragLayer)); BoardPane.getStartingSpace(dragLayer).revalidate(); BoardPane.getStartingSpace(dragLayer).repaint(); BoardPane.resetPane(dragLayer); return; } // Set the current board space & starting space BoardPane.setCurrentSpace(dragLayer, (BoardSpace) BoardPane.getSelectedObj(dragLayer)); // If space is not taken, add tile to space, otherwise put back in starting space if (!BoardSpace.Taken(BoardPane.getCurrentSpace(dragLayer))) { BoardSpace.setTile(BoardPane.getCurrentSpace(dragLayer), BoardPane.getDragTile(dragLayer)); BoardPane.getCurrentSpace(dragLayer).revalidate(); BoardPane.getCurrentSpace(dragLayer).repaint(); //BoardPane.setDragTile(dragLayer, null); } else { BoardPane.getStartingSpace(dragLayer).add(BoardPane.getDragTile(dragLayer)); BoardPane.getStartingSpace(dragLayer).revalidate(); BoardPane.getStartingSpace(dragLayer).repaint(); } BoardPane.resetPane(dragLayer); } } }
Stuck with making Kakurasu game
We are learning in school java graphic and now we have to build a game called Kakurasu (https://www.brainbashers.com/showkakurasu.asp) I'm so stuck and I don't know how to do it. As far as I came. I've done a frame with a panel inside a panel which has 7x7 buttons that change from 0 to 1 and from white to green when pressed. The idea is that I make the first raw on the top and on the left to be the numbers 1-5 and then on the bottom and right side the random generated numbers. This is my first code: import javax.swing.*; import java.awt.*; public class Start { public static JButton[][] gumbi; public static void main(String[] args) { buttons = new JButton[7][7]; JFrame window = new JFrame("Kakurasu"); JPanel panel = new JPanel(new BorderLayout()); JPanel playingField = new JPanel(new GridLayout(7, 7)); Listner1 p = new Listner1(buttons); panel.add(playingField, BorderLayout.CENTER); window.add(panel); for (int i = 0; i < 7; i++) { for (int j = 0; j < 7; j++) { buttons[i][j] = new JButton("0"); playingField.add(buttons[i][j], BorderLayout.CENTER); buttons[i][j].addActionListener(p); buttons[i][j].setBackground(Color.WHITE); } } window.setVisible(true); window.setSize(500, 500); window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } } This is my second code: import javax.swing.*; import java.awt.*; import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class Poslusalec1 implements ActionListener { public JButton[][] buttons; public Listner1(JButton[][] gumbi) { this.buttons = buttons; } public void actionPerformed(ActionEvent e) { JButton button = (JButton) e.getSource(); String tmp = button.getText(); int n = Integer.parseInt(tmp); n += 1; if (n == 2) { n = 0; } button.setText("" + n); if (button.getBackground() == Color.WHITE) { button.setBackground(Color.GREEN); } else { button.setBackground(Color.WHITE); } for (int i = 0; i < buttons.length; i++) { for (int j = 0; j < buttons[i].length; j++) { if (button == buttons[i][j]) { System.out.println(i + ", " + j); } } } } } Is it possible to assign different actionlisteners to different buttons inside a gridlayout? Thanks for any help.
I'm so stuck and I don't know how to do it. To solve any computer problem, you break the problem down into smaller and smaller problems, until you're comfortable that you can code each small problem. Generally, when coding a GUI, you should use the model / view / controller pattern. In Java Swing, this means: The view may read values from the model. The view may not update the model. The controller updates the model. The controller repaints / revalidates the view. So, let's create a model for a JButton. The model will hold the across value of the JButton, the down value of the JButton, and the background color of the JButton. package com.ggl.testing; import java.awt.Color; public class KakurasuCell { private final int acrossValue; private final int downValue; private Color backgroundColor; public KakurasuCell(int acrossValue, int downValue, Color backgroundColor) { this.acrossValue = acrossValue; this.downValue = downValue; this.backgroundColor = backgroundColor; } public Color getBackgroundColor() { return backgroundColor; } public void setBackgroundColor(Color backgroundColor) { this.backgroundColor = backgroundColor; } public int getAcrossValue() { return acrossValue; } public int getDownValue() { return downValue; } } This is a Java object. It holds multiple types of values. Now, we create another model for a grid of JButtons. You should recognize this from your code. package com.ggl.testing; import java.awt.Color; public class KakurasuGrid { private int gridWidth; private KakurasuCell[][] cells; public KakurasuGrid(int gridWidth) { setGridWidth(gridWidth); } public int getGridWidth() { return gridWidth; } public void setGridWidth(int gridWidth) { this.gridWidth = gridWidth; this.cells = new KakurasuCell[gridWidth][gridWidth]; setCells(); } public KakurasuCell[][] getCells() { return cells; } private void setCells() { for (int i = 0; i < gridWidth; i++) { for (int j = 0; j < gridWidth; j++) { KakurasuCell cell = new KakurasuCell((j + 1), (i + 1), Color.GRAY); cells[i][j] = cell; } } } } This should be enough to get you started. You still need to create the answers, create the GUI, and add the controller methods.
JButtons disappear after the popup menu shows
I added listeners to my JButtons for the popup menu but when the popup menu appears the JButtons disappear and I would need to hover my cursor on the buttons to make them appear again. Why is it like this? (all the methods here are in the same class) public Inventory() { setLayout(null); setBounds(0, 0, 175, 210); initPopupMenu(); // this just sets what is inside the popup menu int x; // 30 buttons for(x = 0; x < 30; x++) { button[x] = new JButton(); add(button[x]); button[x].addMouseListener(this); } x = 0; // it's a grid of buttons for(int i = 0; i < 5; i++) for(int j = 0; j < 6; j++) { button[x].setBounds(i*35+1,j*35+1, 33,33); x++; } } public void mouseClicked(MouseEvent e) { for(int j = 0; j < 30; j++) // i tried this one but it still disappears button[j].repaint(); for(int i = 0; i < 30; i++) { if(e.getSource() == button[i]) { System.out.println("You pressed Button "+i); popup.show(e.getComponent(), e.getX(), e.getY()); } } } This is what happens,
Stop using null Layout, seems like that can be one of the issues regarding this. Your JFrame appears sort of BLACK to me, is this some THEME or a new LOOK AND FEEL you are using, that can be the cause of this thing too. Here check this out, it's working flawlessly here with this code : import java.awt.*; import java.awt.event.*; import javax.swing.*; public class ButtonPopUp { private static final int SIZE = 30; private JButton[] button = new JButton[SIZE]; private JPopupMenu popup = new JPopupMenu("Hello World"); private void createAndDisplayGUI() { JFrame frame = new JFrame("Button POP UP Example"); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); frame.setLocationByPlatform(true); final JPanel contentPane = new JPanel(); contentPane.setLayout(new GridLayout(0, 5)); JMenuItem menuItem1 = new JMenuItem("Menu Item 1"); JMenuItem menuItem2 = new JMenuItem("Menu Item 2"); //popup.add(greetings); popup.insert(menuItem1, 0); popup.insert(menuItem2, 1); for (int i = 0; i < SIZE; i++) { button[i] = new JButton(); button[i].setBorder(BorderFactory.createEtchedBorder()); button[i].addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent me) { System.out.println("I am WORKING!!"); popup.show((JComponent)me.getSource(), me.getX(), me.getY()); } }); contentPane.add(button[i]); } frame.getContentPane().add(contentPane); frame.setSize(175, 250); frame.setVisible(true); } public static void main(String... args) { SwingUtilities.invokeLater(new Runnable() { public void run() { new ButtonPopUp().createAndDisplayGUI(); } }); } } Here is the output :