I am making a game which has a store where in game coins can be spent. I want to display the amount of coins you have to spend. This value changes constantly as the game progresses. I have it capable of displaying the initial value and changing with purchases but it will not update from the other class.
Here is my code:
public StoreFrame(Run game,You y) {
super("Store");
theGame=game;
setLayout(null);
you=y;
try {
storeBack = ImageIO.read(new File("backgrounds/store.png"));
}
catch (IOException e) {
}
//background
setContentPane(new JLabel(new ImageIcon(storeBack)));
coins = new JLabel("Coins: "+you.gettotCoins());//here is the problem
coins.setFont(new Font("SanSerif", Font.BOLD, 18));
coins.setForeground(Color.black);
coins.setBounds(25, 25, 100, 100);
add(coins);
setSize (800,600);
setResizable(false);
setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
}
The class the text comes from:
public class You {
private int totCoins;
public You(int p) {
totCoins=110;//starting money
}
public int gettotCoins() {
return totCoins;
}
public void settotCoins(int subtract) {
totCoins-=subtract;
}
}
Please help
Because using design patterns is good practice, you could consider using the Observer pattern. The idea is to make an interface defining one (or more) methods that can be called when something needs to be updated. All classes that are interested in the updates can then implement this interface and the updated subject keeps a list of those observers.
In your case, this means that you could define a
CoinObserver
interface (try to use meaningful names) like this:Next, a list of listeners needs to be kept where your amount of coins is stored. As I assume this is in the
You
class, your class would look as follows using the Observer pattern:Finally, you will have to extend the
JLabel
for your coins to implement this interface as follows and let it "subscribe" itself as aCoinObserver
:Note that this solution will gather a lot of observers, because they are never removed from
you
. This could be solved by overwriting thedispose()
method, but then you should usesetDefaultCloseOperation (JFrame.DISPOSE_ON_CLOSE);
(although I'm not completely sure about that) and keep a field to theYou
in order to use it outside the constructor.This might seem like a lot of work to call
setText("Coins: " + you.getTotCoins())
method as you suggested, but it might be worth the while if your code starts to get more complex. Some of the main advantages might be:label.setText("...")
every time you change the amount of coins, because every time a new value is set for the coins, the observers will be notified.CoinObserver
, implement thecoinsChanged(int newAmount)
method and add it to the list of observers without a need to change anything to your existing code.You
class in your GUI (you only need the Observer-interface i.e.addCoinObserver(co)
andremoveCoinObserver(co)
). Also yourYou
class won't ever know what the observers exactly are, it only knows about the interface ofCoinObserver
. This allows to program towards the MVC model and is generally good practice.and there are probably more. A last thing I would like to note here: if you only change the value of your coins in one place and it is very unlikely that you would be interested in coins anywhere else, you shouldn't be using the observer pattern. Design patterns can help you in all possible ways, but they shouldn't be overused.