if else statement wont work java - java

The question field should contain 36 questions, the answer to these question are on the 36 buttons in the grid.
When the user selects the clicks the correct button answer the button is taken off the grid, the aim is to clear the grid so the grid is empty.
if the user clicks an incorrect button the game restarts.
i am having a problem with adding the question label.
the question field should display 36 question starting with what is 0 + 1 when the user clicks the correct button it then shows
question 2 shows in the field which is what is 1+1 and so till question 36
i have tried to get this by Changing this line of code
gui.statusLabel.setText("what is 0+ 1" + gui.buttonCounter);
to this:
gui.statusLabel.setText("what is " + gui.buttonCounter + "+ 1");
but the games doesnt work properly although the correct answer is selected the code keeps saying doing the "else" in this code ie. Incorrect button clicked, start again: what is 0+ 1
if(clickedNumber == gui.buttonCounter){
gui.buttonCounter++;
buttonClicked.setText("");//optional - clears correct selection
if(gui.buttonCounter > gui.ROWS*gui.COLUMNS) gui.reset();
gui.statusLabel.setText("what is 0+ 1" + gui.buttonCounter);
} else {
gui.reset();
gui.statusLabel.setText("Incorrect button clicked, start again: what is 0+ 1");
}
}
}
how do i fix this? so when i click the correct answer button it moves to the next question and does not display Incorrect button clicked, start again: what is 0+ 1.
full code
class NewClass {
final int ROWS = 6;
final int COLUMNS = 6;
JButton[] buttons = new JButton[ROWS * COLUMNS];
JLabel statusLabel = new JLabel("", JLabel.CENTER);
java.util.List<Integer> buttonNumbers = new ArrayList<Integer>();
int buttonCounter = 1;
public NewClass() {
JPanel buttonPanel = new JPanel(new GridLayout(ROWS, COLUMNS));
ButtonListener listener = new ButtonListener(NewClass.this);
for (int x = 0, y = ROWS * COLUMNS; x < y; x++) {
buttons[x] = new JButton();
buttons[x].addActionListener(listener);
buttonPanel.add(buttons[x]);
buttonNumbers.add(new Integer(x + 1));
}
reset();
JFrame frame = new JFrame();
frame.getContentPane().add(statusLabel, BorderLayout.NORTH);
frame.getContentPane().add(buttonPanel, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public void reset() {
Collections.shuffle(buttonNumbers);
for (int x = 0, y = ROWS * COLUMNS; x < y; x++) {
buttons[x].setText(String.valueOf(buttonNumbers.get(x)));
}
buttonCounter = 1;
statusLabel.setText("Please click button " + buttonCounter);
}
public static void main(String[] args) {
new NewClass();
}
class ButtonListener implements ActionListener {
NewClass gui;
ButtonListener(NewClass g) {
gui = g;
}
public void actionPerformed(ActionEvent e) {
JButton buttonClicked = (JButton) e.getSource();
int clickedNumber = Integer.parseInt(buttonClicked.getText());
if (clickedNumber == gui.buttonCounter) {
gui.buttonCounter++;
buttonClicked.setText("");// optional - clears correct selection
if (gui.buttonCounter > gui.ROWS * gui.COLUMNS)
gui.reset();
// gui.statusLabel.setText("Please click button" +
// gui.buttonCounter);
gui.statusLabel.setText("what is " + buttonCounter);
} else {
gui.reset();
gui.statusLabel
.setText("Incorrect button clicked, start again: 0 + 1");
}
}
}
}

So, taking the code from your previous question and adding
System.out.println("ClickedNumber = " + clickedNumber);
System.out.println("gui.buttonCounter = " + gui.buttonCounter);
Into the actionPerformed method it asks...
"What is 0+1 1" (which should be "What is 0+1"). I click "1", which outputs...
ClickedNumber = 1
gui.buttonCounter = 1
So looking at the if statement;
if (clickedNumber == gui.buttonCounter) {
This is true...
Then it asks...
"What is 2+1". I click "3", which outputs...
ClickedNumber = 3
gui.buttonCounter = 2
So looking at the if statement;
if (clickedNumber == gui.buttonCounter) {
Which is false.
There is a logic error in your code. Basically, it's coming down to you not actually knowing what the question is...
Runnable example
Basically what this does is asks...
"What is " + buttonCounter + "+1"?
In the if condition, we assume the buttonCounter is 0 indexed, meaning we need to increase the comparison by 1
if (clickedNumber == (gui.buttonCounter + 1)) {
Or you could reduce the clickedNumeber by 1
if ((clickedNumber - 1) == gui.buttonCounter) {
Remember, you question is always asks "What's the next number", not what's the current number...
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
class NewClass {
final int ROWS = 6;
final int COLUMNS = 6;
JButton[] buttons = new JButton[ROWS * COLUMNS];
JLabel statusLabel = new JLabel("", JLabel.CENTER);
java.util.List<Integer> buttonNumbers = new ArrayList<Integer>();
int buttonCounter = 1;
public NewClass() {
JPanel buttonPanel = new JPanel(new GridLayout(ROWS, COLUMNS));
ButtonListener listener = new ButtonListener(NewClass.this);
for (int x = 0, y = ROWS * COLUMNS; x < y; x++) {
buttons[x] = new JButton();
buttons[x].addActionListener(listener);
buttonPanel.add(buttons[x]);
buttonNumbers.add(new Integer(x + 1));
}
reset();
JFrame frame = new JFrame();
frame.getContentPane().add(statusLabel, BorderLayout.NORTH);
frame.getContentPane().add(buttonPanel, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public void reset() {
Collections.shuffle(buttonNumbers);
for (int x = 0, y = ROWS * COLUMNS; x < y; x++) {
buttons[x].setText(String.valueOf(buttonNumbers.get(x)));
}
buttonCounter = 0;
statusLabel.setText("Please click button " + buttonCounter + "+1");
}
public static void main(String[] args) {
new NewClass();
}
class ButtonListener implements ActionListener {
NewClass gui;
ButtonListener(NewClass g) {
gui = g;
}
public void actionPerformed(ActionEvent e) {
JButton buttonClicked = (JButton) e.getSource();
int clickedNumber = Integer.parseInt(buttonClicked.getText());
System.out.println("ClickedNumber = " + clickedNumber);
System.out.println("gui.buttonCounter = " + gui.buttonCounter);
if (clickedNumber == (gui.buttonCounter + 1)) {
gui.buttonCounter++;
buttonClicked.setText("");// optional - clears correct selection
if (gui.buttonCounter > gui.ROWS * gui.COLUMNS) {
gui.reset();
}
// gui.statusLabel.setText("Please click button" +
// gui.buttonCounter);
gui.statusLabel.setText("what is " + buttonCounter + "+1");
} else {
gui.reset();
gui.statusLabel
.setText("Incorrect button clicked, start again: 0 + 1");
}
}
}
}
Updated with winner condition
if (clickedNumber == (gui.buttonCounter + 1)) {
if (gui.buttonCounter == (gui.ROWS * gui.COLUMNS) - 1) {
JOptionPane.showMessageDialog(null, "You Win", "Winner", JOptionPane.INFORMATION_MESSAGE);
} else {
gui.buttonCounter++;
buttonClicked.setText("");// optional - clears correct selection
if (gui.buttonCounter > gui.ROWS * gui.COLUMNS) {
gui.reset();
}
// gui.statusLabel.setText("Please click button" +
// gui.buttonCounter);
gui.statusLabel.setText("what is " + buttonCounter + "+1");
}
} else {
gui.reset();
gui.statusLabel
.setText("Incorrect button clicked, start again: 0 + 1");
}

Related

Can't figure out how to code my calculator

I am trying to code a simple calculator like the one you would see in windows (non-scientific). I can not for the life of me figure out how to properly change the text after pressing an operator but still see the original entry that wont change until the next digit is pressed, have the equals key do the same operation if used multiple times (ie: 5+5 = 10 +5 = 15), and when I input a digit that is the same (5+5) it won't accept the second digit. I know I am very close and am probably missing a certain boolean that could allow my code to work properly, but Im not sure where to look. Thanks for any help.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class JCalculator extends JFrame implements ActionListener {
/** intialize the jlabel, jbutton, string that makes the buttons and jpanel that will hold the buttons
*
*/
private JTextField display = new JTextField("0", SwingConstants.RIGHT);
private JPanel buttonPanel = new JPanel();
private JPanel displayPanel = new JPanel();
private JButton newButton, divButton, multiButton, equalsButton, clearButton, plusButton, minusButton;
private String[] arrayButtons = {"7","8", "9", "/", "4", "5", "6", "x", "1", "2", "3", "-", "0","C", "=", "+"};
private int operand = 0;
private int firstInput = 0, secondInput = 0, answer = 0;
JCalculator() {
/** creates the jframe */
JFrame jfrm = new JFrame("Calculator");
/** sets the size of the jfrm and then positions it in the center of screen */
jfrm.setSize(480, 300);
jfrm.setLocationRelativeTo(null);
/** sets the program to close on exit */
jfrm.setDefaultCloseOperation(jfrm.EXIT_ON_CLOSE);
/** ImageIcon img = new ImageIcon(JCalculator.png);
*
*/
/**sets initial layout to border */
jfrm.setLayout(new BorderLayout());
/** makes a panel named display that holds the Jtext display
* enables it and justifies it right
*/
displayPanel.setLayout(new BorderLayout());
displayPanel.add(display, BorderLayout.CENTER);
display.setHorizontalAlignment(JTextField.RIGHT);
display.setEnabled(false);
/** makes a panel for buttons that is a grid layout
*
*/
buttonPanel.setLayout(new GridLayout(4,4));
/** makes a loop to make all of the 16 buttons for the calculator
* the operands all have their own specific buttons
*/
for (int i = 0; i < arrayButtons.length; i++) {
if (arrayButtons[i].equals("/")) {
divButton = new JButton(arrayButtons[i]);
divButton.addActionListener(this);
buttonPanel.add(divButton);
} else if (arrayButtons[i].equals("x")) {
multiButton = new JButton(arrayButtons[i]);
multiButton.addActionListener(this);
buttonPanel.add(multiButton);
} else if (arrayButtons[i].equals("=")) {
equalsButton = new JButton(arrayButtons[i]);
equalsButton.addActionListener(this);
buttonPanel.add(equalsButton);
} else if (arrayButtons[i].equals("C")) {
clearButton = new JButton(arrayButtons[i]);
clearButton.addActionListener(this);
buttonPanel.add(clearButton);
} else if (arrayButtons[i].equals("+")) {
plusButton = new JButton(arrayButtons[i]);
plusButton.addActionListener(this);
buttonPanel.add(plusButton);
} else if (arrayButtons[i].equals("-")) {
minusButton = new JButton(arrayButtons[i]);
minusButton.addActionListener(this);
buttonPanel.add(minusButton);
} else {
newButton = new JButton(arrayButtons[i]);
newButton.addActionListener(this);
buttonPanel.add(newButton);
}
}
/** adds the two panels to the jfrm
* sets jfrm visibility to true
* sets equalsButton to the default button
*/
jfrm.add(displayPanel, BorderLayout.NORTH);
jfrm.add(buttonPanel, BorderLayout.CENTER);
jfrm.getRootPane().setDefaultButton(equalsButton);
jfrm.setVisible(true);
}
public void actionPerformed(ActionEvent ae) {
String s = ae.getActionCommand();
char stringCheck = s.charAt(0);
if (answer == Integer.parseInt(display.getText())) {
display.setText("0");
}
if (Character.isDigit(stringCheck) && display.getText().length() < 8) {
if (display.getText().equals("0")) {
display.setText(s);
} else {
display.setText(display.getText().concat(s));
}
} if (s.equals("+")){
answer = Integer.parseInt(display.getText());
operand = 1;
} if (s.equals( "-")){
answer = Integer.parseInt(display.getText());
operand = 2;
} if (s.equals("x")){
answer = Integer.parseInt(display.getText());
operand = 3;
} if (s.equals("/")){
answer = Integer.parseInt(display.getText());
operand = 4;
} if (s.equals("C")){
firstInput = 0;
secondInput = 0;
answer = 0;
operand = 0;
display.setText("0");
} if (s.equals("=")){
switch(operand){
case 1:
answer += Integer.parseInt(display.getText());
display.setText(Integer.toString(answer));
break;
case 2:
answer -= Integer.parseInt(display.getText());
display.setText(Integer.toString(answer));
break;
case 3:
answer *= Integer.parseInt(display.getText());
display.setText(Integer.toString(answer));
break;
case 4:
if(Integer.parseInt(display.getText()) > 0 || Integer.parseInt(display.getText()) < 0) {
answer /= Integer.parseInt(display.getText());
display.setText(Integer.toString(answer));
break;
} else {
display.setText("Div by 0");
}
}
if(answer > 100000000 || answer < -100000000){
display.setText("Overlow");
}
}
}
public static void main (String [] args){
/**
* run program
*/
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new JCalculator();
}
});
}
}

Main method in different class can't detect button press

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

JLabel and swap the text it holds via the JLabel's setText(...) method

The question field should contain 36 questions, the answer to these question are on the 36 buttons in the grid.
i am having a problem getting question field to display 36 question starting with what is 0 + 1 when the user clicks the correct button it then shows question 2 shows in the field which is what is 1+1 and so till question 36
so how do i get one question JLabel and swap the text it holds via the JLabel's setText(...) method
here is my code
import java.awt.*;
import java.awt.event.*;
import java.awt.event.ActionListener;
import java.util.*;
import javax.swing.*;
class NewClass {
final int ROWS = 6;
final int COLUMNS = 6;
JButton[] buttons = new JButton[ROWS*COLUMNS];
JLabel statusLabel = new JLabel("",JLabel.CENTER);
java.util.List<Integer> buttonNumbers = new ArrayList<Integer>();
int buttonCounter = 1;
public NewClass() {
JPanel buttonPanel = new JPanel(new GridLayout(ROWS,COLUMNS));
ButtonListener listener = new ButtonListener(NewClass.this);
for(int x = 0, y = ROWS*COLUMNS; x < y; x++){
buttons[x] = new JButton();
buttons[x].addActionListener(listener);
buttonPanel.add(buttons[x]);
buttonNumbers.add(new Integer(x+1));
}
reset();
JFrame frame = new JFrame();
frame.getContentPane().add(statusLabel,BorderLayout.NORTH);
frame.getContentPane().add(buttonPanel,BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public void reset(){
Collections.shuffle(buttonNumbers);
for(int x = 0, y = ROWS*COLUMNS; x < y; x++){
buttons[x].setText(String.valueOf(buttonNumbers.get(x)));
}
buttonCounter = 1;
statusLabel.setText("what is 0+ 1 " + buttonCounter);
}
public static void main(String[] args) {
new NewClass();
}
}
class ButtonListener implements ActionListener {
NewClass gui;
ButtonListener(NewClass g){
gui = g;
}
public void actionPerformed(ActionEvent e) {
JButton buttonClicked = (JButton)e.getSource();
int clickedNumber = Integer.parseInt(buttonClicked.getText());
if(clickedNumber == gui.buttonCounter){
gui.buttonCounter++;
buttonClicked.setText("");//optional - clears correct selection
if(gui.buttonCounter > gui.ROWS*gui.COLUMNS) gui.reset();
gui.statusLabel.setText("what is 0+ 1" + gui.buttonCounter);
}
else {
gui.reset();
gui.statusLabel.setText("Incorrect button clicked, start again: what is 0+ 1");
}
}
}
Change one line of code in the action listener. Change this:
gui.statusLabel.setText("what is 0+ 1" + gui.buttonCounter);
to this:
gui.statusLabel.setText("what is " + gui.buttonCounter + "+ 1");
Now it will ask:
what is 0+ 1
what is 1+ 1
what is 2+ 1
what is 3+ 1
..........................................
what is 1937655087345+ 1

Updating JButton on a timer in a do-while loop

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

Java exception handling with multiple classes

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.

Categories