【发布时间】:2023-04-07 20:28:01
【问题描述】:
我正在尝试将数据添加到具有与主应用程序不同的控制器的TableView。经过一番修改,我用静态TableView 和调用更新的静态方法做了一段时间。但是,我在代码的其他地方遇到了这种方法的问题,someotherresearch 让我相信FXMLLoader 可能会有所帮助。
但是应该添加的数据没有显示在表格中。 System.out.println("adding info"); 在控制台中出现的次数是预期的两倍,但表格仍然是空的。它是在使用静态方法时填充的。我猜我的FXMLLoader 正在创建一个与程序启动时创建的实例不同的实例。下面的代码有什么问题,主要是在主类showMainStage部分?
主类:
package test.controller;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class InteractionTest extends Application {
private Stage mainStage;
/**
* Show the main window.
*
* @throws IOException
*/
private void showMainStage() throws IOException {
final FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("/fxml/Main.fxml"));
final Parent root = loader.load();
final BorderPane bp = (BorderPane) root;
mainStage = new Stage();
mainStage.setScene(new Scene(bp));
mainStage.setTitle("Interaction test");
mainStage.setMaximized(false);
mainStage.show();
final Info i1 = new Info("1");
i1.setPosition(1);
i1.setTitle("Info 1");
final Info i2 = new Info("2");
i2.setPosition(2);
i2.setTitle("Info 2");
final List<Info> infoList = new ArrayList<>();
infoList.add(i1);
infoList.add(i2);
final FXMLLoader tableLoader = new FXMLLoader(getClass().getResource("/fxml/InfoTable.fxml"));
final Parent parent = tableLoader.load();
final InfoTableController itc = (InfoTableController) tableLoader.getController();
itc.updateTable(infoList);
}
@Override
public void start(final Stage initStage) throws Exception {
try {
showMainStage();
} catch (final IOException e) {
e.printStackTrace();
}
}
/**
* Main method.
*
* @param args
*/
public static void main(final String[] args) {
launch();
}
}
表控制器:
package test.controller;
import java.io.IOException;
import java.util.List;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.SortType;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
/**
* Holds a {@link TableView} to display the infos for further interaction. Is
* the controller for InfoTable.fxml.
*
*/
public class InfoTableController {
/**
* A {@link ScrollPane} for the {@link Info} table.
*/
@FXML
private ScrollPane infoTablePane;
/**
* A {@link TableView} for the {@link Info}s.
*/
private final TableView<Info> table = new TableView<>();
/**
* Build the column headers during initialization.
*/
@FXML
public void initialize() {
final TableColumn<Info, String> positionColumn = new TableColumn<>("#");
positionColumn.setEditable(false);
positionColumn.setPrefWidth(15.0);
positionColumn.setMaxWidth(50.0);
positionColumn.setSortable(true);
positionColumn.setSortType(SortType.ASCENDING);
positionColumn.setCellValueFactory(new PropertyValueFactory<>("position"));
final TableColumn<Info, String> titleColumn = new TableColumn<>("Title");
titleColumn.setEditable(true);
titleColumn.setPrefWidth(200.0);
titleColumn.setMaxWidth(1000.0);
titleColumn.setCellValueFactory(new PropertyValueFactory<>("title"));
table.getColumns().addAll(positionColumn, titleColumn);
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
table.getSortOrder().add(positionColumn);
table.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
table.getSelectionModel().setCellSelectionEnabled(true);
table.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
final String id = newValue.getId();
final FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/InfoDisplay.fxml"));
try {
final Parent parent = loader.load();
} catch (final IOException e1) {
e1.printStackTrace();
}
final InfoDisplayController idc = (InfoDisplayController) loader.getController();
idc.displayDocument(id);
});
infoTablePane.setContent(table);
infoTablePane.setFitToWidth(true);
infoTablePane.setFitToHeight(true);
}
/**
* Sorts the {@link #table}.
*/
public void sortTable() {
table.sort();
}
/**
* Adds table entries.
*
*/
public void updateTable(final List<Info> infoList) {
table.getItems().clear();
for (final Info info : infoList) {
System.out.println("adding info");
table.getItems().add(info);
}
}
}
显示控制器:
package test.controller;
import javafx.fxml.FXML;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TextArea;
/**
* Displays infos for reading. Controller for InfoDisplay.fxml.
*
*/
public class InfoDisplayController {
@FXML
private TabPane infoDisplayTabPane;
/**
* Constructor.
*/
public InfoDisplayController() {
}
@FXML
public void initialize() {
infoDisplayTabPane.getTabs().add(new Tab("test in class"));
}
/**
* Displays the selected document in tabs.
*
* @param id The selected document's id.
*/
public void displayDocument(final String id) {
// get the underlying Lucene document with the id; omitted for this example
System.out.println("attempting to display " + id);
infoDisplayTabPane.getTabs().clear();
final TextArea textArea = new TextArea("My info text.");
final ScrollPane scrollPane = new ScrollPane(textArea);
final Tab tab = new Tab("info", scrollPane);
infoDisplayTabPane.getTabs().add(tab);
}
}
信息对象:
package test.controller;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
public class Info {
/**
* The id as pulled from the Lucene index.
*/
private final String id;
/**
* The position.
*/
private final SimpleIntegerProperty position = new SimpleIntegerProperty(0);
/**
* The title.
*/
private final SimpleStringProperty title = new SimpleStringProperty("Title");
/**
* Constructor.
*/
public Info(final String id) {
this.id = id;
}
public String getId() {
return id;
}
public int getPosition() {
return position.get();
}
public void setPosition(final int position) {
this.position.set(position);
}
public String getTitle() {
return title.get();
}
public void setTitle(final String title) {
this.title.set(title);
}
}
Main.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.Text?>
<BorderPane id="BorderPane"
fx:controller="test.controller.InteractionTest"
xmlns:fx="http://javafx.com/fxml">
<top>
</top>
<center>
<SplitPane dividerPositions="0.5" orientation="HORIZONTAL"
focusTraversable="true">
<items>
<fx:include source="InfoTable.fxml" />
<fx:include source="InfoDisplay.fxml" />
</items>
</SplitPane>
</center>
<bottom>
</bottom>
</BorderPane>
InfoTable.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.control.*?>
<ScrollPane xmlns:fx="http://javafx.com/fxml/1"
fx:controller="test.controller.InfoTableController"
fx:id="infoTablePane">
</ScrollPane>
InfoDisplay.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<BorderPane xmlns:fx="http://javafx.com/fxml/1"
prefHeight="500" prefWidth="500" minHeight="200" minWidth="200"
fx:controller="test.controller.InfoDisplayController">
<center>
<TabPane fx:id="infoDisplayTabPane"><Tab text="test"></Tab></TabPane>
</center>
</BorderPane>
【问题讨论】: