Javafx TableView显示问题

时间:2016-06-05 01:23:32

标签: java javafx tableview

我使用fx创建了一个表格视图,它显示了数据库中的信息,每当我搜索数据库并显示结果时,由于某种原因,它会显示检索到的最后一个值乘以找到的结果数量但它应该做的是显示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(" ","_"));
    }
}

2 个答案:

答案 0 :(得分:1)

这里有两个关键问题(正如其他人已在评论中指出的那样):

<小时/> 表格未显示完整的商品信息:

仔细查看您的代码:

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。您可以通过更改名称来修复此问题,以反映您已设置的代码分组 例如,在您设置typeColumn的地方,您应该设置typeColumn宽度和cellValueFactory,而不是nameColumn,因为这是在上面完成的

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

enter image description here

  

我设法让数组正确存储对象但是什么时候   我显示数组,它只显示类型列中的值,但是   在第一栏中显示它们

这也是由于只修改了nameColumn,最后修改是:

nameColumn.setCellValueFactory(new PropertyValueFactory<>("type"));

覆盖了初始值:

nameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));

意味着它是从type而不是name填充的 遵循此步骤也应该纠正该问题

<小时/> 重复行

从最后一张图片中,列现在正在填充,但行是相同的。这是因为TableViewData字段被声明为static

最好还是阅读其他答案,以便更清楚地了解这一点,例如:

我尝试描述它(对于这种情况)将是:


当所有字段都是静态时,每个对象都不再是唯一的。创建后,它们都将引用相同的值,因此当您创建new实例时,您创建的每个实例都将反映该实例的值。这在上图中可见,因为这是我添加到列表中的最后一项。

要解决此问题,您可以:

  1. 从变量声明中删除static关键字
  2. 使用TableViewData.someVariableName
  3. 删除替换this.someVariableName

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

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

    enter image description here

答案 1 :(得分:0)

嗨,您需要更正以下代码

nameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));

。 。

nameColumn.setCellValueFactory(new PropertyValueFactory<TableViewData,SimpleStringProperty>("name"));

。 。

请相应地更改所有列