2017-09-25 104 views
0

我如何做編輯TableView的按鈕動作。當我觸摸按鈕時,我需要將TextArea的文字放到表格中。如果把System.out.println放在inputToTable()這是工作。在InputController通過主FXML文件fx:include一次,一次,通過你的tableControllerInit()方法創建FXMLLoader控制器之間的JavaFx動作

public class InputController { 

    public TextArea inputArea; 
    public Button inputButton; 
    private TableController tableController; 

    public void initialize() { 
     tableControllerInit(); 
    } 

    public void inputToTable() { 
     if(inputArea.getText() != "") { 
      tableController.tableInfo.setItems(FXCollections.observableArrayList(new InputObject(inputArea.getText()))); 
     } 
    } 

    private void tableControllerInit() { 
     try { 
      FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("table.fxml")); 
      fxmlLoader.load(); 
      tableController = fxmlLoader.getController(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

public class TableController { 

    @FXML TableView<InputObject> tableInfo; 
    @FXML TableColumn<InputObject, String> col1; 

    public void initialize() { 
     col1.setCellValueFactory(new PropertyValueFactory<>("text")); 
    } 
} 

public class Controller implements Initializable { 

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

    } 
} 

public class InputObject { 
    String text; 

    public InputObject(String text) { 
     this.text = text; 
    } 

    public String getText() { 
     return text; 
    } 

    public void setText(String text) { 
     this.text = text; 
    } 
} 



<BorderPane fx:controller="sample.Controller" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1"> 
    <left> 
     <fx:include source="table.fxml"/> 
    </left> 
    <center> 
     <fx:include source="input.fxml"/> 
    </center> 
</BorderPane> 

<TableView fx:controller="sample.TableController" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:id="tableInfo" prefHeight="400.0" prefWidth="330.0"> 
    <columns> 
     <TableColumn fx:id="col1" prefWidth="75.0" text="Output" /> 
    </columns> 
    <columnResizePolicy> 
     <TableView fx:constant="CONSTRAINED_RESIZE_POLICY" /> 
    </columnResizePolicy> 
</TableView> 

<VBox fx:controller="sample.InputController" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" alignment="TOP_CENTER" prefHeight="200.0" prefWidth="100.0" BorderPane.alignment="CENTER"> 
    <children> 
     <TextArea fx:id="inputArea" prefHeight="188.0" prefWidth="270.0" /> 
     <Button fx:id="inputButton" onAction="#inputToTable" mnemonicParsing="false" text="Input"> 
      <VBox.margin> 
       <Insets bottom="30.0" left="30.0" right="30.0" top="30.0" /> 
      </VBox.margin> 
     </Button> 
    </children> 
</VBox> 

回答

1

您加載table.fxml兩次。因此,創建了兩個TableController實例,一個與您從table.fxml加載的第一個UI相關聯,另一個與您從table.fxml加載的第二個UI相關聯。

您通過fx:include加載的UI顯示在主FXML文件中定義的VBox中。您加載FXMLLoader的用戶界面從不顯示(實際上,您甚至不會保留對它的引用,只需調用loader.load()並放棄結果)。當您嘗試更新表格的項目時(您是否真的打算替換所有現有的項目,順便說一下?),您可以參考第二個控制器實例,該實例與從未顯示的UI相關聯。因此,您正在更新未顯示的表格,並且您從未看到任何結果。

您真正需要做的是在與兩個fx:include相關聯的兩個控制器之間共享相同的數據。您可以簡單地將這兩個控制器注入主控制器,如文檔中的"Nested Controllers"部分所述。

首先,給fx:include元件fx:id屬性:

<BorderPane fx:controller="sample.Controller" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1"> 
    <left> 
     <fx:include fx:id="table" source="table.fxml"/> 
    </left> 
    <center> 
     <fx:include fx:id="input" source="input.fxml"/> 
    </center> 
</BorderPane> 

然後,可以通過用附加到fx:id"Controller"創建字段注入控制器到主控制器。建立一個單一的可觀察到的列表,這將代表在表中顯示的項目的列表中,並把它傳遞到每個控制器:

public class Controller implements Initializable { 

    @FXML 
    private TableController tableController ; 

    @FXML 
    private InputController inputController ; 

    @Override 
    public void initialize(URL location, ResourceBundle resources) { 
     ObservableList<InputObject> items = FXCollections.observableArrayList(); 
     tableController.setTableItems(items); 
     inputController.setTableItems(items); 
    } 
} 

最後,只定義在每個其它兩個控制器的明顯的方法:

public class TableController { 

    @FXML 
    private TableView<InputObject> tableInfo; 
    @FXML 
    private TableColumn<InputObject, String> col1; 

    public void initialize() { 
     col1.setCellValueFactory(new PropertyValueFactory<>("text")); 
    } 

    public void setTableItems(ObservableList<InputObject> tableItems) { 
     tableInfo.setItems(tableItems); 
    } 
} 

現在表格顯示在主控制器的initalize()方法中創建的items列表的內容,並且InputController對同一列表有引用。所以你所要做的就是更新InputController中的列表。我以爲你只是想添加項目表(不全部更換):

public class InputController { 

    @FXML 
    private TextArea inputArea; 
    @FXML 
    private Button inputButton; 

    private ObservableList<InputObject> tableItems ; 

    public void setTableItems(ObservableList<InputObject> tableItems) { 
     this.tableItems = tableItems ; 
    } 

    public void inputToTable() { 
     if(! inputArea.getText().isEmpty()) { 
      tableItems.add(new InputObject(inputArea.getText())); 
     } 
    } 


} 

更一般地,如果你有更多的數據不同的控制器之間共享,您將創建一個或多個「模型」類並與控制器共享模型實例。然後您可以觀察模型的屬性並更新它們。有關更全面的示例,請參閱Applying MVC With JavaFx

相關問題