Ваш пример кода не был завершен, поэтому я с нуля создал быстрое приложение, которое демонстрирует, как это сделать.
По сути, вам нужно будет передать выбранный элемент из TableView
на новый контроллер, когдаВы создаете его.
Вот полный список примера программы, которая демонстрирует это (6 файлов):
Main.java
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
try {
FXMLLoader loader = new FXMLLoader(Main.class.getResource("MainLayout.fxml"));
primaryStage.setTitle("TableView Sample");
primaryStage.setScene(new Scene(loader.load()));
primaryStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
}
MainController.java
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Modality;
import javafx.stage.Stage;
import java.io.IOException;
public class MainController {
// Define the FXML controls
@FXML
private TableView<Data> tblDataView;
@FXML
private TableColumn<Data, String> colName;
@FXML
private TableColumn<Data, String> colEmail;
@FXML
private Button btnDoThings;
@FXML
private void initialize() {
// Create sample Data objects for the TableView
ObservableList<Data> dataList = FXCollections.observableArrayList();
dataList.add(new Data("Bob", "bob@email.com"));
dataList.add(new Data("Harley", "harley@coolspot.com"));
dataList.add(new Data("Jane", "jane@email.com"));
dataList.add(new Data("Moby", "mobyboy@toocool.com"));
// Setup the TableView columns to display the correct data
colName.setCellValueFactory(new PropertyValueFactory<>("name"));
colEmail.setCellValueFactory(new PropertyValueFactory<>("email"));
// Bind the list of sample data to the TableView
tblDataView.setItems(dataList);
// Set the action for the button
btnDoThings.setOnAction(event -> doThings());
}
private void doThings() {
// If no item has been selected from the table, do nothing
if (tblDataView.getSelectionModel().getSelectedItem() == null) return;
// Load the new window
try {
FXMLLoader loader = new FXMLLoader(Main.class.getResource("EditorLayout.fxml"));
// Create the new controller and pass the currently selected data item to it
EditorController controller = new EditorController(tblDataView.getSelectionModel().getSelectedItem());
// Set the controller to the loader
loader.setController(controller);
Stage editorStage = new Stage();
editorStage.setTitle("Edit Item");
// Centers the editor window over the current window
editorStage.initOwner(tblDataView.getScene().getWindow());
// Ensures the new window needs to be closed before the current window can be used again
editorStage.initModality(Modality.APPLICATION_MODAL);
editorStage.setScene(new Scene(loader.load()));
editorStage.showAndWait();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Здесь вы познакомитесь с методом doThings()
.Вы увидите, что новый объект EditorController
создан и добавлен в loader
.Вы можете использовать конструктор этого контроллера (следующий список кодов) для передачи ссылки на выбранный в данный момент элемент для редактирования.
Вы также можете повторно использовать тот же EditorController
, чтобы добавить новые записи в список,передав new Data(null, null)
через контроллер.Конечно, вам также необходимо добавить его в базовый список TableView
.
EditorController.java
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
public class EditorController {
@FXML
private TextField txtName;
@FXML
private TextField txtEmail;
@FXML
private Button btnSave;
private Data data;
// Constructor to accept the object to be edited
public EditorController(Data data) {
this.data = data;
}
@FXML
private void initialize() {
// Bind the data to the textfields
txtName.textProperty().bindBidirectional(data.nameProperty());
txtEmail.textProperty().bindBidirectional(data.emailProperty());
btnSave.setOnAction(e -> handleSave());
}
private void handleSave() {
// Just close the stage
((Stage) txtEmail.getScene().getWindow()).close();
}
}
Этот простой контроллер получает выбранныйСтрока элемента из MainController
, а затем привязывает свои данные к текстовым полям.Любые изменения, внесенные в данные, автоматически обновляются и в главном окне.
Именно здесь вы можете реализовать дополнительные возможности, такие как возможность отмены изменений и т. Д. Но это должно помочь вам начать работу.в правильном направлении, по крайней мере, имея данные, доступные для манипулирования.
MainLayout.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.VBox?>
<AnchorPane xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="sample.tableViewSample.MainController">
<children>
<VBox alignment="CENTER" spacing="10.0">
<children>
<TableView fx:id="tblDataView">
<columns>
<TableColumn fx:id="colName" prefWidth="75.0" text="Name"/>
<TableColumn fx:id="colEmail" prefWidth="200.0" text="Email"/>
</columns>
</TableView>
<Button fx:id="btnDoThings" mnemonicParsing="false" text="Do Things!"/>
</children>
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
</VBox>
</children>
</AnchorPane>
EditorLayout.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1">
<children>
<VBox spacing="10.0">
<children>
<GridPane hgap="10.0" vgap="5.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="-Infinity"/>
<ColumnConstraints hgrow="ALWAYS" minWidth="10.0"/>
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
</rowConstraints>
<children>
<Label text="Name:"/>
<Label text="Email:" GridPane.rowIndex="1"/>
<TextField fx:id="txtName" GridPane.columnIndex="1"/>
<TextField fx:id="txtEmail" GridPane.columnIndex="1" GridPane.rowIndex="1"/>
</children>
</GridPane>
<HBox alignment="CENTER" spacing="10.0" VBox.vgrow="NEVER">
<children>
<Button fx:id="btnSave" defaultButton="true" mnemonicParsing="false" text="Save Changes"/>
</children>
</HBox>
</children>
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
</VBox>
</children>
</AnchorPane>