gpt4 book ai didi

Controller 之间的 JavaFx 操作

转载 作者:行者123 更新时间:2023-12-02 02:35:31 25 4
gpt4 key购买 nike

我如何执行按钮操作来编辑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 两次:一次通过主 FXML 文件中的 fx:include 加载,一次在 InputController 中加载,通过您在 tableControllerInit() 方法中创建的 FXMLLoader。因此,将创建 TableController 的两个实例,一个与从 table.fxml 加载的第一个 UI 关联,另一个与从 table 加载的第二个 UI 关联.fxml

通过 fx:include 加载的 UI 显示在主 FXML 文件中定义的 VBox 中。使用 FXMLLoader 加载的 UI 永远不会显示(事实上,您甚至从未保留对它的引用,您只需调用 loader.load() 并丢弃结果) 。当您尝试更新表的项目时(顺便问一下,您真的打算替换所有现有项目吗?),您会引用第二个 Controller 实例,该实例与从不显示的 UI 关联。因此,您正在更新一个未显示的表,并且您永远看不到任何结果。

您真正需要做的是在与两个 fx:include 关联的两个 Controller 之间共享相同的数据。您只需将这两个 Controller 注入(inject)主 Controller 即可完成此操作,如 "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” 的字段,将 Controller 注入(inject)主 Controller 。创建一个可观察列表,它将表示表中显示的项目列表,并将其传递给每个 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);
}
}

最后,只需在其他两个 Controller 中定义明显的方法即可:

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);
}
}

现在表格正在显示在主 Controller 的 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()));
}
}


}

更一般地说,如果您有更多数据要在不同 Controller 之间共享,您可以创建一个或多个“模型”类并与 Controller 共享一个模型实例。然后您可以观察模型的属性并更新它们。请参阅Applying MVC With JavaFx以获得更全面的示例。

关于 Controller 之间的 JavaFx 操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46415391/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com