I need to make the following exceptions: NoSuchRowException if the row is not between 1 and 3, IllegalSticksException if the number of sticks taken is not between 1 and 3, and NotEnoughSticksException if the number of sticks taken is between 1 and 3, but more than the number of sticks remaining in that row. My issue is I really don't understand the syntax. If someone could help me get started with one exception, I think I can figure the others out.
So far I have the main class:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package nimapp;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/**
*
* #author jrsullins
*/
public class NimApp extends JFrame implements ActionListener {
private static final int ROWS = 3;
private JTextField[] gameFields; // Where sticks for each row shown
private JTextField rowField; // Where player enters row to select
private JTextField sticksField; // Where player enters sticks to take
private JButton playButton; // Pressed to take sticks
private JButton AIButton; // Pressed to make AI's move
private NimGame nim;
public NimApp() {
// Build the fields for the game play
rowField = new JTextField(5);
sticksField = new JTextField(5);
playButton = new JButton("PLAYER");
AIButton = new JButton("COMPUTER");
playButton.addActionListener(this);
AIButton.addActionListener(this);
AIButton.setEnabled(false);
// Create the layout
JPanel mainPanel = new JPanel(new BorderLayout());
getContentPane().add(mainPanel);
JPanel sticksPanel = new JPanel(new GridLayout(3, 1));
mainPanel.add(sticksPanel, BorderLayout.EAST);
JPanel playPanel = new JPanel(new GridLayout(3, 2));
mainPanel.add(playPanel, BorderLayout.CENTER);
// Add the fields to the play panel
playPanel.add(new JLabel("Row: ", JLabel.RIGHT));
playPanel.add(rowField);
playPanel.add(new JLabel("Sticks: ", JLabel.RIGHT));
playPanel.add(sticksField);
playPanel.add(playButton);
playPanel.add(AIButton);
// Build the array of textfields to display the sticks
gameFields = new JTextField[ROWS];
for (int i = 0; i < ROWS; i++) {
gameFields[i] = new JTextField(10);
gameFields[i].setEditable(false);
sticksPanel.add(gameFields[i]);
}
setSize(350, 150);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
nim = new NimGame(new int[]{3, 5, 7});
draw();
}
// Utility function to redraw game
private void draw() {
for (int row = 0; row < ROWS; row++) {
String sticks = "";
for (int j = 0; j < nim.getRow(row); j++) {
sticks += "| ";
}
gameFields[row].setText(sticks);
}
rowField.setText("");
sticksField.setText("");
}
public void actionPerformed(ActionEvent e) {
// Player move
if (e.getSource() == playButton) {
// Get the row and number of sticks to take
int row = Integer.parseInt(rowField.getText())-1;
int sticks = Integer.parseInt(sticksField.getText());
// Play that move
nim.play(row, sticks);
// Redisplay the board and enable the AI button
draw();
playButton.setEnabled(false);
AIButton.setEnabled(true);
// Determine whether the game is over
if (nim.isOver()) {
JOptionPane.showMessageDialog(null, "You win!");
playButton.setEnabled(false);
}
}
// Computer move
if (e.getSource() == AIButton) {
// Determine computer move
nim.AIMove();
// Redraw board
draw();
AIButton.setEnabled(false);
playButton.setEnabled(true);
// Is the game over?
if (nim.isOver()) {
JOptionPane.showMessageDialog(null, "You win!");
playButton.setEnabled(false);
}
}
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
NimApp a = new NimApp();
}
}
The support class:
package nimapp;
import java.util.Random;
import javax.swing.JOptionPane;
import java.io.*;
import java.lang.*;
public class NimGame {
int x = 1;
int[] Sticks; //creating an array of sticks
int totalSticks = 0;
public NimGame(int[] initialSticks){
Sticks = initialSticks;}
public int getRow(int r){
return Sticks[r];}
public void play(int r, int s) throws IllegalSticksException {
try {
Sticks[r]=Sticks[r]-s;
if(s < 0 || s > 3)
throw new IllegalSticksException();
} catch (IllegalSticksException ex){
JOptionPane.showMessageDialog(null, "Not a valid row!");
} catch (IndexOutOfBoundsException e){
JOptionPane.showMessageDialog(null, "Too Many Sticks!");
}
}
public boolean isOver(){
int theTotal = 0;
for (int i = 0; i< Sticks.length; i++){
theTotal = Sticks[i];
System.out.println(Sticks[i]);
System.out.println(theTotal);
}
totalSticks = theTotal;
if (totalSticks <= 0){
return true;
}
else return false;
}
public void AIMove(){
Random randomInt = new Random ();
boolean tryRemove = true;
while(tryRemove && totalSticks >= 1){
int RandomRow = randomInt.nextInt(3);
if(Sticks[RandomRow] <= 0)//the computer can't remove from this row
continue;
//the max number to remove from row
int size = 3;
if( Sticks[RandomRow] < 3)//this row have least that 3 cards
size = Sticks[RandomRow];//make the max number to remove from the row be the number of cards on the row
int RandomDiscard = randomInt.nextInt(size) + 1;
Sticks[RandomRow] = Sticks[RandomRow] - RandomDiscard;
//I don't know if this is needed, but since we remove a RandomDiscard amount lest decrease the totalSticks
totalSticks = totalSticks - RandomDiscard;
//exit loop
tryRemove = false;
}
if(totalSticks <= 1){
int RandomRow = 0;
Sticks[RandomRow] = Sticks[RandomRow]-1;
isOver();
}
}
}
My issue is I really don't understand the syntax.
There is nothing wrong with the syntax as you have written it.
The problem is that you are catching the exception at the wrong place. You are (apparently) intending play to propagate the IllegalSticksException to its caller. But that won't happen because you are catching it within the play method.
There are two possible fixes depending on what you actually intent to happen.
You could remove the throws IllegalSticksException from the play signature.
You could remove the catch (IllegalSticksException ex){ ... } in play and catch/handle the exception at an outer level.
Related
I have a created a simple tic tac toe GUI GAME. I want to extend it by changing what is displayed on the buttons from just text "X" and "O" to fancy graphic "X" and "O" (by providing jpg or png files) and also add sounds using .wav files.
This is my code for my game: (It works perfectly.. I just need help with the extensions.. Thanks)
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class TicTacToeGUI implements ActionListener
{
//Class constants
private static final int WINDOW_WIDTH = 300;
private static final int WINDOW_HEIGHT = 300;
private static final int TEXT_WIDTH = 30;
private static final String PLAYER_X = "X"; // player using "X"
private static final String PLAYER_O = "O"; // player using "O"
private static final String EMPTY = ""; // empty cell
private static final String TIE = "T"; // game ended in a tie
private String player; // current player (PLAYER_X or PLAYER_O)
private String winner; // winner: PLAYER_X, PLAYER_O, TIE, EMPTY = in progress
private int numFreeSquares; // number of squares still free
private JMenuItem resetItem; // reset board
private JMenuItem quitItem; // quit
private JLabel gameText; // current message
private JButton board[][]; // 3x3 array of JButtons
private JFrame window = new JFrame("TIC-TAC-TOE");
/**
* Constructs a new Tic-Tac-Toe GUI board
*/
public TicTacToeGUI()
{
setUpGUI(); // set up GUI
setFields(); // set up other fields
}
/**
* Set up the non-GUI fields
*
*/
private void setFields()
{
winner = EMPTY;
numFreeSquares = 9;
player = PLAYER_X;
}
/**
* reset the game so we can start again.
*
*/
private void resetGame()
{
// reset board
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
board[i][j].setText(EMPTY);
board[i][j].setEnabled(true);
}
}
gameText.setText("Game in Progress: X's turn");
// reset other fields
setFields();
}
/**
* Action Performed (from actionListener Interface).
* (This method is executed when a button is selected.)
*
* #param the action event
*/
public void actionPerformed(ActionEvent e)
{
// see if it's a menu item
if(e.getSource() instanceof JMenuItem)
{
JMenuItem select = (JMenuItem) e.getSource();
if (select==resetItem)
{
resetGame();// reset
return;
}
System.exit(0); // must be quit
}
// it must be a button
JButton chose = (JButton) e.getSource(); // set chose to the button clicked
chose.setText(player); // set its text to the player's mark
chose.setEnabled(false); // disable button (can't choose it now)
numFreeSquares--;
//see if game is over
if(haveWinner(chose))
{
winner = player; // must be the player who just went
}
else if(numFreeSquares==0)
{
winner = TIE; // board is full so it's a tie
}
// if have winner stop the game
if (winner!=EMPTY)
{
disableAll(); // disable all buttons
// print winner
String s = "Game over: ";
if (winner == PLAYER_X)
{
s += "X wins";
}
else if (winner == PLAYER_O)
{
s += "O wins";
}
else if (winner == TIE)
{
s += "Tied game";
}
gameText.setText(s);
}
else
{
// change to other player (game continues)
if (player==PLAYER_X)
{
player=PLAYER_O;
gameText.setText("Game in progress: O's turn");
}
else
{
player=PLAYER_X;
gameText.setText("Game in progress: X's turn");
}
}
}
/**
* Returns true if filling the given square gives us a winner, and false
* otherwise.
*
* #param Square just filled
*
* #return true if we have a winner, false otherwise
*/
private boolean haveWinner(JButton c)
{
// unless at least 5 squares have been filled, we don't need to go any further
// (the earliest we can have a winner is after player X's 3rd move).
if(numFreeSquares>4)
{
return false;
}
// find the square that was selected
int row=0, col=0;
outerloop: // a label to allow us to break out of both loops
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if (c==board[i][j])
{
// object identity
row = i;
col = j; // row, col represent the chosen square
break outerloop; // break out of both loops
}
}
}
// check row "row"
if( board[row][0].getText().equals(board[row][1].getText()) && board[row][0].getText().equals(board[row][2].getText()) )
{
return true;
}
// check column "col"
if (board[0][col].getText().equals(board[1][col].getText()) &&board[0][col].getText().equals(board[2][col].getText()) )
{
return true;
}
// if row=col check one diagonal
if (row == col)
{
if( board[0][0].getText().equals(board[1][1].getText()) && board[0][0].getText().equals(board[2][2].getText()) )
{
return true;
}
}
// if row=2-col check other diagonal
if (row == 2-col)
{
if( board[0][2].getText().equals(board[1][1].getText()) && board[0][2].getText().equals(board[2][0].getText()) )
{
return true;
}
}
// no winner yet
return false;
}
/**
* Disables all buttons (game over)
*/
private void disableAll()
{
if (numFreeSquares==0)
{
return; // nothing to do
}
int i, j;
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
board[i][j].setEnabled(false);
}
}
}
/**
* Set up the GUI
*
*/
private void setUpGUI()
{
// for control keys
final int SHORTCUT_MASK = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
window.setSize(WINDOW_WIDTH,WINDOW_HEIGHT);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// set up the menu bar and menu
JMenuBar menubar = new JMenuBar();
window.setJMenuBar(menubar); // add menu bar to our frame
JMenu fileMenu = new JMenu("Game"); // create a menu called "Game"
menubar.add(fileMenu); // and add to our menu bar
resetItem = new JMenuItem("Reset"); // create a menu item called "Reset"
fileMenu.add(resetItem); // and add to our menu (can also use ctrl-R:)
resetItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R, SHORTCUT_MASK));
resetItem.addActionListener(this);
quitItem = new JMenuItem("Quit"); // create a menu item called "Quit"
fileMenu.add(quitItem); // and add to our menu (can also use ctrl-Q:)
quitItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, SHORTCUT_MASK));
quitItem.addActionListener(this);
window.getContentPane().setLayout(new BorderLayout()); // default so not required
JPanel gamePanel = new JPanel();
gamePanel.setLayout(new GridLayout(3, 3));
window.getContentPane().add(gamePanel, BorderLayout.CENTER);
gameText = new JLabel("Game in Progress: X's turn");
window.getContentPane().add(gameText, BorderLayout.SOUTH);
// create JButtons, add to window, and action listener
board = new JButton[3][3];
Font font = new Font("Dialog", Font.BOLD, 24);
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
board[i][j] = new JButton(EMPTY);
board[i][j].setFont(font);
gamePanel.add(board[i][j]);
board[i][j].addActionListener(this);
}
}
window.setVisible(true);
}
}
To assign an image to a JButton you can either use constructor or a method below:
JButton myButton = new JButton(new ImageIcon("D:\\icon.png"));
setIcon(new ImageIcon("D:\\icon.png"));
Of course provide your own file path.
To play some .wav sounds you can use this:
import java.io.File;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
public class MusicPlayer {
private Clip clip;
public void play() {
try {
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(new File("D:\\sound.wav").getAbsoluteFile());
clip = AudioSystem.getClip();
clip.open(audioInputStream);
clip.start();
}
catch(Exception ex) {
System.out.println("Error with playing sound.");
ex.printStackTrace();
}
}
}
I'm making a program for practice and it's basically simulating winning/losing Powerball tickets. Anyways, the main class is in launchPowerBall.java and the button that I am trying to detect when clicked is in PowerBallGUI.java. The button works by itself, however, the main in launchPowerBall.java isn't able to detect it even though I set up myself a few setters and getters. Any clue what alternative I can do instead? Because it seems as though even though I run it through a while(true) loop and I keep pressing the button, there seems to be no detection from the main method.
Here's the action listener for the JButton:
start.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// If the button is pressed, delete text field and replace with new content
setButtonPressed(true);
outputText.setText("");
outputText.setText(outText);
}
});
Here's what I'm trying to do for the main method:
public static void main(String[] args) throws InterruptedException {
// Build the GUI object
PowerBallGUI GUI = new PowerBallGUI();
GUI.buildGUI();
//GUI.setTextArea("banana");
// Build the PowerBall object
PowerBall roll = new PowerBall();
while(true) {
if (GUI.getJButton().getModel().isPressed()) {
System.out.println("TEST");
}
}
}
Here's the three files if you need to see my code:
1) https://gist.github.com/anonymous/e5950413470202cd1ac6d24e238ff693
2) https://gist.github.com/anonymous/773e4e4454a79c057da78eed038fade1
3) https://gist.github.com/anonymous/82335e634c1f84607d3021b4d683cc65
Powerball...
public class PowerBall {
private int[] numbers = {0, 0, 0, 0, 0};
private int[] lotteryNumbers = {0, 0, 0, 0, 0};
private int powerBall;
private int lotteryPowerBall;
private double balance;
private double winnings;
/*** Constructor Methods ***/
public PowerBall() {
powerBall = 0;
balance = 1000;
winnings = 0;
}
/*** Mutator Methods ***/
public void randomize() {
int i;
int highestNumber = 59;
int highestPowerball = 32;
int temp = 0;
for (i = 0; i < numbers.length; i++) {
// Choose a random number
temp = (int)(Math.random() * highestNumber);
numbers[i] = temp;
}
// Choose a random Powerball number
powerBall = (int)(Math.random() * highestPowerball);
// Choose the lottery numbers
for (i = 0; i < lotteryNumbers.length; i++) {
temp = (int)(Math.random() * highestNumber);
lotteryNumbers[i] = temp;
}
lotteryPowerBall = (int)(Math.random() * highestPowerball);
}
public void calculate() {
int matches = 0;
int powerballMatches = 0;
if (balance > 0) {
// Check to see if there are any matches between the two sets of numbers
for (int i = 0; i < numbers.length; i++) {
for (int j = 0; j < lotteryNumbers.length; j++) {
if (numbers[i] == lotteryNumbers[j]) {
matches++;
}
}
}
// Check to see if the two different powerball numbers match
if (powerBall == lotteryPowerBall) {
powerballMatches = 1;
}
// Calculate the balance/winnings if there were any matches
if (matches == 0 && powerballMatches == 0) {
balance = balance - 2;
winnings = winnings - 2;
} else if (matches == 0 && powerballMatches == 1) {
balance = balance + 4;
winnings = winnings + 4;
} else if (matches == 0 && powerballMatches == 0 || matches == 1 && powerballMatches == 0) {
balance = balance - 2;
winnings = winnings - 2;
} else if (matches == 2 && powerballMatches == 1) {
balance = balance + 7;
winnings = winnings + 7;
} else if (matches == 3 && powerballMatches == 0) {
balance = balance + 7;
winnings = winnings + 7;
} else if (matches == 3 && powerballMatches == 1) {
balance = balance + 100;
winnings = winnings + 100;
} else if (matches == 4 && powerballMatches == 0) {
balance = balance + 100;
winnings = winnings + 100;
} else if (matches == 4 && powerballMatches == 1) {
balance = balance + 50000;
winnings = winnings + 50000;
} else if (matches == 5 && powerballMatches == 0) {
balance = balance + 1000000;
winnings = winnings + 1000000;
} else if (matches == 5 && powerballMatches == 1) {
balance = balance + 10000000;
winnings = winnings + 10000000;
}
//System.out.println("There is currently " + matches + " number matches.");
//System.out.println("There is currently " + powerballMatches + " powerball number matches.\n");
} else {
System.out.println("YOU ARE BROKE!");
}
}
/*** Accessor/Observor Methods ***/
public void displayBalance() {
System.out.print("Your balance is at: $");
System.out.printf("%.2f", balance);
}
public void displayWinnings() {
System.out.print("\nYou have currently won: $");
System.out.printf("%.2f", winnings);
System.out.println("\n");
}
public String toString() {
StringBuilder builder = new StringBuilder();
StringBuilder builder2 = new StringBuilder();
if (numbers.length == lotteryNumbers.length) {
for (int i = 0; i < numbers.length; i++) {
if (i < numbers.length - 1) {
builder.append(numbers[i] + ", ");
builder2.append(lotteryNumbers[i] + ", ");
} else {
builder.append(numbers[i] + " + ");
builder2.append(lotteryNumbers[i] + " + ");
}
}
} else {
return "ERROR: Numbers max set of numbers doesn't match Lottery Numbers max set of numbers!\n";
}
return "Your set of numbers were: " + builder + Integer.toString(powerBall) +
"\nThe powerball numbers were: " + builder2 + lotteryPowerBall;
}
}
Launcher
public class launchPowerBall {
public static void main(String[] args) throws InterruptedException {
// Build the GUI object
PowerBallGUI GUI = new PowerBallGUI();
GUI.buildGUI();
//GUI.setTextArea("banana");
// Build the PowerBall object
PowerBall roll = new PowerBall();
while(true) {
if (GUI.getJButton().getModel().isPressed()) {
System.out.println("TEST");
}
}
//System.out.println("TOO LATE!");
//while (true) {
/*roll.randomize();
System.out.println(roll.toString());
roll.calculate();
roll.displayBalance();
roll.displayWinnings();
Thread.sleep(500); */
//}
}
}
GUI
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.Window;
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.JTextArea;
import javax.swing.SwingConstants;
public class PowerBallGUI {
private JButton start = new JButton("Launch the Powerball!");
private boolean buttonPressed = false;
private String outText;
/*** Constructor Methods ***/
public PowerBallGUI() {
#SuppressWarnings("unused")
JTextArea outputText = new JTextArea("Press the 'Launch the Powerball' button to start!");
}
/*** Setters ***/
/*** Sets the JTextArea object ***/
public void setTextArea (String str) {
this.outText = str;
}
public void setButtonPressed (Boolean bool) {
this.buttonPressed = bool;
}
/*** Getters ***/
public Boolean getButtonPressed() {
return this.buttonPressed;
}
public JButton getJButton() {
return this.start;
}
/*** Builds the GUI ***/
public void buildGUI() {
// Create the Java Frame itself
JFrame frame = new JFrame("Can YOU win the Powerball? v1.0 (Programmed by: Josh Yang)");
// Sets the default close operation of the frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Sets the size of the frame
frame.setSize(800, 500);
// Sets the location of the frame
centerGUI(frame);
// Allows the frame to be seen
frame.setVisible(true);
// Disables frame resizing
//frame.setResizable(false);
// Create the Java Panel itself
JPanel panel = new JPanel();
JPanel contentPanel = new JPanel();
JPanel launchPanel = new JPanel();
// Sets the sides of the Java panels
panel.setSize(800, 150);
// Set the panel background color
panel.setBackground(Color.YELLOW);
contentPanel.setBackground(Color.YELLOW);
launchPanel.setBackground(Color.PINK);
// Add the panel onto the frame
frame.add(panel, "North");
frame.add(contentPanel, BorderLayout.CENTER);
frame.add(launchPanel, BorderLayout.SOUTH);
// Set top panel's preferred size dimensions
panel.setPreferredSize(new Dimension(800, 100));
// Adds components onto the panel
JLabel title = new JLabel("Can YOU win the lottery? v1.0", SwingConstants.CENTER);
title.setFont(new Font("Serif", Font.BOLD, 25));
panel.add(title);
String text = "Basically, we start you off at $1000 and buy tickets in increments of $2 until you win big (if you do, that is)!";
JLabel description = new JLabel();
description.setText(text);
description.setFont(new Font("Serif", Font.PLAIN, 16));
panel.add(description);
// ContentPanel area
JLabel cDescription = new JLabel("Output: ");
contentPanel.add(cDescription);
JTextArea outputText = new JTextArea(17, 60);
outputText.setBackground(Color.PINK);
outputText.setEditable(false);
outputText.setText("Press the 'Launch the Powerball' button to start!");
contentPanel.add(outputText);
start.setLocation(100, 100);
launchPanel.add(start);
// Add an action listener to the JButton
start.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// If the button is pressed, delete text field and replace with new content
setButtonPressed(true);
outputText.setText("");
outputText.setText(outText);
}
});
frame.revalidate();
//frame.pack();
}
/*** Centers the GUI based on screen size ***/
public static void centerGUI(Window frame) {
// Gets the size of the screen
Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
int x = (int) ((dimension.getWidth() - frame.getWidth()) / 2);
int y = (int) ((dimension.getHeight() - frame.getHeight()) / 2);
// Set the frame location based on x and y
frame.setLocation(x, y);
}
}
The simple solution is to take the functionality you're "trying" to execute in the main method and put in the ActionListener...
start.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// If the button is pressed, delete text field and replace with new content
PowerBall roll = new PowerBall();
roll.randomize();
System.out.println(roll.toString());
roll.calculate();
roll.displayBalance();
roll.displayWinnings();
setButtonPressed(true);
outputText.setText("");
outputText.setText(outText);
}
});
If you "really" want to do more work in the main, you will need to generate some kind of observer pattern which can notified when something occurs.
You could put one on Powerball so it could notify you of a status change or on the GUI which notify you that the start button was pressed
First time user here, so please bear with me...I want to create a code that asks the user for the number of rows and columns they want to create multiplication table, but I honestly don't know where to go from here...Can someone help? I'd like for some specifics...such as...create a for loop here for this purpose...
sorry if my code is not formatted correctly...this is what i have so far..it correctly asks the user for a number of rows and columns and displays those rows and columns..I want to make it so once the user clicks a button at a certain intersection, the answer will be displayed.
For example: the first button when clicked will display "1*1=1"
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Scanner;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class SquareGrid {
private int rowCount;
private int colCount;
public SquareGrid(int rowCount, int colCount){
this.rowCount=rowCount;
this.colCount= colCount;
}
JFrame theFrame;
JButton[][] buttons;
JPanel panel;
private void createAndShowGui(){
theFrame = new JFrame ("grid");
buttons = new JButton[rowCount][colCount];
panel = new JPanel();
panel.setLayout(new GridLayout(rowCount, colCount));
for(int rowCounter = 0; rowCounter < rowCount; rowCounter++)
for(int colCounter = 0; colCounter < colCount; colCounter++){
final JButton j = new JButton("not clicked");
j.setActionCommand((rowCount + 1) * (colCount + 1) + "");
j.addActionListener(new ActionListener(){
boolean clicked = false;
#Override
public void actionPerformed(ActionEvent event) {
if(clicked == false) clicked = true;
else clicked = false;
if (clicked) {
j.setText(j.getActionCommand());
}
}
});
String event;
buttons[rowCounter][colCounter] = j;
panel.add(j);
}
theFrame.add(panel);
theFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
theFrame.pack();
theFrame.setVisible(true);
}
public static void main(String[] args){
Scanner input = new Scanner(System.in);
System.out.println("Enter number of rows");
int rowCount=input.nextInt();
Scanner input1=new Scanner(System.in);
System.out.println("Enter number of columns");
int colCount=input1.nextInt();
SquareGrid h = new SquareGrid(colCount,rowCount);
h.createAndShowGui();
}
}
I want to make it so once the user clicks a button at a certain intersection, the answer will be displayed.
For example: the first button when clicked will display "1*1=1"
You can set the actionCommand in your loop, with the multiplication already done from your loop count.
final JButton j = new JButton("not clicked");
j.setActionCommand((rowCounter + 1) * (colCounter + 1) + "");
Then just use that actionCommand
if (clicked) {
j.setText(j.getActionCommand());
UPDATE
Not sure what you changed, but try this
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Scanner;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class SquareGrid {
private int rowCount;
private int colCount;
public SquareGrid(int rowCount, int colCount) {
this.rowCount = rowCount;
this.colCount = colCount;
}
JFrame theFrame;
JButton[][] buttons;
JPanel panel;
private void createAndShowGui() {
theFrame = new JFrame("grid");
buttons = new JButton[rowCount][colCount];
panel = new JPanel();
panel.setLayout(new GridLayout(rowCount, colCount));
for (int rowCounter = 0; rowCounter < rowCount; rowCounter++) {
for (int colCounter = 0; colCounter < colCount; colCounter++) {
final JButton j = new JButton("not clicked");
j.setActionCommand((rowCounter + 1) * (colCounter + 1) + "");
j.addActionListener(new ActionListener() {
boolean clicked = false;
#Override
public void actionPerformed(ActionEvent event) {
if(clicked == false) clicked = true;
else clicked = false;
if (clicked) {
j.setText(j.getActionCommand());
} else {
j.setText("not clicked");
}
}
});
buttons[rowCounter][colCounter] = j;
panel.add(j);
JButton buttonClicked = (j); //THIS WAS ADDED
}
}
theFrame.add(panel);
theFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
theFrame.pack();
theFrame.setVisible(true);
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Enter number of rows");
int rowCount = input.nextInt();
Scanner input1 = new Scanner(System.in);
System.out.println("Enter number of columns");
int colCount = input1.nextInt();
SquareGrid h = new SquareGrid(colCount, rowCount);
h.createAndShowGui();
}
}
When a button is clicked, you can tell which button has been clicked by getting it from the event:
JButton buttonClicked = (JButton) event.getSource();
All you need to do now is to find the row and the column of this button inside your 2D array of buttons, and to compute the multiplication.
PS: you don't even have to use event.getSource() to get the button, since you already have the j variable referencing this button.
EDIT:the row and columns are available from the outside variables, which simply need to be made final:
for(int rowCounter = 0; rowCounter < rowCount; rowCounter++)
for(int colCounter = 0; colCounter < colCount; colCounter++){
final JButton j = new JButton("not clicked");
final int row = rowCounter;
final int col = colCounter;
// now you can use row and col inside your listener.
John Hurley's CS202 class ROFL -John Hurley's CS202 class ROFL
Program is 10x10 board, I need to check if the user's input is a duplicate of any number in that same column, but I can't figure it out. When I tried it, it always check the same box. For example, if I entered 4 in [1][1] (going by 10x10 grid), it automatically checks right after I entered that [1][1] is the same as my input and erases it. My professor wants me to check it with the "CheckWinner" method. This is my code so far in my eventhandler:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package firstgui;
import java.awt.event.*;
import java.util.Scanner;
import javax.swing.*;
/**
*
* #author douglas moody
*/
public class EventHandler implements ActionListener{
// EventBoard is the name of the array containing all the JButton withi teh EventHandler
// board (in the other program) is the name of the array containing all the JButton withi the FirstGui program
JButton[][] EventBoard;
private static String player = " ";
// this method is called from FirstGui to tell the Eventhandler the board array
public void setEventBoard (JButton[][] inboard){
EventBoard = inboard;
}
public void actionPerformed(ActionEvent e) {
JButton clickedbutton;
// clickedbutton will now point to the Button actually clicked
clickedbutton = (JButton) e.getSource();
player = JOptionPane.showInputDialog("Enter a number from 1-10");
if(player.matches("[1-9]|10")){
clickedbutton.setText(player);
}else{
JOptionPane.showMessageDialog(null, "Invalid Input", "Invalid Input", JOptionPane.ERROR_MESSAGE);
}
// call the routine to check if the player who just moved won
if (CheckWinner(player)){
JOptionPane.showMessageDialog(null, "Player: " + player + " won");
}
}
private boolean CheckWinner(String inplayer) {
int count = 0, count2 = 0;
// this loop checks the columns on the Board
for (int i=0; i<=9; i++){
for (int j=0; j<=9; j++) {
if (EventBoard[i][j].getText().equals( inplayer )){
JOptionPane.showMessageDialog(null, "copy");
EventBoard[i][j].setText("");
}
}
if (count == 10 && count2 == 10) return true;
}
return false;
}
}
Pass the reference the JButton that triggered the action to the CheckWinner method and simply ignore it when performing you checks...
For example...
private boolean CheckWinner(JButton source, String inplayer) {
//...
if (EventBoard[i][j] != source &&
EventBoard[i][j].getText().equals( inplayer )){
JOptionPane.showMessageDialog(null, "copy");
EventBoard[i][j].setText("");
}
Updated...
To check the values in a given column, you need to know which column to check. I've not tested this, but something like the example below, should help...
private boolean CheckWinner(JButton source, String inplayer) {
int buttonColumn = -1;
for (int col = 0; col < EventBoard.length; col++) {
for (JButton item : EventBoard[col]) {
if (item == source) {
buttonColumn = col;
break;
}
}
}
boolean match = false;
for (JButton item : EventBoard[buttonColumn]) {
if (source != item && item.getText().equals(inplayer)) {
match = true;
break;
}
}
return match;
}
I'm having some trouble getting a JButton to update repeatedly (used with a timer) in a do-while loop. I'm working on a simple game, played on a 10 * 10 grid of tile objects which correspond to a JButton arrayList with 100 buttons.
This part of the program handles simple pathfinding (i.e. if I click on character, then an empty tile, the character will move through each tile on its way to the destination). There is a delay between each step so the user can see the character's progress.
In the current state of things, the movement is correct, but the JButton is only updated when the character reaches the destination, not on intermediate steps.
public void move(int terrainTile)
{
int currentPosition = actorList.get(selectedActor).getPosition();
int movementValue = 0;
int destination = terrainTile;
int destinationX = destination / 10;
int destinationY = destination % 10;
do
{
currentPosition = actorList.get(selectedActor).getPosition(); // Gets PC's current position (before move)
System.out.println("Old position is " + currentPosition);
int currentX = currentPosition / 10;
int currentY = currentPosition % 10;
if(actorList.get(selectedActor).getCurrentAP() > 0)
{
movementValue = 0;
if(destinationX > currentX)
{
movementValue += 10;
}
if(destinationX < currentX)
{
movementValue -= 10;
}
if(destinationY > currentY)
{
movementValue += 1;
}
if(destinationY < currentY)
{
movementValue -= 1;
}
int nextStep = currentPosition + movementValue;
myGame.setActorIdInTile(currentPosition, -1); //Changes ActorId in PC current tile back to -1
scrubTiles(currentPosition);
actorList.get(selectedActor).setPosition(nextStep); // Sets new position in actor object
System.out.println("Actor " + selectedActor + " " + actorList.get(selectedActor).getName() + " position has been updated to " + nextStep);
myGame.setActorIdInTile(nextStep, selectedActor); // Sets ActorId in moved to Tile
System.out.println("Tile " + nextStep + " actorId has been updated to " + selectedActor);
buttons.get(nextStep).setIcon(new ImageIcon(actorList.get(selectedActor).getImageName()));
// If orthagonal move AP-4
if(movementValue == 10 || movementValue == -10 || movementValue == 1 || movementValue == -1)
{
actorList.get(selectedActor).reduceAP(4);
}
// If diagonal move AP-6
else
{
actorList.get(selectedActor).reduceAP(6);
}
System.out.println(actorList.get(selectedActor).getName() + " has " + actorList.get(selectedActor).getCurrentAP() + " AP remaining");
try
{
Thread.sleep(500); // one second
}
catch (Exception e){}
buttons.get(nextStep).repaint();
}
else
{
System.out.println(actorList.get(selectedActor).getName() + " has insufficient AP to move");
break;
}
}while(destination != (currentPosition + movementValue));
What I've tried:
buttons.get(nextStep).repaint(); (Tried putting a command to repaint the button after setting the imageIcon. No change.
buttons.get(nextStep).revalidate(); (No 100% sure what this does - it came up as a potential solution, but doesn't work.
Steps 1 & 2 combined
Looked into the swing timer class - movement doesn't occur everytime an actionEvent is fired, (only if character is selected and target tile is empty) so not sure how I could get this to work
Any help would be greatly appreciated!
I really dont' know exactly what you wanted to know in your comments, though +1 to the answer above, seems to me that's the real cause. Have a look at this example program, simply add your call to the move(...) method inside the timerAction, seems like that can work for you. Here try this code :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GridExample
{
private static final int SIZE = 36;
private JButton[] buttons;
private int presentPos;
private int desiredPos;
private Timer timer;
private Icon infoIcon =
UIManager.getIcon("OptionPane.informationIcon");
private ActionListener timerAction = new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
buttons[presentPos].setIcon(null);
if (desiredPos < presentPos)
{
presentPos--;
buttons[presentPos].setIcon(infoIcon);
}
else if (desiredPos > presentPos)
{
presentPos++;
buttons[presentPos].setIcon(infoIcon);
}
else if (desiredPos == presentPos)
{
timer.stop();
buttons[presentPos].setIcon(infoIcon);
}
}
};
public GridExample()
{
buttons = new JButton[SIZE];
presentPos = 0;
desiredPos = 0;
}
private void createAndDisplayGUI()
{
JFrame frame = new JFrame("Grid Game");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel contentPane = new JPanel();
contentPane.setLayout(new GridLayout(6, 6, 5, 5));
for (int i = 0; i < SIZE; i++)
{
final int counter = i;
buttons[i] = new JButton();
buttons[i].setActionCommand("" + i);
buttons[i].addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
desiredPos = Integer.parseInt(
(String) buttons[counter].getActionCommand());
timer.start();
}
});
contentPane.add(buttons[i]);
}
buttons[presentPos].setIcon(infoIcon);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
timer = new Timer(1000, timerAction);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new GridExample().createAndDisplayGUI();
}
});
}
}
This is because you are doing your do { } while in the UI thread. To solve this, you should use a SwingWorker, or a javax.swing.Timer