ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

JavaFx:如何在GridPane中比较动态创建的TextFields的值?

2019-10-09 01:14:12  阅读:442  来源: 互联网

标签:java javafx javafx-8 javafx-2


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

enter image description here

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

enter image description here

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

enter image description here

我正在创建像这样的TextField:

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

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

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

我尝试这样做,但它不起作用(这里我将值转换为字符串并仅比较检查):

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

解决方法:

实际上,做你想做的事情并不容易,因为你需要重构代码(代码并不是要做这样的高级要求,但它对你的基本要求很好).但是,你可以这样做:

首先,使用无效TextField的最后一行索引定义要更新的全局变量(从此处您将得出结论,这将一次更改一个无效TextField的边框颜色):

public static int textFieldIndex = -1;

现在,在已经有getComponent(int row,int column,GridPane表)的方法的帮助下,创建另一个静态方法来检查所有TextFields是否一次都有有效值:

/**
* 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; 
}

现在,您需要在validateTable()方法中使用上述方法并进行一些调整:

// 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的值:

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());
}

测试

Test

标签:java,javafx,javafx-8,javafx-2
来源: https://codeday.me/bug/20191009/1875652.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有