我无法将TableView项目与FXML中的ObservableList绑定.
当我设置materialTable.setItems(materialDataObservableList)时,一切正常.在按钮单击事件.
但是我不想让按钮知道TableView,所以我想将materialTable.items绑定到materialDataObservableList属性.
我究竟做错了什么?
或者也许我不明白绑定是如何工作的…
感谢帮助!
<GridPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="464.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.xxx.sm.frontend.fx.MainSceneController">
/*
*/
<children>
<VBox prefHeight="200.0" prefWidth="100.0">
<children>
<Button fx:id="getMaterialsButton" mnemonicParsing="false" onAction="#getMaterialsButton" text="Get materials" />
<TableView fx:id="materialTable" editable="true" prefHeight="413.0" prefWidth="600.0" items="${materialDataObservableList}" >
//Columns here
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
</columnResizePolicy>
</TableView>
</children>
</VBox>
</children>
public class MainSceneController {
private ObservableList<MaterialData> materialDataObservableList;
public TableView materialTable;
public Button getMaterialsButton;
public void getMaterialsButton() {
getMaterialsFromRESTController();
}
private void getMaterialsFromRESTController() {
MaterialClient controller = new MaterialClient();
try {
materialDataObservableList = FXCollections.observableArrayList(controller.getMaterias());
} catch (IOException e) {
System.out.println("Failed to connect to RESTController");
}
//materialTable.setItems(materialDataObservableList);
}
public ObservableList<MaterialData> getMaterialDataObservableList() {
return materialDataObservableList;
}
}
解决方法:
如果要从MainSceneController的构造函数中调用getMaterialsFromRESTController()(因此,一旦控制器可用于FXMLLoader,它就会被初始化),然后
<TableView fx:id="materialTable" editable="true" prefHeight="413.0" prefWidth="600.0"
items="${controller.materialDataObservableList}" >
将工作. (请注意,您使用${controller.property}访问控制器的属性.)
如果没有,您可以按如下所示修改控制器以使其工作:
public class MainSceneController {
private final ObservableList<MaterialData> materialDataObservableList
= FXCollections.observableArrayList();
public TableView materialTable;
public Button getMaterialsButton;
public void getMaterialsButton() {
getMaterialsFromRESTController();
}
private void getMaterialsFromRESTController() {
MaterialClient controller = new MaterialClient();
try {
materialDataObservableList.setAll(controller.getMaterias());
} catch (IOException e) {
System.out.println("Failed to connect to RESTController");
}
}
public ObservableList<MaterialData> getMaterialDataObservableList() {
return materialDataObservableList;
}
}
然后上面的FXML应该可以工作.
这是一个SSCCE:
BindTableItemsExample.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.cell.PropertyValueFactory?>
<?import javafx.scene.control.Button?>
<?import javafx.geometry.Insets?>
<BorderPane xmlns:fx="http://javafx.com/fxml/1" fx:controller="TableController">
<center>
<TableView items="${controller.items}">
<columns>
<TableColumn text="Item">
<cellValueFactory><PropertyValueFactory property="name" /></cellValueFactory>
</TableColumn>
</columns>
</TableView>
</center>
<bottom>
<Button text="Load" onAction="#loadItems" BorderPane.alignment="center" >
<BorderPane.margin>
<Insets top="5" left="5" right="5" bottom="5"/>
</BorderPane.margin>
</Button>
</bottom>
</BorderPane>
TableController.java:
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
public class TableController {
private final ObservableList<Item> items = FXCollections.observableArrayList();
@FXML
private void loadItems() {
items.setAll(createItems());
}
private List<Item> createItems() {
return IntStream.rangeClosed(1, 100)
.mapToObj(i -> "Item "+i)
.map(Item::new)
.collect(Collectors.toList());
}
public ObservableList<Item> getItems() {
return items ;
}
public static class Item {
private final StringProperty name = new SimpleStringProperty();
public Item(String name) {
setName(name);
}
public final StringProperty nameProperty() {
return this.name;
}
public final java.lang.String getName() {
return this.nameProperty().get();
}
public final void setName(final java.lang.String name) {
this.nameProperty().set(name);
}
}
}
BindTableItemsTest.java(应用程序类):
import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class BindTableItemsTest extends Application {
@Override
public void start(Stage primaryStage) throws IOException {
FXMLLoader loader = new FXMLLoader(getClass().getResource("BindTableItemsExample.fxml"));
primaryStage.setScene(new Scene(loader.load(), 600, 600));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}