JavaFx:如何在GridPane中比较动态创建的TextFields的值? [英] JavaFx: How to compare values of dynamically created TextFields inside GridPane?

查看:162
本文介绍了JavaFx:如何在GridPane中比较动态创建的TextFields的值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用JavaFx开发一个应用程序,其中我在GridPane中创建动态TextFields,并且有一个Button最初被禁用,如下所示:

I'm developing an application using JavaFx in which I'm creating dynamic TextFields inside a GridPane and there is a Button which is initially disabled like this:

< a href =https://i.stack.imgur.com/vnw6E.png =nofollow noreferrer>

所以我想要的是如果第1列TextFields值小于第3列TextFields值,则按钮应该像这样启用:

So what I want is if Column 1 TextFields values are less than Column 3 TextFields values, button should be enable like this:

但是,如果任何一列,请说3 TextField值变得小于同一行的第1列TextField值,它应禁用按钮并以红色显示特定的TextField边框,并将鼠标悬停在该字段上时应显示一些警告:

But let say if any of Column 3 TextField value become less than Column 1 TextField value of same row, it should disable button and show that specific TextField border in red color and when hover mouse over that field should display some warning:

我正在创建这样的TextField:

I'm creating TextField like this:

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

            for(int i=0; i<rows; i++){
            TextField textField1 = new JFXTextField();
            textField1.setAlignment(Pos.CENTER);
            TextField textField2 = new JFXTextField();
            textField2.setAlignment(Pos.CENTER);
            TextField textField3 = new JFXTextField();
            textField3.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);
         }
        return table;
    }

之后我正在创建另一个方法来从特定行的表返回组件和列如下:

After that 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;
     }

我试图这样做,但它没有用(我在这里转换)将值转换为字符串并仅比较检查):

I tried to do like this but it's not working (Here I'm converting values into string and comparing just for the check):

private boolean isTextEqual(GridPane table, Button button){

        for(Node node : table.getChildren()){ 
            if(node instanceof TextField){
                for(int i=1 ; i<=ComboBox().getValue(); i++){
                    String str = ((TextField)DynamicGridpanes.getComponent (i, 0, table)).getText();
                    ((TextField)DynamicGridpanes.getComponent (i, 2, table)).textProperty().addListener((obs, old, newV)->{ 
                    if(newV.toString()==str){
                        button.setDisable(false);
                    }
                    else{
                        button.setDisable(true);
                    }
                 });
                    }
                }
            }

        return true;
    }


推荐答案

实际上它并不容易做你想做的事,因为你需要重构你的代码(代码不是为了达到这样的高级要求,但它对于你的基本要求是好的)。但是,您可以执行以下操作:

Actually it's not that easy to do what you want, because the code you have needs to be refactored (the code is not meant to do such advanced requirements but it's fine for the basic requirements you have). However, you can do something like this:

首先,使用全局变量>无效 TextField 的最后一行索引(从这里你可以得出结论,这将改变一个无效<$ c的边框颜色$ c> TextField 一次):

First, define a global variable to be updated with the last row index of the invalid TextField (From here you shall conclude that this will change the border color for ONE invalid TextField at a time):

public static int textFieldIndex = -1;

现在借助该方法您已经拥有 getComponent( int row,int column,GridPane table),创建另一个静态方法来检查 ALL TextFields 是否有有效值一次:

Now with the help of the method you already have getComponent (int row, int column, GridPane table), create another static method to check if ALL TextFields have Valid Values at one time:

/**
* This method to check at run time with every change in any TextField 
* if the corresponding TextField has a valid value(i.e contains number and
* the first TextField value is less than the second)
* @param table
* @param numRows
*/
private static boolean hasValidValue(GridPane table, int numRows){
   // cycle through every row in the table
   // and compare every two TextFields
   for(int i=0; i<numRows; i++){
      try{ // try because user may enters a non-number input (to avoid crash)
         // the first TextField is always at column index 0 , the second at column index 3
         if(Integer.parseInt(((TextField)(getComponent (i, 0, table))).getText())>
            Integer.parseInt(((TextField)(getComponent (i, 3, table))).getText())){
            // before returning false
            textFieldIndex = i; // update at which row the TextField is less
            return false;
          }
       }catch(NumberFormatException e){ // if it contains invalid input(non-digit)
            return false;
       }
   }
   return true; 
}

现在你需要在<$ c中使用上述方法$ c> validateTable()方法并进行一些调整:

Now you need to use the above method in the validateTable() method and do some adjustments:

// pass the comboBox.getValue() to the third parameter
private void validateTable(GridPane table, Button button, int numRows) {

   for(Node textField : table.getChildren()){ 
      if(textField instanceof TextField){
         ((TextField)textField).textProperty().addListener((obs, old, newV)->{
           // first of all remove the red border from the invalid TextField (if any)
          // we know that via textFieldIndex which should be -1 if there is no lesser
          // actually it's a pain 
          if(textFieldIndex!=-1){
            ((TextField) getComponent(textFieldIndex, 3, table)).setStyle("");
          }
          if(isAllFilled(table)){ // if all filled ( you already have this method)
             if(hasValidValue(table,numRows)){ // check for validity
                button.setDisable(false); // then make the button active again
             }
             else{// if it's not a valid value
                  // re-style the TextField which has lesser value
                 ((TextField) getComponent(textFieldIndex, 3, table)).
                                        setStyle("-fx-border-color: red;");
                  button.setDisable(true); 
             }
          }
          else{
               button.setDisable(true);
          }
       });
     }  
   }
}

现在在你的 tabPane ChangeListener 在方法中添加第三个para(因为你已经拥有它,你只需要添加 ComboBox 的值:

Now in your tabPane ChangeListener add the third para to the method (because you already have it you need just to add the value of ComboBox:

tabPane.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Tab>(){
   ....
   ....
   ....
   // I think you have here anchorPane not containerB in the original code
   validateTable((GridPane) containerB.getChildren().get(0), test, comboBox.getValue());
}






测试

这篇关于JavaFx:如何在GridPane中比较动态创建的TextFields的值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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