I tried .equals() and ==, but nothing help. All labels I storage in ArrayList of my own class, which have JLabel.
How can I get the index of the label in ArrayList or something else?
Can my problem in using ArrayList?
MouseListener
private static MouseListener clicklvl1=new MouseListener() {
#Override
public void mouseClicked(MouseEvent e) {
for (int i=0;i<shahtars.size();i+=1){
if (e.getSource()==shahtars.get(i).uiShahtar){
IDofClickedObject=i;
}
}
if (IDofClickedObject!=-1){
if (counter == 0) {
shahtars.get(IDofClickedObject).uiShahtar.setIcon(new ImageIcon("E:\\aaa\\ShahtarLvL1(Clicked).png"));
counter = 1;
} else if (counter == 1) {
// uiShahtar.setIcon(new ImageIcon("E:\\aaa\\ShahtarLvL1.png"));
shahtars.get(IDofClickedObject).uiShahtar.setIcon(new ImageIcon("E:\\aaa\\ShahtarLvL1.png"));
counter = 0;
}
}
System.out.print("x "+shahtars.get(IDofClickedObject).uiShahtar.getX()+" y "+shahtars.get(IDofClickedObject).uiShahtar.getY());
}
My class
class FillShahtar implements Cloneable {
static JLabel uiShahtar;
static int energy;
static double power;
static double speed;
String name;
And the last
FillShahtar(int chose) {
switch (chose){
case 1:{
plankaDown = 1;
plankaUp = 11;
int xRand = (int) ( 0+Math.random()*1000);
int yRand =(int) (0+Math.random()*600);
int counter=0;
/////////////////////////debug/////////////////
System.out.print(xRand+" "+yRand+"\n");
//////////////////////////////////////////////
energy = (int) (plankaDown + Math.random() * plankaUp );
power = (int) (plankaDown + Math.random() * plankaUp );
speed = (int) (plankaDown + Math.random() * plankaUp );
uiShahtar = new JLabel();
uiShahtar.setIcon(new ImageIcon("E:\\aaa\\ShahtarLvL1.png"));
uiShahtar.setLayout(new FlowLayout());
uiShahtar.setSize(50,50);
uiShahtar.setLocation(xRand,yRand);
uiShahtar.setVisible(true);
uiShahtar.addMouseListener(clicklvl1);
// mainPanel.add(shahtars.get(counter).uiShahtar);
counter+=1;
break;
}
Clicked image must change the image, but change only last Label.
Since JLabel inherits from swing's Component class, you can add a MouseListener (or MouseAdapter) to each of your clickable labels. Using this EventListener you can find the clicked label like this:
JLabel l = new JLabel();
l.addMouseListener(new MouseAdapter() {
#Override
public void mouseReleased(MouseEvent e) {
JLabel clickedLabel = (JLabel) e.getComponent();
}
});
In order to get the index of the clicked label within the ArrayList, use the indexOf(Object) method provided by the ArrayList:
int index = list.indexOf(clickedLabel);
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
With this code, i want to develop a program that enables the user to enter 5 int values into a single textfield. These values will be stored in an array and upon pressing the button, a bar graph will be drawn to represent the entered values. Class BtnHandler handles the button click event and class gegHandler handles the textfield enter event. I can't get the user input to be collected in the array. Here is my code.
package voorbeeld0805;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Vb0805 extends JFrame {
public static void main( String args[] ) {
JFrame frame = new Vb0805();
frame.setSize( 300, 300 );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.setTitle( "Voorbeeld 0805" );
frame.setContentPane( new Tekenpaneel() );
frame.setVisible( true );
}
}
class Tekenpaneel extends JPanel {
private Staafdiagram staafdiagram;
private JButton knopTeken;
private JTextField gegevensVak;
private JLabel lblNo;
private int[] lengtes = new int [5];
public Tekenpaneel() {
setBackground( Color.ORANGE );
knopTeken = new JButton("Teken");
knopTeken.addActionListener(new BtnHandler());
gegevensVak = new JTextField(5);
gegevensVak.addActionListener(new gegHandler());
lblNo = new JLabel("Enter Value");
add(knopTeken);
add (gegevensVak);
add (lblNo);
}
public void paintComponent( Graphics g ) {
super.paintComponent( g );
if (staafdiagram != null)
{
staafdiagram.teken( g, 50, 250 );
}
this.requestFocusInWindow();
}
class BtnHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
//To test using the first constructor. Works perfectly
/*int [] lengtes = { 144, 98, 117, 130, 172, 173 };
staafdiagram = new Staafdiagram( lengtes, 30 );*/
repaint();
}
}
class gegHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
//Here user input should be collected, placed in an array and
//saved in staafdiagram.setLengtes();
for (int i = 0; i < lengtes.length; i++){
lblNo.setText("Next Value Is " + i++);
lengtes[i] = Integer.parseInt( gegevensVak.getText());
gegevensVak.setText("");//clear textfield after entering a value
}
}
}
}
class Staafdiagram {
private int[] lengtes;
private int witruimte;//this generates the spaces between the bars
//First contructor with 2 arguments array en space
public Staafdiagram( int[] lengtes, int witruimte ) {
this.lengtes = lengtes;
this.witruimte = witruimte;
}
//Second constructor with only 1 argument space
public Staafdiagram(int witruimte ) {
this.witruimte = witruimte;
}
//With this, i want the user input to be collected in an array
public void setLengtes(int[] lengtes) {
this.lengtes = lengtes;
}
//To calculate the bar with the highest value
public int bepaalMax(){
int maximum = lengtes [0];
for (int i = 1; i < lengtes.length; i++){
if (lengtes[i] > maximum)
{
maximum = lengtes[i];
}
}
return maximum;
}
//To calculate the bar with the lowest value
public int bepaalMin(){
int minimum = lengtes [0];
for (int i = 1; i < lengtes.length; i++){
if (lengtes[i] < minimum)
{
minimum = lengtes[i];
}
}
return minimum;
}
public void teken( Graphics g, int x, int y ) {
int startX = x;
// Draw the bars
for( int lengte : lengtes ) {
if (lengte == bepaalMax())
g.setColor(Color.red);
else if (lengte == bepaalMin())
g.setColor(Color.green);
else
g.setColor(Color.black);
g.fillRect( x, y - 20 - lengte, 20, lengte );
x += witruimte;
}
// Display the values under the bars
x = startX;
for( int lengte : lengtes ) {
g.drawString( String.format( "%d", lengte ), x, y );
x += witruimte;
}
}
}
If you add an ActionListener on a JTextField, the actionPerformed() method is called when you "action" this field : here is the enter key pressed.
If you want associate the button to your action, you should rather enrich the ActionListener you defined on the JButton to also get the values entered by the user. The idea is chaining the both as both operations should performed one after the other one :
These values will be stored in an array and upon pressing the button,
a bar graph will be drawn to represent the entered values.
class BtnHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
// collection information from textfield
for (int i = 0; i < lengtes.length; i++){
lblNo.setText("Next Value Is " + i++);
lengtes[i] = Integer.parseInt( gegevensVak.getText());
gegevensVak.setText("");//clear textfield after entering a value
}
// rendering
staafdiagram = new Staafdiagram( lengtes, 30 );*/
repaint();
}
}
Get the input from the text field as text
split to string array
Convert to int
MOdify your code as follows.
class BtnHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
//To test using the first constructor. Works perfectly
/*int [] lengtes = { 144, 98, 117, 130, 172, 173 };
staafdiagram = new Staafdiagram( lengtes, 30 );*/
String textInt=gegevensVak .getText(); //gegevensVak is the name of the textfield you mentioned
String[] strArray = textInt.split();
//now convert the string to int and add to a new array
repaint();
}
}
Please Help. When I run this GUI the numbers run off the frame. I know I have to use JTextArea and append but where do I put that in my code. can someone explain to me in simple terms and show me? I want to make it scroll vertically and horizontally and when I do add the JTextArea I get this error: error: cannot find symbol panel.setMessage(message);
import java.io.*;
import java.util.*;
import java.lang.*;
import java.text.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class prime extends JFrame
{
public static void main(String[] args)
{
prime frame = new prime();
}
private JTextArea panel;
private JPanel inPanel;
private JTextField inField;
public prime()
{
final int width = 500;
final int height = 500;
setSize(width, height);
setTitle("Find Prime Numbers");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new JTextArea(20, 10);
add(new JScrollPane(panel), "Center");
inPanel = new JPanel();
inPanel.add(new JLabel("Enter Your Number", SwingConstants.RIGHT));
inField = new JTextField(20);
ActionListener inListener = new TextListener();
inField.addActionListener(inListener);
inPanel.add(inField);
add(inPanel, "South");
setVisible(true);
}
private class TextListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
String message = inField.getText();
inField.setText("");
panel.setMessage(message);
}
}
class TextPanel extends JPanel
{
private String message;
private Color backGroundColor;
public TextPanel()
{
message = "";
backGroundColor = Color.white;
}
public TextPanel(String x, Color background)
{
message = x;
backGroundColor = background;
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
int width = getWidth();
int height = getHeight();
setBackground(backGroundColor);
g2.setColor(Color.black);
Font x = new Font("TimesNewRoman", Font.BOLD,20);
g2.setFont(x);
FontMetrics fm = g2.getFontMetrics(x);
g2.drawString(message,50, 50);
if(!(message.equals("")))
g2.drawString(previousPrime(message),50,78);
}
public void setMessage(String message) {
if (isPrime(Integer.parseInt(message))){
this.message = message + " is a prime number.";
}
else
this.message = message + " is not a prime number.";
repaint();
}
public boolean isPrime(int num){
for(int i = 2; i < num; i++){
if (num % i == 0)
return false;
}
if(num < 2)
return false;
return true;
}
public String previousPrime(String message){
String totalPrimeNum = "";
int finalNum = Integer.parseInt(message.substring(0,message.indexOf(" ")));
int count = 0;
for(int i = 2; i < finalNum; i++){
if(isPrime(i)) {
totalPrimeNum += " " + i;
count++;
}
if(count == 10) {
totalPrimeNum += "\n";
count = 0;
}
}
if (isPrime(Integer.parseInt(message.substring(0,message.indexOf(" ")))))
totalPrimeNum += " " + finalNum;
System.out.println(totalPrimeNum);
return totalPrimeNum;
}}}
Look at what you have and what you want to achieve. You have a method which can verify if a value is a prime or not, but it does not produce any output. You have a JTextArea which allows you to add content to it.
You have a square peg and a round hole. One of these things needs to change. You have control over the setMessage method, but you don't have control over the JTextArea, this would suggest that the setMessage needs to change. While you could pass the JTextArea to the setMessage method, a better solution would be to change the setMessage to return some kind of meaningful value or simply get rid of it in favor of using the isPrime method instead
Take your TestPane and move the functionality used to calculate and test for a prime number to a new class, for example...
public class PrimeCalculator {
public boolean isPrime(int num) {
for (int i = 2; i < num; i++) {
if (num % i == 0) {
return false;
}
}
if (num < 2) {
return false;
}
return true;
}
public String previousPrime(String message) {
StringBuilder totalPrimeNum = new StringBuilder(128);
int finalNum = Integer.parseInt(message.substring(0, message.indexOf(" ")));
int count = 0;
for (int i = 2; i < finalNum; i++) {
if (isPrime(i)) {
totalPrimeNum.append(" ").append(i);
count++;
}
if (count == 10) {
totalPrimeNum.append("\n");
count = 0;
}
}
if (isPrime(Integer.parseInt(message.substring(0, message.indexOf(" "))))) {
totalPrimeNum.append(" ").append(finalNum);
}
System.out.println(totalPrimeNum);
return totalPrimeNum.toString();
}
}
This now makes no assumptions over what you want to do and simply produces output. You can now use these methods and make decisions about how to use the output, for example...
private class TextListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent event) {
PrimeCalculator calc = new PrimeCalculator();
String message = inField.getText();
inField.setText("");
String text = message + " is not a prime number\n";
try {
if (calc.isPrime(Integer.parseInt(message))) {
text = message + " is a prime number\n";
}
} catch (NumberFormatException exp) {
text = message + " is not a valid integer\n";
}
panel.append(message);
panel.setCaretPosition(panel.getDocument().getLength());
}
}
Sometimes, you need to rethink your design to support what it is you want to achieve.
The process of verifying and calculating the prime numbers should do just that, they should not do anything else (like update the screen), this way you can decouple the code and re-use it in different ways which you didn't original think of (like outputting to a file or the web)
See How to Use Text Areas and How to Use Scroll Panes for more details
I'm new to Java and I am having some trouble with my assignment.
I have a Panel containing 100 JLabels:
for(int i=0;i<100;i++)
{
num[i] = new JLabel(""+i, JLabel.CENTER);
mainPanel.add(num[i]);
}
And a button to set image icon for the label when clicked
public void actionPerformed(ActionEvent ae)
{
int a = ran.nextInt(6) +1;//random number
int b +=a;
if(b>=100)
{
b=99;
num[b].setIcon(icon);
}
else
{
num[b].setIcon(icon);
}
}
How can i remove the icon from the last position and update it to a new position?
You can try to remember the index of the array of the label, for which you tried to set the icon.
For example-
int b = 0; // make b an instance variable
public void actionPerformed(ActionEvent ae)
{
int a = ran.nextInt(6) +1;//random number
num[b].setIcon(null); //remove the icon from from previously set label
b=a; //since b already has some value, b+=a might create unexpected result, hence just assigned a
if(b>=100)
{
b=99;
num[b].setIcon(icon);
}
else
{
num[b].setIcon(icon);
}
}
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
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.