gpt4 book ai didi

java - 线程通信: How to signal that a key was clicked? java.lang.IllegalMonitorStateException

转载 作者:行者123 更新时间:2023-12-02 13:29:10 26 4
gpt4 key购买 nike

我有一个带有 TextField 的简单 JavaFX 阶段。我想做的是:当用户将字母插入文本字段时,我想打印“现在”(只是为了看看它是否有效)。我使用线程是因为稍后我想扫描字典以查看用户输入的字母是否是字典中单词的一部分。

但我得到:java.lang.IllegalMonitorStateException

有什么想法吗?我似乎不理解 Condition.await 和多线程的整个概念..

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class DictionaryThreading extends Application {


private static Lock lock = new ReentrantLock();
public static Condition condition = lock.newCondition();

public static void main(String[] args) {
launch();
}

private static class ScanWords implements Runnable{

@Override
public void run() {
lock.lock();
try{
while(true){
this.wait();
System.out.println("clicked");
}
} catch (Exception e){
e.printStackTrace();
} finally{
lock.unlock();
}
}

}

@Override
public void start(Stage primaryStage) throws Exception {
StackPane pane = new StackPane();

new ScanWords().run();
TextField tf = new TextField("Please enter a word");
tf.setOnKeyPressed(e -> {});
pane.getChildren().add(tf);

Scene scene = new Scene(pane);
primaryStage.setScene(scene);
primaryStage.show();

}

}

最佳答案

不需要创建一个除了等待用户事件之外什么都不做的线程。 JavaFX 框架已经为您提供了这一点(它是任何 UI 工具包的基本功能之一)。要响应文本字段中文本的更改,您所需要做的就是使用文本字段的文本属性注册更改监听器:

public void start(Stage primaryStage) throws Exception {
StackPane pane = new StackPane();

TextField tf = new TextField("Please enter a word");
tf.textProperty().addListener((obs, oldText, newText) -> {
System.out.println("text changed");
});
pane.getChildren().add(tf);

Scene scene = new Scene(pane);
primaryStage.setScene(scene);
primaryStage.show();

}

如果您需要执行的响应文本更改的操作需要很长时间,那么您应该在文本字段的监听器中的后台线程中启动该进程。如果您正在搜索大型内容,您可能希望取消任何现有搜索,这样您就不会出现大量同时运行的搜索。 JavaFX Service class提供您所需的功能:

public class SearchService extends Service<List<String>> {

// modify and access only on FX Application Thread:
private String searchString ;

@Override
protected Task<List<String>> createTask() {
final String s = searchString ;
return new Task<List<String>>() {
@Override
protected List<String> call() throws Exception {
List<String> matches = new ArrayList<>();
// do search for strings matching s
// be sure to check isCancelled() regularly
return matches ;
}
};
}

public String getSearchString() {
checkThread();
return searchString ;
}

public void setSearchString(String searchString) {
checkThread();
this.searchString = searchString ;
}

private void checkThread() {
if (! Platform.isFxApplicationThread()) {
throw new IllegalStateException("Not on FX Application Thread");
}
}
}

然后你就可以了

public void start(Stage primaryStage) throws Exception {
StackPane pane = new StackPane();

SearchService searchService = new SearchService();

searchService.setOnSucceeded(e -> {
List<String> matches = searchService.getValue();
// do whatever you need with search results...
// this is called on FX application thread
});

TextField tf = new TextField("Please enter a word");
tf.textProperty().addListener((obs, oldText, newText) -> {
searchService.cancel();
searchService.setSearchText(newText);
searchService.restart();
});
pane.getChildren().add(tf);

Scene scene = new Scene(pane);
primaryStage.setScene(scene);
primaryStage.show();

}

关于java - 线程通信: How to signal that a key was clicked? java.lang.IllegalMonitorStateException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43256552/

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