Can you add JButtons inside a JPanel - java

I'm making a Battleship game using one board. The picture below shows how the board GUI should look. My current code sets up a board without the 'menu-layer'. (see picture)
I tried doing this using Swing GUI designer in Intellij and got the following form (see picture), but can't find a way to insert these buttons inside the panel. Currently, I have got the following code.
package BattleshipGUI;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class BoardFrame extends JFrame {
//variables
Ships ship = new Ships();
static final Color colorHit = Color.red;
static final Color colorNormal = Color.gray;
static final Color colorWater = Color.blue;
static final Color colorCarrier = Color.yellow;
static final Color colorBattleship = Color.BLACK;
static final Color colorSubmarine = Color.magenta;
static final Color colorDestroyer = Color.white;
int[][] map;
private Container contents;
int cols;
int rows;
boolean equalPoints;
Player p1 = new Player();
Player p2 = new Player();
private JPanel mainPanel; // I tried using the GUI swing designer, but I cant manage to create
//a menu-layer on top of the buttons
private JButton buttonHighScores;
private JButton quitGame;
private JLabel player1Points;
private JLabel player2Points;
private JLabel playerTurn;
JButton[][] tiles = new JButton[100][100]; // I create 100*100 buttons, but only assign the right
// number to them
public void setMap(int[][] map) {
this.map = map;
}
public void SetFrame(int r, int c) {
this.rows = r;
this.cols = c;
}
public BoardFrame(int r, int c) {
super("Battleship");
setSize(400,450); // I create a frame
this.setLayout(new GridLayout(r, c)); // I set the layout depending on the number of rows and
//columns
AttackHandler attackHandler = new AttackHandler(); // action event class
p1.turn = true; // player 1's turn is true, he commences
p2.turn= false; //player 2's turn is false
for (int i =0; i<r; i++) {
for (int j =0; j <c; j++) {
tiles[i][j] = new JButton(); // this is where all the buttons are declared
tiles[i][j].setBackground(colorNormal);
add(tiles[i][j]);
tiles[i][j].addActionListener(attackHandler);
}
}
setResizable(true);
setLocationRelativeTo(null);
setVisible(true);
setDefaultCloseOperation(this.DISPOSE_ON_CLOSE);
setSize(400,450); //the size of my frame
}
public class AttackHandler implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (source == tiles[i][j]) {
isHit(i, j);
return;
}
}
}
}
}
public void isHit(int row, int col) {
// the map consists of an 2D array
//where 0's represent the water, 1's represent the tiles that are
//already hit, and the other represent the ships
if (AllHit()) {
JOptionPane.showMessageDialog(null, "All Ships Destructed!");
setWinner();
String winner =DecideWinner();
JOptionPane.showMessageDialog(null, winner+" has won!", "Winner",
JOptionPane.PLAIN_MESSAGE);
int again = JOptionPane.showConfirmDialog(null, "Play Again", "Play
Again",JOptionPane.YES_NO_OPTION);
if (again==0){
Main.main(null);
}
dispose();
}
else if (map[row][col] == 5) {
AddPoint(p1.turn, 5); // this should add points to the player that
//has the turn
tiles[row][col].setBackground(colorCarrier);
map[row][col] = 1;
} else if (map[row][col] == 4) {
AddPoint(p1.turn, 4);
tiles[row][col].setBackground(colorBattleship);
map[row][col] = 1;
} else if (map[row][col] == 3) {
AddPoint(p1.turn, 3);
tiles[row][col].setBackground(colorSubmarine);
map[row][col] = 1;
} else if (map[row][col] == 2) {
AddPoint(p1.turn, 2);
tiles[row][col].setBackground(colorDestroyer);
map[row][col] = 1;
} else if (map[row][col] == 1) {
System.out.println("Already Hit!");
} else if (map[row][col] == 0 || map[row][col] == 9) {
tiles[row][col].setBackground(colorWater);
map[row][col] = 1;
}
p1.changeTurn(p1.turn); // every click, the turn of each player should
//switch from true to false, p1 starts with value
//true, and p2 with false
p2.changeTurn(p2.turn);
System.out.println("Points Player 1: "+p1.points);
System.out.println("Points Player 2: "+p2.points);
}
public boolean AllHit() { // if all ships are hit, a message pops up
boolean allHit = true;
for (int i = 0; i<rows;i++) {
for (int j = 0; j < cols; j++) {
if (map[i][j] != 1 && map[i][j] != 0) {
allHit = false;
break;
}
}
}
return allHit;
}
public void AddRandomShips(int rows, int cols) {
int[][] map = ship.setRandomShips(rows, cols);
setMap(map);
}
public void AddShipsNotRandom(int size, int[][] coordinates){
int[][] map = ship.PlaceShips(size, coordinates);
setMap(map);
}
public void ScoreMethod(boolean scoreMethod){
if(scoreMethod){
equalPoints = true;
}
else if(!scoreMethod){ // the second method adjusts the score
//for the second player because the first player
//is more likely to hit a ship
equalPoints = false;
}
}
public void AddPoint(boolean turn,int amount){
if (turn){
p1.points = p1.points+ amount;
}
else p2.points = p2.points+amount;
}
public void setWinner(){
if(p1.points>p2.points){
p1.setWon();
}
else p2.setWon();
}
public String DecideWinner(){
if (p1.won == true){
return "Player 1";
}
else return "Player 2";
}
}
This is how the GUI should look like:
This is what my code generates:
this is the for that I designed using Intellij's Swing Designer (the panel with 'buttons' should be filled with the JButtons I created in the code):
UPDATE :
Thanks to mr. Kroukamp, I was able to add a menu-overlay. The code looks like this:
package BattleshipGUI;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;
import java.awt.Dimension;
public class BoardFrame extends JFrame {
//variables
Ships ship = new Ships();
static final Color colorNormal = Color.gray;
static final Color colorWater = Color.blue;
static final Color colorCarrier = Color.yellow;
static final Color colorBattleship = Color.BLACK;
static final Color colorSubmarine = Color.magenta;
static final Color colorDestroyer = Color.white;
int[][] map;
int cols;
int rows;
boolean equalPoints;
Player p1 = new Player();
Player p2 = new Player();
JButton[][] tiles = new JButton[100][100];
public void setMap(int[][] map) {
this.map = map;
}
public void SetFrame(int r, int c) {
this.rows = r;
this.cols = c;
}
JButton highScoresButton = new JButton("High Scores");
JLabel player1ScoreTitleLabel = new JLabel(String.valueOf(p1.points));
JLabel turnTitleLabel = new JLabel(Turn());
JLabel player2ScoreTitleLabel = new JLabel(String.valueOf(p1.points));
JButton quitGameButton = new JButton("Quite Game");
JFrame frame = new JFrame("Battleship");
public BoardFrame(int r, int c) {
super("Battleship");
AttackHandler attackHandler = new AttackHandler(); // action event class
p1.turn = true; // player 1's turn is true, he commences
p2.turn= false; //player 2's turn is false
JFrame frame = new JFrame("Battleship");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// panel 1 (yellow border)
JPanel panel1 = new JPanel(new GridBagLayout());
JButton highScoresButton = new JButton("High Scores");
JLabel player1ScoreTitleLabel = new JLabel(String.valueOf(p1.points));
JLabel turnTitleLabel = new JLabel(Turn());
JLabel player2ScoreTitleLabel = new JLabel(String.valueOf(p1.points));
JButton quitGameButton = new JButton("Quite Game");
GridBagConstraints s = new GridBagConstraints();
s.weightx = 1;
s.gridx = 0;
s.gridy = 0;
panel1.add(highScoresButton, s);
s.weightx = 1;
s.gridx = 1;
s.gridy = 0;
panel1.add(player1ScoreTitleLabel, s);
s.weightx = 1;
s.gridx = 2;
s.gridy = 0;
panel1.add(turnTitleLabel);
s.weightx = 1;
s.gridx = 3;
s.gridy = 0;
panel1.add(player2ScoreTitleLabel, s);
s.weightx = 1;
s.gridx = 4;
s.gridy = 0;
panel1.add(quitGameButton, s);
// panel 2 (red border)
JPanel panel2 = new JPanel();
GridLayout layout = new GridLayout(r, c);
layout.setHgap(0);
layout.setVgap(0);
panel2.setLayout(layout);
panel2.setBorder(new LineBorder(Color.blue, 4));
for (int i =0; i<r; i++) {
for (int j =0; j < c; j++) {
tiles[i][j] = new JButton(){
#Override
public Dimension getPreferredSize() {
return new Dimension(100,100);
}
};
tiles[i][j].setBackground(colorNormal);
panel2.add(tiles[i][j]);
tiles[i][j].addActionListener(attackHandler);
}
}
frame.add(panel1, BorderLayout.NORTH);
frame.add(panel2, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
public class AttackHandler implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (source == tiles[i][j]) {
isHit(i, j);
return;
}
}
}
}
}
public void isHit(int row, int col) {
if (AllHit()) {
JOptionPane.showMessageDialog(null, "All Ships Destructed!");
setWinner();
String winner =DecideWinner();
if(p1.won){
p1.checkHighScore();
}
else if (p2.won){
p2.checkHighScore();
}
JOptionPane.showMessageDialog(null, winner, "Winner",
JOptionPane.PLAIN_MESSAGE);
int again = JOptionPane.showConfirmDialog(null, "Play Again", "Play
Again",JOptionPane.YES_NO_OPTION);
if (again==0){
Main.main(null);
}
frame.dispose();
}
else if (map[row][col] == 5) {
AddPoint(p1.turn, 5);
tiles[row][col].setBackground(colorCarrier);
map[row][col] = 1;
} else if (map[row][col] == 4) {
AddPoint(p1.turn, 4);
tiles[row][col].setBackground(colorBattleship);
map[row][col] = 1;
} else if (map[row][col] == 3) {
AddPoint(p1.turn, 3);
tiles[row][col].setBackground(colorSubmarine);
map[row][col] = 1;
} else if (map[row][col] == 2) {
AddPoint(p1.turn, 2);
tiles[row][col].setBackground(colorDestroyer);
map[row][col] = 1;
} else if (map[row][col] == 1) {
System.out.println("Already Hit!");
} else if (map[row][col] == 0 || map[row][col] == 9) {
tiles[row][col].setBackground(colorWater);
map[row][col] = 1;
}
p1.changeTurn(p1.turn);
p2.changeTurn(p2.turn);
// I cannot find a way to change the labels....
player1ScoreTitleLabel.setText(String.valueOf(p1.points));
player2ScoreTitleLabel.setText(String.valueOf(p2.points));
turnTitleLabel.setText(Turn());
System.out.println("Points Player 1: "+p1.points);
System.out.println("Points Player 2: "+p2.points);
}
public boolean AllHit() {
boolean allHit = true;
for (int i = 0; i<rows;i++) {
for (int j = 0; j < cols; j++) {
if (map[i][j] != 1 && map[i][j] != 0) {
allHit = false;
break;
}
}
}
return allHit;
}
public void AddRandomShips(int rows, int cols) {
int[][] map = ship.setRandomShips(rows, cols);
setMap(map);
}
public void AddShipsNotRandom(int size, int[][] coordinates){
int[][] map = ship.PlaceShips(size, coordinates);
setMap(map);
}
public void ScoreMethod(boolean scoreMethod){
if(scoreMethod){
equalPoints = true;
}
else {
equalPoints = false;
}
}
public void AddPoint(boolean turn,int amount){
if (turn){
p1.points = p1.points+ amount;
}
else p2.points = p2.points+amount;
}
public void setWinner(){
if(p1.points>p2.points){
p1.setWon();
}
else if (p2.points>p1.points){
p2.setWon();
}
}
public String DecideWinner(){
if (p1.won){
return "Player 1 won the game!";
}
else if (p2.won){
return "Player 2 won the game!";
}
else return "It's a tie!";
}
public String Turn(){
if (p1.turn){
return "Player 1";
}else return "Player 2";
}
This generates the following GUI:
However, I am still struggling finding a way to change the values of the text of the score JLabels, the following code did not work for me:
player1ScoreTitleLabel.setText(String.valueOf(p1.points));
player2ScoreTitleLabel.setText(String.valueOf(p2.points));
turnTitleLabel.setText(Turn())

Adding to my comment here is a small example to help get you started without the burden of an IDE for building your UI incorporating as much of Swing best practices as possible:
I opted to use JLabels as it just makes more sense
The yellow border represents panel1 which makes use of a GridBagLayout.
The red panel represents panel2 which makes use of a GridLayout.
Finally the 2 JPanels are added to a JFrame which by default uses BorderLayout.
TestApp.java:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;
public class TestApp {
public TestApp() {
createAndShowGui();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(TestApp::new);
}
private void createAndShowGui() {
JFrame frame = new JFrame("TestApp");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// panel 1 (yellow border)
JPanel panel1 = new JPanel(new GridBagLayout());
JButton highScoresButton = new JButton("High Scores");
JLabel player1ScoreLabel = new JLabel("<html>Player 1 Score:<br><h2>950</h2>");
JLabel turnLabel = new JLabel("<html>Turn:<br><h1>Player 1</h1>");
JLabel player2ScoreLabel = new JLabel("<html>Player 2 Score:<br><h2>925</h2>");
JButton quitGameButton = new JButton("Quit Game");
GridBagConstraints c = new GridBagConstraints();
c.weightx = 1;
c.gridx = 0;
c.gridy = 0;
panel1.add(highScoresButton, c);
c.weightx = 1;
c.gridx = 1;
c.gridy = 0;
panel1.add(player1ScoreLabel, c);
c.weightx = 1;
c.gridx = 2;
c.gridy = 0;
panel1.add(turnLabel);
c.weightx = 1;
c.gridx = 3;
c.gridy = 0;
panel1.add(player2ScoreLabel, c);
c.weightx = 1;
c.gridx = 4;
c.gridy = 0;
panel1.add(quitGameButton, c);
panel1.setBorder(new LineBorder(Color.YELLOW, 4)); // just for visual purposes of the answer
// panel 2 (red border)
JPanel panel2 = new JPanel();
GridLayout layout = new GridLayout(8, 8);
layout.setHgap(5);
layout.setVgap(5);
panel2.setLayout(layout);
panel2.setBorder(new LineBorder(Color.RED, 4)); // just for visual purposes of the answer
for (int i = 0; i < 64; i++) {
JLabel label = new JLabel() {
#Override
public Dimension getPreferredSize() {
return new Dimension(100, 100);
}
};
label.setOpaque(true);
label.setBackground(Color.DARK_GRAY);
panel2.add(label);
}
frame.add(panel1, BorderLayout.NORTH);
frame.add(panel2, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
}

Related

JButtons won't appear until I hover over them with the mouse

i have a problem with a grid i created. the buttons of this smallerGrid will not appear until i hover over them with the mouse.
each smallerGrid consists of a 3x3 grid which fits into a biggerGrid also 3x3 grid that conatins the smaller grids.
that is a brief explanation of how i am constructing the sudoku grid.
You will find the code below.
Thank you in advance.
import java.awt.*;
import javax.swing.*;
public class MyGridLayout {
private int filledFields = 0;
private JFrame mainFrame;
private JPanel panelForSolvingButton;
private JPanel smallerGridPanel;
private boolean solvingButtonAppeared = false;
SudokuCell[][] biggerGrid = new SudokuCell[10][10];
MyGridLayout() {
mainFrame = new JFrame("sudoku-solver");
mainFrame.setLayout(new BorderLayout());
smallerGridPanel = new JPanel(new GridLayout(3, 3));
mainFrame.add(smallerGridPanel, BorderLayout.CENTER);
panelForSolvingButton = new JPanel();
panelForSolvingButton.setLayout(new FlowLayout(FlowLayout.RIGHT));
mainFrame.add(panelForSolvingButton, BorderLayout.SOUTH);
mainFrame.pack();
mainFrame.setSize(600,600);
mainFrame.setLocationRelativeTo(null);
mainFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
mainFrame.setResizable(false);
addRegularButtons();
}
void addRegularButtons() {
int currentCol = 0;
int currentRow = 0;
int smallerGridFirstCol = 0;
int firstRowOfLayer = 0;
for (int layerOfGrids = 0; layerOfGrids < 3; ++layerOfGrids) {
for (int gridOfLayer = 0; gridOfLayer < 3; ++gridOfLayer) {
JComponent smallerGrid = new JPanel(new GridLayout(3, 3));
smallerGrid.setBorder(BorderFactory.createLineBorder(Color.BLACK));
smallerGridPanel.add(smallerGrid);
for (int j = 0; j < 3; ++j) {
for (int k = 0; k < 3; ++k) {
var cell = new SudokuCell(currentRow, currentCol);
smallerGrid.add(cell);
biggerGrid[currentRow][currentCol++] = cell;
cell.addActionListener(new CellActionListener(this));
}
currentRow++;
currentCol = smallerGridFirstCol;
}
smallerGridPanel.revalidate();
currentRow = firstRowOfLayer;
smallerGridFirstCol += 3;
currentCol = smallerGridFirstCol;
}
firstRowOfLayer += 3;
currentRow = firstRowOfLayer;
smallerGridFirstCol = currentCol = 0;
}
mainFrame.revalidate();
mainFrame.setVisible(true);
}
// checking if the solving process can begin
// (filled fields must at least reach 17)
void makeSolveButtonAppear() {
JButton solveButton = new JButton();
solveButton.setBackground(Color.white);
solveButton.setFont(new Font("Arial", Font.PLAIN, 20));
solveButton.setOpaque(false);
solveButton.setText("Solve ?");
panelForSolvingButton.add(solveButton);
}
public boolean isSolvingButtonAppeared() {
return solvingButtonAppeared;
}
public void setSolvingButtonAppeared(boolean solvingButtonAppeared) {
this.solvingButtonAppeared = solvingButtonAppeared;
}
public int getFilledFields() {
return filledFields;
}
public void setFilledFields(int filledFields) {
this.filledFields = filledFields;
}
public JPanel getPanelForSolvingButton() {
return panelForSolvingButton;
}
public static void main(String[] args) {
var gridLayout = new MyGridLayout();
}
}
package mainFrame;
import java.awt.*;
import java.util.HashMap;
import java.util.Map;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.MatteBorder;
public class SudokuCell extends JButton {
private int x;
private int y;
public SudokuCell(int x, int y) {
this.x = x;
this.y = y;
setBackground(Color.white);
setOpaque(true);
setFont(new Font("Arial", Font.PLAIN, 20));
}
#Override
public int getX() {
return x;
}
#Override
public int getY() {
return y;
}
}
package mainFrame;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class CellActionListener implements ActionListener {
private int clicked = 0;
MyGridLayout currentGrid;
CellActionListener(MyGridLayout currentGrid) {
this.currentGrid = currentGrid;
}
#Override
public void actionPerformed(ActionEvent e) {
if(clicked ==0) currentGrid.setFilledFields(currentGrid.getFilledFields()+1);
//clicked (number of clicks) must remain between 0 and 9
clicked = (clicked % 9) + 1;
((JButton) e.getSource()).setText(Integer.toString(clicked));
//first click on the button means an entry has been made
//which means one less needed filledField out of 17
if(!currentGrid.isSolvingButtonAppeared() && currentGrid.getFilledFields() >= 17) {
currentGrid.makeSolveButtonAppear();
currentGrid.setSolvingButtonAppeared(true);
}
}
}```

Creating a counter for bubblesort

I'm trying to make a counter that counts up every time a number is swapped. I think I'm on the right track, but my counter doesn't show, however, it compiles and runs okay. This code sorts all the numbers from smallest to largest and I need to count up how many times it swaps.
It needs to be placed in the bubblesort() method. I believe you would have to add swapItems to +1 to counter every time it makes a move. If someone could help me here that would be much appreciated.
The code that has ">" on the left side of it is the counter part of the code.
// Sorting Application
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Sort2 extends JFrame implements ActionListener{
private TextField[] items = new TextField[6];
private JButton btnSort, btnClear, btnReset;
private TextField tmp;
private Label status;
private int pauseInterval = 100; // ms
public static void main(String[] args) {
new Sort2().setVisible(true);
}
public Sort2() {
init();
}
public void init() {
setTitle("Sorting Algorithms");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(440, 200);
JPanel jp = new JPanel(new BorderLayout());
jp.setPreferredSize(new Dimension(440, 200));
jp.setBackground(Color.white);
JPanel itemPanel = new JPanel();
itemPanel.setBackground(Color.white);
for (int i = 0; i < items.length; i++) {
items[i] = new TextField(3);
items[i].setPreferredSize(new Dimension(30,40));
itemPanel.add(items[i]);
}
initItems();
itemPanel.add(new Label("Temp:"));
tmp = new TextField(4);
tmp.setPreferredSize(new Dimension(30,40));
tmp.setEditable(false);
itemPanel.add(tmp);
itemPanel.add(new Label(""))
.setPreferredSize(new Dimension(380, 65));
JPanel buttonPanel = new JPanel();
buttonPanel.setBackground(Color.white);
btnSort = new JButton("Sort");
btnReset = new JButton("Reset");
btnClear = new JButton("Clear");
btnSort.addActionListener(this);
btnClear.addActionListener(this);
btnReset.addActionListener(this);
buttonPanel.add(btnSort);
buttonPanel.add(btnClear);
buttonPanel.add(btnReset);
status = new Label("Wating ... ");
status.setPreferredSize(new Dimension(380, 40));
JPanel statusPanel = new JPanel();
statusPanel.setBackground(Color.white);
statusPanel.add(status, BorderLayout.SOUTH);
jp.add(itemPanel, BorderLayout.NORTH);
jp.add(buttonPanel, BorderLayout.CENTER);
jp.add(statusPanel, BorderLayout.SOUTH);
getContentPane().add(jp);
}
private void initItems() {
for (int i = 0; i < items.length; i++) {
items[i].setText((
String.valueOf((int)(Math.random()*100))));
}
}
private void pause(int ms) {
try {
Thread.sleep(ms);
}
catch (InterruptedException e) {
showStatus(e.toString());
}
}
private void assign(TextField to, TextField from) {
Color tobg = to.getBackground();
to.setBackground(Color.green);
pause(pauseInterval);
to.setText(from.getText());
pause(pauseInterval);
to.setBackground(tobg);
}
private void swapItems(TextField t1, TextField t2) {
assign(tmp,t1);
assign(t1,t2);
assign(t2,tmp);
}
private boolean greaterThan(TextField t1, TextField t2) {
boolean greater;
Color t1bg = t1.getBackground();
Color t2bg = t2.getBackground();
t1.setBackground(Color.cyan);
t2.setBackground(Color.cyan);
pause(pauseInterval);
greater = Integer.parseInt(t1.getText()) <
Integer.parseInt(t2.getText());
pause(pauseInterval);
t1.setBackground(t1bg);
t2.setBackground(t2bg);
return greater;
}
> private void bubbleSort() {
> int currentCount = 0;
> showStatus("Sorting ...");
> boolean swap = true;
> while (swap) {
> swap=false;
> for (int i = 0; i < items.length-1; i++) {
> if (greaterThan(items[i],items[i+1])) {
> swapItems(items[i],items[i+1]);
> swap=true;
> for (int step = 1; step <= items.length+1; step++) {
> currentCount = currentCount + 1;
> }
> }
> } //for
> } // while
> showStatus("Sort complete" + " number of swaps = " + currentCount);
> } // bubbleSort
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
switch (command) {
case "Clear":
for (int i = 0; i < items.length; i++) {
items[i].setText("");
}
break;
case "Sort":
bubbleSort();
break;
case "Reset":
initItems();
break;
default:
showStatus("Unrecognised button: " + e.toString());
}
}
private void showStatus(String s) {
status.setText(s);
}
}
Please find the updated working code which count the swapping.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Label;
import java.awt.TextField;
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;
public class Counter extends JFrame implements ActionListener {
private TextField[] items = new TextField[6];
private JButton btnSort, btnClear, btnReset;
private TextField tmp;
private Label status;
private JLabel cntLabel;
private int pauseInterval = 100;
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
Counter f = new Counter();
f.init();
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
public Counter() {
// init();
}
public void init() {
setTitle("Sorting Algorithms");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(440, 200);
JPanel jp = new JPanel(new BorderLayout());
jp.setPreferredSize(new Dimension(440, 200));
jp.setBackground(Color.white);
JPanel itemPanel = new JPanel(new FlowLayout());
itemPanel.setBackground(Color.white);
for (int i = 0; i < items.length; i++) {
items[i] = new TextField(3);
items[i].setPreferredSize(new Dimension(30, 40));
itemPanel.add(items[i]);
}
initItems();
itemPanel.add(new Label("Temp:"));
tmp = new TextField(4);
tmp.setPreferredSize(new Dimension(30, 40));
tmp.setEditable(false);
itemPanel.add(tmp);
itemPanel.add(cntLabel).setPreferredSize(new Dimension(100, 65));
JPanel buttonPanel = new JPanel();
buttonPanel.setBackground(Color.white);
btnSort = new JButton("Sort");
btnReset = new JButton("Reset");
btnClear = new JButton("Clear");
btnSort.addActionListener(this);
btnClear.addActionListener(this);
btnReset.addActionListener(this);
buttonPanel.add(btnSort);
buttonPanel.add(btnClear);
buttonPanel.add(btnReset);
status = new Label("Wating ... ");
status.setPreferredSize(new Dimension(380, 40));
JPanel statusPanel = new JPanel();
statusPanel.setBackground(Color.white);
statusPanel.add(status, BorderLayout.SOUTH);
jp.add(itemPanel, BorderLayout.NORTH);
jp.add(buttonPanel, BorderLayout.CENTER);
jp.add(statusPanel, BorderLayout.SOUTH);
getContentPane().add(jp);
}
private void initItems() {
for (int i = 0; i < items.length; i++) {
items[i].setText((String.valueOf((int) (Math.random() * 100))));
}
// if(null!=swapLabel)
// swapLabel.setText("");
cntLabel = new JLabel("0");
}
private void pause(int ms) {
try {
Thread.sleep(ms);
} catch (InterruptedException e) {
showStatus(e.toString());
}
}
private void assign(TextField to, TextField from) {
Color tobg = to.getBackground();
to.setBackground(Color.green);
pause(pauseInterval);
to.setText(from.getText());
pause(pauseInterval);
to.setBackground(tobg);
}
private void swapItems(TextField t1, TextField t2) {
assign(tmp, t1);
assign(t1, t2);
assign(t2, tmp);
}
private boolean greaterThan(TextField t1, TextField t2) {
boolean greater;
Color t1bg = t1.getBackground();
Color t2bg = t2.getBackground();
t1.setBackground(Color.cyan);
t2.setBackground(Color.cyan);
pause(pauseInterval);
greater = Integer.parseInt(t1.getText()) < Integer.parseInt(t2.getText());
pause(pauseInterval);
t1.setBackground(t1bg);
t2.setBackground(t2bg);
return greater;
}
private void bubbleSort() {
int currentCount = 0;
int n = 0;
showStatus("Sorting ...");
boolean swap = true;
while (swap) {
swap = false;
for (int i = 0; i < items.length - 1; i++) {
if (greaterThan(items[i], items[i + 1])) {
swapItems(items[i], items[i + 1]);
swap = true;
currentCount++;
}
} // for
} // while
showStatus("Sort complete : Swap count = " + currentCount);
} // bubbleSort
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
switch (command) {
case "Clear":
for (int i = 0; i < items.length; i++) {
items[i].setText("");
}
cntLabel = new JLabel("0");
break;
case "Sort":
bubbleSort();
break;
case "Reset":
initItems();
break;
default:
showStatus("Unrecognised button: " + e.toString());
}
}
private void showStatus(String s) {
status.setText(s);
}
}
If I understand correctly, I think that the problem is that you have an unnecessary for loop (the one with the step variable). All you need to do is delete that loop and just have the following instead:
currentCount += 1;
// Alternatively, you could also do 'currentCount = currentCount + 1;' or 'currentCount++;'
So basically, the if statement in your bubbleSort() method should look something like this:
if (greaterThan(items[i], items[i + 1])) {
swapItems(items[i], items[i + 1]);
swap = true;
currentCount += 1;
}

java programing swing application

import java.awt.BorderLayout;
import java.applet.Applet;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.*;
import java.awt.FlowLayout;
import java.awt.event.*;
import java.awt.*;
public class MemoryGame implements ActionListener
{
Label mostra;
public int delay = 1000; //1000 milliseconds
public void init()
{
//add(mostra = new Label(" "+0));
}
public void Contador()
{
ActionListener counter = new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
tempo++;
TempoScore.setText("Tempo: " + tempo);
}
};
new Timer(delay, counter).start();
}
public void updateHitMiss()
{
HitScore.setText("Acertou: " + Hit);
MissScore.setText("Falhou: " + Miss);
PontosScore.setText("Pontos: " + Pontos);
}
private JFrame window = new JFrame("Jogo da Memoria");
private static final int WINDOW_WIDTH = 500; // pixels
private static final int WINDOW_HEIGHT = 500; // pixels
private JButton exitBtn, baralharBtn, solveBtn, restartBtn;
ImageIcon ButtonIcon = createImageIcon("card1.png");
private JButton[] gameBtn = new JButton[16];
private ArrayList<Integer> gameList = new ArrayList<Integer>();
private int Hit, Miss, Pontos;
public int tempo = 0;
private int counter = 0;
private int[] btnID = new int[2];
private int[] btnValue = new int[2];
private JLabel HitScore, MissScore,TempoScore, PontosScore;
private JPanel gamePnl = new JPanel();
private JPanel buttonPnl = new JPanel();
private JPanel scorePnl = new JPanel();
protected static ImageIcon createImageIcon(String path)
{
java.net.URL imgURL = MemoryGame.class.getResource(path);
if (imgURL != null)
{
return new ImageIcon(imgURL);
}
else
{
System.err.println("Couldn't find file: " + path);
return null;
}
}
public MemoryGame()
{
createGUI();
createJPanels();
setArrayListText();
window.setTitle("Jogo da Memoria");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
window.setVisible(true);
Contador();
}
public void createGUI()
{
for (int i = 0; i < gameBtn.length; i++)
{
gameBtn[i] = new JButton(ButtonIcon);
gameBtn[i].addActionListener(this);
}
HitScore = new JLabel("Acertou: " + Hit);
MissScore = new JLabel("Falhou: " + Miss);
TempoScore = new JLabel("Tempo: " + tempo);
PontosScore = new JLabel("Pontos: " + Pontos);
exitBtn = new JButton("Sair");
exitBtn.addActionListener(this);
baralharBtn = new JButton("Baralhar");
baralharBtn.addActionListener(this);
solveBtn = new JButton("Resolver");
solveBtn.addActionListener(this);
restartBtn = new JButton("Recomecar");
restartBtn.addActionListener(this);
}
public void createJPanels()
{
gamePnl.setLayout(new GridLayout(4, 4));
for (int i = 0; i < gameBtn.length; i++)
{
gamePnl.add(gameBtn[i]);
}
buttonPnl.add(baralharBtn);
buttonPnl.add(exitBtn);
buttonPnl.add(solveBtn);
buttonPnl.add(restartBtn);
buttonPnl.setLayout(new GridLayout(1, 0));
scorePnl.add(HitScore);
scorePnl.add(MissScore);
scorePnl.add(TempoScore);
scorePnl.add(PontosScore);
scorePnl.setLayout(new GridLayout(1, 0));
window.add(scorePnl, BorderLayout.NORTH);
window.add(gamePnl, BorderLayout.CENTER);
window.add(buttonPnl, BorderLayout.SOUTH);
}
public void setArrayListText()
{
for (int i = 0; i < 2; i++)
{
for (int ii = 1; ii < (gameBtn.length / 2) + 1; ii++)
{
gameList.add(ii);
}
}
}
public boolean sameValues()
{
if (btnValue[0] == btnValue[1])
{
return true;
}
return false;
}
public void actionPerformed(ActionEvent e)
{
if (exitBtn == e.getSource())
{
System.exit(0);
}
if (baralharBtn == e.getSource())
{
//
}
if (solveBtn == e.getSource())
{
for (int i = 0; i < gameBtn.length; i++)
{
gameBtn[i].setText("" + gameList.get(i));
gameBtn[btnID[0]].setEnabled(false);
gameBtn[btnID[1]].setEnabled(false);
}
}
for (int i = 0; i < gameBtn.length; i++)
{
if (gameBtn[i] == e.getSource())
{
gameBtn[i].setText("" + gameList.get(i));
gameBtn[i].setEnabled(false);
counter++;
if (counter == 3)
{
if (sameValues())
{
gameBtn[btnID[0]].setEnabled(false);
gameBtn[btnID[1]].setEnabled(false);
gameBtn[btnID[0]].setVisible(false);
gameBtn[btnID[1]].setVisible(false);
Hit = Hit +1;
Pontos = Pontos + 25;
}
else
{
gameBtn[btnID[0]].setEnabled(true);
gameBtn[btnID[0]].setText("");
gameBtn[btnID[1]].setEnabled(true);
gameBtn[btnID[1]].setText("");
Miss = Miss +1;
Pontos = Pontos - 5;
}
counter = 1; //permite 2(3) clikes de cada vez
}
/*if (Pontos <= 0)
{
Pontos=0;
} */
if (counter == 1) // se carregar 1º botão
{
btnID[0] = i;
btnValue[0] = gameList.get(i);
}
if (counter == 2) // se carregar 2º botão
{
btnID[1] = i;
btnValue[1] = gameList.get(i);
}
}
}
if (restartBtn == e.getSource())
{
Hit=0;
Miss=0;
tempo=-1;
Pontos=0;
for (int i = 0; i < gameBtn.length; i++) /* what i want to implement(restart button) goes here, this is incomplete because it only clean numbers and "transforms" into regular JButton, the last two clicks
on the 4x4 grid (btnID[0] and btnID[1]), but i want to clean all the visible
numbers in the grid 4x4, and want to transform all grid 4x4 into default (or
regular color, white and blue) JButton, the grid numbers stay in same order
or position. */
{
gameBtn[btnID[0]].setEnabled(true);
gameBtn[btnID[0]].setText("");
gameBtn[btnID[1]].setEnabled(true);
gameBtn[btnID[1]].setText("");
}
/*
restartBtn.addActionListener(new ActionListener()
{
JFrame.dispatchEvent(new WindowEvent(JFrame, WindowEvent.WINDOW_CLOSING)); // this line is getting errors (MemoryGame.java:233: error: <identifier> expected
JFrame.dispatchEvent(new WindowEvent(JFrame, WindowEvent.WINDOW_CLOSING));
illegal start of type,')' expected, ';' expected all in the same line )
private JFrame window = new JFrame("Jogo da Memoria");
// something not right, i think frame is replaced by JFrame but i dont know, be
}); */
}
updateHitMiss();
}
public static void main(String[] args)
{
new MemoryGame();
}
}
</code>
Hi,
I want to add a restart button (mouse click), i am running notepadd++, when i click on restart button (recomeçar), it should restart this memory game, all counters set to zero etc, clean the grid 4x4, all numbers that were visible when i click the restart the button they all disaapear (but they are in same place or order) thus only show regular JButtons, the game should go to the starting point like when it first open the application, all numbers are not visible. (the functionality of restart button is equal to exit application and then restart).
Restart button code in lines 215 to 239, issues reported on comments between those lines.
I'm not sure if I fully understand your question, but here's what i think would help:
Add an ActionListener to your button with:
button.addActionListener(new ActionListener() {
});,
with button being the name of your JButton.
Within your ActionListener, call frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));, with frame being the name of your JFrame.
Then, run all of the methods you use to initialize your game (including the one that opens the JFrame).
Comment if you need clarification or more help.

Hello I am creating a TicTacToe game for myself to understand Java better

however I am not sure where I am supposed to enter the whoWins() method. Do I enter this method in the actionperformed Method of the buttons or do i need to something different. Please help.
public class TTT extends JFrame implements ActionListener {
private JButton buttons[] = new JButton[9];
private JButton exitButton;
public JLabel title;
public JPanel titlePanel, panel;
private int count = 0;
int symbolCount = 0;
private boolean win = false;
public TTT() {
title = new JLabel("Welcome to my Tic Tac Toe Game!");
titlePanel = new JPanel();
title.setFont(new Font(Font.SERIF, 0, 30));
titlePanel.add(title);
this.add(titlePanel, BorderLayout.NORTH);
panel = new JPanel(new GridLayout(3, 3));
for (int i = 0; i < buttons.length; i++) {
buttons[i] = new JButton();
panel.add(buttons[i]);
buttons[i].setEnabled(true);
buttons[i].addActionListener(this);
}
this.add(panel, BorderLayout.CENTER);
JPanel panel1 = new JPanel(new FlowLayout(FlowLayout.CENTER));
exitButton = new JButton("Quit");
panel1.add(exitButton);
this.add(panel1, BorderLayout.SOUTH);
exitButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.exit(WIDTH);
}
});
}
public void whoWins() {
//Determines who wins using for the horizontal rows.
if (buttons[0].getText() == buttons[1].getText() && buttons[1].getText() == buttons[2].getText() && buttons[0].getText() != "") {
win = true;
} else if (buttons[3].getText() == buttons[4].getText() && buttons[4].getText() == buttons[5].getText() && buttons[3].getText() != "") {
win = true;
} else if (buttons[6].getText() == buttons[7].getText() && buttons[7].getText() == buttons[8].getText() && buttons[6].getText() != "") {
win = true;
} //Determines the verticles wins
else if (buttons[0].getText() == buttons[3].getText() && buttons[3].getText() == buttons[6].getText() && buttons[0].getText() != "") {
win = true;
} else if (buttons[1].getText() == buttons[4].getText() && buttons[4].getText() == buttons[7].getText() && buttons[1].getText() != "") {
win = true;
} else if (buttons[2].getText() == buttons[5].getText() && buttons[5].getText() == buttons[8].getText() && buttons[2].getText() != "") {
win = true;
}
// Diagnol Wins
else if (buttons[0].getText()==buttons[4].getText()&&buttons[4].getText()==buttons[8].getText()&& buttons[0].getText()!= "") {
win = true;
}else if (buttons[2].getText()==buttons[4].getText()&&buttons[4].getText()==buttons[6].getText()&& buttons[1].getText()!= "") {
win = true;
}else {
win = false;
}
//who won
if (win = true) {
JOptionPane.showMessageDialog(null, "wins");
}else if (count == 9 && win == false) {
JOptionPane.showMessageDialog(null, "Tie game");
}
}
public static void main(String[] args) {
TTT ref1 = new TTT();
ref1.setTitle("Tic Tac Toe");
ref1.setVisible(true);
ref1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ref1.setSize(500, 500);
ref1.setLocationRelativeTo(null);
// ref1.whoWins();
}
#Override
public void actionPerformed(ActionEvent e) {
count++;
for (JButton button : buttons) {
if (button == e.getSource()) {
if (symbolCount % 2 == 0) {
button.setText("X");
button.setEnabled(false);
} else {
button.setText("O");
button.setEnabled(false);
}
}
}
if (count >= buttons.length) {
JOptionPane.showMessageDialog(null, "End");
}
symbolCount++;
}
}
If you really want to do this right, then I suggest making some big changes, some M-V-C type changes:
First and foremost, separate out the logic of the game from the game GUI. This would mean that the code that determines who wins should not be in any code that contains GUI type code. This will be your "model"
Next you should never have GUI code implement listener interfaces, so try to get that out of the GUI and possibly have it go into its own class, the "Control" class.
Finally the GUI or "View" class will concern itself with displaying the model's state and getting input from the user and transmitting this input to the control.
For example,...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.util.EnumMap;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.SwingPropertyChangeSupport;
public class TicTacToeMain {
private static void createAndShowGui() {
TttView view = null;
try {
view = new TttView();
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
TttModel model = new TttModel();
new TttControl(model, view);
JFrame frame = new JFrame("Tic Tac Toe");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(view.getMainPanel());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
enum TttPiece {
EMPTY, X, O
}
class TttView {
public static final String IMAGE = "/imgFolder/TicTacToe.png";
private static final int GAP = 5;
private JPanel mainPanel = new JPanel();
private JPanel tttPanel = new JPanel();
private Map<TttPiece, Icon> iconMap = new EnumMap<>(TttPiece.class);
private JLabel[][] grid = new JLabel[TttModel.ROWS][TttModel.COLS];
private TttControl control;
public TttView() throws IOException {
BufferedImage img = ImageIO.read(getClass().getResourceAsStream(IMAGE));
Icon[] imgIcons = splitImg(img);
iconMap.put(TttPiece.X, imgIcons[0]);
iconMap.put(TttPiece.O, imgIcons[1]);
iconMap.put(TttPiece.EMPTY, createEmptyIcon(imgIcons[0]));
tttPanel.setLayout(new GridLayout(grid.length, grid[0].length, GAP, GAP));
tttPanel.setBackground(Color.black);
MyMouseAdapter mouseAdapter = new MyMouseAdapter();
for (int row = 0; row < grid.length; row++) {
for (int col = 0; col < grid[row].length; col++) {
grid[row][col] = new JLabel(iconMap.get(TttPiece.EMPTY));
grid[row][col].setOpaque(true);
grid[row][col].setBackground(Color.LIGHT_GRAY);
grid[row][col].addMouseListener(mouseAdapter);
tttPanel.add(grid[row][col]);
}
}
JPanel btnPanel = new JPanel(new GridLayout(1, 0, 5, 0));
btnPanel.add(new JButton(new ClearAction("Clear", KeyEvent.VK_C)));
btnPanel.add(new JButton(new ExitAction("Exit", KeyEvent.VK_X)));
int blGap = 2;
mainPanel.setLayout(new BorderLayout(blGap, blGap));
mainPanel.setBorder(BorderFactory.createEmptyBorder(blGap, blGap, blGap,
blGap));
mainPanel.add(tttPanel, BorderLayout.CENTER);
mainPanel.add(btnPanel, BorderLayout.SOUTH);
}
public void setControl(TttControl control) {
this.control = control;
}
public JComponent getMainPanel() {
return mainPanel;
}
private Icon createEmptyIcon(Icon icon) {
int width = icon.getIconWidth();
int height = icon.getIconHeight();
BufferedImage img = new BufferedImage(width, height,
BufferedImage.TYPE_INT_ARGB);
return new ImageIcon(img);
}
private Icon[] splitImg(BufferedImage img) {
int w = img.getWidth();
int h = img.getHeight();
int gap = 5;
Icon[] icons = new ImageIcon[2];
icons[0] = new ImageIcon(img.getSubimage(0, 0, w / 2 - gap, h / 2 - gap));
icons[1] = new ImageIcon(img.getSubimage(w / 2 + gap, 0, w / 2 - gap, h
/ 2 - gap));
return icons;
}
private class MyMouseAdapter extends MouseAdapter {
#Override
public void mousePressed(MouseEvent e) {
if (control == null) {
return;
}
for (int row = 0; row < grid.length; row++) {
for (int col = 0; col < grid[row].length; col++) {
if (grid[row][col] == e.getSource()) {
control.gridPress(row, col);
}
}
}
}
}
private class ClearAction extends AbstractAction {
public ClearAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent evt) {
if (control != null) {
control.clear();
}
}
}
private class ExitAction extends AbstractAction {
public ExitAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent evt) {
if (control != null) {
control.exit(evt);
}
}
}
public void setGridIcon(int row, int col, TttPiece tttPiece) {
grid[row][col].setIcon(iconMap.get(tttPiece));
}
}
class TttControl {
private TttModel model;
private TttView view;
public TttControl(TttModel model, TttView view) {
this.model = model;
this.view = view;
view.setControl(this);
model.addPropertyChangeListener(new ModelListener());
}
public void exit(ActionEvent evt) {
Window win = SwingUtilities
.getWindowAncestor((Component) evt.getSource());
win.dispose();
}
public void gridPress(int row, int col) {
try {
model.gridPress(row, col);
} catch (TttException e) {
// TODO: notify user
// e.printStackTrace();
}
}
public void clear() {
model.clear();
}
private class ModelListener implements PropertyChangeListener {
#Override
public void propertyChange(PropertyChangeEvent evt) {
if (TttModel.GRID_POSITION.equals(evt.getPropertyName())) {
TttPiece[][] tttGrid = model.getTttGrid();
for (int row = 0; row < tttGrid.length; row++) {
for (int col = 0; col < tttGrid[row].length; col++) {
view.setGridIcon(row, col, tttGrid[row][col]);
}
}
}
}
}
}
class TttModel {
public static final int ROWS = 3;
public static final int COLS = ROWS;
public static final String GRID_POSITION = "grid position";
private SwingPropertyChangeSupport pcSupport = new SwingPropertyChangeSupport(
this);
private TttPiece[][] tttGrid = new TttPiece[ROWS][COLS];
private TttPiece player = TttPiece.X;
private boolean gameOver;
public TttModel() {
clear();
}
public void setGridPosition(int row, int col, TttPiece piece)
throws TttException {
if (gameOver) {
return;
}
if (tttGrid[row][col] == TttPiece.EMPTY) {
tttGrid[row][col] = piece;
checkForWin(row, col, piece);
nextPlayer();
pcSupport.firePropertyChange(GRID_POSITION, null, tttGrid);
} else {
String message = "Invalid setGridPosition for row: %d, col: %d, piece: %s. "
+ "Spot already occupied by piece: %s";
message = String.format(message, row, col, piece, tttGrid[row][col]);
throw new TttException(message);
}
}
public TttPiece[][] getTttGrid() {
return tttGrid;
}
public void gridPress(int row, int col) throws TttException {
setGridPosition(row, col, player);
}
public void nextPlayer() {
player = player == TttPiece.X ? TttPiece.O : TttPiece.X;
}
private void checkForWin(int row, int col, TttPiece piece) {
// TODO finish
}
public void clear() {
for (int row = 0; row < tttGrid.length; row++) {
for (int col = 0; col < tttGrid[row].length; col++) {
tttGrid[row][col] = TttPiece.EMPTY;
}
}
player = TttPiece.X;
pcSupport.firePropertyChange(GRID_POSITION, null, tttGrid);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
pcSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
pcSupport.removePropertyChangeListener(listener);
}
}
#SuppressWarnings("serial")
class TttException extends Exception {
public TttException() {
super();
}
public TttException(String message) {
super(message);
}
}
Using for my images:
With GUI looking like:
I am also interested in writing a Tic Tac Toe game, so I copied your code, and did a little modification, and it passed test, check following:
package eric.j2se.swing;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
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.JOptionPane;
import javax.swing.JPanel;
/**
* <p>
* Simple game of Tic Tac Toe.
* </p>
*
* #author eric
* #date Apr 16, 2014 11:03:48 AM
*/
#SuppressWarnings("serial")
public class TicTacToe extends JFrame implements ActionListener {
// 2 players
public static final char playerX = 'X';
public static final char playerO = 'O';
// null player
public static final char playerN = 'N';
// the winer, init to null player
private Character winner = playerN;
// indicate whether game over
private boolean gameOver = false;
// count of button used,
private int count = 0;
private Character buttonPlayers[] = new Character[9];
private JButton buttons[] = new JButton[9];
private JButton exitButton;
public JLabel title;
public JPanel titlePanel, panel;
public TicTacToe() {
// init buttonPlayers
for (int i = 0; i < 9; i++) {
buttonPlayers[i] = playerN;
}
// init title
title = new JLabel("Welcome to Tic Tac Toe!");
titlePanel = new JPanel();
title.setFont(new Font(Font.SERIF, 0, 30));
titlePanel.add(title);
this.add(titlePanel, BorderLayout.NORTH);
// init 9 button
panel = new JPanel(new GridLayout(3, 3));
for (int i = 0; i < buttons.length; i++) {
buttons[i] = new JButton();
panel.add(buttons[i]);
buttons[i].setEnabled(true);
buttons[i].addActionListener(this);
}
// init exit button
this.add(panel, BorderLayout.CENTER);
JPanel panel1 = new JPanel(new FlowLayout(FlowLayout.CENTER));
exitButton = new JButton("Quit");
panel1.add(exitButton);
this.add(panel1, BorderLayout.SOUTH);
exitButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.exit(WIDTH);
}
});
}
public void whoWins() {
// determine winner - horizontal rows
if (!gameOver) {
for (int i = 0; i < 3; i++) {
if ((buttonPlayers[0 + i * 3] != playerN) && (buttonPlayers[0 + i * 3].equals(buttonPlayers[1 + i * 3]))
&& buttonPlayers[1 + i * 3].equals(buttonPlayers[2 + i * 3])) {
winner = buttonPlayers[0 + i * 3];
gameOver = true;
break;
}
}
}
// determine winner - vertical rows
if (!gameOver) {
for (int i = 0; i < 3; i++) {
if ((buttonPlayers[i + 0 * 3] != playerN) && (buttonPlayers[i + 0 * 3].equals(buttonPlayers[i + 1 * 3]))
&& buttonPlayers[i + 1 * 3].equals(buttonPlayers[i + 2 * 3])) {
winner = buttonPlayers[i + 0 * 3];
gameOver = true;
break;
}
}
}
// determine winner - diagonal rows
if (!gameOver) {
int winButtonIndex = -1;
if ((buttonPlayers[0] != playerN) && (buttonPlayers[0].equals(buttonPlayers[4])) && buttonPlayers[4].equals(buttonPlayers[8])) {
winButtonIndex = 0;
} else if ((buttonPlayers[2] != playerN) && (buttonPlayers[2].equals(buttonPlayers[4])) && buttonPlayers[4].equals(buttonPlayers[6])) {
winButtonIndex = 2;
}
if (winButtonIndex >= 0) {
winner = buttonPlayers[winButtonIndex];
gameOver = true;
}
}
// full
if (count == 9) {
gameOver = true;
}
if (gameOver) {
String tip = "";
switch (winner) {
case playerO:
tip = "Player O win!";
break;
case playerX:
tip = "Player X win!";
break;
default:
tip = "Draw game!";
break;
}
JOptionPane.showMessageDialog(null, tip);
}
}
#Override
public void actionPerformed(ActionEvent e) {
for (int i = 0; i < buttons.length; i++) {
JButton button = buttons[i];
if (button == e.getSource()) {
Character currentPlayer = (count % 2 == 1 ? playerX : playerO);
button.setText(String.valueOf(currentPlayer));
buttonPlayers[i] = currentPlayer;
button.setEnabled(false);
break;
}
}
count++;
whoWins();
}
public static void main(String[] args) {
TicTacToe ref1 = new TicTacToe();
ref1.setTitle("Tic Tac Toe");
ref1.setVisible(true);
ref1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ref1.setSize(500, 500);
ref1.setLocationRelativeTo(null);
}
}
about when to call the win check:
check each time you click 1 of the 9 buttons,
about the flag:
I use 2 flag instead of 1 flag to indicate game over & winner, because in TTT game, draw game is very usual, after play several times, you always get draw game ...
a little suggestion to your code:
when compare string, use equals(), not ==,
define const values in variable, not write it in logic, e.g. 'O' 'X',
don't repeat code, try use logic control to make it short & easy to read & easy to maintain,

Fail to reset the panel to initial state

I have problem with the Play Again button, which is to reset the panel to initial state.
The Play Again button should reset the panel, it does reshuffle the gameList, but not reset the panel, which means all the buttons remain and lost the ActionListener function.
Here is my program :
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import static java.util.Collections.*;
public class MemoryGame extends JFrame
{
private JButton exitButton, replayButton;
private JButton[] gameButton = new JButton[16];
private ArrayList<Integer> gameList = new ArrayList<Integer>();
private int counter = 0;
private int[] buttonID = new int[2];
private int[] buttonValue = new int[2];
public static Point getCenterPosition(int frameWidth, int frameHeight)
{
Toolkit toolkit = Toolkit.getDefaultToolkit();
Dimension dimension = toolkit.getScreenSize();
int x = (dimension.width - frameWidth)/2;
int y = (dimension.height - frameHeight)/2;
return (new Point(x,y));
}
public MemoryGame(String title)
{
super(title);
initial();
}
public void initial()
{
for (int i = 0; i < gameButton.length; i++)
{
gameButton[i] = new JButton();
gameButton[i].setFont(new Font("Serif", Font.BOLD, 28));
gameButton[i].addActionListener(new ButtonListener());
}
exitButton = new JButton("Exit");
replayButton = new JButton("Play Again");
exitButton.addActionListener(new ButtonListener());
replayButton.addActionListener(new ButtonListener());
Panel gamePanel = new Panel();
gamePanel.setLayout(new GridLayout(4, 4));
for (int i = 0; i < gameButton.length; i++)
{
gamePanel.add(gameButton[i]);
}
Panel buttonPanel = new Panel();
buttonPanel.add(replayButton);
buttonPanel.add(exitButton);
buttonPanel.setLayout(new GridLayout(1, 0));
add(gamePanel, BorderLayout.CENTER);
add(buttonPanel, BorderLayout.SOUTH);
for (int i = 0; i < 2; i++)
{
for (int j = 1; j < (gameButton.length / 2) + 1; j++)
{
gameList.add(j);
}
}
shuffle(gameList);
int newLine = 0;
for (int a = 0; a < gameList.size(); a++)
{
newLine++;
System.out.print(" " + gameList.get(a));
if (newLine == 4)
{
System.out.println();
newLine = 0;
}
}
}
public boolean sameValues()
{
if (buttonValue[0] == buttonValue[1])
{
return true;
}
return false;
}
private class ButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
if (exitButton == e.getSource())
{
System.exit(0);
}
else if (replayButton == e.getSource())
{
initial();
}
for (int i = 0; i < gameButton.length; i++)
{
if (gameButton[i] == e.getSource())
{
gameButton[i].setText("" + gameList.get(i));
gameButton[i].setEnabled(false);
counter++;
if (counter == 3)
{
if (sameValues())
{
gameButton[buttonID[0]].setEnabled(false);
gameButton[buttonID[1]].setEnabled(false);
}
else
{
gameButton[buttonID[0]].setEnabled(true);
gameButton[buttonID[0]].setText("");
gameButton[buttonID[1]].setEnabled(true);
gameButton[buttonID[1]].setText("");
}
counter = 1;
}
if (counter == 1)
{
buttonID[0] = i;
buttonValue[0] = gameList.get(i);
}
if (counter == 2)
{
buttonID[1] = i;
buttonValue[1] = gameList.get(i);
}
}
}
}
}
public static void main(String[] args)
{
int x, y;
int width = 500;
int height = 500;
Point position = getCenterPosition(width, height);
x = position.x;
y = position.y;
JFrame frame = new MemoryGame("Memory Game");
frame.setBounds(x, y, width, height);
frame.setVisible(true);
frame.setResizable(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
How can I solve this problem?
EDIT :
Another problem is after reset(), all buttons seem like become sameValue(). I have insert some audio to the buttons, and it's happen in the condition of the ButtonListener. Here is the part :
if (counter == 3)
{
if (sameValues())
{
gameButton[buttonID[0]].setEnabled(false);
gameButton[buttonID[1]].setEnabled(false);
}
Seems like it's satisfy the condition sameValue(), but why?
LATEST UPDATE :
Problem Solved. Latest code is not uploaded.
In the initial() method the code is creating a new GUI. It would be preferable to retain handles to the original controls, and reset them to a 'begin game' state and the correct values (for number).
Alternatives with your current method are to remove() and add() new for every component (not recommended) or to use a CardLayout (not necessary - see first suggestion).
Ok, I've fixed your code.
Be sure to check out my comment to your question and let me know if it works (I did a quick test and it went fine)
package varie;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import static java.util.Collections.shuffle;
import javax.swing.JButton;
import javax.swing.JFrame;
public class MemoryGame extends JFrame {
private JButton exitButton, replayButton;
private JButton[] gameButton = new JButton[16];
private ArrayList<Integer> gameList = new ArrayList<>();
private int counter = 0;
private int[] buttonID = new int[2];
private int[] buttonValue = new int[2];
public static Point getCenterPosition(int frameWidth, int frameHeight) {
Toolkit toolkit = Toolkit.getDefaultToolkit();
Dimension dimension = toolkit.getScreenSize();
int x = (dimension.width - frameWidth) / 2;
int y = (dimension.height - frameHeight) / 2;
return (new Point(x, y));
}
public MemoryGame(String title) {
super(title);
initial();
}
public void initial() {
for (int i = 0; i < gameButton.length; i++) {
gameButton[i] = new JButton();
gameButton[i].setFont(new Font("Serif", Font.BOLD, 28));
gameButton[i].addActionListener(new ButtonListener());
}
exitButton = new JButton("Exit");
replayButton = new JButton("Play Again");
exitButton.addActionListener(new ButtonListener());
replayButton.addActionListener(new ButtonListener());
Panel gamePanel = new Panel();
gamePanel.setLayout(new GridLayout(4, 4));
for (int i = 0; i < gameButton.length; i++) {
gamePanel.add(gameButton[i]);
}
Panel buttonPanel = new Panel();
buttonPanel.add(replayButton);
buttonPanel.add(exitButton);
buttonPanel.setLayout(new GridLayout(1, 0));
add(gamePanel, BorderLayout.CENTER);
add(buttonPanel, BorderLayout.SOUTH);
for (int i = 0; i < 2; i++) {
for (int j = 1; j < (gameButton.length / 2) + 1; j++) {
gameList.add(j);
}
}
shuffle(gameList);
int newLine = 0;
for (int a = 0; a < gameList.size(); a++) {
newLine++;
System.out.print(" " + gameList.get(a));
if (newLine == 4) {
System.out.println();
newLine = 0;
}
}
}
public boolean sameValues() {
if (buttonValue[0] == buttonValue[1]) {
return true;
}
return false;
}
public void reset() {
for(int i = 0; i< gameButton.length; i++){
gameButton[i].setEnabled(true);
gameButton[i].setText("");
for(ActionListener al : gameButton[i].getActionListeners()){
gameButton[i].removeActionListener(al);
}
gameButton[i].addActionListener(new ButtonListener());
}
buttonID = new int[2];
buttonValue = new int[2];
counter = 0;
shuffle(gameList);
int newLine = 0;
for (int a = 0; a < gameList.size(); a++) {
newLine++;
System.out.print(" " + gameList.get(a));
if (newLine == 4) {
System.out.println();
newLine = 0;
}
}
}
private class ButtonListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if (exitButton.equals(e.getSource())) {
System.exit(0);
} else if (replayButton.equals(e.getSource())) {
reset();
} else {
for (int i = 0; i < gameButton.length; i++) {
if (gameButton[i].equals(e.getSource())) {
gameButton[i].setText("" + gameList.get(i));
gameButton[i].setEnabled(false);
counter++;
if (counter == 3) {
if (sameValues()) {
gameButton[buttonID[0]].setEnabled(false);
gameButton[buttonID[1]].setEnabled(false);
} else {
gameButton[buttonID[0]].setEnabled(true);
gameButton[buttonID[0]].setText("");
gameButton[buttonID[1]].setEnabled(true);
gameButton[buttonID[1]].setText("");
}
counter = 1;
}
if (counter == 1) {
buttonID[0] = i;
buttonValue[0] = gameList.get(i);
}
if (counter == 2) {
buttonID[1] = i;
buttonValue[1] = gameList.get(i);
}
}
}
}
}
}
public static void main(String[] args) {
int x, y;
int width = 500;
int height = 500;
Point position = getCenterPosition(width, height);
x = position.x;
y = position.y;
JFrame frame = new MemoryGame("Memory Game");
frame.setBounds(x, y, width, height);
frame.setVisible(true);
frame.setResizable(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

Categories