首先,道歉这是多久。JLabel.setText()仅设置循环中最后一个元素的文本
我试图做一个简单的轮盘赌游戏,允许用户添加玩家,为这些玩家下注,并旋转轮盘,代表一个简单的JLabel,更新它的文本,每个数字它通过。
但是,我遇到了一个bug,我遇到了很多麻烦:JLabel只更新我的循环中最后一个元素的文本。
基本上,我的解决办法是这样的:
当用户按下标有“旋转”按钮(假设用户已经加入到游戏中),我调用一个方法,从一个叫SpinWheelService
类,它是可观察到单这反过来又调用notifyObservers()
方法:
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
String description = null;
if (ADD_PLAYER.equals(cmd)) {
addDialog();
} else if (PLACE_BET.equals(cmd)) {
betDialog();
} else if (SPIN.equals(cmd)) {
SpinWheelService.sws.setSpinWheelService();
} else if (DISPLAY.equals(cmd)) {
System.out.println("Display selected!");
}
}
这里是我SpinWheelService
类:
package model;
import java.util.*;
public class SpinWheelService extends Observable {
public static SpinWheelService sws = new SpinWheelService();
public void setSpinWheelService() {
setChanged();
notifyObservers();
}
}
为SpinWheelService
注册的唯一的听众是这个班,其中GameEngine是我的游戏引擎,处理内部游戏逻辑,WheelCallbackImpl是更新视图类:
class SpinWheelObserver implements Observer {
GameEngine gameEngine;
ArrayList<SimplePlayer> players;
WheelCallbackImpl wheelCall;
int n;
public SpinWheelObserver(GameEngine engine, WheelCallbackImpl wheel, ArrayList<SimplePlayer> playerList) {
players = playerList;
gameEngine = engine;
wheelCall = wheel;
}
public void update(Observable sender, Object arg) {
// check if any players are present
if (players.size() == 0) {
System.out.println("Empty player array!");
return;
}
do {
gameEngine.spin(40, 1, 300, 30, wheelCall);
n = wheelCall.playback();
} while (n== 0);
}
}
这里说明的要点是我gameEngine.spin()
方法,这是这样的:
public class GameEngineImpl implements GameEngine {
private List<Player> playerList = new ArrayList<Player>();
// method handles the slowing down of the roulette wheel, printing numbers at an incremental delay
public void delay(int millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
System.out.println("Sleep method failed.");
}
}
public void spin(int wheelSize, int initialDelay, int finalDelay,
int delayIncrement, WheelCallback callback) {
Random rand = new Random();
int curNo = rand.nextInt(wheelSize) + 1;
int finalNo = 0;
assert (curNo >= 1);
// while loop handles how long the wheel will spin for
while (initialDelay <= finalDelay) {
delay(initialDelay);
initialDelay += delayIncrement;
// handles rotating nature of the wheel, ensures that if it reaches wheel size, reverts to 1
if (curNo > wheelSize) {
curNo = 1;
callback.nextNumber(curNo, this);
curNo++;
}
assert (curNo <= wheelSize);
callback.nextNumber(curNo, this);
curNo++;
finalNo = curNo - 1;
}
calculateResult(finalNo);
callback.result(finalNo, this);
}
方法callback.nextNumber(库尔诺,此):
public void nextNumber(int nextNumber, GameEngine engine) {
String strNo = Integer.toString(nextNumber);
assert (nextNumber >= 1);
System.out.println(nextNumber);
wcWheel.setCounter(strNo);
}
凡,wcWheel是我的我的观点,这包含方法setCounter()单一实例:
public void setCounter(String value) {
label.setText(value);
}
对不起,我的解释是如何错综复杂的,但基本上它归结为是setCounter()
肯定是被称为,但似乎只在最终号码上调用setText()
方法。所以我留下的是一个空的标签,在整个轮盘完成旋转之前不会显示数字。
我确定setCounter()
在事件派发线程上运行,我怀疑这是一个并发问题,但我不知道如何更正它。
我试图包含所有相关的代码,但如果我错过了任何东西,请提及它,我也会发布它。
我在我的智慧结束在这里,所以如果任何人都会有足够的帮助,那将是如此之大。
谢谢!
所有这些代码是作为Spin“按钮处理函数的一部分在AWT线程上执行的吗?还是你在单独的线程上运行? – stridecolossus
另外,你说你确定'setCounter'正在被调用 - 你有调试它以查看它被调用的时间和频率,以及/或者在被调用时抛出一个'println'来查看行为? – stridecolossus
我确定它被调用,因为我曾经有一个println语句可以打印'值',这是在终端相应更新,它只是''setText()'方法正在播放 – user2893128