2016-10-29 24 views
0

我在寫這段代碼時遇到問題。該項目是一個密碼管理器應用程序,併爲這個當前衝刺我創建了一個Password模型和其他類持有PasswordArrayList一個叫做PasswordList。我在每個控制器類作爲private變量來創建一個PasswordList對象,並通過加載下一個場景的控制和設置PasswordList沿傳遞當前控制器的PasswordList(使同一列表在整個項目通過)。但是,創建一個新的Password對象時,將其添加到這個PasswordList,然後切換場景時,PasswordListnull在場景之間傳遞參數的麻煩

所以,我有一個PasswordUI這是查看器,從那裏用戶可以點擊「添加」按鈕來查看CreatePasswordUI。我已經過測試,確保密碼已創建併成功添加到PasswordList,方法是將其打印到控制檯並使用調試器,然後檢查所有內容。我甚至可以返回添加另一個密碼,並且該列表仍然具有以前創建的所有對象Password。然而,在PasswordUI,將PasswordList還是來了作爲null即使我從以前的現場傳遞PasswordList

我堅持,不知道該怎麼辦。

public class PasswordUIController implements Initializable { 

    private PasswordList passList; 
    /** 
    * Initializes the controller class. 
    */ 
    @FXML 
    TreeTableView passwordInfo; 
    @FXML 
    TreeTableColumn<String,String> acctColumn; 
    @FXML 
    Parent root; 
    @FXML 
    private void backButtonAction(ActionEvent event) throws Exception { 
     Stage stage = (Stage) root.getScene().getWindow(); 
     FXMLLoader loader = new FXMLLoader(getClass().getResource("MainMenuUI.fxml"));  
     Pane mainMenuUI = (Pane)loader.load();   
     MainMenuController controller = loader.<MainMenuController>getController(); 
     controller.setPassList(passList); 

     Scene scene = new Scene(mainMenuUI); 
     stage.setTitle("Main Menu"); 
     stage.setScene(scene); 
     stage.show(); 
    } 
    @FXML 
    private void addButtonAction(ActionEvent event) throws Exception { 
     Stage stage = (Stage) root.getScene().getWindow(); 
     FXMLLoader loader = new FXMLLoader(getClass().getResource("CreatePasswordUI.fxml"));  
     Pane createPassUI = (Pane)loader.load();   
     CreatePasswordUIController controller = loader.<CreatePasswordUIController>getController(); 
     controller.setPassList(passList); 

     Scene scene = new Scene(createPassUI); 
     stage.setTitle("Create Password"); 
     stage.setScene(scene); 
     stage.show(); 
    } 
    @Override 
    public void initialize(URL url, ResourceBundle rb) { 
     PasswordList pList = passList; 
     if (pList != null) { 
      ArrayList<Password> thePasswords = pList.getPasswordList();   
      TreeItem<String> passwords = new TreeItem<>("Passwords"); 
      for (int i = 0; i < thePasswords.size(); i++) { 
       Password thePass = thePasswords.get(i); 
       //Creating tree items 
       TreeItem<String> username = new TreeItem<>("Username: " + thePass.getUsername()); 
       TreeItem<String> password = new TreeItem<>("Password: " + thePass.getPassword()); 
       TreeItem<String> comment = new TreeItem<>("Comment: " + thePass.getComment()); 

       //Creating the root element 
       TreeItem<String> account = new TreeItem<>(thePass.getAccount()); 
       account.setExpanded(true); 

       //Adding tree items to the root 
       account.getChildren().setAll(username, password, comment); 
       passwords.getChildren().add(account); 
      } 
      //Creating a column 
      acctColumn = new TreeTableColumn<>("Account"); 

      //Defining cell content 
      acctColumn.setCellValueFactory(new Callback<TreeTableColumn.CellDataFeatures<String, String>, ObservableValue<String>>() { 
       @Override 
       public ObservableValue<String> call(TreeTableColumn.CellDataFeatures<String, String> param){ 
        return new SimpleStringProperty(param.getValue().getValue()); 
       } 
      }); 

      //Creating a tree table view 
      passwordInfo = new TreeTableView<>(); 
      passwordInfo.setRoot(passwords); 
      passwordInfo.getColumns().add(acctColumn); 
     } else { 

     } 
    }  

    /** 
    * @return the passList 
    */ 
    public PasswordList getPassList() { 
     return passList; 
    } 

    /** 
    * @param passList the passList to set 
    */ 
    public void setPassList(PasswordList passList) { 
     this.passList = passList; 
    } 

} 

public class CreatePasswordUIController implements Initializable { 

    private PasswordList passList; 
    /** 
    * Initializes the controller class. 
    */ 
    @FXML 
    Parent root; 
    @FXML 
    TextField accountTxt; 
    @FXML 
    TextField usernameTxt; 
    @FXML 
    TextField passwordTxt; 
    @FXML 
    TextField passwordTxt2; 
    @FXML 
    TextArea commentArea; 
    @FXML 
    TextField passwordGeneratorTxt; 
    @FXML 
    Label rating; 
    @FXML 
    Label matching; 
    @FXML 
    Label incorrect; 
    @FXML 
    private void backButtonAction(ActionEvent event) throws Exception { 
     Stage stage = (Stage) root.getScene().getWindow(); 
     FXMLLoader loader = new FXMLLoader(getClass().getResource("MainMenuUI.fxml"));  
     Pane mainMenuUI = (Pane)loader.load();   
     MainMenuController controller = loader.<MainMenuController>getController(); 
     controller.setPassList(passList); 

     Scene scene = new Scene(mainMenuUI); 
     stage.setTitle("Main Menu"); 
     stage.setScene(scene); 
     stage.show(); 
    } 
    @FXML 
    private void submitButtonAction(ActionEvent event) throws Exception { 
     String account = accountTxt.getText(); 
     String username = usernameTxt.getText(); 
     String password = passwordTxt.getText(); 
     String password2 = passwordTxt2.getText(); 
     String comment = commentArea.getText(); 
     if (password.equals(password2) && username.length()>2) { 
      PasswordList pList = passList; 
      Password thePass = new Password(account, username, password, comment); 
      pList.addPassword(thePass); 
      Stage stage = (Stage) root.getScene().getWindow(); 
      FXMLLoader loader = new FXMLLoader(getClass().getResource("PasswordUI.fxml"));  
      Pane passwordUI = (Pane)loader.load();   
      PasswordUIController controller = loader.<PasswordUIController>getController(); 
      controller.setPassList(pList); 

      Scene scene = new Scene(passwordUI); 
      stage.setTitle("Password"); 
      stage.setScene(scene);  
      stage.show(); 
     } else { 
      incorrect.setVisible(true); 
     } 
    } 
    @FXML 
    private void generateButtonAction(ActionEvent event) { 
     PasswordGenerator passGen = new PasswordGenerator(); 
     String password = passGen.generatePassword(true); 
     passwordGeneratorTxt.setText(password); 
    } 
    @Override 
    public void initialize(URL url, ResourceBundle rb) { 
     PasswordRater rater = new PasswordRater(); 
     passwordTxt.textProperty().addListener(new ChangeListener() { 
      @Override 
      public void changed(ObservableValue observable, Object oldVal,Object newVal) { 
       String password = passwordTxt.getText(); 
       rater.setPassword(password); 
       String ratingStr = rater.displayLevel(); 
       rating.setText(ratingStr); 
       rating.setVisible(true); 
       if (passwordTxt.getText().equals(passwordTxt2.getText()) && !password.equals("")) { 
        matching.setText("Good!"); 
       } 
       else 
       { 
        matching.setText("Passwords do not match."); 
       } 
      } 
     }); 
     passwordTxt2.textProperty().addListener(new ChangeListener() { 
      @Override 
      public void changed(ObservableValue observable, Object oldVal,Object newVal) { 
       String password = passwordTxt.getText(); 
       String password2 = passwordTxt2.getText(); 
       if (password.equals(password2) && !password.equals("")) { 
        matching.setText("Good!"); 
       } else { 
        matching.setText("Passwords do not match."); 
       } 
       matching.setVisible(true); 
      } 
     }); 
    }  

    /** 
    * @return the passList 
    */ 
    public PasswordList getPassList() { 
     return passList; 
    } 

    /** 
    * @param passList the passList to set 
    */ 
    public void setPassList(PasswordList passList) { 
     this.passList = passList; 
    } 

} 

回答

0

具有在每個控制器一個新的密碼列表的問題是,每次被創建,你基本上是在一個單獨的方法尋找一個新的實例。 要麼你可以嘗試單例,就像在整個應用程序中只創建一個對象一樣,或者爲了更簡單的方法,你可以在主類中有一個靜態列表,然後在隨後的控制器中重用它。

0

如果使用fx:controller屬性指定的FXML文件中的控制器和不指定控制器工廠,FXMLLoader procedes如下:輸入

    1. load()方法在讀fx:controller屬性創建在屬性值中指定的控制器類的新實例。
    2. fx:id屬性的任何元件被注入到控制器實例的approprieate字段。
    3. 控制器的initialize方法被調用時,如果有一個
    4. load()完成返回被FXML文件

    的根元素創建的元素對於

    FXMLLoader loader = new FXMLLoader(getClass().getResource("CreatePasswordUI.fxml"));  
    Pane createPassUI = (Pane)loader.load();   
    CreatePasswordUIController controller = loader.<CreatePasswordUIController>getController(); 
    controller.setPassList(passList); 
    

    但是工作你」 d需要不同的操作順序:

    1. 
    2. 
    3. 
    5. 
    controller.setPassList(passList); 
    4. 
    

    如果要以這種方式創建控制器,請將用於初始化TreeTableView的代碼移動到setPassList方法。

    順便說一句:我很確定創建一個新的TreeTableView是不是你想要的。相反,你應該將數據集由FXMLLoader創建的現有TreeTableView

    PasswordUIController

    @Override 
    public void initialize(URL url, ResourceBundle rb) { 
        // displaying the item itself in the TreeTableColumn defys 
        // the purpose of Tree**Table**View, but we'll ignore this here 
        acctColumn.setCellValueFactory(new Callback<TreeTableColumn.CellDataFeatures<String, String>, ObservableValue<String>>() { 
         @Override 
         public ObservableValue<String> call(TreeTableColumn.CellDataFeatures<String, String> param){ 
          return new SimpleStringProperty(param.getValue().getValue()); 
         } 
        }); 
    } 
    
    public void setPassList(PasswordList passList) { 
        if (passList == null) { 
         throw new IllegalArgumentException(); 
        } 
        this.passList = passList; 
    
        ArrayList<Password> thePasswords = passList.getPasswordList();   
        TreeItem<String> passwords = new TreeItem<>("Passwords"); 
        for (int i = 0; i < thePasswords.size(); i++) { 
         Password thePass = thePasswords.get(i); 
         //Creating tree items 
         TreeItem<String> username = new TreeItem<>("Username: " + thePass.getUsername()); 
         TreeItem<String> password = new TreeItem<>("Password: " + thePass.getPassword()); 
         TreeItem<String> comment = new TreeItem<>("Comment: " + thePass.getComment()); 
    
         //Creating the root element 
         TreeItem<String> account = new TreeItem<>(thePass.getAccount()); 
         account.setExpanded(true); 
    
         //Adding tree items to the root 
         account.getChildren().setAll(username, password, comment); 
         passwords.getChildren().add(account); 
        } 
    
        // set content of the TreeTableView 
        passwordInfo.setRoot(passwords); 
    } 
    

    有將數據傳遞到FXML控制器的其他方式。你可以在這裏找到一些很好的答案:Passing Parameters JavaFX FXML