我是Java和编程的新手,我正在尝试为学校项目构建一个带有数据库的小型桌面应用程序。 我有一个主窗口,其中有一个从MySql数据库填充的TableView,我添加了几个按钮来添加编辑和删除条目。单击“添加”按钮时,会弹出一个新窗口以插入数据(使用TextField控件)。它工作正常,表更新。但是,我无法对“编辑”按钮执行相同操作。我想从TableView中获取所选项目,当我按下编辑按钮时,我希望新窗口中的TextFields填充所选项目中的数据。我不知道如何做这项工作。我将衷心感谢您的帮助。我几乎在Google上尝试过每一件事。
主Java:
package proiect;
import javafx.beans.property.SimpleStringProperty;
public class Languages {
int langId;
SimpleStringProperty langName;
SimpleStringProperty langCode;
SimpleStringProperty cName;
public Languages(int langId, String langName, String langCode, String cName) {
this.langId = langId;
this.langName = new SimpleStringProperty (langName);
this.langCode = new SimpleStringProperty (langCode);
this.cName = new SimpleStringProperty (cName);
}
}
主控制器:
package proiect;
import java.io.IOException; import java.net.URL; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ResourceBundle; import java.util.logging.Level; import java.util.logging.Logger; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.scene.Scene; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; import javafx.scene.control.TextField; import javafx.scene.layout.BorderPane; import javafx.stage.Modality; import javafx.stage.Stage;
public class Tab1Controller {
Connection cnx;
Stage addLang;
AddlangController ctrlAdd;
Stage editLang;
EditlangController ctrlEdit;
int indexSelect;
@FXML
private ResourceBundle resources;
@FXML
private URL location;
@FXML
TableView<Languages> tlanguages;
@FXML
private TableColumn<Languages, Integer> langId;
@FXML
private TableColumn<Languages, String> langName;
@FXML
private TableColumn<Languages, String> langCode;
@FXML
private TableColumn<Languages, String> cName;
@FXML
private TextField searchlang;
@FXML
void add(ActionEvent event) {
addLang.showAndWait();
}
@FXML
void deleteLang(ActionEvent event) {
try {
int poz = (int) tlanguages.getSelectionModel().getSelectedIndex();
Languages lang = tlanguages.getItems().get(poz);
int id = lang.langId;
String cda = "delete from languages where langId = " + id;
Statement stm = cnx.createStatement();
stm.executeUpdate(cda);
stm.close();
load();
} catch (SQLException ex) {
Logger.getLogger(Tab1Controller.class.getName()).log(Level.SEVERE,
null, ex);
}
}
@FXML
void editLang(ActionEvent event) {
editLang.showAndWait();
}
@FXML
void cancelLang(ActionEvent event) {
}
public void load() {
tlanguages.getItems().clear();
String cda = "select * from languages order by langname";
ResultSet rs;
try {
Statement stmt;
stmt = cnx.createStatement();
rs = stmt.executeQuery(cda);
while (rs.next()) {
int langId = rs.getInt("langId");
String langName = rs.getString("langName");
String langCode = rs.getString("langCode");
String cName = rs.getString("cName");
Languages lang;
lang = new Languages(langId, langName, langCode, cName);
tlanguages.getItems().add(lang);
}
stmt.close();
} catch (SQLException ex) {
Logger.getLogger(Tab1Controller.class
.getName()).log(Level.SEVERE, null, ex);
}
}
@FXML
void initialize() {
langName.setCellValueFactory(cellData -> cellData.getValue().langName);
langCode.setCellValueFactory(cellData -> cellData.getValue().langCode);
cName.setCellValueFactory(cellData -> cellData.getValue().cName);
try {
Class.forName("com.mysql.jdbc.Driver");
cnx = DriverManager.getConnection("jdbc:mysql://localhost/Proiect?characterEncoding=utf8", "root", "");
} catch (ClassNotFoundException ex) {
Logger.getLogger(Tab1Controller.class.getName()).log(Level.SEVERE, null, ex);
} catch (SQLException ex) {
Logger.getLogger(Tab1Controller.class.getName()).log(Level.SEVERE, null, ex);
}
load();
//Get the window for "Add languages"
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("Addlang.fxml"));
BorderPane container = (BorderPane) loader.load();
ctrlAdd = loader.getController();
addLang = new Stage();
addLang.setTitle("Add languages");
addLang.initModality(Modality.APPLICATION_MODAL);
Scene scena = new Scene(container);
addLang.setScene(scena);
ctrlAdd.ctrl = this;
} catch (IOException ex) {
Logger.getLogger(Tab1Controller.class.getName()).log(Level.SEVERE, null, ex);
}
// Get the window Edit Languages
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("Editlang.fxml"));
BorderPane container = (BorderPane) loader.load();
ctrlEdit = loader.getController();
editLang = new Stage();
editLang.setTitle("Edit languages");
editLang.initModality(Modality.APPLICATION_MODAL);
Scene scena = new Scene(container);
editLang.setScene(scena);
ctrlEdit.ctrl = this;
tlanguages.getSelectionModel().selectedIndexProperty().addListener((object, oldValue, newValue) -> {
indexSelect = (int) newValue;
});
} catch (IOException ex) {
Logger.getLogger(Tab1Controller.class.getName()).log(Level.SEVERE, null, ex);
}
} }
编辑控制器:
package proiect;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
public class EditlangController {
Tab1Controller ctrl;
@FXML
private ResourceBundle resources;
@FXML
private URL location;
@FXML
TextField lName;
@FXML
TextField lCode;
@FXML
TextField country;
@FXML
TableView<Languages> tlanguages;
@FXML
void cancel(ActionEvent event) {
((Node) (event.getSource())).getScene().getWindow().hide();
}
private String apostrof(String s) {
return "'" + s + "'";
}
@FXML
void editLang(ActionEvent event) {
}
public void populate() {
}
@FXML
void initialize() {
}
}
答案 0 :(得分:0)
您的代码示例未完整,因此我从头开始构建了一个快速应用程序,演示了如何执行此操作。
基本上,您需要在创建时将所选项目从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>