簡體   English   中英

控制器之間的JavaFx操作

[英]JavaFx actions between controllers

我如何做按鈕動作來編輯TableView 當我觸摸按鈕時,我需要將文本從TextArea放到表格中。 如果將System.out.println放在inputToTable()則可以正常工作。

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>

您加載table.fxml兩次:通過一次fx:include主FXML文件,而一旦在InputController ,通過FXMLLoader您在創建tableControllerInit()方法。 因此,的兩個實例TableController被創建,一個具有從加載第一UI相關聯table.fxml ,和一個與您從加載第二UI相關聯table.fxml

通過fx:include加載的UI將顯示在主FXML文件中定義的VBox中。 FXMLLoader加載的UI永遠不會顯示(實際上,您甚至從不保留對它的引用,只需調用loader.load()並丟棄結果)。 當您嘗試更新表的項目(順便說一句,您真的要替換所有現有項目嗎?)時,您引用的第二個控制器實例與從未顯示過的UI關聯。 因此,您正在更新未顯示的表,並且永遠不會看到任何結果。

您真正需要做的是在與兩個fx:include關聯的兩個控制器之間共享相同的數據。 您可以簡單地通過將這兩個控制器注入到主控制器中來執行此操作,如文檔中的“嵌套控制器”部分所述。

首先,給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()));
        }
    }


}

更一般而言,如果您有更多的數據要在不同的控制器之間共享,則可以創建一個或多個“模型”類,並與控制器共享模型實例。 然后,您可以觀察模型的屬性並進行更新。 有關更全面的示例,請參見將MVC與JavaFx一起使用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM