我使用 fx 创建了一个 TableView ,它显示来自数据库的信息,每当我搜索数据库并显示结果时,由于某种原因,它会显示检索到的最后一个值乘以找到的结果量,但它应该做的是显示 observableList
中的每一项。我做错了什么?
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import java.util.ArrayList;
/**
* Created by user on 02/06/2016.
*/
public class Main extends Application {
TableView<TableViewData> table;
ObservableList<TableViewData> itemList = FXCollections.observableArrayList();
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("Welcome");
primaryStage.setResizable(false);
TableColumn<TableViewData, String> nameColumn = new TableColumn<>("Name");
nameColumn.setMinWidth(200);
nameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
TableColumn<TableViewData, String> brandColumn = new TableColumn<>("Brand");
nameColumn.setMinWidth(200);
nameColumn.setCellValueFactory(new PropertyValueFactory<>("brand"));
TableColumn<TableViewData, Integer> quantityColumn = new TableColumn<>("Quantity");
nameColumn.setMinWidth(200);
nameColumn.setCellValueFactory(new PropertyValueFactory<>("quantity"));
TableColumn<TableViewData, Double> priceColumn = new TableColumn<>("Price");
nameColumn.setMinWidth(200);
nameColumn.setCellValueFactory(new PropertyValueFactory<>("price"));
TableColumn<TableViewData, String> typeColumn = new TableColumn<>("Type");
nameColumn.setMinWidth(200);
nameColumn.setCellValueFactory(new PropertyValueFactory<>("type"));
table = new TableView<>();
table.getColumns().addAll(nameColumn, quantityColumn, priceColumn, typeColumn, brandColumn);
TextField query = new TextField();
query.setPromptText("Search");
ComboBox column = new ComboBox();
//adds the optons for the combo box
column.getItems().addAll(
"Name",
"Price",
"Item Type",
"Brand",
"Details"
);
Button searchButton = new Button("Search");
searchButton.setOnAction(e -> {
try {
itemList = DatabaseHandling.search(column.getValue().toString(), query.getText());
table.getItems().addAll(itemList);
} catch (Exception ex) {
Errors.error("Please select a an option from the box", "error");
}
});
HBox searchBox = new HBox();
searchBox.getChildren().addAll(query, column, searchButton);
searchBox.setPadding(new Insets(10, 10, 10, 10));
searchBox.setSpacing(10);
Button createItem = new Button("Create");
createItem.setOnAction(e -> MainFunctions.createItem());
Button deleteItem = new Button("Delete");
Button editItem = new Button("Edit");
editItem.setOnAction(e -> MainFunctions.editItem());
HBox itemManipulationBox = new HBox();
itemManipulationBox.getChildren().addAll(createItem, deleteItem, editItem);
itemManipulationBox.setPadding(new Insets(10, 10, 10, 10));
itemManipulationBox.setSpacing(10);
VBox layout = new VBox();
layout.getChildren().addAll(table, searchBox, itemManipulationBox);
Scene scene = new Scene(layout);
primaryStage.setScene(scene);
primaryStage.show();
}
}
<小时/>
这是搜索按钮调用的搜索函数:
public static ObservableList<TableViewData> search(String column, String query){
String name=null;
String brand = null;
String type=null;
int quantity=0;
double price =0.00;
String newQuery = query.replace(" ","_");
String s = "SELECT * FROM ITEM " +
"WHERE "+column+" LIKE '%"+newQuery+"%';";
Connection con =db_connectionHandler.connect();
ObservableList<TableViewData> items = FXCollections.observableArrayList();
items.clear();
try{
Statement st=con.createStatement();
st.executeUpdate(s);
ResultSet rs=st.executeQuery(s);
while(rs.next()){
items.add(new TableViewData(rs.getString("NAME"),rs.getInt("QUANTITY"),rs.getDouble("PRICE"),rs.getString("TYPE"),rs.getString("BRAND")));
}
for(TableViewData i: items) {
System.out.println();
}
db_connectionHandler.endConnect(con,st,rs);
return items;
}
catch(SQLException e){
System.out.print("error: "+e.getMessage());
}
db_connectionHandler.endConnect(con,null,null);
return items;
}
<小时/>
TableViewData
的类对象:
public class TableViewData {
private static SimpleStringProperty name;
private static SimpleStringProperty brand;
private static int quantity;
private static double price;
private static SimpleStringProperty type;
//constructor for item object
public TableViewData(String Fname, int Fquantity, double Fprice, String Ftype, String Fbrand ){
TableViewData.name=new SimpleStringProperty(Fname);
TableViewData.quantity= new Integer(Fquantity);
TableViewData.price= new Double(Fprice);
TableViewData.type=new SimpleStringProperty(Ftype);
TableViewData.brand=new SimpleStringProperty(Fbrand);
}
public static String getName() {
return name.get();
}
public static void setName(String name) {
TableViewData.name.set(name.replace(" ","_"));
}
public static String getBrand() {
return brand.get();
}
public static void setBrand(String brand) {
TableViewData.brand.set(brand.replace(" ","_"));
}
public static int getQuantity() {
return quantity;
}
public static void setQuantity(int quantity) {
TableViewData.quantity = quantity;
}
public static double getPrice() {
return price;
}
public static void setPrice(double price) {
TableViewData.price = price;
}
public static String getType() {
return type.get();
}
public static void setType(String type) {
TableViewData.type.set(type.replace(" ","_"));
}
}
最佳答案
这里有两个关键问题(正如其他人已经在评论中指出的那样):
<小时/> 表格未显示完整的项目信息:仔细查看您的代码:
TableColumn<TableViewData, String> nameColumn = new TableColumn<>("Name");
nameColumn.setMinWidth(200);
nameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
TableColumn<TableViewData, String> brandColumn = new TableColumn<>("Brand");
nameColumn.setMinWidth(200);
nameColumn.setCellValueFactory(new PropertyValueFactory<>("brand"));
TableColumn<TableViewData, Integer> quantityColumn = new TableColumn<>("Quantity");
nameColumn.setMinWidth(200);
nameColumn.setCellValueFactory(new PropertyValueFactory<>("quantity"));
TableColumn<TableViewData, Double> priceColumn = new TableColumn<>("Price");
nameColumn.setMinWidth(200);
nameColumn.setCellValueFactory(new PropertyValueFactory<>("price"));
TableColumn<TableViewData, String> typeColumn = new TableColumn<>("Type");
nameColumn.setMinWidth(200);
nameColumn.setCellValueFactory(new PropertyValueFactory<>("type"));
您仅修改 nameColumn
。您可以通过更改名称来反射(reflect)您设置的代码分组来解决此问题
例如您设置的位置 typeColumn
,您应该设置 typeColumn
width 和 cellValueFactory,而不是 nameColumn
正如上面所做的那样
通过这些更改,您的表格将如下所示:
i manage to get the array to correctly store the objects however when i display the array it will only show values from the type column, but display them in the first column
这也是由于仅 nameColumn
正在修改,最后一次修改为:
nameColumn.setCellValueFactory(new PropertyValueFactory<>("type"));
覆盖了初始值:
nameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
这意味着它是从 type
开始填充的而不是name
遵循此步骤也应该可以解决该问题
从上一张图像开始,列现在正在填充,但行是相同的。这是由于TableViewData
字段被声明为 static
最好阅读其他答案,以便更清楚地了解此问题,例如:
我尝试描述它(对于这种情况)是:
当每个对象的所有字段都是静态时,它们就不再是唯一的。创建后,它们都将引用相同的值,因此当您创建
new
时实例,您创建的每个实例都将反射(reflect)该实例的值。这在上图中可见,因为这是我添加到列表中的最后一项。 要解决此问题,您可以:
- 删除
static
变量声明中的关键字 - 删除替换
TableViewData.someVariableName
与this.someVariableName
使用this
将在对象的变量中查找匹配项,这将防止方法参数具有相同名称时发生冲突。这篇文章应该提供更多详细信息:Using the this Keyword
经过这些更改,表格现在应如下所示:
关于Javafx TableView 显示问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37636569/