JavaFX 8 TableView 未从 ObservableList 填充(无 FXML)
JavaFX 8 TableView not populating from ObservableList (no FXML)
我相信我已经搜索了所有类似的问题,但仍然没有在任何地方看到我的问题。我正在从根据我的控制台输出成功的数据库中填充 ObservableList
。我有一个学校项目的多控制器设置来创建一个调度程序应用程序。我有一个用作 borderPane 的根控制器,两个用于约会和客户的功能控制器,它们都是单例,以及一个不允许每个视图实例化其自己的 DataView 的共享 DataView 控制器。我已经在每个控制器上实现了 toString
以吐出每个元素的值 and/or 对象 ID 是什么,并且一切似乎都对齐了。我一辈子都弄不明白为什么 ListView
或 TableView
不输出绑定数据。这是我试图绑定到 ListView
和 TableView
的视图数据
public class AppointmentView implements IAppointmentView {
private final ZonedDateTime createdDate;
private final String createdBy;
// Interface needs these components
private ReadOnlyStringProperty title;
private ReadOnlyStringProperty description;
private ReadOnlyStringProperty location;
private ReadOnlyStringProperty contact;
private ReadOnlyStringProperty url;
private ReadOnlyStringProperty customerName;
private ReadOnlyObjectProperty<ZonedDateTime> start;
private ReadOnlyObjectProperty<ZonedDateTime> end;
private ReadOnlyProperty<ZonedDateTime> lastUpdated;
/***
*
* @param title
* @param description
* @param location
* @param contact
* @param url
* @param customerName
* @param start
* @param end
* @param createDate
* @param createdBy
* @param lastUpdate
*/
public AppointmentView(String title, String description, String location, String contact, String url, String customerName, Timestamp start, Timestamp end, Timestamp createDate, String createdBy, Timestamp lastUpdate) {
this.title = new SimpleStringProperty(title);
this.description = new SimpleStringProperty(description);
this.location = new SimpleStringProperty(location);
this.contact = new SimpleStringProperty(contact);
this.customerName = new SimpleStringProperty(customerName);
this.start = new SimpleObjectProperty<>(ZonedDateTime.ofInstant(start.toInstant(), ZoneId.systemDefault()));
this.end = new SimpleObjectProperty<>(ZonedDateTime.ofInstant(end.toInstant(), ZoneId.systemDefault()));
this.lastUpdated = new SimpleObjectProperty<>(ZonedDateTime.ofInstant(lastUpdate.toInstant(), ZoneId.systemDefault()));
this.url = new SimpleStringProperty(url);
this.createdDate = ZonedDateTime.ofInstant(createDate.toInstant(), ZoneId.systemDefault());
this.createdBy = createdBy;
}
public String getTitle() {
return title.getValue();
}
ReadOnlyStringProperty titleProperty() {
return title;
}
public String getDescription() {
return description.getValue();
}
ReadOnlyStringProperty descriptionProperty() {
return description;
}
public String getLocation() {
return location.getValue();
}
ReadOnlyStringProperty locationProperty() {
return location;
}
public String getContact() {
return contact.getValue();
}
ReadOnlyStringProperty contactProperty() {
return contact;
}
public String getUrl() {
return url.getValueSafe();
}
ReadOnlyStringProperty urlProperty() {
return url;
}
public String getCustomerName() {
return customerName.getValue();
}
ReadOnlyStringProperty customerNameProperty() {
return customerName;
}
public ZonedDateTime getStart() {
return ZonedDateTime.ofInstant(start.getValue().toInstant(), ZoneId.systemDefault());
}
ReadOnlyProperty<ZonedDateTime> startProperty() {
return start;
}
public ZonedDateTime getEnd() {
return ZonedDateTime.ofInstant(end.getValue().toInstant(), ZoneId.systemDefault());
}
ReadOnlyProperty<ZonedDateTime> endProperty() {
return end;
}
public LocalDate getCreateDate() {
return createdDate.toLocalDate();
}
public String getCreatedBy() {
return createdBy;
}
public ZonedDateTime getLastUpdate() {
return ZonedDateTime.ofInstant(lastUpdated.getValue().toInstant(), ZoneId.systemDefault());
}
ReadOnlyProperty<ZonedDateTime> lastUpdatedProperty() {
return lastUpdated;
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("AppointmentView{");
sb.append("createdDate=").append(createdDate);
sb.append(", createdBy='").append(createdBy).append('\'');
sb.append(", titleProperty=").append(title);
sb.append(", descriptionProperty=").append(description);
sb.append(", locationProperty=").append(location);
sb.append(", contactProperty=").append(contact);
sb.append(", urlProperty=").append(url);
sb.append(", customerName=").append(customerName);
sb.append(", startProperty=").append(start);
sb.append(", endProperty=").append(end);
sb.append(", lastUpdated=").append(lastUpdated);
sb.append('}');
return sb.toString();
}
}
这是 AppViewController:
public class AppViewController extends BorderPane {
private BorderPane rootPane;
private MenuBar menuBar;
private Menu fileMenu;
private Menu editMenu;
private Menu reportMenu;
private Menu helpMenu;
private MenuItem closeMenuItem;
private MenuItem copyMenuItem;
private MenuItem monthlyAppointmentReportMenuItem;
private MenuItem consultantScheduleMenuItem;
private MenuItem customersByCountryMenuItem;
private MenuItem aboutMenuItem;
private VBox vbAppView;
private TabPane tpAppPane;
private Tab tabCustomers;
private ScrollPane spCustomerEditor;
private Tab tabAppointments;
private ScrollPane spAppointmentEditor;
private MainApp mainApp;
private static AppViewController instance;
private static AppointmentViewController appointmentViewController = AppointmentViewController.getInstance();
private static CustomerViewController customerViewController = CustomerViewController.getInstance();
private static DataViewController dataViewController;
private AppViewController() {
initialize();
}
public static AppViewController getInstance() {
if (instance == null) {
new AppViewController();
}
return instance;
}
/**
* Called to initialize a controller after its root element has been
* completely processed.
**/
public void initialize() {
instance = this;
this.rootPane = new BorderPane();
this.menuBar = new MenuBar();
this.fileMenu = new Menu("_File");
this.editMenu = new Menu("_Edit");
this.reportMenu = new Menu("_Report");
this.helpMenu = new Menu("_Help");
this.closeMenuItem = new MenuItem("Close");
this.copyMenuItem = new MenuItem("Copy");
this.monthlyAppointmentReportMenuItem = new MenuItem("Monthly Appointment Report");
this.consultantScheduleMenuItem = new MenuItem("Consultant Schedule Report");
this.customersByCountryMenuItem = new MenuItem("Customers by Country Report");
this.aboutMenuItem = new MenuItem("About");
this.vbAppView = new VBox();
this.tpAppPane = new TabPane();
this.tabCustomers = new Tab("Customers");
this.tabCustomers.setClosable(false);
this.spCustomerEditor = new ScrollPane();
this.tabAppointments = new Tab("Appointments");
this.tabAppointments.setClosable(false);
this.spAppointmentEditor = new ScrollPane();
// populate menus and menuBar and add them to top pane
this.fileMenu.getItems().setAll(closeMenuItem);
this.fileMenu.setMnemonicParsing(true);
this.editMenu.getItems().setAll(copyMenuItem);
this.editMenu.setMnemonicParsing(true);
this.reportMenu
.getItems()
.setAll(monthlyAppointmentReportMenuItem, consultantScheduleMenuItem, customersByCountryMenuItem);
this.reportMenu.setMnemonicParsing(true);
this.helpMenu.getItems().setAll(aboutMenuItem);
this.helpMenu.setMnemonicParsing(true);
this.menuBar.getMenus().addAll(fileMenu, editMenu, reportMenu, helpMenu);
this.rootPane.setTop(menuBar);
// populate scroll panes with included views
this.spAppointmentEditor.setContent(getAppointmentView());
this.spCustomerEditor.setContent(getCustomerView());
// populate tab panes and controllers and add them to the center pane
this.tabAppointments.setContent(spAppointmentEditor);
this.tabCustomers.setContent(spCustomerEditor);
this.tpAppPane.getTabs().addAll(tabAppointments, tabCustomers);
vbAppView.getChildren().addAll(tpAppPane);
this.rootPane.setCenter(vbAppView);
// add data view to bottom pane
this.rootPane.setBottom(AppointmentViewController.getDataView());
setupEventHandlers(this);
}
private void setupEventHandlers(AppViewController appViewController) {
this.tabCustomers.setOnSelectionChanged((event -> {
if (tabCustomers.isSelected()) {
// Change to Customer View
setCustomerView();
} else {
setAppointmentView();
}
}));
this.tabAppointments.setOnSelectionChanged(event -> {
if (tabAppointments.isSelected()) {
setAppointmentView();
} else {
setCustomerView();
}
});
this.closeMenuItem.setOnAction(event -> quitApp());
this.tpAppPane.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
if(newValue.getText().toLowerCase().equals("Customer".toLowerCase())){
setCustomerView();
}
if (newValue.getText().toLowerCase().equals("Appointments".toLowerCase())){
setAppointmentView();
}
});
}
private void setCustomerView() {
CustomerViewController customerViewController = CustomerViewController.getInstance();
setDataView(customerViewController.getDataViewController().tabPane);
customerViewController.getGpCustomerEditor().getChildren().filtered(node -> toggleTextFields(node, true));
}
private void setAppointmentView() {
AppointmentViewController controller = AppointmentViewController.getInstance();
setDataView(controller.getDataViewController().tabPane);
controller.getGpAppointmentEditor().getChildren().filtered(node -> toggleTextFields(node, true));
}
/***
* Sets whether text fields are enabled or disabled
* true = disable Text Fields
* false = enable Text Fields
* @param node the child nodes of the editor
* @param disabled whether to disable or enable the text fields
* @return whether node was affected or not
*/
public static boolean toggleTextFields(Node node, boolean disabled) {
if (node instanceof TextField) {
((TextField) node).setEditable(!disabled);
node.setDisable(disabled);
return true;
}
return false;
}
public void setMainApp(MainApp mainApp) {
this.mainApp = mainApp;
}
private void quitApp() {
Platform.exit();
}
public Parent getBorderPane() {
return rootPane;
}
public TabPane getTpAppPane() {
return tpAppPane;
}
public Tab getTabCustomers() {
return tabCustomers;
}
public Tab getTabAppointments() {
return tabAppointments;
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("AppViewController{");
sb.append("\nrootPane=").append(rootPane);
sb.append(",\n menuBar=").append(menuBar);
sb.append(",\n fileMenu=").append(fileMenu);
sb.append(",\n editMenu=").append(editMenu);
sb.append(",\n reportMenu=").append(reportMenu);
sb.append(",\n helpMenu=").append(helpMenu);
sb.append(",\n closeMenuItem=").append(closeMenuItem);
sb.append(",\n copyMenuItem=").append(copyMenuItem);
sb.append(",\n monthlyAppointmentReportMenuItem=").append(monthlyAppointmentReportMenuItem);
sb.append(",\n consultantScheduleMenuItem=").append(consultantScheduleMenuItem);
sb.append(",\n customersByCountryMenuItem=").append(customersByCountryMenuItem);
sb.append(",\n aboutMenuItem=").append(aboutMenuItem);
sb.append(",\n vbAppView=").append(vbAppView);
sb.append(",\n tpAppPane=").append(tpAppPane);
sb.append(",\n tabCustomers=").append(tabCustomers);
sb.append(",\n spCustomerEditor=").append(spCustomerEditor);
sb.append(",\n tabAppointments=").append(tabAppointments);
sb.append(",\n spAppointmentEditor=").append(spAppointmentEditor);
sb.append(",\n dataViewController=").append(dataViewController);
sb.append("\n}");
return sb.toString();
}
public void setDataViewController(DataViewController dataViewController) {
this.dataViewController = dataViewController;
}
public DataViewController getDataViewController() {
return dataViewController;
}
}
以及约会视图:
private TableView<AppointmentView> tvAppointments = new TableView<>();
private TableColumn<AppointmentView, String> tcTitle = new TableColumn<>("Title");
private TableColumn<AppointmentView, String> tcDescription = new TableColumn<>("Description");
private TableColumn<AppointmentView, String> tcLocation = new TableColumn<>("Location");
private TableColumn<AppointmentView, String> tcContact = new TableColumn<>("Contact");
private TableColumn<AppointmentView, String> tcUrl = new TableColumn<>("URL");
private TableColumn<AppointmentView, String> tcCustomerName = new TableColumn<>("Customer Name");
private TableColumn<AppointmentView, ZonedDateTime> tcStart = new TableColumn<>("Start Time");
private TableColumn<AppointmentView, ZonedDateTime> tcEnd = new TableColumn<>("End Time");
private TableColumn<AppointmentView, ZonedDateTime> tcCreateDate = new TableColumn<>("Created Date");
private TableColumn<AppointmentView, String> tcCreatedBy = new TableColumn<>("Created By");
private TableColumn<AppointmentView, Timestamp> tcLastUpdate = new TableColumn<>("Last Updated");
---- snip ----
this.tcTitle.setCellValueFactory(new PropertyValueFactory<>("title"));
this.tcTitle.setVisible(true);
this.tcTitle.setMinWidth(50);
this.tcCustomerName.setCellValueFactory(new PropertyValueFactory<>("customerName"));
this.tcCustomerName.setVisible(true);
this.tcCustomerName.setMinWidth(40);
this.tcDescription.setCellValueFactory(new PropertyValueFactory<>("description"));
this.tcDescription.setVisible(true);
this.tcDescription.setMinWidth(100);
this.tcLocation.setCellValueFactory(new PropertyValueFactory<>("location"));
this.tcLocation.setVisible(true);
this.tcLocation.setMinWidth(40);
this.tcContact.setCellValueFactory(new PropertyValueFactory<>("contact"));
this.tcContact.setVisible(true);
this.tcContact.setMinWidth(40);
this.tcUrl.setCellValueFactory(new PropertyValueFactory<>("url".toUpperCase()));
this.tcUrl.setVisible(true);
this.tcUrl.setMinWidth(40);
this.tcStart.setCellValueFactory(new PropertyValueFactory<>("start"));
this.tcStart.setVisible(true);
this.tcStart.setMinWidth(40);
this.tcEnd.setCellValueFactory(new PropertyValueFactory<>("end"));
this.tcEnd.setVisible(true);
this.tcEnd.setMinWidth(40);
this.tcCreateDate.setCellValueFactory(new PropertyValueFactory<>("createDate"));
this.tcCreateDate.setVisible(true);
this.tcCreateDate.setMinWidth(40);
this.tcCreatedBy.setCellValueFactory(new PropertyValueFactory<>("createdBy"));
this.tcCreatedBy.setVisible(true);
this.tcCreatedBy.setMinWidth(40);
this.tcLastUpdate.setCellValueFactory(new PropertyValueFactory<>("lastUpdate"));
this.tcLastUpdate.setVisible(true);
this.tcLastUpdate.setMinWidth(40);
this.tvAppointments = new TableView<>();
this.tvAppointments.setItems(appointmentViews);
this.tvAppointments.getColumns().addAll(
tcTitle,
tcDescription,
tcLocation,
tcContact,
tcUrl,
tcCustomerName,
tcStart,
tcEnd,
tcCreateDate,
tcCreatedBy,
tcLastUpdate);
this.lvListView = new ListView<>();
this.lvListView.setItems(appointmentViews);
this.dataViewController.setTableView(this.tvAppointments);
this.dataViewController.setLblListView(new Label("Appointment List"));
this.dataViewController.setListView(this.lvListView);
this.dataViewController.setLblTableView(new Label("Appointments"));
以及我正在尝试操作的基础 DataViewController:
public class DataViewController extends TabPane {
// private static DataViewController instance;
public TabPane tabPane;
private Tab tabTableView;
private Tab tabListView;
private VBox vbListView;
private VBox vbTableView;
private Label lblListView;
private Label lblTableView;
protected ScrollPane spListView;
protected ScrollPane spTableView;
private ListView<?> listView;
private TableView<?> tableView;
private MainApp mainApp;
public DataViewController() {
initialize();
}
/* public static DataViewController getInstance(){
if(instance == null){
new DataViewController();
}
return instance;
}*/
/**
* Called to initialize a controller after its root element has been
* completely processed.
*
*/
public void initialize() {
// this.instance = this;
this.tabPane = new TabPane();
this.tabPane.setPrefHeight(250.0);
this.tabPane.setMaxHeight(400.0);
this.tabPane.setMaxWidth(Integer.MAX_VALUE);
this.tabTableView = new Tab("Table View");
this.tabTableView.setClosable(false);
this.tabListView = new Tab("List View");
this.tabListView.setClosable(false);
this.spListView = new ScrollPane();
this.spTableView = new ScrollPane();
this.lblListView = new Label("List View");
this.lblTableView = new Label("Table View");
this.vbListView = new VBox();
this.vbTableView = new VBox();
this.listView = new ListView<>();
this.tableView = new TableView<>();
this.vbListView.getChildren().setAll(this.lblListView, this.listView);
this.spListView.setContent(this.listView);
this.tabListView.setContent(this.spListView);
this.vbTableView.getChildren().setAll(this.lblTableView, this.spTableView);
this.spTableView.setContent(this.tableView);
this.tabTableView.setContent(vbTableView);
this.tabPane.getTabs().setAll(tabListView, tabTableView);
}
public Label getLblListView() {
return lblListView;
}
public void setLblListView(Label lblListView) {
this.lblListView = lblListView;
}
public Label getLblTableView() {
return lblTableView;
}
public void setLblTableView(Label lblTableView) {
this.lblTableView = lblTableView;
}
public ListView<?> getListView() {
return listView;
}
public void setListView(ListView<?> listView) {
this.listView = listView;
}
public TableView<?> getTableView() {
return tableView;
}
public void setTableView(TableView<?> tableView) {
this.tableView = tableView;
}
public void setMainApp(MainApp mainApp){
this.mainApp = mainApp;
}
/* public static DataViewController getInstance() {
if (instance == null){
instance = new DataViewController();
}
return instance;
}*/
@Override
public String toString() {
return new StringBuilder()
.append("DataViewController{")
.append("\ntabPane=")
.append(tabPane)
.append(", \ntabTableView=")
.append(tabTableView)
.append(", \ntabListView=")
.append(tabListView)
.append(", \nvbListView=")
.append(vbListView)
.append(", \nvbTableView=")
.append(vbTableView)
.append(", \nlblListView=")
.append(lblListView.getText())
.append(", \nlblTableView=")
.append(lblTableView.getText())
.append(", \nspListView=")
.append(spListView)
.append(", \nspTableView=")
.append(spTableView)
.append(", \nlistView=")
.append(listView.getItems())
.append(", \ntableView=")
.append(tableView.getColumns())
.append("\n}")
.toString();
}
}
如前所述,我进行了一些 toString 调用和实现,并且我一直在 DataViewController 中看到对象:
listView=[AppointmentView{createdDate=2017-09-02T00:00-07:00[America/Los_Angeles], createdBy='test1', titleProperty=StringProperty [value: Meet with Amari], descriptionProperty=StringProperty [value: Meeting WR of the Raiders], locationProperty=StringProperty [value: Raiders HQ, Alameda], contactProperty=StringProperty [value: Jack DelRio], urlProperty=StringProperty [value: raiders.com], customerName=StringProperty [value: Amari Cooper], startProperty=ObjectProperty [value: 2017-09-04T16:00-07:00[America/Los_Angeles]], endProperty=ObjectProperty [value: 2017-09-04T16:15-07:00[America/Los_Angeles]], lastUpdated=ObjectProperty [value: 2017-09-02T23:07-07:00[America/Los_Angeles]]}, AppointmentView{createdDate=2017-09-02T00:00-07:00[America/Los_Angeles], createdBy='test1', titleProperty=StringProperty [value: Meet with Amari], descriptionProperty=StringProperty [value: Meeting WR of the Raiders], locationProperty=StringProperty [value: Raiders HQ, Alameda], contactProperty=StringProperty [value: Jack DelRio], urlProperty=StringProperty [value: raiders.com], customerName=StringProperty [value: Amari Cooper], startProperty=ObjectProperty [value: 2017-09-04T16:00-07:00[America/Los_Angeles]], endProperty=ObjectProperty [value: 2017-09-04T16:15-07:00[America/Los_Angeles]], lastUpdated=ObjectProperty [value: 2017-09-02T23:07-07:00[America/Los_Angeles]]}],
tableView=[javafx.scene.control.TableColumn@6167e82, javafx.scene.control.TableColumn@50658769, javafx.scene.control.TableColumn@f65aae1, javafx.scene.control.TableColumn@2d5ab3ab, javafx.scene.control.TableColumn@180d2aec, javafx.scene.control.TableColumn@64afb84b, javafx.scene.control.TableColumn@463f349d, javafx.scene.control.TableColumn@3e80101a, javafx.scene.control.TableColumn@4fab076c, javafx.scene.control.TableColumn@565f8332, javafx.scene.control.TableColumn@697bdeb8]
下面是调用它的 MainApp 方法:
private void initLayout() {
// rootPane = new BorderPane();
appointmentViewController = AppointmentViewController.getInstance();
appointmentView = appointmentViewController.apAppointmentView;
appointmentViewController.setMainApp(this);
dataViewController = appointmentViewController.getDataViewController();
dataView = dataViewController.tabPane;
dataViewController.setMainApp(this);
customerViewController = CustomerViewController.getInstance();
customerView = customerViewController.apCustomerView;
customerViewController.setMainApp(this);
appViewController = AppViewController.getInstance();
appView = appViewController.getBorderPane();
appViewController.setMainApp(this);
appViewController.setDataViewController(appointmentViewController.getDataViewController());
System.out.println(this.dataViewController);
System.out.println(this.dataView);
System.out.println(appointmentViewController.toString());
System.out.println(customerViewController.toString());
System.out.println(appViewController.toString());
rootPane = (BorderPane) appView;
scene = new Scene(rootPane);
scene.getStylesheets().add("/styles/Styles.css");
primaryStage.setScene(scene);
primaryStage.show();
}
我已经设置了 CellValueFactories 等。我在这里错过了什么?
UI 是这样显示的:
在DataViewController
中,场景结构是从构造函数初始化的。使用此 class 中的任何 setter 修改字段,它确实 not 以任何方式修改场景,留下旧的空白 ListView
在场景中,但打印包含来自 toString
方法的项目的新场景。
我相信我已经搜索了所有类似的问题,但仍然没有在任何地方看到我的问题。我正在从根据我的控制台输出成功的数据库中填充 ObservableList
。我有一个学校项目的多控制器设置来创建一个调度程序应用程序。我有一个用作 borderPane 的根控制器,两个用于约会和客户的功能控制器,它们都是单例,以及一个不允许每个视图实例化其自己的 DataView 的共享 DataView 控制器。我已经在每个控制器上实现了 toString
以吐出每个元素的值 and/or 对象 ID 是什么,并且一切似乎都对齐了。我一辈子都弄不明白为什么 ListView
或 TableView
不输出绑定数据。这是我试图绑定到 ListView
和 TableView
public class AppointmentView implements IAppointmentView {
private final ZonedDateTime createdDate;
private final String createdBy;
// Interface needs these components
private ReadOnlyStringProperty title;
private ReadOnlyStringProperty description;
private ReadOnlyStringProperty location;
private ReadOnlyStringProperty contact;
private ReadOnlyStringProperty url;
private ReadOnlyStringProperty customerName;
private ReadOnlyObjectProperty<ZonedDateTime> start;
private ReadOnlyObjectProperty<ZonedDateTime> end;
private ReadOnlyProperty<ZonedDateTime> lastUpdated;
/***
*
* @param title
* @param description
* @param location
* @param contact
* @param url
* @param customerName
* @param start
* @param end
* @param createDate
* @param createdBy
* @param lastUpdate
*/
public AppointmentView(String title, String description, String location, String contact, String url, String customerName, Timestamp start, Timestamp end, Timestamp createDate, String createdBy, Timestamp lastUpdate) {
this.title = new SimpleStringProperty(title);
this.description = new SimpleStringProperty(description);
this.location = new SimpleStringProperty(location);
this.contact = new SimpleStringProperty(contact);
this.customerName = new SimpleStringProperty(customerName);
this.start = new SimpleObjectProperty<>(ZonedDateTime.ofInstant(start.toInstant(), ZoneId.systemDefault()));
this.end = new SimpleObjectProperty<>(ZonedDateTime.ofInstant(end.toInstant(), ZoneId.systemDefault()));
this.lastUpdated = new SimpleObjectProperty<>(ZonedDateTime.ofInstant(lastUpdate.toInstant(), ZoneId.systemDefault()));
this.url = new SimpleStringProperty(url);
this.createdDate = ZonedDateTime.ofInstant(createDate.toInstant(), ZoneId.systemDefault());
this.createdBy = createdBy;
}
public String getTitle() {
return title.getValue();
}
ReadOnlyStringProperty titleProperty() {
return title;
}
public String getDescription() {
return description.getValue();
}
ReadOnlyStringProperty descriptionProperty() {
return description;
}
public String getLocation() {
return location.getValue();
}
ReadOnlyStringProperty locationProperty() {
return location;
}
public String getContact() {
return contact.getValue();
}
ReadOnlyStringProperty contactProperty() {
return contact;
}
public String getUrl() {
return url.getValueSafe();
}
ReadOnlyStringProperty urlProperty() {
return url;
}
public String getCustomerName() {
return customerName.getValue();
}
ReadOnlyStringProperty customerNameProperty() {
return customerName;
}
public ZonedDateTime getStart() {
return ZonedDateTime.ofInstant(start.getValue().toInstant(), ZoneId.systemDefault());
}
ReadOnlyProperty<ZonedDateTime> startProperty() {
return start;
}
public ZonedDateTime getEnd() {
return ZonedDateTime.ofInstant(end.getValue().toInstant(), ZoneId.systemDefault());
}
ReadOnlyProperty<ZonedDateTime> endProperty() {
return end;
}
public LocalDate getCreateDate() {
return createdDate.toLocalDate();
}
public String getCreatedBy() {
return createdBy;
}
public ZonedDateTime getLastUpdate() {
return ZonedDateTime.ofInstant(lastUpdated.getValue().toInstant(), ZoneId.systemDefault());
}
ReadOnlyProperty<ZonedDateTime> lastUpdatedProperty() {
return lastUpdated;
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("AppointmentView{");
sb.append("createdDate=").append(createdDate);
sb.append(", createdBy='").append(createdBy).append('\'');
sb.append(", titleProperty=").append(title);
sb.append(", descriptionProperty=").append(description);
sb.append(", locationProperty=").append(location);
sb.append(", contactProperty=").append(contact);
sb.append(", urlProperty=").append(url);
sb.append(", customerName=").append(customerName);
sb.append(", startProperty=").append(start);
sb.append(", endProperty=").append(end);
sb.append(", lastUpdated=").append(lastUpdated);
sb.append('}');
return sb.toString();
}
}
这是 AppViewController:
public class AppViewController extends BorderPane {
private BorderPane rootPane;
private MenuBar menuBar;
private Menu fileMenu;
private Menu editMenu;
private Menu reportMenu;
private Menu helpMenu;
private MenuItem closeMenuItem;
private MenuItem copyMenuItem;
private MenuItem monthlyAppointmentReportMenuItem;
private MenuItem consultantScheduleMenuItem;
private MenuItem customersByCountryMenuItem;
private MenuItem aboutMenuItem;
private VBox vbAppView;
private TabPane tpAppPane;
private Tab tabCustomers;
private ScrollPane spCustomerEditor;
private Tab tabAppointments;
private ScrollPane spAppointmentEditor;
private MainApp mainApp;
private static AppViewController instance;
private static AppointmentViewController appointmentViewController = AppointmentViewController.getInstance();
private static CustomerViewController customerViewController = CustomerViewController.getInstance();
private static DataViewController dataViewController;
private AppViewController() {
initialize();
}
public static AppViewController getInstance() {
if (instance == null) {
new AppViewController();
}
return instance;
}
/**
* Called to initialize a controller after its root element has been
* completely processed.
**/
public void initialize() {
instance = this;
this.rootPane = new BorderPane();
this.menuBar = new MenuBar();
this.fileMenu = new Menu("_File");
this.editMenu = new Menu("_Edit");
this.reportMenu = new Menu("_Report");
this.helpMenu = new Menu("_Help");
this.closeMenuItem = new MenuItem("Close");
this.copyMenuItem = new MenuItem("Copy");
this.monthlyAppointmentReportMenuItem = new MenuItem("Monthly Appointment Report");
this.consultantScheduleMenuItem = new MenuItem("Consultant Schedule Report");
this.customersByCountryMenuItem = new MenuItem("Customers by Country Report");
this.aboutMenuItem = new MenuItem("About");
this.vbAppView = new VBox();
this.tpAppPane = new TabPane();
this.tabCustomers = new Tab("Customers");
this.tabCustomers.setClosable(false);
this.spCustomerEditor = new ScrollPane();
this.tabAppointments = new Tab("Appointments");
this.tabAppointments.setClosable(false);
this.spAppointmentEditor = new ScrollPane();
// populate menus and menuBar and add them to top pane
this.fileMenu.getItems().setAll(closeMenuItem);
this.fileMenu.setMnemonicParsing(true);
this.editMenu.getItems().setAll(copyMenuItem);
this.editMenu.setMnemonicParsing(true);
this.reportMenu
.getItems()
.setAll(monthlyAppointmentReportMenuItem, consultantScheduleMenuItem, customersByCountryMenuItem);
this.reportMenu.setMnemonicParsing(true);
this.helpMenu.getItems().setAll(aboutMenuItem);
this.helpMenu.setMnemonicParsing(true);
this.menuBar.getMenus().addAll(fileMenu, editMenu, reportMenu, helpMenu);
this.rootPane.setTop(menuBar);
// populate scroll panes with included views
this.spAppointmentEditor.setContent(getAppointmentView());
this.spCustomerEditor.setContent(getCustomerView());
// populate tab panes and controllers and add them to the center pane
this.tabAppointments.setContent(spAppointmentEditor);
this.tabCustomers.setContent(spCustomerEditor);
this.tpAppPane.getTabs().addAll(tabAppointments, tabCustomers);
vbAppView.getChildren().addAll(tpAppPane);
this.rootPane.setCenter(vbAppView);
// add data view to bottom pane
this.rootPane.setBottom(AppointmentViewController.getDataView());
setupEventHandlers(this);
}
private void setupEventHandlers(AppViewController appViewController) {
this.tabCustomers.setOnSelectionChanged((event -> {
if (tabCustomers.isSelected()) {
// Change to Customer View
setCustomerView();
} else {
setAppointmentView();
}
}));
this.tabAppointments.setOnSelectionChanged(event -> {
if (tabAppointments.isSelected()) {
setAppointmentView();
} else {
setCustomerView();
}
});
this.closeMenuItem.setOnAction(event -> quitApp());
this.tpAppPane.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
if(newValue.getText().toLowerCase().equals("Customer".toLowerCase())){
setCustomerView();
}
if (newValue.getText().toLowerCase().equals("Appointments".toLowerCase())){
setAppointmentView();
}
});
}
private void setCustomerView() {
CustomerViewController customerViewController = CustomerViewController.getInstance();
setDataView(customerViewController.getDataViewController().tabPane);
customerViewController.getGpCustomerEditor().getChildren().filtered(node -> toggleTextFields(node, true));
}
private void setAppointmentView() {
AppointmentViewController controller = AppointmentViewController.getInstance();
setDataView(controller.getDataViewController().tabPane);
controller.getGpAppointmentEditor().getChildren().filtered(node -> toggleTextFields(node, true));
}
/***
* Sets whether text fields are enabled or disabled
* true = disable Text Fields
* false = enable Text Fields
* @param node the child nodes of the editor
* @param disabled whether to disable or enable the text fields
* @return whether node was affected or not
*/
public static boolean toggleTextFields(Node node, boolean disabled) {
if (node instanceof TextField) {
((TextField) node).setEditable(!disabled);
node.setDisable(disabled);
return true;
}
return false;
}
public void setMainApp(MainApp mainApp) {
this.mainApp = mainApp;
}
private void quitApp() {
Platform.exit();
}
public Parent getBorderPane() {
return rootPane;
}
public TabPane getTpAppPane() {
return tpAppPane;
}
public Tab getTabCustomers() {
return tabCustomers;
}
public Tab getTabAppointments() {
return tabAppointments;
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("AppViewController{");
sb.append("\nrootPane=").append(rootPane);
sb.append(",\n menuBar=").append(menuBar);
sb.append(",\n fileMenu=").append(fileMenu);
sb.append(",\n editMenu=").append(editMenu);
sb.append(",\n reportMenu=").append(reportMenu);
sb.append(",\n helpMenu=").append(helpMenu);
sb.append(",\n closeMenuItem=").append(closeMenuItem);
sb.append(",\n copyMenuItem=").append(copyMenuItem);
sb.append(",\n monthlyAppointmentReportMenuItem=").append(monthlyAppointmentReportMenuItem);
sb.append(",\n consultantScheduleMenuItem=").append(consultantScheduleMenuItem);
sb.append(",\n customersByCountryMenuItem=").append(customersByCountryMenuItem);
sb.append(",\n aboutMenuItem=").append(aboutMenuItem);
sb.append(",\n vbAppView=").append(vbAppView);
sb.append(",\n tpAppPane=").append(tpAppPane);
sb.append(",\n tabCustomers=").append(tabCustomers);
sb.append(",\n spCustomerEditor=").append(spCustomerEditor);
sb.append(",\n tabAppointments=").append(tabAppointments);
sb.append(",\n spAppointmentEditor=").append(spAppointmentEditor);
sb.append(",\n dataViewController=").append(dataViewController);
sb.append("\n}");
return sb.toString();
}
public void setDataViewController(DataViewController dataViewController) {
this.dataViewController = dataViewController;
}
public DataViewController getDataViewController() {
return dataViewController;
}
}
以及约会视图:
private TableView<AppointmentView> tvAppointments = new TableView<>();
private TableColumn<AppointmentView, String> tcTitle = new TableColumn<>("Title");
private TableColumn<AppointmentView, String> tcDescription = new TableColumn<>("Description");
private TableColumn<AppointmentView, String> tcLocation = new TableColumn<>("Location");
private TableColumn<AppointmentView, String> tcContact = new TableColumn<>("Contact");
private TableColumn<AppointmentView, String> tcUrl = new TableColumn<>("URL");
private TableColumn<AppointmentView, String> tcCustomerName = new TableColumn<>("Customer Name");
private TableColumn<AppointmentView, ZonedDateTime> tcStart = new TableColumn<>("Start Time");
private TableColumn<AppointmentView, ZonedDateTime> tcEnd = new TableColumn<>("End Time");
private TableColumn<AppointmentView, ZonedDateTime> tcCreateDate = new TableColumn<>("Created Date");
private TableColumn<AppointmentView, String> tcCreatedBy = new TableColumn<>("Created By");
private TableColumn<AppointmentView, Timestamp> tcLastUpdate = new TableColumn<>("Last Updated");
---- snip ----
this.tcTitle.setCellValueFactory(new PropertyValueFactory<>("title"));
this.tcTitle.setVisible(true);
this.tcTitle.setMinWidth(50);
this.tcCustomerName.setCellValueFactory(new PropertyValueFactory<>("customerName"));
this.tcCustomerName.setVisible(true);
this.tcCustomerName.setMinWidth(40);
this.tcDescription.setCellValueFactory(new PropertyValueFactory<>("description"));
this.tcDescription.setVisible(true);
this.tcDescription.setMinWidth(100);
this.tcLocation.setCellValueFactory(new PropertyValueFactory<>("location"));
this.tcLocation.setVisible(true);
this.tcLocation.setMinWidth(40);
this.tcContact.setCellValueFactory(new PropertyValueFactory<>("contact"));
this.tcContact.setVisible(true);
this.tcContact.setMinWidth(40);
this.tcUrl.setCellValueFactory(new PropertyValueFactory<>("url".toUpperCase()));
this.tcUrl.setVisible(true);
this.tcUrl.setMinWidth(40);
this.tcStart.setCellValueFactory(new PropertyValueFactory<>("start"));
this.tcStart.setVisible(true);
this.tcStart.setMinWidth(40);
this.tcEnd.setCellValueFactory(new PropertyValueFactory<>("end"));
this.tcEnd.setVisible(true);
this.tcEnd.setMinWidth(40);
this.tcCreateDate.setCellValueFactory(new PropertyValueFactory<>("createDate"));
this.tcCreateDate.setVisible(true);
this.tcCreateDate.setMinWidth(40);
this.tcCreatedBy.setCellValueFactory(new PropertyValueFactory<>("createdBy"));
this.tcCreatedBy.setVisible(true);
this.tcCreatedBy.setMinWidth(40);
this.tcLastUpdate.setCellValueFactory(new PropertyValueFactory<>("lastUpdate"));
this.tcLastUpdate.setVisible(true);
this.tcLastUpdate.setMinWidth(40);
this.tvAppointments = new TableView<>();
this.tvAppointments.setItems(appointmentViews);
this.tvAppointments.getColumns().addAll(
tcTitle,
tcDescription,
tcLocation,
tcContact,
tcUrl,
tcCustomerName,
tcStart,
tcEnd,
tcCreateDate,
tcCreatedBy,
tcLastUpdate);
this.lvListView = new ListView<>();
this.lvListView.setItems(appointmentViews);
this.dataViewController.setTableView(this.tvAppointments);
this.dataViewController.setLblListView(new Label("Appointment List"));
this.dataViewController.setListView(this.lvListView);
this.dataViewController.setLblTableView(new Label("Appointments"));
以及我正在尝试操作的基础 DataViewController:
public class DataViewController extends TabPane {
// private static DataViewController instance;
public TabPane tabPane;
private Tab tabTableView;
private Tab tabListView;
private VBox vbListView;
private VBox vbTableView;
private Label lblListView;
private Label lblTableView;
protected ScrollPane spListView;
protected ScrollPane spTableView;
private ListView<?> listView;
private TableView<?> tableView;
private MainApp mainApp;
public DataViewController() {
initialize();
}
/* public static DataViewController getInstance(){
if(instance == null){
new DataViewController();
}
return instance;
}*/
/**
* Called to initialize a controller after its root element has been
* completely processed.
*
*/
public void initialize() {
// this.instance = this;
this.tabPane = new TabPane();
this.tabPane.setPrefHeight(250.0);
this.tabPane.setMaxHeight(400.0);
this.tabPane.setMaxWidth(Integer.MAX_VALUE);
this.tabTableView = new Tab("Table View");
this.tabTableView.setClosable(false);
this.tabListView = new Tab("List View");
this.tabListView.setClosable(false);
this.spListView = new ScrollPane();
this.spTableView = new ScrollPane();
this.lblListView = new Label("List View");
this.lblTableView = new Label("Table View");
this.vbListView = new VBox();
this.vbTableView = new VBox();
this.listView = new ListView<>();
this.tableView = new TableView<>();
this.vbListView.getChildren().setAll(this.lblListView, this.listView);
this.spListView.setContent(this.listView);
this.tabListView.setContent(this.spListView);
this.vbTableView.getChildren().setAll(this.lblTableView, this.spTableView);
this.spTableView.setContent(this.tableView);
this.tabTableView.setContent(vbTableView);
this.tabPane.getTabs().setAll(tabListView, tabTableView);
}
public Label getLblListView() {
return lblListView;
}
public void setLblListView(Label lblListView) {
this.lblListView = lblListView;
}
public Label getLblTableView() {
return lblTableView;
}
public void setLblTableView(Label lblTableView) {
this.lblTableView = lblTableView;
}
public ListView<?> getListView() {
return listView;
}
public void setListView(ListView<?> listView) {
this.listView = listView;
}
public TableView<?> getTableView() {
return tableView;
}
public void setTableView(TableView<?> tableView) {
this.tableView = tableView;
}
public void setMainApp(MainApp mainApp){
this.mainApp = mainApp;
}
/* public static DataViewController getInstance() {
if (instance == null){
instance = new DataViewController();
}
return instance;
}*/
@Override
public String toString() {
return new StringBuilder()
.append("DataViewController{")
.append("\ntabPane=")
.append(tabPane)
.append(", \ntabTableView=")
.append(tabTableView)
.append(", \ntabListView=")
.append(tabListView)
.append(", \nvbListView=")
.append(vbListView)
.append(", \nvbTableView=")
.append(vbTableView)
.append(", \nlblListView=")
.append(lblListView.getText())
.append(", \nlblTableView=")
.append(lblTableView.getText())
.append(", \nspListView=")
.append(spListView)
.append(", \nspTableView=")
.append(spTableView)
.append(", \nlistView=")
.append(listView.getItems())
.append(", \ntableView=")
.append(tableView.getColumns())
.append("\n}")
.toString();
}
}
如前所述,我进行了一些 toString 调用和实现,并且我一直在 DataViewController 中看到对象:
listView=[AppointmentView{createdDate=2017-09-02T00:00-07:00[America/Los_Angeles], createdBy='test1', titleProperty=StringProperty [value: Meet with Amari], descriptionProperty=StringProperty [value: Meeting WR of the Raiders], locationProperty=StringProperty [value: Raiders HQ, Alameda], contactProperty=StringProperty [value: Jack DelRio], urlProperty=StringProperty [value: raiders.com], customerName=StringProperty [value: Amari Cooper], startProperty=ObjectProperty [value: 2017-09-04T16:00-07:00[America/Los_Angeles]], endProperty=ObjectProperty [value: 2017-09-04T16:15-07:00[America/Los_Angeles]], lastUpdated=ObjectProperty [value: 2017-09-02T23:07-07:00[America/Los_Angeles]]}, AppointmentView{createdDate=2017-09-02T00:00-07:00[America/Los_Angeles], createdBy='test1', titleProperty=StringProperty [value: Meet with Amari], descriptionProperty=StringProperty [value: Meeting WR of the Raiders], locationProperty=StringProperty [value: Raiders HQ, Alameda], contactProperty=StringProperty [value: Jack DelRio], urlProperty=StringProperty [value: raiders.com], customerName=StringProperty [value: Amari Cooper], startProperty=ObjectProperty [value: 2017-09-04T16:00-07:00[America/Los_Angeles]], endProperty=ObjectProperty [value: 2017-09-04T16:15-07:00[America/Los_Angeles]], lastUpdated=ObjectProperty [value: 2017-09-02T23:07-07:00[America/Los_Angeles]]}],
tableView=[javafx.scene.control.TableColumn@6167e82, javafx.scene.control.TableColumn@50658769, javafx.scene.control.TableColumn@f65aae1, javafx.scene.control.TableColumn@2d5ab3ab, javafx.scene.control.TableColumn@180d2aec, javafx.scene.control.TableColumn@64afb84b, javafx.scene.control.TableColumn@463f349d, javafx.scene.control.TableColumn@3e80101a, javafx.scene.control.TableColumn@4fab076c, javafx.scene.control.TableColumn@565f8332, javafx.scene.control.TableColumn@697bdeb8]
下面是调用它的 MainApp 方法:
private void initLayout() {
// rootPane = new BorderPane();
appointmentViewController = AppointmentViewController.getInstance();
appointmentView = appointmentViewController.apAppointmentView;
appointmentViewController.setMainApp(this);
dataViewController = appointmentViewController.getDataViewController();
dataView = dataViewController.tabPane;
dataViewController.setMainApp(this);
customerViewController = CustomerViewController.getInstance();
customerView = customerViewController.apCustomerView;
customerViewController.setMainApp(this);
appViewController = AppViewController.getInstance();
appView = appViewController.getBorderPane();
appViewController.setMainApp(this);
appViewController.setDataViewController(appointmentViewController.getDataViewController());
System.out.println(this.dataViewController);
System.out.println(this.dataView);
System.out.println(appointmentViewController.toString());
System.out.println(customerViewController.toString());
System.out.println(appViewController.toString());
rootPane = (BorderPane) appView;
scene = new Scene(rootPane);
scene.getStylesheets().add("/styles/Styles.css");
primaryStage.setScene(scene);
primaryStage.show();
}
我已经设置了 CellValueFactories 等。我在这里错过了什么?
UI 是这样显示的:
在DataViewController
中,场景结构是从构造函数初始化的。使用此 class 中的任何 setter 修改字段,它确实 not 以任何方式修改场景,留下旧的空白 ListView
在场景中,但打印包含来自 toString
方法的项目的新场景。