我正在制作一个游戏,其中有一个可以花费游戏币的商店。我想显示你必须花费的硬币数量。随着游戏的进行,这个值会不断变化。我有能力显示初始值并随着购买而变化,但它不会从其他类更新。
这是我的代码:
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);
}
文本来自的类:
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;
}
}
请帮忙
答案 0 :(得分:1)
因为使用设计模式是一种很好的做法,所以可以考虑使用Observer模式。我们的想法是创建一个接口,定义一个(或多个)方法,当需要更新某些内容时可以调用这些方法。然后,对更新感兴趣的所有类都可以实现此接口,并且更新的主题将保留这些观察者的列表。
在您的情况下,这意味着您可以定义CoinObserver
接口(尝试使用有意义的名称),如下所示:
public interface CoinObserver {
void coinsChanged(int newAmount);
}
接下来,需要保存一个监听器列表,以存储您的硬币数量。我假设这是在You
类中,使用Observer模式,您的类看起来如下:
public class You {
private int totCoins;
private Collection<CoinObserver> coinObservers;
public You(int p) {
totCoins=110;
coinObservers = new ArrayList<>(); //or any collection you like
}
public int getTotCoins() {
return totCoins;
}
//Setters turn out to be very useful in this case if used correctly
private void setTotCoins(int newCoins) {
totCoins = newCoins;
coinsChanged();
}
public void subtractCoins(int subtract) {
setTotCoins(totCoins - subtract);
}
public void addCoinObserver(CoinObserver co) {
coinObservers.add(co);
}
public void removeCoinObserver(CoinObserver co) {
coinObservers.remove(co);
}
private void coinsChanged() {
for(CoinObserver co : coinObservers) {
co.coinsChanged(getTotCoins());
}
}
}
最后,您必须为您的硬币扩展JLabel
以实现此界面,如下所示,让它“订阅”自己为CoinObserver
:
public class CoinLabel extends JLabel implements CoinObserver {
public CoinLabel(You you) {
super("Coins: " + you.getTotCoins());
setFont(new Font("SanSerif", Font.BOLD, 18));
setForeground(Color.black);
setBounds(25, 25, 100, 100);
you.addCoinObserver(this);
}
@Override
public void coinsChanged(int newAmount) {
setText("Coins: " + newAmount);
}
}
请注意,此解决方案将收集大量观察者,因为它们永远不会从you
中删除。这可以通过覆盖dispose()
方法来解决,但是你应该使用setDefaultCloseOperation (JFrame.DISPOSE_ON_CLOSE);
(虽然我不完全确定),并将字段保存到You
以便使用它在构造函数之外。
如您所建议的那样调用setText("Coins: " + you.getTotCoins())
方法似乎需要做很多工作,但如果您的代码开始变得更复杂,那么它可能值得花时间。一些主要优点可能是:
label.setText("...")
,因为每次为硬币设置新值时,观察者都会收到通知。CoinObserver
,然后实现coinsChanged(int newAmount)
方法并将其添加到观察者列表中,而无需在所有金额可能发生变化的情况下反复绘制条形图。需要对现有代码进行任何更改。You
类(您只需要观察者界面即addCoinObserver(co)
和removeCoinObserver(co)
)。此外,您的You
类将永远不知道观察者到底是什么,它只知道CoinObserver
的接口。这允许对MVC model进行编程,这通常是一种很好的做法。可能还有更多。我要在这里注意的最后一件事:如果你只在一个地方改变你的硬币的价值而且你不太可能对其他任何地方的硬币感兴趣,你就不应该使用观察者模式。设计模式可以以各种可能的方式帮助您,但不应过度使用它们。
答案 1 :(得分:0)
我找到了一种方法来做到这一点。在访问此框架的类中,只需说
theStore.coins.setText("Coins: "+you.gettotCoins());
这会将新文本传递到类中并使其更新
感谢上述所有帮助我走上正轨的人