在javafx中创建自动完成搜索表单

在javafx中创建自动完成搜索表单,java,javafx,Java,Javafx,想知道我想要什么 单击文本字段时,会出现下拉列表,其中包含用户在文本字段中键入时过滤掉的建议。箱子的高度也应实时调整,以容纳所有物品,或最多10件物品 我用一个组合框设法让它在某种程度上起作用,但它的边缘感觉有点粗糙,似乎不可能达到我想要的效果(除非关闭并重新打开下拉列表,否则它不会调整大小) 新想法是,创建一个文本字段,然后在下拉列表中显示一个按钮的VBox。唯一的问题是,我不知道如何定位下拉列表,使其不会停留在noral流中,从而可以覆盖文本字段下方的任何现有元素。有什么想法吗?您想做的事

想知道我想要什么

单击文本字段时,会出现下拉列表,其中包含用户在文本字段中键入时过滤掉的建议。箱子的高度也应实时调整,以容纳所有物品,或最多10件物品

我用一个组合框设法让它在某种程度上起作用,但它的边缘感觉有点粗糙,似乎不可能达到我想要的效果(除非关闭并重新打开下拉列表,否则它不会调整大小)


新想法是,创建一个文本字段,然后在下拉列表中显示一个按钮的VBox。唯一的问题是,我不知道如何定位下拉列表,使其不会停留在noral流中,从而可以覆盖文本字段下方的任何现有元素。有什么想法吗?

您想做的事情已经实现了,并且已经包含在中。它是开源的,我认为它会满足您的需要。看起来有点像这样


您甚至可以向它添加自定义节点,以便<代码>交叉< /代码>也可以完成。

请考虑此“强”示例>,您可以将该想法应用到您的项目中。

import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class SearchFormJavaFX  extends Application{

    @Override
    public void start(Stage ps) throws Exception {
        String[] options = {"How do I get a passport",
                            "How do I delete my Facebook Account",
                            "How can I change my password",
                            "How do I write some code in my question :D"}; 

        // note that you don't need to stick to these types of containers, it's just an example
        StackPane root = new StackPane();
        GridPane container = new GridPane();
        HBox searchBox = new HBox();

        ////////////////////////////////////////////////////

        TextField text = new TextField(); 

        // add a listener to listen to the changes in the text field
        text.textProperty().addListener((observable, oldValue, newValue) -> {
            if(container.getChildren().size()>1){ // if already contains a drop-down menu -> remove it 
                container.getChildren().remove(1);
            }
            container.add(populateDropDownMenu(newValue, options),0,1); // then add the populated drop-down menu to the second row in the grid pane
        });

        // those buttons just for example
        // note that you can add action listeners to them ..etc
        Button close = new Button("X");
        Button search = new Button("Search");
        searchBox.getChildren().addAll(text,close,search);


        /////////////////////////////////////////////////

        // add the search box to first row
        container.add(searchBox, 0, 0);
        // the colors in all containers only for example
        container.setBackground(new Background(new BackgroundFill(Color.GRAY, null,null)));
        ////////////////////////////////////////////////

        root.getChildren().add(container);

        Scene scene = new Scene(root, 225,300);
        ps.setScene(scene);
        ps.show();


    }


    // this method searches for a given text in an array of Strings (i.e. the options)
    // then returns a VBox containing all matches
    public static VBox populateDropDownMenu(String text, String[] options){
        VBox dropDownMenu = new VBox();
        dropDownMenu.setBackground(new Background(new BackgroundFill(Color.GREEN, null,null))); // colors just for example
        dropDownMenu.setAlignment(Pos.CENTER); // all these are optional and up to you

        for(String option : options){ // loop through every String in the array
            // if the given text is not empty and doesn't consists of spaces only, as well as it's a part of one (or more) of the options
            if(!text.replace(" ", "").isEmpty() && option.toUpperCase().contains(text.toUpperCase())){ 
                Label label = new Label(option); // create a label and set the text 
                // you can add listener to the label here if you want
                // your user to be able to click on the options in the drop-down menu
                dropDownMenu.getChildren().add(label); // add the label to the VBox
            }
        }

        return dropDownMenu; // at the end return the VBox (i.e. drop-down menu)
    }



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

}

公共邮件(文本字段接收){
ArrayList=新建ArrayList();
对于(int i=0;i
目前真的没有什么可分享的。在我做任何其他事情之前,我仍在试图弄清楚如何使项目脱离正常流程。谢谢你的回复,但这是一个大学项目,所以我不能使用任何第三方库。我将试着通读一遍,看看是否能弄明白他们是如何做到的。@Alex请将代码复制粘贴到您的IDE中,然后自己尝试。我知道颜色不太令人惊奇,但这只是一个例子:)这基本上是我想要的一切,但问题是下拉列表不会悬停在其他所有内容上,因此如果我在文本字段下面添加另一个元素,下拉菜单会将其向下推。@Alex我重新阅读了你的评论,我看到了你在说什么。。。请阅读有关
StackPane
属性的更多信息,因为它可以做您想要做的事情(即,在堆栈窗格中的文本字段下放置其他元素,然后以与上一个索引相同的方式添加和删除下拉菜单)。这就是我第一次让你写代码的方式。但是,功能已经实现,您需要的是与您的问题无关的结构!另外,我问的唯一问题是关于结构。再说一遍,我要为此承担责任,我希望如果我问一个更具体的问题,有人会告诉我另一种方法。不过,我可能应该特别问一下定位问题。并不是说我不欣赏你所做的。任何花时间帮助我的人都很棒!谢谢你这么做,真的。它只是没有回答我的问题。@Alex砰砰地一声,别担心:)这用图书馆吗?就我所见,CustomTextField和TextFields不是类。是的,TextField是javafx.scene.control.TextField的defaut类,CustomTextField是control Fx库中的类
public void pushEmails(TextField Receptient) {
    ArrayList<CustomTextField> list = new ArrayList<>();

    for (int i = 0; i < Sendemails.size(); i++) {
        CustomTextField logo=new CustomTextField(Sendemails.get(i));
        ImageView logoView=new ImageView(new Image("/Images/Gmail.png"));
        logo.setRight(logoView);
        list.add(logo);
    }

    TextFields.bindAutoCompletion(Receptient, list);
}