JScrollPane没有正确更新

时间:2015-04-20 19:56:33

标签: java swing user-interface tree jtable

我必须在JTable中插入新产品,以便在按下“添加产品”按钮后,表格应自动更新所提供的新数据。所有产品都写入文件,并在打印出表格时从中读取。问题是我的表只保持不变,只有在我退出GUI应用程序并再次输入后,我才能看到新更新的JTable。

以下是GUI类的相关代码:

private class ManageProductsListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            ...
            addProductBtn.addActionListener(new AddProductListener());
            removeProductBtn.addActionListener(new RemoveProductListener());
            manageProductsPanel.add(warehouse);
            manageProductsPanel.setVisible(true);
            finalPanel.add(manageProductsPanel, BorderLayout.CENTER);
        }
    }

    private class AddProductListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
                ...
                manageProductsPanel.remove(warehouse);
                Product product = new Product(insertProductName.getText(), Integer.parseInt(insertPrice.getText()), Integer.parseInt(insertStock.getText()));
                warehouse.addProduct(product);
                warehouse.writeFile();
                warehouse.printProducts();
                manageProductsPanel.add(warehouse);
                ... 
        }
    }

这是Warehouse类的一部分:

public class Warehouse extends JPanel {
    ...        
    private TreeSet<Product> products = new TreeSet<Product>();
    private JTable productsTable;
    private Object[][] data;
    private String[] columns = {"Product name", "Price", "In stock", "Understock", "Overstock"};

    public Warehouse() {
    }

    public void addProduct(Product newProduct) {
        products.add(newProduct);
    }

    public void writeFile() {
        try {
            FileOutputStream fos = new FileOutputStream("products.txt");
            ObjectOutputStream oos = new ObjectOutputStream(fos);


            Iterator<Product> i = products.iterator();
            while (i.hasNext()) {
                oos.writeObject(i.next());
            }
            oos.close();
        } catch (IOException i) {
            i.printStackTrace();
        }
    }

    public void readFile() {
        ...
    }

    public void printProducts() {
        data = new Object[products.size()][5];
        Iterator<Product> iterator = products.iterator();
        int i = 0;
        while (iterator.hasNext()) {
            Product p = iterator.next();
            data[i][0] = p.getProductName();
            data[i][1] = p.getPrice();
            data[i][2] = p.getStock();
            data[i][3] = p.checkUnderstock();
            data[i][4] = p.checkOverstock();
            i++;
        }
        createTable();
    }

    public void createTable() {
        productsTable = new JTable(data, columns);
        productsTable.setPreferredScrollableViewportSize(new Dimension(600, 200));
        productsTable.setFillsViewportHeight(true);
        JScrollPane scroll = new JScrollPane(productsTable);
        add(scroll);
    }

任何帮助将不胜感激。提前谢谢!

3 个答案:

答案 0 :(得分:0)

无法添加评论,因此我必须将其作为答案发布。您是否尝试在添加表格后重新验证面板?

manageProductsPanel.revalidate()

答案 1 :(得分:0)

    products.add(newProduct);

您不应该更新产品TreeSet。这不会更新TableModel中的数据,因此当然不会更新表。数据应仅包含在TableModel中,对数据的所有更新都应直接对TableModel进行。

因此,您需要一个可以容纳Product对象的自定义TableModel。

查看Row Table Model以获取允许您存储自定义对象的通用TableModel。然后,JButtonTableModel.java代码展示了如何扩展RowTableModel以支持您的自定义对象。

然后,当您创建新产品时,只需使用新创建的ProductTableModel的addRow(...)方法。

编辑:

上面的答案是正确的解决方案。您永远不应该保留两份数据。

  

我添加了另一个新产品,另一个新表出现等等

这是因为您的Warehouse类是使用FlowLayout的JPanel,所以当您不断向其添加组件时,面板会不断增长。

解决方案是不要继续创建新组件。然后,当您添加新产品时,无需继续创建新的JTable和JScrollPanse。

相反,当您创建Warehouse类时,您将创建表和ScrollPane。该表将是空的。

然后,当您将产品添加到产品列表时,您可以创建一个新的DefaultTablModel。然后,您只需使用table.setModel(...)方法更新表。现在,该表将重新显示新数据。

答案 2 :(得分:0)

另一个解决方案可能是无痛的是在更新后重置表的模型:

productsTable.setModel(new DefaultTableModel(data, columns));