javafx中代码区的自动完成
Autocompletion in codearea in javafx
如何在 codearea 中的当前插入符号位置创建列表视图,同时在 javafx 中键入自动完成功能?到目前为止,我找到了当前正在键入的单词,并查看该单词是否包含在数组中。这是我到目前为止的代码。提前致谢!
String[] keyphrases = new String[]{"int main(){\n}", "cout", "cin"};
((CodeArea)tabPane.getSelectionModel().getSelectedItem().getContent()).textProperty().addListener(new ChangeListener<String>()
{
@Override
public void changed(ObservableValue<? extends String> observableValue, String s, String s2) {
CodeArea sto = ((CodeArea)tabPane.getSelectionModel().getSelectedItem().getContent());
String curr = "";
String currFinal = "";
for (int i = sto.getAnchor(); i > 0; i--) {
if (sto.getText().charAt(i) == '\n' || sto.getText().charAt(i) == ' ') {
break;
}else {
curr += sto.getText().charAt(i);
}
}
for (int i = curr.length()-1; i >= 0; i--) {
currFinal += curr.charAt(i);
}
System.out.println(currFinal);
ArrayList<String> fil = new ArrayList<String>();
for (int i = 0; i < keyphrases.length; i++) {
if (keyphrases[i].contains(currFinal)) {
fil.add(keyphrases[i]);
}
}
//display fil as listview in caret position?
}
});
如果您询问如何在插入符号位置显示 ListView,请查看以下方法。这是在当前插入符位置显示 ListView 的一般高级方法。您可以关联逻辑并根据您的要求进行更改。
我相信这将为您提供有关如何处理所需的基础知识。话虽如此,还有许多其他更好的方法。
核心思想是依靠插入符节点(路径)边界,而不是进行复杂的计算来查找插入符在文本中的位置。
import javafx.application.Application;
import javafx.geometry.Bounds;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.control.TextArea;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
import javafx.scene.shape.Path;
import javafx.stage.Popup;
import javafx.stage.Stage;
public class TextAreaCaretPositionDemo extends Application {
private Bounds caretBoundsInScreen;
private Node caret;
@Override
public void start(Stage stage) throws Exception {
final VBox root = new VBox();
root.setSpacing(10);
root.setPadding(new Insets(10));
final Scene sc = new Scene(root, 350, 200);
stage.setScene(sc);
stage.setTitle("TextArea Caret Position");
stage.show();
TextArea textArea = new TextArea() {
@Override
protected void layoutChildren() {
super.layoutChildren();
if (caret == null) {
final Region content = (Region) lookup(".content");
// Looking for the caret path node and add a listener to its bounds to keep track of its position in screen.
content.getChildrenUnmodifiable().stream()
.filter(node -> node instanceof Path)
.map(node -> (Path) node)
// Find a more better way to find the caret path node
.filter(path -> path.getStrokeWidth() == 1 && path.fillProperty().isBound() && path.strokeProperty().isBound())
.findFirst().ifPresent(path -> {
path.boundsInLocalProperty().addListener((obs, old, bounds) -> {
if (bounds.getWidth() > 0 && bounds.getHeight() > 0) {
caretBoundsInScreen = path.localToScreen(bounds);
}
});
caret = path;
});
}
}
};
textArea.setWrapText(true);
VBox.setVgrow(textArea, Priority.ALWAYS);
ListView<String> list = new ListView<>();
list.setPrefSize(150,200);
list.getItems().addAll("One","Two","Three");
Popup popup = new Popup();
popup.setAutoHide(true);
popup.getContent().addAll(list);
Button show = new Button("Show ListView");
show.setOnAction(e->{
popup.show(caret, caretBoundsInScreen.getMinX(), caretBoundsInScreen.getMaxY());
});
root.getChildren().addAll(show,textArea);
textArea.setText("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.");
}
}
根据 Sai 的回答,我创建了自己的解决方案!
codeArea.textProperty().addListener(new ChangeListener<String>()
{
@Override
public void changed(ObservableValue<? extends String> observableValue, String s, String s2) {
String curr = "";
String currFinal = "";
for (int i = codeArea.getAnchor(); i > 0; i--) {
if (codeArea.getText().charAt(i) == '\n' || codeArea.getText().charAt(i) == ' ') {
break;
}else {
curr += codeArea.getText().charAt(i);
}
}
for (int i = curr.length()-1; i >= 0; i--) {
currFinal += curr.charAt(i);
}
if (currFinal != "") {
ArrayList<String> fil = new ArrayList<String>();
for (int i = 0; i < keyphrases.length; i++) {
if (keyphrases[i].contains(currFinal)) {
fil.add(keyphrases[i]);
}
}
System.out.println("Fil " + fil);
if (popup != null) {
popup.hide();
}
if (fil.size() > 0) {
ListView lop = new ListView();
for (int i = 0; i < fil.size(); i++) {
lop.getItems().add(fil.get(i));
}
popup = new Popup();
lop.setMaxHeight(80);
popup.getContent().addAll(lop);
popup.show(codeArea, codeArea.getCaretBounds().get().getMaxX(), codeArea.getCaretBounds().get().getMaxY());
codeArea.requestFocus();
}
codeArea.requestFocus();
}else {
if (popup != null) {
popup.hide();
}
}
}
});
如何在 codearea 中的当前插入符号位置创建列表视图,同时在 javafx 中键入自动完成功能?到目前为止,我找到了当前正在键入的单词,并查看该单词是否包含在数组中。这是我到目前为止的代码。提前致谢!
String[] keyphrases = new String[]{"int main(){\n}", "cout", "cin"};
((CodeArea)tabPane.getSelectionModel().getSelectedItem().getContent()).textProperty().addListener(new ChangeListener<String>()
{
@Override
public void changed(ObservableValue<? extends String> observableValue, String s, String s2) {
CodeArea sto = ((CodeArea)tabPane.getSelectionModel().getSelectedItem().getContent());
String curr = "";
String currFinal = "";
for (int i = sto.getAnchor(); i > 0; i--) {
if (sto.getText().charAt(i) == '\n' || sto.getText().charAt(i) == ' ') {
break;
}else {
curr += sto.getText().charAt(i);
}
}
for (int i = curr.length()-1; i >= 0; i--) {
currFinal += curr.charAt(i);
}
System.out.println(currFinal);
ArrayList<String> fil = new ArrayList<String>();
for (int i = 0; i < keyphrases.length; i++) {
if (keyphrases[i].contains(currFinal)) {
fil.add(keyphrases[i]);
}
}
//display fil as listview in caret position?
}
});
如果您询问如何在插入符号位置显示 ListView,请查看以下方法。这是在当前插入符位置显示 ListView 的一般高级方法。您可以关联逻辑并根据您的要求进行更改。
我相信这将为您提供有关如何处理所需的基础知识。话虽如此,还有许多其他更好的方法。
核心思想是依靠插入符节点(路径)边界,而不是进行复杂的计算来查找插入符在文本中的位置。
import javafx.application.Application;
import javafx.geometry.Bounds;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.control.TextArea;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
import javafx.scene.shape.Path;
import javafx.stage.Popup;
import javafx.stage.Stage;
public class TextAreaCaretPositionDemo extends Application {
private Bounds caretBoundsInScreen;
private Node caret;
@Override
public void start(Stage stage) throws Exception {
final VBox root = new VBox();
root.setSpacing(10);
root.setPadding(new Insets(10));
final Scene sc = new Scene(root, 350, 200);
stage.setScene(sc);
stage.setTitle("TextArea Caret Position");
stage.show();
TextArea textArea = new TextArea() {
@Override
protected void layoutChildren() {
super.layoutChildren();
if (caret == null) {
final Region content = (Region) lookup(".content");
// Looking for the caret path node and add a listener to its bounds to keep track of its position in screen.
content.getChildrenUnmodifiable().stream()
.filter(node -> node instanceof Path)
.map(node -> (Path) node)
// Find a more better way to find the caret path node
.filter(path -> path.getStrokeWidth() == 1 && path.fillProperty().isBound() && path.strokeProperty().isBound())
.findFirst().ifPresent(path -> {
path.boundsInLocalProperty().addListener((obs, old, bounds) -> {
if (bounds.getWidth() > 0 && bounds.getHeight() > 0) {
caretBoundsInScreen = path.localToScreen(bounds);
}
});
caret = path;
});
}
}
};
textArea.setWrapText(true);
VBox.setVgrow(textArea, Priority.ALWAYS);
ListView<String> list = new ListView<>();
list.setPrefSize(150,200);
list.getItems().addAll("One","Two","Three");
Popup popup = new Popup();
popup.setAutoHide(true);
popup.getContent().addAll(list);
Button show = new Button("Show ListView");
show.setOnAction(e->{
popup.show(caret, caretBoundsInScreen.getMinX(), caretBoundsInScreen.getMaxY());
});
root.getChildren().addAll(show,textArea);
textArea.setText("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.");
}
}
根据 Sai 的回答,我创建了自己的解决方案!
codeArea.textProperty().addListener(new ChangeListener<String>()
{
@Override
public void changed(ObservableValue<? extends String> observableValue, String s, String s2) {
String curr = "";
String currFinal = "";
for (int i = codeArea.getAnchor(); i > 0; i--) {
if (codeArea.getText().charAt(i) == '\n' || codeArea.getText().charAt(i) == ' ') {
break;
}else {
curr += codeArea.getText().charAt(i);
}
}
for (int i = curr.length()-1; i >= 0; i--) {
currFinal += curr.charAt(i);
}
if (currFinal != "") {
ArrayList<String> fil = new ArrayList<String>();
for (int i = 0; i < keyphrases.length; i++) {
if (keyphrases[i].contains(currFinal)) {
fil.add(keyphrases[i]);
}
}
System.out.println("Fil " + fil);
if (popup != null) {
popup.hide();
}
if (fil.size() > 0) {
ListView lop = new ListView();
for (int i = 0; i < fil.size(); i++) {
lop.getItems().add(fil.get(i));
}
popup = new Popup();
lop.setMaxHeight(80);
popup.getContent().addAll(lop);
popup.show(codeArea, codeArea.getCaretBounds().get().getMaxX(), codeArea.getCaretBounds().get().getMaxY());
codeArea.requestFocus();
}
codeArea.requestFocus();
}else {
if (popup != null) {
popup.hide();
}
}
}
});