gpt4 book ai didi

java - JTextArea 文本消失

转载 作者:行者123 更新时间:2023-11-30 05:50:29 25 4
gpt4 key购买 nike

我正在为一个项目制作国际象棋程序。我正在尝试将一个移动历史记录框添加到板的一侧。移动历史运行良好,数据正确发送到文本区域,但 JTextArea 中的文本在 AI 考虑他的移动时消失了。

public void aiMove(){
if (!playing){ return; }
paintImmediately(0,0,totalX,totalY);
ai = eve.getMove(chess,wtm,aiOut); //text disappears here
chess.makeMove(ai);
wtm = !wtm;
humanMove = true;
writeMove(ai); //updates move history, text reappears here
playing = stillPlaying();
repaint();
}

private void writeMove(Move move){
char c = "abcdefgh".charAt(7-move.fromY);
char h ="abcdefgh".charAt(7-move.toY);
String s = Character.toString(c)+(move.fromX+1)+" - "+Character.toString(h)+(move.toX+1)+" ";
if (!wtm){
String q = chess.getFullMove()+". "+s+" ";
moves.setText(moves.getText()+q);
}
else {
moves.setText(moves.getText()+s+"\n");
}
}

这是正在发生的事情的打印屏幕。 http://s13.postimage.org/mh7hltfk7/JText_Area_disappear.png


已解决感谢所有回复。我更改了 aiMove() 以便它创建一个线程。这是我所做的。

尝试#3... Swing 对我来说还是那么陌生。我不想将 writeMove 更改为 getMove,否则我将不得不稍微重写 human's turn。由于该项目基本上已经完成,我正在努力避免尽可能多的工作:)无论如何,GUI 完全是可选的,我这样做只是为了好玩,并尝试学习一些 swing。

public void aiMove(){
if (!playing){ return; }
if (!aiThread.isAlive()){
aiThread = new Thread(){
public void run(){
ai = eve.getMove(chess,wtm,aiOut);
chess.makeMove(ai);
wtm = !wtm;
humanMove = true;
SwingUtilities.invokeLater(new Runnable(){
public void run(){
writeMove(ai);
}
});
repaint();
playing = stillPlaying();
}
};
aiThread.start();
}
}

它还解决了我之前遇到的一个问题,如果我按住“a”键(强制 ai 移动),它会排队许多强制 ai 移动。现在不会发生这种情况。

最佳答案

问题是您的 AI 思维是 CPU 密集型/耗时的,因此它被认为是一项长时间运行的任务。您不应该在 GUI 事件调度线程上执行长时间运行的任务,因为这会导致 UI 看起来卡住,因此只在任务完成后显示更新。

幸运的是,您可以使用两种不同的方法:

The SwingWorker subclass can define a method, done, which is automatically invoked on the event dispatch thread when the background task is finished.

SwingWorker implements java.util.concurrent.Future. This interface allows the background task to provide a return value to the other thread. Other methods in this interface allow cancellation of the background task and discovering whether the background task has finished or been cancelled.

The background task can provide intermediate results by invoking SwingWorker.publish, causing SwingWorker.process to be invoked from the event dispatch thread.

The background task can define bound properties. Changes to these properties trigger events, causing event-handling methods to be invoked on the event dispatch thread.

  • 或者为 AI 思考创建单独的 Thread 并将 setText 调用包装在 SwingUtilities.invokeLater(...);

    Thread t=new Thread(new Runnable() {
    @Override
    public void run() {
    }
    });
    t.start();

更新

阅读 MadProgrammers 评论(+1)后,请记住通过 SwingUtilities.invokeLater(..) block 在 EDT 上创建/操作您的 GUI/Swing 组件。您可以阅读更多信息 here .

更新 2:

那个编辑打败了重点,SwingUtilitites block 中对 EDT 的唯一调用应该是 setText 或至少只有操作 Swing 组件的代码,即

public void aiMove(){
if (!playing){ return; }
if (!aiThread.isAlive()){ //originally initialized by constructor
aiThread = new Thread(){
public void run(){
ai = eve.getMove(chess,wtm,aiOut);
chess.makeMove(ai);
wtm = !wtm;
humanMove = true;
SwingUtilities.invokeLater(new Runnable(){
public void run(){
writeMove(ai);
}
});
repaint();
playing = stillPlaying();
}
};
aiThread.start();
}
}

关于java - JTextArea 文本消失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14005730/

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