gpt4 book ai didi

java - 如何输出到 GUI、暂停,然后输出其他内容(例如使用 SwingWorker)?

转载 作者:行者123 更新时间:2023-12-01 12:24:10 24 4
gpt4 key购买 nike

我正在用 Java 制作一个简单的基于文本的回合制战斗游戏(作为学习练习,所以我试图理解我所做的一切),我想模拟对手的回合。这本质上涉及打印出一条消息(例如“轮到敌人了”),处理敌人的轮到,暂停(使用 Thread.sleep ),然后打印出另一条消息(“例如“轮到你了”)。

我的 GUI 是一个带有 Swing 元素的 JApplet 类,尽管这是因为它易于制作和理解,而不是因为我对使用 Swing 有任何执着。我没有多线程方面的经验,但已经了解到 SwingWorker 在这种情况下很有用(在长时间的后台进程运行时更新 Swing GUI)。这是一个没有实际游戏代码的版本,为了简单起见,所有代码都包含在同一个类中:

public class SimpleGame extends JApplet implements ActionListener {
private Game game;
private String inputCommand;
private JTextArea textOutput;
private JTextField inputField;
public void init() {
textOutput = new JTextArea();
DefaultCaret caret = (DefaultCaret) textOutput.getCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
textOutput.setEditable(false);
Container window = getContentPane();
window.setLayout(new BorderLayout());
window.add(textOutput, BorderLayout.CENTER);
JButton submitButton = new JButton("Submit");
submitButton.addActionListener(this);
inputField = new JTextField(20);
inputField.addActionListener(this);
JPanel inputPanel = new JPanel();
inputPanel.add(inputField);
inputPanel.add(submitButton);
window.add(inputPanel, BorderLayout.SOUTH);
inputField.requestFocusInWindow();
game = new Game();
}
public class GuiUpdater extends SwingWorker<Boolean, String> {
private String command;
public GuiUpdater(String inputCommand) {
super();
command = inputCommand;
}
public void publish(String chunk) {
super.publish(chunk);
}
protected Boolean doInBackground() throws Exception {
Output.setWorker(this);
boolean successfulCommand = game.performCommand(command);
return successfulCommand;
}
protected void process(List<String> chunks) {
for (String chunk : chunks) {
textOutput.append(chunk);
}
}
}
public void actionPerformed(ActionEvent event) {
if (game.isItYourTurn()) {
inputCommand = inputField.getText();
if (inputCommand.length() != 0) {
GuiUpdater worker = new GuiUpdater(inputCommand);
worker.execute();
boolean successfulCommand;
try {
successfulCommand = worker.get();
} catch (InterruptedException | ExecutionException e) {
successfulCommand = false;
}
if (!successfulCommand) {
textOutput.append("Invalid command.\n");
}
inputField.setText("");
}
} else {
textOutput.append("\nWait for your turn!\n");
}
}
private static class Output {
private static GuiUpdater worker;
static void setWorker(GuiUpdater newWorker) {
worker = newWorker;
}
static void update(String updateText) {
worker.publish(updateText);
}
}
private class Game {
private boolean yourTurn;
public Game() {
yourTurn = true;
}
public boolean isItYourTurn() {
return yourTurn;
}
public boolean performCommand(String inputString) throws InterruptedException {
yourTurn = false;
// perform player action
Output.update("\nEnemy turn");
Thread.sleep(1000);
// perform enemy action
Output.update("\nYour turn");
yourTurn = true;
return true;
}
}
}

不幸的是,不是输出一行,等待一秒钟,然后输出第二行,而是在所有 sleep 完成后将所有行输出到 Swing GUI。如果我将 Output.update("text") 替换为 System.out.println("text") 那么计时将按预期进行,但显然我没有我的游戏只想依赖控制台输出。

如果有人对我做错了什么有解释,或者有在输出之间暂停的替代方法,我将不胜感激。干杯!

最佳答案

您对worker.get() 的调用会阻塞swing-applet 线程,直到worker 完成为止。您需要将对结果的处理移至 SwingWorker did() 方法中,该方法在 doInBackground() 方法完成之前不会执行。这部分代码应该如下所示:

public class GuiUpdater extends SwingWorker<Boolean, String> {
private String command;

public GuiUpdater(String inputCommand) {
super();
command = inputCommand;
}

public void publish(String chunk) {
super.publish(chunk);
}

@Override
protected Boolean doInBackground() throws Exception {
Output.setWorker(this);
boolean successfulCommand = game.performCommand(command);
return successfulCommand;
}

@Override
protected void process(List<String> chunks) {
for (String chunk : chunks) {
textOutput.append(chunk);
}
}

@Override
protected void done() {
boolean successfulCommand;
try {
successfulCommand = get();
} catch (InterruptedException | ExecutionException e) {
successfulCommand = false;
}
if (!successfulCommand) {
textOutput.append("Invalid command.\n");
}
inputField.setText("");
}
}

@Override
public void actionPerformed(ActionEvent event) {
if (game.isItYourTurn()) {
inputCommand = inputField.getText();
if (inputCommand.length() != 0) {
GuiUpdater worker = new GuiUpdater(inputCommand);
worker.execute();
}
} else {
textOutput.append("\nWait for your turn!\n");
}
}

关于java - 如何输出到 GUI、暂停,然后输出其他内容(例如使用 SwingWorker)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26476465/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com