java - javafx 中代码区域的自动补全

标签 java listview javafx autocomplete richtextfx

如何在 javafx 中输入自动完成功能时在 codearea 中当前插入符号位置创建 ListView ?到目前为止,我找到了当前正在输入的单词,并查看该单词是否包含在数组中。这是我到目前为止的代码。预先感谢您!

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 的通用高级方法。您可以根据您的要求关联逻辑并进行更改。

我相信这将为您提供有关如何处理所需的基础知识。话虽如此,还有许多其他更好的方法。

核心思想是依赖插入符节点(Path)边界,而不是进行复杂的计算来查找插入符在文本中的位置。

enter image description here

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.");
    }
}

关于java - javafx 中代码区域的自动补全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67167220/

相关文章:

java - 为什么需要复制 volatile 变量而不是直接使用它?

c# - 如何访问 onRowDataBound 事件

java - 如何单击 javafx slider

java - 使用 FragmentStatePagerAdapter 通过 ViewPager 保留 fragment 的位置

java - 如何使 JPA 列仅在 JUnit 测试期间可插入?

android - 使用 RxJava 从 Internet 获取数据时,ListView 无法显示项目数据

java - JavaFX ListView 中的 WPF ListView.ItemTemplate 等效项是什么?

java - Shift+单击以选择 JavaFX TableView 中的多个单元格挂起

Java 通过引用传递 boolean 列表

java - 带有俄语网址的 ImageView