JavaFX-获取在TextArea中键入的当前单词
我正在尝试获取JavaFXTextArea中当前键入的单词或部分单词,以传递给一个非常基本的自动完成getPredictions(字符串前缀);方法 现在我在KeyTyped上使用一个事件处理程序,我将跟踪键入的每个字符,并将其与之前键入的单词连接起来,在空格上重置。这将有很多陷阱,我可以看到,AutoRead在键入一个单词时被打开,如果后面的空格被击中,并且插入符号在单词的末尾,则得到前面的单词。 我很好奇,是否有任何人都能想到的另一种方法,我使用TextInputControl方法将单词的字符串从插入符号位置返回到最后一个空格。我还没有让它按我的方式工作,但我会在这一点上发布我所拥有的 我基本上需要得到当前键入的单词,将当前插入符号位置保留为use类型JavaFX-获取在TextArea中键入的当前单词,java,string,javafx,textarea,Java,String,Javafx,Textarea,我正在尝试获取JavaFXTextArea中当前键入的单词或部分单词,以传递给一个非常基本的自动完成getPredictions(字符串前缀);方法 现在我在KeyTyped上使用一个事件处理程序,我将跟踪键入的每个字符,并将其与之前键入的单词连接起来,在空格上重置。这将有很多陷阱,我可以看到,AutoRead在键入一个单词时被打开,如果后面的空格被击中,并且插入符号在单词的末尾,则得到前面的单词。 我很好奇,是否有任何人都能想到的另一种方法,我使用TextInputControl方法将单词的字
public AutoSpellingTextArea() {
// register and handle KEY_TYPED event
this.addEventHandler(KeyEvent.KEY_TYPED,new EventHandler<KeyEvent>(){
public void handle(KeyEvent t) {
// BUG -- turning on autocomplete in middle of word.
if(autoCompleteOn) {
//TODO
String pre = getCurrentPrefix(t.getCharacter());
if(pre != null) {
List<String> choices = ac.predictCompletions(pre, NUM_COMPLETIONS);
}
}
}
});
}
也许您只需观察
caratPositionProperty
并回溯到最后一个空格字符即可获得所需的内容:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class AutoCompleteTextAreaTest extends Application {
@Override
public void start(Stage primaryStage) {
TextArea textArea = new TextArea();
Label currentWord = new Label();
textArea.caretPositionProperty().addListener((obs, oldPosition, newPosition) -> {
String text = textArea.getText().substring(0, newPosition.intValue());
int index ;
for (index = text.length() - 1; index >= 0 && ! Character.isWhitespace(text.charAt(index)); index--);
String prefix = text.substring(index+1, text.length());
currentWord.setText(prefix);
});
BorderPane root = new BorderPane(textArea, currentWord, null, null, null);
primaryStage.setScene(new Scene(root, 600, 600));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
你也可以将这个想法扩展到从CARAT位置向前搜索,这样如果游标在一个单词的中间,你就可以识别出插入时可能会出现的所有可能的单词。 下面是一个SSCCE,使用我在网上找到的随机单词列表来演示这一点:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.TextArea;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class AutoCompleteTextAreaTest extends Application {
private static final String WORD_LIST_URL = "https://raw.githubusercontent.com/dwyl/english-words/master/words.txt?raw=true";
@Override
public void start(Stage primaryStage) {
StackPane loadingRoot = new StackPane(new ProgressBar());
Scene scene = new Scene(loadingRoot, 600, 600);
List<String> words = new ArrayList<>();
Task<List<String>> loadWordsTask = new Task<List<String>>() {
@Override
public List<String> call() throws Exception {
try (BufferedReader in = new BufferedReader(new InputStreamReader(new URL(WORD_LIST_URL)
.openConnection()
.getInputStream()))) {
return in.lines()
.collect(Collectors.toList());
}
}
};
ListView<String> suggestions = new ListView<>();
TextArea textArea = new TextArea();
textArea.caretPositionProperty().addListener((obs, oldPosition, newPosition) -> {
String text = textArea.getText().substring(0, newPosition.intValue());
int index ;
for (index = text.length() - 1;
index >= 0 && ! Character.isWhitespace(text.charAt(index));
index--);
String prefix = text.substring(index+1, text.length());
for (index = newPosition.intValue();
index < textArea.getLength() && ! Character.isWhitespace(textArea.getText().charAt(index));
index++);
String suffix = textArea.getText().substring(newPosition.intValue(), index);
// replace regex wildcards (literal ".") with "\.". Looks weird but correct...
prefix = prefix.replaceAll("\\.", "\\.");
suffix = suffix.replaceAll("\\.", "\\.");
Pattern pattern = Pattern.compile(prefix+".*"+suffix,
Pattern.CASE_INSENSITIVE);
suggestions.getItems().setAll(
words.stream().filter(word -> pattern.matcher(word).matches())
.sorted(Comparator.comparing(String::length))
.limit(100)
.collect(Collectors.toList())
);
});
BorderPane root = new BorderPane(textArea, null, suggestions, null, null);
loadWordsTask.setOnSucceeded(e -> {
words.addAll(loadWordsTask.getValue());
scene.setRoot(root);
});
loadWordsTask.setOnFailed(e -> {
suggestions.setPlaceholder(new Label("Could not load word list"));
loadWordsTask.getException().printStackTrace();
scene.setRoot(root);
});
Thread t = new Thread(loadWordsTask);
t.setDaemon(true);
t.start();
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
导入java.io.BufferedReader;
导入java.io.InputStreamReader;
导入java.net.URL;
导入java.util.ArrayList;
导入java.util.Comparator;
导入java.util.List;
导入java.util.regex.Pattern;
导入java.util.stream.collector;
导入javafx.application.application;
导入javafx.concurrent.Task;
导入javafx.scene.scene;
导入javafx.scene.control.Label;
导入javafx.scene.control.ListView;
导入javafx.scene.control.ProgressBar;
导入javafx.scene.control.TextArea;
导入javafx.scene.layout.BorderPane;
导入javafx.scene.layout.StackPane;
导入javafx.stage.stage;
公共类AutoCompleteTextAreaTest扩展了应用程序{
私有静态最终字符串单词\u列表\u URL=”https://raw.githubusercontent.com/dwyl/english-words/master/words.txt?raw=true";
@凌驾
公共无效开始(阶段primaryStage){
StackPane loadingRoot=新的StackPane(new ProgressBar());
场景=新场景(loadingRoot,600600);
List words=new ArrayList();
Task loadWordsTask=新任务(){
@凌驾
公共列表调用()引发异常{
try(BufferedReader in=new BufferedReader(new InputStreamReader)(新URL)(单词列表URL)
.openConnection()
.getInputStream())){
在.lines()中返回
.collect(Collectors.toList());
}
}
};
ListView建议=新建ListView();
TextArea TextArea=新建TextArea();
textArea.caretPositionProperty().addListener((obs、oldPosition、newPosition)->{
String text=textArea.getText().substring(0,newPosition.intValue());
整数指数;
for(index=text.length()-1;
index>=0&&!Character.isWhitespace(text.charAt(index));
指数——);
字符串前缀=text.substring(索引+1,text.length());
for(index=newPosition.intValue();
indexpattern.matcher(word.matches())
.sorted(Comparator.comparing(字符串::长度))
.限额(100)
.collect(收集器.toList())
);
});
BorderPane root=新的BorderPane(文本区域,null,建议,null,null);
loadWordsTask.setOnSucceeded(e->{
addAll(loadWordsTask.getValue());
scene.setRoot(root);
});
loadWordsTask.setOnFailed(e->{
建议.setPlaceholder(新标签(“无法加载单词列表”);
loadWordsTask.getException().printStackTrace();
scene.setRoot(root);
});
线程t=新线程(loadWordsTask);
t、 setDaemon(true);
t、 start();
初级阶段。场景(场景);
primaryStage.show();
}
公共静态void main(字符串[]args){
发射(args);
}
}
也许您只需观察caratPositionProperty
并回溯到最后一个空格字符即可获得所需的内容:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class AutoCompleteTextAreaTest extends Application {
@Override
public void start(Stage primaryStage) {
TextArea textArea = new TextArea();
Label currentWord = new Label();
textArea.caretPositionProperty().addListener((obs, oldPosition, newPosition) -> {
String text = textArea.getText().substring(0, newPosition.intValue());
int index ;
for (index = text.length() - 1; index >= 0 && ! Character.isWhitespace(text.charAt(index)); index--);
String prefix = text.substring(index+1, text.length());
currentWord.setText(prefix);
});
BorderPane root = new BorderPane(textArea, currentWord, null, null, null);
primaryStage.setScene(new Scene(root, 600, 600));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
你也可以将这个想法扩展到从CARAT位置向前搜索,这样如果游标在一个单词的中间,你就可以识别出插入时可能会出现的所有可能的单词。 下面是一个SSCCE,使用我在网上找到的随机单词列表来演示这一点:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.TextArea;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class AutoCompleteTextAreaTest extends Application {
private static final String WORD_LIST_URL = "https://raw.githubusercontent.com/dwyl/english-words/master/words.txt?raw=true";
@Override
public void start(Stage primaryStage) {
StackPane loadingRoot = new StackPane(new ProgressBar());
Scene scene = new Scene(loadingRoot, 600, 600);
List<String> words = new ArrayList<>();
Task<List<String>> loadWordsTask = new Task<List<String>>() {
@Override
public List<String> call() throws Exception {
try (BufferedReader in = new BufferedReader(new InputStreamReader(new URL(WORD_LIST_URL)
.openConnection()
.getInputStream()))) {
return in.lines()
.collect(Collectors.toList());
}
}
};
ListView<String> suggestions = new ListView<>();
TextArea textArea = new TextArea();
textArea.caretPositionProperty().addListener((obs, oldPosition, newPosition) -> {
String text = textArea.getText().substring(0, newPosition.intValue());
int index ;
for (index = text.length() - 1;
index >= 0 && ! Character.isWhitespace(text.charAt(index));
index--);
String prefix = text.substring(index+1, text.length());
for (index = newPosition.intValue();
index < textArea.getLength() && ! Character.isWhitespace(textArea.getText().charAt(index));
index++);
String suffix = textArea.getText().substring(newPosition.intValue(), index);
// replace regex wildcards (literal ".") with "\.". Looks weird but correct...
prefix = prefix.replaceAll("\\.", "\\.");
suffix = suffix.replaceAll("\\.", "\\.");
Pattern pattern = Pattern.compile(prefix+".*"+suffix,
Pattern.CASE_INSENSITIVE);
suggestions.getItems().setAll(
words.stream().filter(word -> pattern.matcher(word).matches())
.sorted(Comparator.comparing(String::length))
.limit(100)
.collect(Collectors.toList())
);
});
BorderPane root = new BorderPane(textArea, null, suggestions, null, null);
loadWordsTask.setOnSucceeded(e -> {
words.addAll(loadWordsTask.getValue());
scene.setRoot(root);
});
loadWordsTask.setOnFailed(e -> {
suggestions.setPlaceholder(new Label("Could not load word list"));
loadWordsTask.getException().printStackTrace();
scene.setRoot(root);
});
Thread t = new Thread(loadWordsTask);
t.setDaemon(true);
t.start();
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
导入java.io.BufferedReader;
导入java.io.InputStreamReader;
导入java.net.URL;
导入java.util.ArrayList;
导入java.util.Comparator;
导入java.util.List;
导入java.util.regex.Pattern;
导入java.util.stream.collector;
导入javafx.application.application;
导入javafx.concurrent.Task;
导入javafx.scene.scene;
导入javafx.scene.control.Label;
导入javafx.scene.control.ListView;
导入javafx.scene.control.ProgressBar;
导入javafx.scene.control.TextArea;
导入javafx.scene.layout.BorderPane;
导入javafx.scene.layout。