JavaFx:如何验证在运行时创建的多功能TextField? [英] JavaFx: How to validate mutilple TextFields creating at run time?

查看:51
本文介绍了JavaFx:如何验证在运行时创建的多功能TextField?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在运行时使用for循环创建多个TextField,并将其添加到Gridpane(具有8列)中,如下所示:

I am creating multiple TextFields at run time using for-loop and adding them to inside Gridpane(which has 8 columns) like this:

public static GridPane table(int rows){
            GridPane table = new GridPane();

            for(int i=0; i<rows; i++){
            JFXTextField textField1 = new JFXTextField();
            textField1.setAlignment(Pos.CENTER);
            JFXTextField textField2 = new JFXTextField();
            textField1.setAlignment(Pos.CENTER);
            JFXTextField textField3 = new JFXTextField();
            textField1.setAlignment(Pos.CENTER);
            JFXTextField textField4 = new JFXTextField();
            textField1.setAlignment(Pos.CENTER);
            JFXTextField textField5 = new JFXTextField();
            textField1.setAlignment(Pos.CENTER);
            JFXTextField textField6 = new JFXTextField();
            textField1.setAlignment(Pos.CENTER);
            JFXTextField textField7 = new JFXTextField();
            textField1.setAlignment(Pos.CENTER);
            JFXTextField textField8 = new JFXTextField();
            textField1.setAlignment(Pos.CENTER);

            //add them to the GridPane
            table.add(textField1, 0, i+1);
            table.add(textField2, 1, i+1);
            table.add(textField3, 2, i+1);
            table.add(textField4, 3, i+1);
            table.add(textField5, 4, i+1);
            table.add(textField6, 5, i+1);
            table.add(textField7, 6, i+1);
            table.add(textField8, 7, i+1);
         }
        return table;
    }

下一步,我正在创建另一个方法,以从表中特定行和列返回组件,如下所示:

Next I'm creating another method to return component from table at specific row and column like this:

public static Node getComponent (int row, int column, GridPane table) {
         for (Node component : table.getChildren()) { // loop through every node in the table
             if(GridPane.getRowIndex(component) == row && 
                             GridPane.getColumnIndex(component) == column) {
                 return component;
             }
         }

         return null;
     }

问题在这里:我想验证每个TextField,因此如果用户忘记写任何TextField,我想禁用Button,为此,我正在使用绑定像这样:

Problem is here: I want to validate each of the TextField, so if user forget to write in any of the TextField, I want to disable the Button, for this purpose I'm using binding like this:

 private void validatingGrid() {
        GridPane table = (GridPane) anchorPane().getChildren().get(0);

        for(int i=1 ; i<=comboBox().getValue(); i++){
            JFXTextField text0 = ((JFXTextField)getComponent (i, 0, table));
            JFXTextField text1 = ((JFXTextField)getComponent (i, 1, table));
            JFXTextField text2 = ((JFXTextField)getComponent (i, 2, table));
            JFXTextField text3 = ((JFXTextField)getComponent (i, 3, table));
            JFXTextField text4 = ((JFXTextField)getComponent (i, 4, table));
            JFXTextField text5 = ((JFXTextField)getComponent (i, 5, table));
            JFXTextField text6 = ((JFXTextField)getComponent (i, 6, table));
            JFXTextField text7 = ((JFXTextField)getComponent (i, 7, table));

                button.disableProperty().bind(
                        Bindings.isEmpty(text0.textProperty())
                        .or(Bindings.isEmpty(text1.textProperty()))
                        .or(Bindings.isEmpty(text2.textProperty()))
                        .or(Bindings.isEmpty(text3.textProperty()))
                        .or(Bindings.isEmpty(text4.textProperty()))
                        .or(Bindings.isEmpty(text5.textProperty()))
                        .or(Bindings.isEmpty(text6.textProperty()))
                        .or(Bindings.isEmpty(text7.textProperty()))
                    );
                }
     }

但是发生的是它仅验证最后一行,如果我在Gridpane中创建3行textfeilds,那么它仅验证第三行而不是第一行和第二行,并且基于第三行条目,它启用了按钮,但是我想在验证所有行之后应启用按钮,否则不启用.请帮助我如何实现这一目标.

But what's happening is it's only validating last row, let say if I create 3 rows of textfeilds in the Gridpane, so it's only validating 3rd row not 1st and 2nd rows and on the basis of 3rd row entries it's enabling the button but I want after validating all of the rows it should enable button otherwise not. Please help me how can I achieve this.

推荐答案

您的绑定逻辑是正确的.但是,由于for loop [for(int i=1 ; i<=comboBox().getValue(); i++)]而引起的问题使您的工作陷于瘫痪.所有TextFields的列索引为 0,唯一的变化是行索引.因此,对于for loop中的所有TextFields,您应该使用getComponent(i, 0, table);,而不必将列索引更改为12 ..等等.但这也无法解决问题,因为在每个循环中,您都将 ALL TextFields分配给相同的 index ,然后将其覆盖在每个循环中,直到它们全部指向索引comboBox().getValue()和列0上的TextField(这就是为什么它适用于您提到的最后一行).

Your binding logic is correct. However, the problem because of the for loop [for(int i=1 ; i<=comboBox().getValue(); i++)], which ruins your work. All TextFields are at column index 0 and the only thing changes is the row index. So you should use getComponent(i, 0, table); for all TextFields in your for loop without changing the column index to 1 , 2 .. and so on. But that also won't solve the problem because in every loop you're assigning ALL TextFields to the same index and then overwrites it in every loop until all of them points to the TextField at index comboBox().getValue() and column 0 (That's why it's working for the last row as you mentioned).

我建议使用其他方法,例如:

I would suggest different approach, something like this:

首先,您需要一种方法来检查所有其他TextFields是否已填充/不为空:

First You need a method to check if all other TextFields are filled/ not empty:

/**
* Check if all the TextFields are filled and not empty
* @param table
*/
 private static boolean isAllFilled(GridPane table){
    for(Node node : table.getChildren()){ // cycle through every component in the table (GridPane)
        if(node instanceof TextField){ // if it's a TextField
        // after removing the leading spaces, check if it's empty
            if(((TextField)node).getText().trim().isEmpty()){
                    return false; // if so, return false
            }
        }       
    }
    return true;
 }

其次,听表中每个TextField的文本更改,并进行每次更改,检查所有其他TextField是否已填充/不为空:

Secondly, Listen to the Text Changes for every TextField in the Table, and with every change, check if all other TextField are filled / not empty:

/**
* To Validate the Table (GridPane)
* This method should be added to the tabPane change listener
* @param table
* @param button
*/
private void validateTable(GridPane table, Button button) {

   for(Node node : table.getChildren()){ // cycle through every component in the table (GridPane)
      if(node instanceof TextField){ // if it's a TextField
        ((TextField)node).textProperty().addListener((obs, old, newV)->{ // add a change listener to every TextField
        // then check if the new value is not empty AND all other TextFields are not empty
          if(!newV.trim().isEmpty()&&isAllFilled(table)){ 
             button.setDisable(false); // then make the button active again
          }
          else{
              button.setDisable(true); // or else, make it disable until it achieves the required condition 
          }
      });
   }    
}

此外,您需要将按钮设置为在创建后禁用一次.

Button button = new Button("Test"); 
button.setDisable(true);

最后,您需要在tabPane更改侦听器块中添加该方法:

Finally, you need to add the method in the tabPane Change Listener Block:

tabPane.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Tab>(){
      .........
      .........
      .........
      validateTable((GridPane) anchorPane().getChildren().get(0), test);
}


测试

这篇关于JavaFx:如何验证在运行时创建的多功能TextField?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆