Javafx TableView 显示问题

标签 java javafx tableview

我使用 fx 创建了一个 TableView ,它显示来自数据库的信息,每当我搜索数据库并显示结果时,由于某种原因,它会显示检索到的最后一个值乘以找到的结果量,但它应该做的是显示 observableList 中的每一项。我做错了什么?

enter image description here

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正如上面所做的那样

通过这些更改,您的表格将如下所示:

enter image description here

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)该实例的值。这在上图中可见,因为这是我添加到列表中的最后一项。

要解决此问题,您可以:

  1. 删除 static变量声明中的关键字
  2. 删除替换TableViewData.someVariableNamethis.someVariableName

使用this将在对象的变量中查找匹配项,这将防止方法参数具有相同名称时发生冲突。这篇文章应该提供更多详细信息:Using the this Keyword

经过这些更改,表格现在应如下所示:

enter image description here

关于Javafx TableView 显示问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37636569/

相关文章:

java - break命令不会停止循环

java - 使用 servlet 和 jsp 截取屏幕截图并将其保存在服务器上

java - 从基于 Java 的对象更新 JavaFX 窗口

java - JavaFX 中的 registerChangeListener 方法有什么作用?

swift - 如何根据标签内容调整表格 View 单元格的大小

ios - 展开可选值时为零,但在打印期间该值存在

java - crawler4j 重新抓取不工作的网站

java - HashMap 包含某个键,但告诉我它没有

Java 以一种干净的方式动态地在多个按钮上使用事件处理程序

menu - 适配 TableView 菜单按钮