JavaFX dynamic TableView未显示数据库中的数据
我使用场景生成器创建了一个TableView,如下所示- 这是FXML代码-JavaFX dynamic TableView未显示数据库中的数据,java,javafx,javafx-2,javafx-8,Java,Javafx,Javafx 2,Javafx 8,我使用场景生成器创建了一个TableView,如下所示- 这是FXML代码- <?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.control.*?> <?import java.lang.*?> <?import javafx.scene.layout.*?> <Pane maxHeight="-Infinity" maxWidth="-Infinity" mi
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="508.0" prefWidth="483.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="imran.jfx.application.Controller">
<children>
<TableView fx:id="tableview" layoutX="19.0" layoutY="94.0" prefHeight="402.0" prefWidth="443.0">
<columns>
<TableColumn fx:id="id" prefWidth="75.0" text="ID" />
<TableColumn fx:id="english" prefWidth="170.0" text="English" />
<TableColumn fx:id="bangla" prefWidth="197.0" text="Bangla" />
</columns>
</TableView>
<Button fx:id="showTableview" layoutX="188.0" layoutY="52.0" mnemonicParsing="false" onAction="#showTableData" text="Show Tables" />
</children>
</Pane>
我尝试连接数据库,并尝试将数据从数据库显示到tableview。我尝试将这些东西实现到控制器类中,如下所示-
package imran.jfx.application;
import java.net.URL;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ResourceBundle;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.control.TableView;
import javafx.util.Callback;
public class Controller implements Initializable{
private ObservableList<ObservableList> data;
@FXML
private TableView<?> tableview;
@FXML
private TableColumn<?, ?> id;
@FXML
private TableColumn<?, ?> english;
@FXML
private TableColumn<?, ?> bangla;
@FXML
private Button showTableview;
ResultSet result;
PreparedStatement doQuery;
Connection conn;
String query;
@Override
public void initialize(URL location, ResourceBundle resources)
{
try
{
Class.forName("org.sqlite.JDBC");
}
catch (ClassNotFoundException e) {
e.printStackTrace();
}
String url="jdbc:sqlite::resource:database/bn_words.db";
try
{
conn = DriverManager.getConnection(url);
}
catch (SQLException e) {
e.printStackTrace();
}
}
public void buildData()
{
data = FXCollections.observableArrayList();
try{
Class.forName("org.sqlite.JDBC");
String url="jdbc:sqlite::resource:database/bn_words.db";
conn = DriverManager.getConnection(url);
String SQL = "SELECT _id,en_word,bn_word from words";
ResultSet rs = conn.createStatement().executeQuery(SQL);
for(int i=0 ; i<rs.getMetaData().getColumnCount(); i++)
{
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());
}
});
tableview.getColumns().addAll(col);
System.out.println("Column ["+i+"] ");
}
while(rs.next()){
ObservableList<String> row = FXCollections.observableArrayList();
for(int i=1 ; i<=rs.getMetaData().getColumnCount(); i++){
row.add(rs.getString(i));
}
System.out.println("Row [1] added "+row );
data.add(row);
}
tableview.setItems(data);
}catch(Exception e){
e.printStackTrace();
System.out.println("Error on Building Data");
}
}
@FXML
void showTableData(ActionEvent event) {
tableview = new TableView();
buildData();
}
}
包imran.jfx.application;
导入java.net.URL;
导入java.sql.Connection;
导入java.sql.DriverManager;
导入java.sql.PreparedStatement;
导入java.sql.ResultSet;
导入java.sql.SQLException;
导入java.util.ResourceBundle;
导入javafx.beans.property.SimpleStringProperty;
导入javafx.beans.value.observeValue;
导入javafx.collections.FXCollections;
导入javafx.collections.ObservableList;
导入javafx.event.ActionEvent;
导入javafx.fxml.fxml;
导入javafx.fxml.Initializable;
导入javafx.scene.control.Button;
导入javafx.scene.control.TableColumn;
导入javafx.scene.control.TableColumn.CellDataFeatures;
导入javafx.scene.control.TableView;
导入javafx.util.Callback;
公共类控制器实现可初始化{
私有可观测列表数据;
@FXML
私有TableView TableView;
@FXML
私有表列id;
@FXML
私人英语专栏;
@FXML
孟加拉邦私人银行;
@FXML
私有按钮显示视图;
结果集结果;
预处理语句doQuery;
连接接头;
字符串查询;
@凌驾
公共void初始化(URL位置、ResourceBundle资源)
{
尝试
{
Class.forName(“org.sqlite.JDBC”);
}
catch(classnotfounde异常){
e、 printStackTrace();
}
String url=“jdbc:sqlite::resource:database/bn_words.db”;
尝试
{
conn=DriverManager.getConnection(url);
}
捕获(SQLE异常){
e、 printStackTrace();
}
}
public void buildData()
{
data=FXCollections.observearraylist();
试一试{
Class.forName(“org.sqlite.JDBC”);
String url=“jdbc:sqlite::resource:database/bn_words.db”;
conn=DriverManager.getConnection(url);
String SQL=“从单词中选择_id、en_word、bn_word”;
ResultSet rs=conn.createStatement().executeQuery(SQL);
对于(int i=0;iNo),请不要忽略这些警告。这些警告是因为您对“泛型”(即参数化)的类型使用原始类型。如果这样做,则可能会导致编译器无法捕获的类型不匹配。使用正确声明的类型并使其正确将使程序更加健壮
例如,TableView
是一个泛型类型:它被声明为TableView
。这里T
是一个类型参数:您可以(粗略地说)将T
视为表示表中每一行中事物类型的变量。当您创建实际的TableView
时,您必须指定特定的TableView
将包含的类型。在您的示例中,每一行都由可观察列表
表示。现在,可观察列表
is也是一个泛型类型:它被声明为observateList
,其中E
表示列表中每个元素的类型。在您的例子中,在buildData()
方法中,您为每一行创建一个observateList
。因此,您的表类型是observateList
,因此您应该替换它
@FXML
private TableView<?> tableView ;
private ObservableList<ObservableList> data;
与
(请注意,由于这些是要添加到表中的列,因此不太清楚为什么在FXML中也定义了列;但对于您要问的问题来说,这有点离题。)
当您使用常规列表作为表的数据类型时,所有这些都变得非常复杂。因为在这里,您知道数据库中有多少列,以及这些列代表什么,所以我强烈建议通过定义一个类来表示每行中的数据,从而使表更加具体。我不知道您的应用程序是,所以我会(可能不正确)猜测它正在做一些翻译。所以我会这样做
public class TranslatedWord {
private final StringProperty id = new SimpleStringProperty();
public StringProperty idProperty() {
return id ;
}
public final String getId() {
return idProperty().get();
}
public final void setId(String id) {
idProperty().set(id);
}
private final StringProperty english = new SimpleStringProperty();
public StringProperty englishProperty() {
return english ;
}
public final String getEnglish() {
return englishProperty().get();
}
public final void setEnglish(String english) {
englishProperty().set(english);
}
private final StringProperty bangla = new SimpleStringProperty();
public StringProperty banglaProperty() {
return bangla ;
}
public final String getBangla() {
return banglaProperty().get();
}
public final void setId(String bangla) {
banglaProperty().set(bangla);
}
}
现在,您创建了一个TableView
和TableColumn
,等等。您的数据
变成了一个可观察列表
,您的buildData()
方法有如下代码
while(rs.next()){
TranslatedWord word = new TranslatedWord();
word.setId(rs.getString("id"));
word.setEnglish(rs.getString("english"));
word.setBangla(rs.getString("bangla"));
System.out.println("Row [1] added "+row );
data.add(row);
}
一旦你习惯了这种结构,你会发现这是一种更容易维护的样式,因为类型指定了它们所代表的内容
这段代码中还有很多其他错误:正如我前面所说的,您正在FXML中创建TableView
和TableColumn
s,但随后您在控制器中创建了新的并对其进行操作。因此,即使您修复了您实际询问的问题,您可能也会发现它不会以y的方式工作在您解决这些问题之前,您也需要这样做。但是消除编译错误和警告将是一个开始…不,不要忽略这些警告。这些警告是因为您对“泛型”类型使用原始类型,即参数化。如果执行此操作,可能会导致编译器无法捕获的类型不匹配。使用正确声明的类型并使其正确将使程序更加健壮
例如,TableView
是一个泛型类型:它被声明为TableView
。这里T
是一个类型参数:您可以(粗略地说)将T
视为表示表中每一行中事物类型的变量。当您创建实际的TableView
时,您必须指定特定的TableView
将包含的类型。在您的示例中,每一行都由可观察列表
表示。现在,可观察列表
i它也是一个泛型类型:它被声明为ObservableL
TableColumn<ObservableList<String>, String> col = new TableColumn<>(rs.getMetaData().getColumnName(i+1));
public class TranslatedWord {
private final StringProperty id = new SimpleStringProperty();
public StringProperty idProperty() {
return id ;
}
public final String getId() {
return idProperty().get();
}
public final void setId(String id) {
idProperty().set(id);
}
private final StringProperty english = new SimpleStringProperty();
public StringProperty englishProperty() {
return english ;
}
public final String getEnglish() {
return englishProperty().get();
}
public final void setEnglish(String english) {
englishProperty().set(english);
}
private final StringProperty bangla = new SimpleStringProperty();
public StringProperty banglaProperty() {
return bangla ;
}
public final String getBangla() {
return banglaProperty().get();
}
public final void setId(String bangla) {
banglaProperty().set(bangla);
}
}
while(rs.next()){
TranslatedWord word = new TranslatedWord();
word.setId(rs.getString("id"));
word.setEnglish(rs.getString("english"));
word.setBangla(rs.getString("bangla"));
System.out.println("Row [1] added "+row );
data.add(row);
}