2017-01-27 2 views
0

유스 케이스JavaFX는 : 새로운 항목이 아이 윈도우 콤보 상자에 추가 될 때 부모 창 - 콤보 상자에 항목을 추가

부모 창 (예 : 데이터를 하나 개의 메뉴가 상단에 메뉴 바를 포함), 그 메뉴에는 단 하나의 메뉴 항목 만 포함됩니다 (예 : 가져 오기). 사용자가 '가져 오기'메뉴 항목을 선택하면 대화 상자 창이 나타납니다. 부모 창에는 comboBox도 있습니다.

대화 상자 창에는 comboBox, textField 및 버튼이 있습니다. 사용자가 textField에 텍스트를 입력하고 버튼을 클릭하면 fruit-name이라는 텍스트가 comboBox에 추가됩니다. 대화 상자를 닫을 다른 버튼이 있습니다 (여기서는 중요하지 않음).

새 항목이 대화 상자의 comboBox에 추가 될 때 상위 창의 comboBox에 새 항목을 자동으로 추가하려고하지만 원하는 결과를 얻을 수 없습니다. 바인딩이 도움이 될 수있는 comboBox 속성을 찾지 못했습니다 (철저히 조사하지 않음).

JavaFX를 처음 사용했습니다. 작동하지 않는 기능을 제외하고는 아래 코드에서 차이가 있으면 올바른 코딩 방법으로 도와주세요.

Main.java (패키지 : 문제)

package problem; 

    import java.io.IOException; 
    import javafx.application.Application; 
    import javafx.stage.Stage; 

    public class Main extends Application { 

     @Override 
     public void start(Stage primaryStage) throws IOException { 
      MainWindowController mwc = new MainWindowController(); 
      mwc.launchMainWindow(primaryStage); 
     } 

     public static void main(String[] args) { 
      launch(args); 
     } 
    } 

MainWindow.fxml (패키지 : 문제)

<?xml version="1.0" encoding="UTF-8"?> 

    <?import javafx.scene.control.ComboBox?> 
    <?import javafx.scene.control.Menu?> 
    <?import javafx.scene.control.MenuBar?> 
    <?import javafx.scene.control.MenuItem?> 
    <?import javafx.scene.layout.VBox?> 

    <VBox prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.102" xmlns:fx="http://javafx.com/fxml/1" fx:controller="problem.MainWindowController"> 
     <children> 
      <MenuBar> 
      <menus> 
       <Menu text="Data"> 
       <items> 
        <MenuItem fx:id="importMenuItem" onAction="#launchImportDialog" text="Import" /> 
       </items> 
       </Menu> 
      </menus> 
      </MenuBar> 
      <ComboBox fx:id="fruitsComboBox" prefWidth="150.0" /> 
     </children> 
    </VBox> 

MainWindowController.java (패키지 : 문제)

package problem; 

    import java.io.IOException; 
    import java.net.URL; 
    import java.util.ResourceBundle; 
    import javafx.collections.ObservableList; 
    import javafx.fxml.FXML; 
    import javafx.fxml.FXMLLoader; 
    import javafx.fxml.Initializable; 
    import javafx.scene.Scene; 
    import javafx.scene.control.ComboBox; 
    import javafx.scene.control.MenuItem; 
    import javafx.scene.layout.VBox; 
    import javafx.stage.Stage; 
    import problem.importdata.ImportDataController; 

    public class MainWindowController implements Initializable { 
     private Stage primaryStage; 
     @FXML 
     private MenuItem importMenuItem; 
     @FXML 
     private ComboBox fruitsComboBox; 

     @Override 
     public void initialize(URL location, ResourceBundle resources) { 
     } 

     public void launchMainWindow(Stage primaryStage) throws IOException { 
      this.primaryStage = primaryStage; 
      FXMLLoader loader = new FXMLLoader(Main.class.getResource("MainWindow.fxml")); 
      VBox root = loader.load(); 
      Scene scene = new Scene(root, 600, 400); 

      primaryStage.setTitle("Problem"); 
      primaryStage.setScene(scene); 
      primaryStage.show(); 
     } 

     @FXML 
     private void launchImportDialog() throws IOException { 
      new ImportDataController().launchImportDialog(primaryStage); 
     } 

     @FXML 
     public void addFruitsComboBox(String fruit) { 
      ObservableList<String> fruitsList = fruitsComboBox.getItems(); 
      fruitsList.add(fruit); 
      fruitsComboBox.setItems(fruitsList); 
     } 
    } 
,

ImportData.fxml (패키지 : problem.importdata)

<?xml version="1.0" encoding="UTF-8"?> 

    <?import javafx.scene.control.Button?> 
    <?import javafx.scene.control.ComboBox?> 
    <?import javafx.scene.control.TextField?> 
    <?import javafx.scene.layout.HBox?> 
    <?import javafx.scene.layout.VBox?> 

    <VBox prefHeight="300.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/8.0.102" xmlns:fx="http://javafx.com/fxml/1" fx:controller="problem.importdata.ImportDataController"> 
     <children> 
      <HBox alignment="TOP_CENTER"> 
      <children> 
       <ComboBox fx:id="fruitsComboBox" prefWidth="150.0" /> 
      </children> 
      </HBox> 
      <HBox alignment="TOP_CENTER"> 
      <children> 
       <TextField fx:id="fruitTextField" /> 
       <Button fx:id="addFruitButton" onAction="#onClickAddFruitBtn" text="Add Fruit" /> 
      </children> 
      </HBox> 
      <HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0"> 
      <children> 
       <Button fx:id="closeButton" onAction="#onClickCloseBtn" text="Close" /> 
      </children> 
      </HBox> 
     </children> 
    </VBox> 

ImportDataController.java : 그것은 때문에 대신 액세스 작동하지 않습니다

package problem.importdata; 

    import java.io.IOException; 
    import javafx.fxml.FXML; 
    import javafx.fxml.FXMLLoader; 
    import javafx.scene.Scene; 
    import javafx.scene.control.Button; 
    import javafx.scene.control.ComboBox; 
    import javafx.scene.control.TextField; 
    import javafx.scene.layout.VBox; 
    import javafx.stage.Modality; 
    import javafx.stage.Stage; 
    import problem.MainWindowController; 
    import problem.Main; 

    public class ImportDataController { 
     private Stage primaryStage; 
     @FXML 
     private ComboBox fruitsComboBox; 
     @FXML 
     private TextField fruitTextField; 
     @FXML 
     private Button addFruitButton; 
     @FXML 
     private Button closeButton; 

     public void launchImportDialog(Stage primaryStage) throws IOException { 
      this.primaryStage = primaryStage; 
      FXMLLoader loader = new FXMLLoader(Main.class.getResource("importdata/ImportData.fxml")); 
      VBox root = loader.load(); 
      Scene scene = new Scene(root, 400, 300); 
      Stage stage = new Stage(); 
      stage.initModality(Modality.WINDOW_MODAL); 
      stage.initOwner(primaryStage); 
      stage.setTitle("Import"); 
      stage.setScene(scene); 
      stage.showAndWait(); 
     } 

     @FXML 
     private void onClickCloseBtn() throws IOException { 
      Stage stage = (Stage) closeButton.getScene().getWindow(); 
    stage.close(); 
     } 

     @FXML 
     private void onClickAddFruitBtn() throws IOException { 
      String fruit = fruitTextField.getText(); 
      fruitsComboBox.getItems().add(fruit); 
      fruitTextField.clear(); 

      // Trying to add fruit data in main windows combo box but it is not working 
      FXMLLoader loader = new FXMLLoader(Main.class.getResource("MainWindow.fxml")); 
      VBox root = loader.load(); 
      MainWindowController mwc = loader.<MainWindowController>getController(); 
      mwc.addFruitsComboBox(fruit); 
     } 
    } 

답변

1
// Trying to add fruit data in main windows combo box but it is not working 
FXMLLoader loader = new FXMLLoader(Main.class.getResource("MainWindow.fxml")); 
VBox root = loader.load(); 
MainWindowController mwc = loader.<MainWindowController>getController(); 
mwc.addFruitsComboBox(fruit); 

(패키지 problem.importdata) 이미 존재하는 컨트롤러, 당신은 새로운 인스턴스를 만들고 있습니다. 귀하의 경우, 여러 가지 방법으로 수행 할 수있는 컨트롤러 간의 데이터를 공유

, 저는 믿습니다, 단순히 당신의 ImportDataController에 당신 주위에 당신의 Stage을 통과 같은 방법을 ComboBox 항목 목록에 대한 참조를 전달하는 잘 될 것입니다 . 이 과일을 가져, 그래서 업데이트 할 수있는 데이터 모델을 필요로 - 문제의 컨트롤러의 역할이 명확하게 정의되어 있기 때문에

new ImportDataController().launchImportDialog(primaryStage, fruitsComboBox.getItems()); 

그것은 그것에게 간단한 방법을 수행하는 의미가 있습니다.

컨트롤러가 더 복잡한 경우이 접근법은 분명한 이유로 끔찍할 것입니다. 길고 지저분한 매개 변수 목록을 실제로 유지하고 싶지는 않습니다.

+0

감사합니다. @Dth ...Stackoverflow를 처음 접했을 때 등록한 사람은 공개적으로 표시되지 않습니다 –

+1

'ImportDataController'에서 또 다른 문제를 수정하지 않으면 여전히 작동하지 않습니다 :'ImportDataController'로 생성 한'new ImportDataController()'는 'ImportData.fxml'에서로드 한 UI 용 컨트롤러 (FXMLLoader가 새 인스턴스를 생성하기 때문에 ...). 'VBox root = loader.load()'전에'loader.setController (this)'가 필요하고'ImportData.fxml'에서'fx : controller' 속성을 제거해야합니다. –

+0

"컨트롤러가 더 복잡하다면 ...". 동일한 접근법은 본질적으로 얼마나 복잡한 지 상관없이 작동합니다. 유일한 차이점은 공유해야하는 데이터를 캡슐화하는 클래스 ("모델")를 정의하고 목록을 전달하는 대신 해당 클래스에 대한 참조를 전달한다는 것입니다. 좋은 대답, btw. –

관련 문제