我从@Fabian得到了一些很好的建议,但是我在ListView中看不到任何数据:
public class MenuController implements Initializable {
@FXML
ListView menuList1;
@Override
public void initialize(URL url, ResourceBundle rb) {
ObservableList<EmployeeDivision> divisionListRow = FXCollections.observableArrayList();
try {
Connection conn;
conn = Connect_db.getConnection();
String query = "SELECT ID,Division FROM tbl_ref_employee_divisions";
PreparedStatement prestate = conn.prepareStatement(query);
ResultSet divsResult = prestate.executeQuery();
while (divsResult.next()) {
divisionListRow.add(new EmployeeDivision(divsResult.getInt(1), divsResult.getString(2)));
menuList1.setCellFactory(lv -> new ListCell<EmployeeDivision>() {
@Override
protected void updateItem(EmployeeDivision item, boolean empty) {
super.updateItem(item, empty);
setText(empty || item == null ? "" : item.getName());
}
});
}
prestate.close();
divsResult.close();
conn.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
}
我不知道lambda的工作原理。但是我会到达那里。
调试我可以看到divisionListRow
正在填充。但是我希望数据divsResult.getString(2)
会出现。
tks
答案 0 :(得分:1)
我可以看到的三件事...
将您的ListView
声明为ListView<EmployeeDivision>
。将其类型设置为EmployeeDivision
。
setCellFactory
不应位于while (divsResult.next())
数据加载循环中。仅需要声明一次,而不是每次将一行从DB装入ObservableList
时都声明一次。
您需要执行menuList1.setItems(divisionListRow)
。 setItems()
是将您的数据与ListView
关联的事物。
这是一个产生如下内容的ListView
的MVCE:
单击状态时,它将部门ID输出到控制台。
MVCE使用SQLite数据库。可以使用此SQL创建MVCE的表和数据。
CREATE TABLE Employee_Divisions (
ID INTEGER,
Division VARCHAR
);
INSERT INTO Employee_Divisions
VALUES
(1, 'Queensland'),
(2, 'New South Wales'),
(3, 'Victoria'),
(4, 'South Australia'),
(5, 'Northern Territory'),
(6, 'Western Australia'),
(7, 'Tasmania');
这是代码。
package test42;
import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.beans.Observable;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import org.sqlite.SQLiteConfig;
public class Test42 extends Application {
private static final String dbName = "TestDB.db";
private static final String dbURL = "jdbc:sqlite:" + dbName;
private static final String dbDriver = "org.sqlite.JDBC";
private Parent createContent() {
//*************************************************************************************
//Declare an ObservableList for the ListView
ObservableList<EmployeeDivisions> olEmployeeDivisions = FXCollections.observableArrayList(empdiv -> new Observable[] {});
//*************************************************************************************
//Get the data from the DB and add it to the ObservableList.
String sql = "SELECT * FROM Employee_Divisions;";
ArrayList<ArrayList<Object>> resultSet = doDatabaseSelect(sql);
olEmployeeDivisions.clear();
for ( ArrayList<Object> resultRow : resultSet ) {
EmployeeDivisions newEmployeeDivision = new EmployeeDivisions();
newEmployeeDivision.addList(resultRow);
olEmployeeDivisions.add(newEmployeeDivision);
}
//*************************************************************************************
//Declare the ListView
ListView<EmployeeDivisions> lvEmployeeDivisions = new ListView<>();
//Set its data to the ObservableList
lvEmployeeDivisions.setItems(olEmployeeDivisions);
//Set its cell factory to only show the division name
lvEmployeeDivisions.setCellFactory(lv -> new ListCell<EmployeeDivisions>() {
@Override
protected void updateItem(EmployeeDivisions item, boolean empty) {
super.updateItem(item, empty);
setText(empty || item == null ? "" : item.getDivisionName());
}
});
//Ouput the division ID when a division name is clicked
lvEmployeeDivisions.setOnMouseClicked((MouseEvent event) -> {
EmployeeDivisions selectedItem = lvEmployeeDivisions.getSelectionModel().getSelectedItem();
if (selectedItem != null) {
System.out.println("Division ID = " + selectedItem.getDivisionId());
}
});
//*************************************************************************************
//Create a BorderPane and add the ListView
BorderPane content = new BorderPane(lvEmployeeDivisions);
return content;
}
//*************************************************************************************
//Data model
private class EmployeeDivisions {
private IntegerProperty divisionId;
private StringProperty divisionName;
private EmployeeDivisions() {
this(0, "");
}
private EmployeeDivisions(
int divisionId,
String divisionName
) {
this.divisionId = new SimpleIntegerProperty(divisionId);
this.divisionName = new SimpleStringProperty(divisionName);
}
private int getDivisionId() {
return divisionId.get();
}
private void setDivisionId(int divisionId) {
this.divisionId.set(divisionId);
}
private IntegerProperty divisionIdProperty() {
return divisionId;
}
private String getDivisionName() {
return divisionName.get();
}
private void setDivisionName(String divisionName) {
this.divisionName.set(divisionName);
}
private StringProperty divisionNameProperty() {
return divisionName;
}
private void addList(ArrayList<Object> list) {
this.divisionId.set((int) list.get(0));
this.divisionName.set((String) list.get(1));
}
}
//*************************************************************************************
//Methods to connect to and query the database and execute DML
public Connection connectToDB() {
Connection cnx = null;
File dbPath = new File(dbName);
if ( dbPath.exists()){
try {
Class.forName(dbDriver);
} catch (ClassNotFoundException exception) {
System.err.println("Database driver class not found");
}
try {
SQLiteConfig config = new SQLiteConfig();
config.enforceForeignKeys(true);
cnx = DriverManager.getConnection(dbURL,config.toProperties());
cnx.setAutoCommit(true);
} catch (SQLException exception) {
System.err.println("Error connecting to database " + dbName);
}
} else {
System.err.println("Database " + dbName + " not found!");
}
return cnx;
}
private ArrayList<ArrayList<Object>> doDatabaseSelect(String sql) {
int colNum = 0;
ArrayList<ArrayList<Object>> resultSet = new ArrayList<>();
Connection cnx = connectToDB();
if ( cnx == null ) return null;
try (
Statement stmt = cnx.createStatement();
) {
try (
ResultSet rs = stmt.executeQuery(sql)
) {
ResultSetMetaData rsMetaData = rs.getMetaData();
//Add each DB row as an Object to the dbRow ArrayList ...
while (rs.next()) {
ArrayList<Object> dbRow = new ArrayList<>();
for ( int i=0; i<rsMetaData.getColumnCount(); i++ ) {
colNum = i + 1;
switch ( rsMetaData.getColumnTypeName(colNum).trim() ) {
case "VARCHAR" :
String stringCol = rs.getString(colNum);
dbRow.add(stringCol);
break;
case "INTEGER" :
int intCol = rs.getInt(colNum);
dbRow.add(intCol);
break;
}
}
//... then add the dbRow to the final resultSet.
resultSet.add(dbRow);
}
//Having added all the DB rows, return the resultSet.
return resultSet;
}
} catch (SQLException exception) {
System.err.println(exception);
return null;
}
}
private void doDatabaseDML(String sql) {
Connection cnx = connectToDB();
if ( cnx == null ) return;
try (
Statement stmt = cnx.createStatement();
) {
cnx.setAutoCommit(true);
stmt.executeUpdate(sql);
} catch (SQLException exception) {
System.err.println(exception);
return;
}
}
@Override
public void start(Stage stage) throws Exception {
stage.setScene(new Scene(createContent()));
stage.setTitle("Test");
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}