javafx中代码区的自动补全

javafx中代码区的自动补全,java,listview,javafx,autocomplete,richtextfx,Java,Listview,Javafx,Autocomplete,Richtextfx,在javafx中键入自动补全时,如何在codearea中的当前插入符号位置创建listview?到目前为止,我找到了当前正在键入的单词,并查看该单词是否包含在数组中。这是我目前掌握的代码。提前谢谢你 String[]keyphases=新字符串[]{“int main(){\n}”、“cout”、“cin”} ((CodeArea)选项卡窗格.getSelectionModel().getSelectedItem().getContent()).textProperty().addListene

在javafx中键入自动补全时,如何在codearea中的当前插入符号位置创建listview?到目前为止,我找到了当前正在键入的单词,并查看该单词是否包含在数组中。这是我目前掌握的代码。提前谢谢你

String[]keyphases=新字符串[]{“int main(){\n}”、“cout”、“cin”}

((CodeArea)选项卡窗格.getSelectionModel().getSelectedItem().getContent()).textProperty().addListener(新的ChangeListener())
{
@凌驾

public void changed(observevalue如果您询问如何在插入符号位置显示列表视图,请检查以下方法。这是在当前插入符号位置显示列表视图的一般高级方法。您可以关联逻辑并根据需要进行更改

我相信这将为你提供所需的基本方法。尽管如此,还有许多其他更好的方法

其核心思想是依赖插入符号节点(路径)边界,而不是通过复杂的计算来查找插入符号在文本中的位置

导入javafx.application.application;
导入javafx.geometry.Bounds;
导入javafx.geometry.Insets;
导入javafx.scene.Node;
导入javafx.scene.scene;
导入javafx.scene.control.Button;
导入javafx.scene.control.ListView;
导入javafx.scene.control.TextArea;
导入javafx.scene.layout.Priority;
导入javafx.scene.layout.Region;
导入javafx.scene.layout.VBox;
导入javafx.scene.shape.Path;
导入javafx.stage.Popup;
导入javafx.stage.stage;
公共类TextAreaCaretPositionDemo扩展应用程序{
私人边界caretBoundsInScreen;
专用节点插入符号;
@凌驾
public void start(Stage)引发异常{
最终VBox根=新VBox();
根起搏(10);
根。设置填充(新插图(10));
最终场景sc=新场景(根,350,200);
第二阶段(sc);
stage.setTitle(“文本区域插入符号位置”);
stage.show();
TextArea TextArea=新建TextArea(){
@凌驾
受保护的void layoutChildren(){
super.layoutChildren();
if(插入符号==null){
最终区域内容=(区域)查找(“.content”);
//查找插入符号路径节点并将侦听器添加到其边界以跟踪其在屏幕中的位置。
content.getChildrenUnmodifiable().stream()
.filter(节点->路径的节点实例)
.map(节点->(路径)节点)
//找到更好的方法来查找插入符号路径节点
.filter(path->path.getStrokeWidth()==1&&path.fillProperty().isBound()&&path.strokeProperty().isBound())
.findFirst().ifPresent(路径->{
path.boundsInLocalProperty().addListener((obs,旧,边界)->{
if(bounds.getWidth()>0&&bounds.getHeight()>0){
caretBoundsInScreen=path.localToScreen(边界);
}
});
插入符号=路径;
});
}
}
};
textArea.setWrapText(true);
setVgrow(textArea,Priority.ALWAYS);
ListView列表=新建ListView();
列表.setPrefSize(150200);
list.getItems().addAll(“一”、“二”、“三”);
Popup Popup=新的Popup();
popup.setAutoHide(true);
popup.getContent().addAll(列表);
按钮显示=新按钮(“显示列表视图”);
显示设置动作(e->{
show(插入符号,caretBoundsInScreen.getMinX(),caretBoundsInScreen.getMaxY());
});
root.getChildren().addAll(show,textArea);
textArea.setText(“Lorem ipsum door sit amet,concetetur adipiscing elit,sed do eiusmod temporal incidedut ut laboure and 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.textProperty().addListener(新的ChangeListener())
{
@凌驾

public void changed(observevalueone快速建议,您不需要每次都创建Popup和ListView实例。我建议将它们移出侦听器,只需更新ListView的内容并在所需位置显示Popup。好的,收到了,谢谢
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.");
    }
}
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();
                }
            }
        }
            
            
    });