Reputation: 45
I know this has been answered serveral times, but I can't seem to find a solution to my problem. I'm trying to create a very, very basic game for myself but I am having issues defining the variable "cash" inside of the button click. My code is:
public Main() {
final int cash = 1000000;
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
JLabel lblCash = new JLabel("Cash: " + cash);
lblCash.setBounds(10, 11, 166, 14);
contentPane.add(lblCash);
JButton btnStake = new JButton("STAKE");
btnStake.setBounds(258, 227, 166, 23);
contentPane.add(btnStake);
final JLabel lblwol = new JLabel("");
lblwol.setBounds(10, 115, 414, 14);
contentPane.add(lblwol);
sa = new JTextField();
sa.setBounds(10, 228, 238, 20);
contentPane.add(sa);
sa.setColumns(10);
btnStake.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
String stringAmmount = sa.getText().toString();
int ammount = Integer.parseInt(stringAmmount);
sa.setText("");
double comp = Math.random();
if (comp < 0.5){
lblwol.setText("Congratulations, you have won: " + ammount);
cash = cash - ammount;
} else {
lblwol.setText("Sorry, you have lost: " + ammount);
}
}
});
}
Upvotes: 1
Views: 939
Reputation: 31689
It appears to me that cash
should not be final
, and you made it final
because the compiler told you that you couldn't say cash = cash - ammount
because the variable cash
was not final
. However, making it final
won't work because then you can't modify the value. Is that what happened?
In Java, when a method contains a statement that creates an anonymous class (as you've done with new ActionListener
), it can't refer to the method's local variables, unless they are final
. (This was a language design decision. C# and JavaScript, which have similar constructs, don't have this restriction.) Here you have a constructor, which isn't really a method, but it behaves like a method. There are two ways around this:
1) Make the variable an instance field, instead of a local variable. Thus, you'd say int cash = 1000000
outside the constructor.
This is an appropriate solution when you could only have one such variable per object. It's also appropriate in your case, since you have cash
inside a constructor. The constructor can't be called more than once per object, so there can be only one cash
for an object.
However, there are cases where this won't work, where the variable is declared inside a method rather than a constructor. Suppose you have a method that creates a new button, and it's possible that multiple buttons will be created with multiple calls to this method, and each new button will have its own listener, each with its own variable that it modifies. Now having just one instance variable for the object won't work. So another way to work around the final
problem is:
2) Make the variable a field inside some other object. You could declare a very simple class that just holds a cash
field:
private static class Wallet { // a Wallet holds cash, hee hee hee
public int cash;
public Wallet(int cash) { this.cash = cash; }
}
and in your method
final Wallet wallet = new Wallet(1000000);
Now the anonymous class can refer to wallet
, because it's final
. But only the reference to the Wallet
object is final, not the fields; so the anonymous class can still modify wallet.cash
. (Another way to create an object is to make it an array of one element. Declaring a new class is more readable, in my opinion.)
I'm mentioning this so that you know how to solve the problem when it comes up--and it does come up fairly frequently. However, in your case, solution 1 is simpler and probably more appropriate.
Upvotes: 0
Reputation: 2102
If you want the value of cash to be changing you should not make it final as it makes it unchanging or constant.
You should make the cash variable an instance variable instead of method local, because usually you want it to live more than the one method call.
public class Main{
// instance variable
int cash = 1000000;
public Main(){
// your logic
}
}
Upvotes: 0
Reputation: 13334
You probably need a constant with initial cash amount and a variable for cash balance (both defined on a class level).
static final int INIT_CASH = 1000000;
int cash = INIT_CASH; // variable intialization
Upvotes: 2