我在JavaFX中执行此程序,该程序将从在Microsoft访问时创建的数据库中获取数据并将其放在表视图中。另外,我在表格视图中创建按钮(添加,删除),当点击添加按钮时,它将打开一个新的FXML页面。在这个页面中有5个TextFiled和两个按钮(添加和取消),当点击添加按钮时,它想要获取TextFiled中的所有数据并将其添加到我的表视图中。但实际上,我无法做到这一点。我希望这里的某个人能够知道如何实现这一目标。
FXMLDocumentController.java
package db;
import java.net.URL;
import java.sql.DriverManager;
import java.sql.Statement;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import java.sql.Connection;
import java.sql.ResultSet;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.Button;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.control.TableView;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.util.Callback;
/**
*
* @author pc
*/
public class FXMLDocumentController implements Initializable {
@FXML
public Statement st;
public TableView<ObservableList> table;
public ObservableList<ObservableList> data;
private Button btnNew = new Button("New Record");
public void buildData(){
data = FXCollections.observableArrayList();
try{
Class.forName("net.ucanaccess.jdbc.UcanaccessDriver");
Connection con = DriverManager.getConnection("jdbc:ucanaccess://D:\\GUI\\Library.accdb","","");
System.out.println("connected...");
st=con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
//SQL FOR SELECTING ALL OF BOOK
String SQL = "SELECT * from BookDB";
//ResultSet
ResultSet rs = con.createStatement().executeQuery(SQL);
/**********************************
* TABLE COLUMN ADDED DYNAMICALLY *
**********************************/
for(int i=0 ; i<rs.getMetaData().getColumnCount(); i++){
//We are using non property style for making dynamic table
final int j = i;
TableColumn col = new TableColumn(rs.getMetaData().getColumnName(i+1));
col.setCellValueFactory(new Callback<CellDataFeatures<ObservableList,String>,ObservableValue<String>>(){
public ObservableValue<String> call(CellDataFeatures<ObservableList, String> param) {
return new SimpleStringProperty(param.getValue().get(j).toString());
}
});
table.getColumns().addAll(col);
System.out.println("Column ["+i+"] ");
}
TableColumn col_action = new TableColumn<>("Action");
col_action.setSortable(false);
col_action.setCellValueFactory(
new Callback<TableColumn.CellDataFeatures<ObservableList, Boolean>,
ObservableValue<Boolean>>() {
@Override
public ObservableValue<Boolean> call(TableColumn.CellDataFeatures<ObservableList, Boolean> p) {
return new SimpleBooleanProperty(p.getValue() != null);
}
});
col_action.setCellFactory(
new Callback<TableColumn<ObservableList, Boolean>, TableCell<ObservableList, Boolean>>() {
@Override
public TableCell<ObservableList, Boolean> call(TableColumn<ObservableList, Boolean> p) {
return new ButtonCell(table);
}
});
table.getColumns().add(col_action);
TableColumn col_Delete = new TableColumn<>("Delete");
col_Delete.setSortable(false);
col_Delete.setCellValueFactory(
new Callback<TableColumn.CellDataFeatures<ObservableList, Boolean>,
ObservableValue<Boolean>>() {
@Override
public ObservableValue<Boolean> call(TableColumn.CellDataFeatures<ObservableList, Boolean> p) {
return new SimpleBooleanProperty(p.getValue() != null);
}
});
col_Delete.setCellFactory(
new Callback<TableColumn<ObservableList, Boolean>, TableCell<ObservableList, Boolean>>() {
@Override
public TableCell<ObservableList, Boolean> call(TableColumn<ObservableList, Boolean> p) {
return new ButtonDelete(table);
}
});
table.getColumns().add(col_Delete);
/********************************
* Data added to ObservableList *
********************************/
while(rs.next()){
//Iterate Row
ObservableList<String> row = FXCollections.observableArrayList();
for(int i=1 ; i<=rs.getMetaData().getColumnCount(); i++){
//Iterate Column
row.add(rs.getString(i));
}
System.out.println("Row [1] added "+row );
data.add(row);
}
//FINALLY ADDED TO TableView
table.setItems(data);
}
catch(Exception e){
e.printStackTrace();
System.out.println("Error on Building Data");
}
}
@Override
public void initialize(URL url, ResourceBundle rb) {
buildData();
table.refresh();
}
//Define the button cell
private class ButtonCell extends TableCell<ObservableList, Boolean> {
final Button cellButton = new Button("Add");
ButtonCell(final TableView tblView){
cellButton.setOnAction(new EventHandler<ActionEvent>(){
@Override
public void handle(ActionEvent t) {
try {
Second s=new Second();
s.start(new Stage());
} catch (Exception ex) {
Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
//Display button if the row is not empty
@Override
protected void updateItem(Boolean t, boolean empty) {
super.updateItem(t, empty);
if(!empty){
setGraphic(cellButton);
}
}
}
//Define the button cell
private class ButtonDelete extends TableCell<ObservableList, Boolean> {
final Button delButton = new Button("Delete");
ButtonDelete(final TableView tblView){
delButton.setOnAction(new EventHandler<ActionEvent>(){
@Override
public void handle(ActionEvent t) {
Stage myDialog = new Stage();
myDialog.initModality(Modality.WINDOW_MODAL);
myDialog.show();
}
});
}
//Display button if the row is not empty
@Override
protected void updateItem(Boolean t, boolean empty) {
super.updateItem(t, empty);
if(!empty){
setGraphic(delButton);
}
}
}
}
FXMLController.java
package db;
import java.net.URL;
import java.sql.Statement;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TextField;
/**
* FXML Controller class
*
* @author pc
*/
public class FXMLController implements Initializable {
@FXML
public TextField t1,t2,t3,t4,t5;
public Statement st;
@FXML
public void btnADD(ActionEvent e)
{
}
@FXML
public void btnCANCEL(ActionEvent e)
{
System.exit(0);
}
@Override
public void initialize(URL url, ResourceBundle rb)
{
}
}
数据库结构
答案 0 :(得分:2)
创建弹出窗口时,向其传递一个回调方法,该方法可以保留数据并刷新表格。弹出窗口应该在消费者添加&#39;单击按钮。以下是加载弹出窗口的示例:
// This method should be called with the table's 'Add' buttons are clicked
public void addButtonClicked() {
try{
// Load the popup
FXMLLoader loader = new FXMLLoader(getClass().getResource("Popup.fxml"));
loader.load();
PopupController controller = loader.getController();
Parent popup = loader.getRoot();
// Give popup a callback method
controller.setup(
(value)->{data.add(value);table.refresh();}
);
// Display popup
Stage stage = new Stage();
stage.setScene(new Scene(popup));
stage.show();
} catch(IOException ex) {
// ToDo: Handle failed popup
}
}
以下是主应用程序以及弹出式fxml和控制器的完整工作示例:
<强> JavaFxApplication.java 强>
import java.io.IOException;
import javafx.application.Application;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class JavaFXApplication20 extends Application {
// Data for the table
private ObservableList<String> data = FXCollections.observableArrayList(
"Item 1","Object 2","Thing 3","Product 4"
);
// The table
private TableView<String> table = new TableView<>(data);
@Override
public void start(Stage stage) throws Exception {
// Content Column
TableColumn<String,String> contentCol = new TableColumn<>("Content");
contentCol.setCellValueFactory(p->new ReadOnlyObjectWrapper(p.getValue()));
// Action Column
TableColumn actionCol = new TableColumn("Action");
actionCol.setCellFactory(param-> new TableCell<String, String>() {
final Button btn = new Button("Add");
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setGraphic(null);
setText(null);
} else {
// Make sure the column of 'Add' buttons
// call the right method
btn.setOnAction(event->addButtonClicked());
setGraphic(btn);
setText(null);
}
}
});
// Display everything on the stage
table.getColumns().addAll(contentCol,actionCol);
Scene scene = new Scene(new VBox(table));
stage.setScene(scene);
stage.show();
}
public void addButtonClicked() {
try{
// Load the popup
FXMLLoader loader = new FXMLLoader(getClass().getResource("Popup.fxml"));
loader.load();
PopupController controller = loader.getController();
Parent popup = loader.getRoot();
// Give popup a callback method
controller.setup(
(value)->{data.add(value);table.refresh();}
);
// Display popup
Stage stage = new Stage();
stage.setScene(new Scene(popup));
stage.show();
} catch(IOException ex) {
// ToDo: Handle failed popup
}
}
public static void main(String[] args) {
launch(args);
}
}
<强> Popup.fxml 强>
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.65" fx:controller="javafxapplication20.PopupController">
<children>
<Button fx:id="button" layoutX="126" layoutY="90" onAction="#addButtonAction" text="Add" />
<Label fx:id="label" layoutX="122.0" layoutY="62.0" minHeight="16" minWidth="69" text="Hello World" />
</children>
</AnchorPane>
<强> PopupController.java 强>
import java.net.URL;
import java.util.ResourceBundle;
import java.util.function.Consumer;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
public class PopupController implements Initializable {
@FXML
private Label label;
@FXML
private Button button;
private Consumer<String> callback;
@Override
public void initialize(URL url, ResourceBundle rb) {
// ToDo: Initialize something
}
public void setup(Consumer<String> callback) {
this.callback = callback;
}
@FXML
private void addButtonAction(ActionEvent event) {
callback.accept(label.getText());
}
}
答案 1 :(得分:0)
我的朋友,基于你的代码,我已经对你的代码进行了一些重构以使其工作,但是代码的结构并不好,如果它是我的项目,我不会使用这个结构,LOL,只是为了参考。 如下所示。
首先,我们需要创建一个TableView的泛型类,在这里我们为它创建Book.java。
package db;
public class Book{
private String id;
private String name;
private String author;
private String publisher;
private String price;
public String getId(){
return this.id;
}
public void setId(String id){
this.id = id;
}
public String getName(){
return this.name;
}
public void setName(String name){
this.name = name;
}
public String getAuthor(){
return this.author;
}
public void setAuthor(String author){
this.author = author;
}
public String getPublisher(){
return this.publisher;
}
public void setPublisher(String publisher){
this.publisher = publisher;
}
public String getPrice(){
return this.price;
}
public void setPrice(String price){
this.price = price;
}
@Override
public int hashCode(){
final int prime = 31;
int result = 1;
result = prime * result + ((this.id == null) ? 0 : this.id.hashCode());
return result;
}
@Override
public boolean equals(Object obj){
if(this == obj)
return true;
if(obj == null)
return false;
if(getClass() != obj.getClass())
return false;
Book other = (Book) obj;
if(this.id == null){
if(other.id != null)
return false;
}else if(!this.id.equals(other.id))
return false;
return true;
}
public void setValue(String columnName, String colData){
if(columnName.contentEquals("BookName")){
setName(colData);
}else if(columnName.contentEquals("Author")){
setAuthor(colData);
}else if(columnName.contentEquals("Publisher")){
setPublisher(colData);
}else if(columnName.contentEquals("Price")){
setPrice(colData);
}else{
//BookId
setId(colData);
}
}
public String getValue(String columnName){
String value = "";
if(columnName.contentEquals("BookName")){
value = getName();
}else if(columnName.contentEquals("Author")){
value = getAuthor();
}else if(columnName.contentEquals("Publisher")){
value = getPublisher();
}else if(columnName.contentEquals("Price")){
value = getPrice();
}else{
//BookId
value = getId();
}
return value;
}
}
然后修改你的FXMLDocumentController.java,如下所示:
package db;
import java.io.IOException;
import java.net.URL;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.control.TableView;
import javafx.stage.Stage;
import javafx.util.Callback;
/**
*
* @author pc
*/
public class FXMLDocumentController implements Initializable{
public Statement st;
@FXML
public TableView<Book> table;
//public ObservableList<ObservableList> data;
private ObservableList<Book> bookData;
//private Button btnNew = new Button("New Record");
public void buildData(){
//data = FXCollections.observableArrayList();
bookData = FXCollections.observableArrayList();
try{
Class.forName("net.ucanaccess.jdbc.UcanaccessDriver");
Connection con = DriverManager.getConnection("jdbc:ucanaccess://D:\\GUI\\Library.accdb", "", "");
System.out.println("connected...");
st = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
// SQL FOR SELECTING ALL OF BOOK
String SQL = "SELECT * from BookDB";
// ResultSet
ResultSet rs = con.createStatement().executeQuery(SQL);
/**********************************
* TABLE COLUMN ADDED DYNAMICALLY *
**********************************/
for(int i = 0; i < rs.getMetaData().getColumnCount(); i++){
// We are using non property style for making dynamic table
String columnName = rs.getMetaData().getColumnName(i + 1);
TableColumn<Book, String> col = new TableColumn<>(columnName);
col.setCellValueFactory(new Callback<CellDataFeatures<Book, String>, ObservableValue<String>>(){
public ObservableValue<String> call(CellDataFeatures<Book, String> param){
Book book = param.getValue();
String cellData = book.getValue(columnName);
return new SimpleStringProperty(cellData);
}
});
table.getColumns().add(col);
System.out.println("Column [" + i + "] ");
}
TableColumn<Book, Boolean> col_action = new TableColumn<>("Action");
col_action.setSortable(false);
col_action.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Book, Boolean>, ObservableValue<Boolean>>(){
@Override
public ObservableValue<Boolean> call(TableColumn.CellDataFeatures<Book, Boolean> p){
return new SimpleBooleanProperty(p.getValue() != null);
}
});
col_action.setCellFactory(new Callback<TableColumn<Book, Boolean>, TableCell<Book, Boolean>>(){
@Override
public TableCell<Book, Boolean> call(TableColumn<Book, Boolean> p){
return new ButtonCell(table);
}
});
table.getColumns().add(col_action);
TableColumn<Book, Boolean> col_Delete = new TableColumn<>("Delete");
col_Delete.setSortable(false);
col_Delete.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Book, Boolean>, ObservableValue<Boolean>>(){
@Override
public ObservableValue<Boolean> call(TableColumn.CellDataFeatures<Book, Boolean> p){
return new SimpleBooleanProperty(p.getValue() != null);
}
});
col_Delete.setCellFactory(new Callback<TableColumn<Book, Boolean>, TableCell<Book, Boolean>>(){
@Override
public TableCell<Book, Boolean> call(TableColumn<Book, Boolean> p){
return new ButtonDelete(table);
}
});
table.getColumns().add(col_Delete);
/********************************
* Data added to ObservableList *
********************************/
while(rs.next()){
Book book = new Book();
// Iterate Row
for(int i = 1; i <= rs.getMetaData().getColumnCount(); i++){
// Iterate Column
String columnName = rs.getMetaData().getColumnName(i);
String columnData = rs.getString(i);
book.setValue(columnName, columnData);
}
System.out.println("Row [1] added " + book.getName());
bookData.add(book);
}
// FINALLY ADDED TO TableView
table.setItems(bookData);
}catch(Exception e){
e.printStackTrace();
System.out.println("Error on Building Data");
}
}
@Override
public void initialize(URL url, ResourceBundle rb){
buildData();
table.refresh();
}
// Define the button cell
private class ButtonCell extends TableCell<Book, Boolean>{
final Button cellButton = new Button("Add");
ButtonCell(final TableView<Book> tblView) {
cellButton.setOnAction(new EventHandler<ActionEvent>(){
@Override
public void handle(ActionEvent t){
try{
//Second s = new Second();
//s.start(new Stage());
openFXMLController();
}catch(Exception ex){
Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
// Display button if the row is not empty
@Override
protected void updateItem(Boolean t, boolean empty){
super.updateItem(t, empty);
if(!empty){
setGraphic(cellButton);
}else{
setGraphic(null);
setText("");
}
}
}
private Stage fxmlControllerStage;
private void openFXMLController(){
if(fxmlControllerStage == null){
FXMLLoader loader = new FXMLLoader(getClass().getResource("FXML.fxml"));
try{
Parent root = loader.load();
fxmlControllerStage = new Stage();
fxmlControllerStage.setScene(new Scene(root));
if(loader.getController() instanceof FXMLController){
FXMLController fxmlController = loader.getController();
fxmlController.setStage(fxmlControllerStage);
fxmlController.setTable(table);
}
}catch(IOException e){
e.printStackTrace();
}
}
fxmlControllerStage.show();
}
// Define the button cell
private class ButtonDelete extends TableCell<Book, Boolean>{
final Button delButton = new Button("Delete");
ButtonDelete(final TableView<Book> tblView) {
delButton.setOnAction(new EventHandler<ActionEvent>(){
@Override
public void handle(ActionEvent t){
bookData.remove(getIndex());
}
});
}
// Display button if the row is not empty
@Override
protected void updateItem(Boolean t, boolean empty){
super.updateItem(t, empty);
if(!empty){
setGraphic(delButton);
}else{
setGraphic(null);
setText("");
}
}
}
}
,最后一个是你的FXMLController.java。我们修改如下:
package db;
import java.net.URL;
import java.sql.Statement;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.ButtonType;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
/**
* FXML Controller class
*
* @author pc
*/
public class FXMLController implements Initializable{
@FXML
public TextField t1;
@FXML
public TextField t2;
@FXML
public TextField t3;
@FXML
public TextField t4;
@FXML
public TextField t5;
public Statement st;
@FXML
public void btnADD(ActionEvent e){
Book book = new Book();
try{
Integer.valueOf(t1.getText());
}catch(NumberFormatException exception){
Alert alert = new Alert(AlertType.ERROR);
alert.setContentText("BookID must be an integer");
alert.showAndWait();
return;
}
try{
Double.valueOf(t5.getText());
}catch(NumberFormatException exception){
Alert alert = new Alert(AlertType.ERROR);
alert.setContentText("Price must be an integer");
alert.showAndWait();
return;
}
book.setId(t1.getText());
book.setName(t2.getText());
book.setAuthor(t3.getText());
book.setPublisher(t4.getText());
book.setPrice(t5.getText());
if(table != null){
table.getItems().add(book);
if(stage != null){
t1.clear();
t2.clear();
t3.clear();
t4.clear();
t5.clear();
stage.close();
}
}
}
@FXML
public void btnCANCEL(ActionEvent e){
Alert alert = new Alert(AlertType.CONFIRMATION);
alert.setContentText("Close Window, Are you sure?");
alert.showAndWait();
ButtonType result = alert.getResult();
if(result == ButtonType.OK){
if(stage != null){
stage.close();
}
}
//System.exit(0);
}
@Override
public void initialize(URL url, ResourceBundle rb){
}
private Stage stage;
public void setStage(Stage stage){
this.stage = stage;
}
private TableView<Book> table;
public void setTable(TableView<Book> table){
this.table = table;
}
}
我们删除了Second.java,因为它什么也没做。
答案 2 :(得分:0)
在Add上打开新的FXML页面(B)点击FXML的TableView页面(A) 保存在新B中输入的数据(在Add Clicked上),然后在新FXML(B)关闭时刷新A上的表格视图。