2016-10-29 4 views
0

私が書いているこのコードに問題があります。このプロジェクトはパスワードキーパーアプリです。この現在のスプリントではPasswordモデルを作成し、ArrayListPasswordPasswordListとする別のクラスを作成しました。私はすべてのコントローラークラスのPasswordListオブジェクトをprivate変数として作成し、次のシーンのコントローラーをロードし、現在のコントローラーPasswordListPasswordListを設定することで、同じリストがプロジェクト全体に渡されるようにします。ただし、新しいPasswordオブジェクトを作成し、これをこのPasswordListに追加してシーンを切り替えると、PasswordListnullになります。シーン間のパラメータの受け渡しに問題があります

私はPasswordUIを視聴しており、そこからユーザーは「追加」ボタンをクリックしてCreatePasswordUIを見ることができます。私は、パスワードが作成され、PasswordListにコンソールに出力し、デバッガを使用して正常に追加されたことを確認しました。すべてがチェックアウトされています。私は別のパスワードを追加するために戻ることができ、リストにはこれまでのすべてのPasswordオブジェクトが作成されています。しかし、PasswordUIでは、前のシーンからPasswordListを渡していても、PasswordListはまだnullとなっています。

私は立ち往生して何をすべきかわかりません。

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

すべてのコントローラに新しいパスワードのリストを持つ問題は、毎回新しいインスタンスが作成され、あなたは基本的にシングルトンのアプローチを見ているということです。 シングルトンは、アプリケーション全体で1つのオブジェクトしか作成されないようにすることも、簡単な方法でメインクラスに1つの静的リストを作成して、それを後続のコントーラで再利用することもできます。

0

あなたがfx:controller属性を使用してFXMLファイルでコントローラを指定し、コントローラファクトリを指定しない場合、FXMLLoader procedes次のように:fx:controller属性が読み込まれたとき

  1. load()方法は
  2. を入力します属性値で指定されたコントローラクラスの新しいインスタンスが作成されます。
  3. 属性がfx:idのすべての要素が、コントローラインスタンスの適切なフィールドに挿入されます。
  4. しかし、あなたの仕事に

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

    についてFXMLファイルのルート要素

用に作成された要素を返す1

  • load()完了がある場合は、コントローラのinitializeメソッドは」と呼ばれています異なる操作順序が必要:

    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

  • 関連する問題