JavaFXTableView作为组合框弹出窗口(已尝试并能够部分实现。需要进一步帮助)

JavaFXTableView作为组合框弹出窗口(已尝试并能够部分实现。需要进一步帮助),javafx,java-8,javafx-8,Javafx,Java 8,Javafx 8,我需要的是: 需要一个可编辑的组合框,该组合框在键入时过滤弹出窗口上的数据,第一个匹配项应高亮显示,并应在按enter键时设置为组合框中的文本 弹出窗口应为具有2列或3列的tableview。(附屏幕截图。)(在图像中,它是一个文本字段,但我更喜欢combo,因此如果用户不确定值,他可以单击combo按钮查看整个列表并选择一个。) 我将绑定一些数据作为源到tableview,它将作为组合框的弹出窗口。 我知道我应该选择自定义控件,但不知道从哪里开始 参考网址: 提前谢谢 到目前为止,我所尝试的

我需要的是:

  • 需要一个可编辑的组合框,该组合框在键入时过滤弹出窗口上的数据,第一个匹配项应高亮显示,并应在按enter键时设置为组合框中的文本
  • 弹出窗口应为具有2列或3列的tableview。(附屏幕截图。)(在图像中,它是一个文本字段,但我更喜欢combo,因此如果用户不确定值,他可以单击combo按钮查看整个列表并选择一个。)
  • 我将绑定一些数据作为源到tableview,它将作为组合框的弹出窗口。 我知道我应该选择自定义控件,但不知道从哪里开始

    参考网址:

    提前谢谢

    到目前为止,我所尝试的:

    伙计们

    根据你们提出的想法,我已经尝试过了,并且能够实现。 (目前,我并没有在文本字段下动态显示tableview(最终,我希望显示dats wat)) 1.包含静态数据的tableview已加载并添加到场景中。 2.在tableview下面有一个文本字段。(名称为txt) 3.在第一个文本字段下面有另一个文本字段(名为txt1)(当我从上一个文本字段按tab键时,光标应该出现在这里)

    我为该表设置了一个谓词集,并且正在更新谓词,因为用户在txt中键入了谓词。(工作) 能够筛选表,并突出显示第一个匹配行。(工作) 当用户按下“Tab”或“Enter”时,tableview中突出显示的行应设置为txt中的值。(工作)

    需要: 1.当我按“Tab”或“Enter”时,高亮显示的行将被设置为文本字段(txt)中的值,并且光标应移动到下一个可聚焦节点。在我的例子中,它是第二个文本字段(txt1)。我不想实时地说txt1.requestFocus()bcoz,我在场景中有很多文本字段,这个控件将是一个用户控件。所以不能硬编码任何东西

  • 当用户在文本字段中键入一些文本(不是全文。例如:“do”,其中我的表包含“Dom”、“Don”),如果存在多个匹配项,当前表中将显示这两个记录,但第一个记录将突出显示。用户应该能够选择第二行,如果他想按向下箭头从文本字段本身
  • 主类 MainController.java application.css MainView.fxml
    
    
    TableView.fxml
    
    

    感谢您的帮助。谢谢

    您的问题有点宽泛,可能有很多方法可以解决,但我将从
    文本字段
    弹出控件
    中显示的
    表格视图
    开始。对表的数据使用
    FilteredList
    ,谓词绑定到文本字段中的text属性。太棒了!谢谢你的推送启动。让我从一个文本字段开始。请提供任何示例代码或示例。哪一部分:这里有几部分。有关表筛选的信息,请参见。剩下的只是简单的编码,我想。。。真的,如果你在某个阶段遇到困难,你只需要尝试一下这个,然后发布一些具体的问题。我可以做一些我已经在一些地方实现的表格过滤,并且工作正常。只需按一下textfield键即可显示带有tableview的弹出窗口。与此同时,我也会努力。谢谢嘿,我已经更新了。你能进一步指导我吗?
    package application;
    
    import javafx.application.Application;
    import javafx.fxml.FXMLLoader;
    import javafx.scene.Scene;
    import javafx.scene.layout.VBox;
    import javafx.stage.Stage;
    
    
    public class Main extends Application {
        @Override
        public void start(Stage primaryStage) {
            try {
                VBox root = FXMLLoader.load(this.getClass().getResource("MainView.fxml"));
                Scene scene = new Scene(root,500,300);
                scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
                primaryStage.setScene(scene);
                primaryStage.show();
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    
    package application;
    
    import java.io.IOException;
    import java.net.URL;
    import java.util.ResourceBundle;
    
    import javafx.application.Platform;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.collections.transformation.FilteredList;
    import javafx.event.ActionEvent;
    import javafx.event.EventHandler;
    import javafx.fxml.FXML;
    import javafx.fxml.FXMLLoader;
    import javafx.fxml.Initializable;
    import javafx.scene.Parent;
    import javafx.scene.control.Button;
    import javafx.scene.control.TableColumn;
    import javafx.scene.control.TableView;
    import javafx.scene.control.TextField;
    import javafx.scene.input.KeyCode;
    import javafx.scene.input.KeyEvent;
    import javafx.stage.Popup;
    
    public class MainController implements Initializable
    {
        private @FXML TableView<Person> table;
        private @FXML TableColumn<Person, String> firstNameCol;
        private @FXML TableColumn<Person, String> lastNameCol;
        private @FXML TableColumn<Person, String> emailCol;
        private @FXML TableColumn<Person, Integer> ageCol;
        private @FXML TextField txt;
        private @FXML TextField txt1;
        private @FXML Button btn;
    
        @Override
        public void initialize(URL location, ResourceBundle resources)
        {
            Platform.runLater(new Runnable() {
                @Override
                public void run() {
                    txt.requestFocus();
                }
            });
    
            ObservableList<Person> obsList =FXCollections.observableArrayList();
            obsList.add(new Person("Sam", "P1LasttName", "P1Email@gmail.com", 20));
            obsList.add(new Person("Dom", "P2LasttName", "P2Email@gmail.com", 30));
            obsList.add(new Person("Ken", "P3LasttName", "P3Email@gmail.com", 40));
            obsList.add(new Person("Don", "P4LasttName", "P4Email@gmail.com", 50));
            obsList.add(new Person("Tom", "P5LasttName", "P5Email@gmail.com", 60));
    
    
            FilteredList<Person> filteredList = new FilteredList<>(obsList, p->true);
            table.setItems(filteredList);
    
            txt.textProperty().addListener((obs, oldValue, newValue) ->{
    
                filteredList.setPredicate(person-> {
                    if(newValue == null || newValue.isEmpty())
                        return true;
                    if(person.getFirstName().trim().toLowerCase().contains(newValue.toLowerCase()))
                        return true;
                    return false;
                });
    
                Platform.runLater(new Runnable() {
                    @Override
                    public void run()
                    {
                        // we don't want repeated selections
                        table.getSelectionModel().clearSelection();
                        //get the focus
                        table.requestFocus();
    
                        //select first item in TableView model
                        table.getSelectionModel().selectFirst();
    
                        //set the focus on the first element
                        table.getFocusModel().focus(0);
    
                        //render the selected item in the TableView
                        //tableClickHandler(null);
                    }
                });
    
                Platform.runLater(new Runnable() {
                    @Override
                    public void run()
                    {
                        txt.requestFocus();
                        txt.end();
                    }
                });
    
            });
    
            table.setOnKeyPressed(new EventHandler<KeyEvent>() {
                @Override
                public void handle(KeyEvent event)
                {
                    if(event.getCode() == KeyCode.ENTER)
                    {
                        txt.setText(table.getSelectionModel().getSelectedItem().getFirstName());
                    }
                }
            });
    
            txt.setOnKeyPressed(new EventHandler<KeyEvent>() {
                @Override
                public void handle(KeyEvent event)
                {
                    if(event.getCode() == KeyCode.ENTER || event.getCode() == KeyCode.TAB)
                    //if(event.getCode() == KeyCode.ENTER)
                    {
                        txt.setText(table.getSelectionModel().getSelectedItem().getFirstName());
                        /*Platform.runLater(new Runnable() {
                            public void run() {
                                txt1.requestFocus();
                            }
                        });*/
                    }
                }
            });
    
            /*txt.addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
                @Override
                public void handle(KeyEvent event)
                {
                    if(event.getCode() == KeyCode.TAB)
                    {
                        //txt.setText(table.getSelectionModel().getSelectedItem().getFirstName());
                        if(txt.getSkin() instanceof BehaviorSkinBase)
                        {
                            //((BehaviorSkinBase)txt.getSkin()).getBehavior().traverseNext();
                            BehaviorBase x = ((BehaviorSkinBase)txt.getSkin()).getBehavior();
                            ((TextFieldBehavior)x).callAction("TraverseNext");
                        }
                        event.consume();
                    }
                }
            });*/
    
            btn.setOnAction(new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent event)
                {
                    /*
                    Popup popup = new Popup();
                    popup.getContent().add(new TableView());
                    //popup.show(txt, txt.localToScreen(0, 0).getX() + txt.getWidth()/2, txt.localToScreen(0, 0).getY() + txt.getHeight());
                    popup.show(txt, txt.localToScreen(0, 0).getX(), txt.localToScreen(0, 0).getY() + txt.getHeight() + 2);
                    */
                    Parent vbox = null;
                    try {
                        vbox = FXMLLoader.load(this.getClass().getResource("TableView.fxml"));
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    Popup popup = new Popup();
                    popup.getContent().add(vbox);
                    //popup.show(txt, txt.localToScreen(0, 0).getX() + txt.getWidth()/2, txt.localToScreen(0, 0).getY() + txt.getHeight());
                    //popup.show(txt, txt.localToScreen(0, 0).getX(), txt.localToScreen(0, 0).getY() + txt.getHeight() + 2);
                    popup.show(txt, txt.localToScreen(0, 0).getX(), txt.localToScreen(0, 0).getY() + txt.getHeight() + 2);
                }
            });
        }
    }
    
    package application;
    
    public class Person
    {
        private String firstName;
        private String lastName;
        private String email;
        private Integer age;
    
        public Person(){}
    
        public Person(String firstName, String lastName, String email, Integer age)
        {
            this.firstName = firstName;
            this.lastName = lastName;
            this.email = email;
            this.age = age;
        }
    
        public String getFirstName()
        {
            return firstName;
        }
    
        public void setFirstName(String firstName)
        {
            this.firstName = firstName;
        }
    
        public String getLastName()
        {
            return lastName;
        }
    
        public void setLastName(String lastName)
        {
            this.lastName = lastName;
        }
    
        public String getEmail()
        {
            return email;
        }
    
        public void setEmail(String email)
        {
            this.email = email;
        }
    
        public Integer getAge()
        {
            return age;
        }
    
        public void setAge(Integer age)
        {
            this.age = age;
        }
    }
    
    .table-row-cell:selected
    {
        -fx-background-color: lightgreen;
        /* the below style will remove the border lines of the selected row */
        -fx-table-cell-border-color: transparent;
    }
    
    <?xml version="1.0" encoding="UTF-8"?>
    
    <?import javafx.geometry.Insets?>
    <?import javafx.scene.control.Button?>
    <?import javafx.scene.control.TableColumn?>
    <?import javafx.scene.control.TableView?>
    <?import javafx.scene.control.TextField?>
    <?import javafx.scene.control.cell.PropertyValueFactory?>
    <?import javafx.scene.layout.VBox?>
    
    <!-- <?import application.Person?> -->
    
    <VBox spacing="10.0" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.MainController">
       <children>
          <TableView fx:id="table" prefHeight="250.0" prefWidth="437.0">
            <columns>
              <TableColumn fx:id="firstNameCol" prefWidth="120.0" text="First Name">
              <cellValueFactory><PropertyValueFactory property="firstName" /></cellValueFactory>
              </TableColumn>
              <TableColumn fx:id="lastNameCol" prefWidth="120.0" text="Last Name">
              <cellValueFactory><PropertyValueFactory property="lastName" /></cellValueFactory>
              </TableColumn>
                <TableColumn fx:id="emailCol" prefWidth="120.0" text="Email">
                <cellValueFactory><PropertyValueFactory property="email" /></cellValueFactory>
                </TableColumn>
                <TableColumn fx:id="ageCol" prefWidth="75.0" text="Age">
                <cellValueFactory><PropertyValueFactory property="age" /></cellValueFactory>
                </TableColumn>
            </columns>
    
          </TableView>
          <Button text="Button" fx:id="btn"/>
          <TextField fx:id="txt" promptText="Type to Filter" />
          <TextField fx:id="txt1" promptText="Focus should be here when tab is pressed from pervious txt" />
       </children>
       <padding>
          <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
       </padding>
    </VBox>
    
    <?xml version="1.0" encoding="UTF-8"?>
    
    <?import javafx.scene.control.TableColumn?>
    <?import javafx.scene.control.TableView?>
    <?import javafx.scene.control.cell.PropertyValueFactory?>
    <?import javafx.scene.layout.VBox?>
    <?import application.Person?>
    <?import javafx.collections.*?>
    
    <!--
    <VBox xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.65">
    <children>
    -->
    
          <!--  <TableView xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.65" fx:id="table" prefHeight="160.0" prefWidth="440.0"> -->
          <TableView xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.65" fx:id="table" prefHeight="140.0">
            <columns>
              <TableColumn fx:id="firstNameCol" prefWidth="120.0" text="First Name">
              <cellValueFactory><PropertyValueFactory property="firstName" /></cellValueFactory>
              </TableColumn>
              <TableColumn fx:id="lastNameCol" prefWidth="120.0" text="Last Name">
              <cellValueFactory><PropertyValueFactory property="lastName" /></cellValueFactory>
              </TableColumn>
                <TableColumn fx:id="emailCol" prefWidth="120.0" text="Email">
                <cellValueFactory><PropertyValueFactory property="email" /></cellValueFactory>
                </TableColumn>
                <TableColumn fx:id="ageCol" prefWidth="75.0" text="Age">
                <cellValueFactory><PropertyValueFactory property="age" /></cellValueFactory>
                </TableColumn>
            </columns>
    
            <columnResizePolicy><TableView fx:constant="CONSTRAINED_RESIZE_POLICY" /></columnResizePolicy>
    
            <items>
            <FXCollections fx:factory="observableArrayList">
            <Person firstName="P1FirstName" lastName="P1LasttName" email="P1Email@gmail.com" age="20"/>
            <Person firstName="P2FirstName" lastName="P2LasttName" email="P2Email@gmail.com" age="30"/>
            <Person firstName="P3FirstName" lastName="P3LasttName" email="P3Email@gmail.com" age="40"/>
            <Person firstName="P4FirstName" lastName="P4LasttName" email="P4Email@gmail.com" age="50"/>
            <Person firstName="P5FirstName" lastName="P5LasttName" email="P5Email@gmail.com" age="60"/>
            </FXCollections>
            </items>
    
          </TableView>
    <!--
    </children>
    </VBox>
    -->