【问题标题】:Javafx TableView display issuesJavafx TableView 显示问题
【发布时间】:2016-06-05 01:23:31
【问题描述】:

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

【问题讨论】:

  • 你使用的是静态字段,显然数据都是一样的。这就是静态的意思。摆脱 TableViewData 中的所有静态。
  • 将表格更改为非静态并没有改变任何东西,还有其他想法吗?
  • 我设法让数组正确存储对象,但是当我显示数组时,它只会显示类型列中的值,但会在第一列中显示它们
  • 您拥有使用变量 nameColumn 的所有列。使用正确的变量名。

标签: java javafx tableview


【解决方案1】:

这里有 2 个关键问题(正如其他人已经在 cmets 中确定的那样):


表格未显示完整的项目信息:

在此处仔细查看您的代码:

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

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

我设法让数组正确存储对象但是当 我显示数组它只会显示类型列中的值,但是 将它们显示在第一列

这也是因为只修改了nameColumn,最后修改的是:

nameColumn.setCellValueFactory(new PropertyValueFactory&lt;&gt;("type"));

覆盖了以下的初始值:

nameColumn.setCellValueFactory(new PropertyValueFactory&lt;&gt;("name"));

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


重复行:

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

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

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


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

要解决此问题,您可以:

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

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

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

【讨论】:

    【解决方案2】:

    你好,下面的代码需要更正

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

    。 . .

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

    。 . .

    请相应地更改所有列

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-23
      • 1970-01-01
      • 2014-10-21
      • 2021-09-07
      • 2018-11-13
      • 2016-09-02
      • 2014-07-28
      • 2015-12-15
      相关资源
      最近更新 更多