2015-04-20 101 views
0

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

下面是从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); 
       ... 
     } 
    } 

下面是从仓库类的一部分:

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); 
    } 

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

回答

0

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

manageProductsPanel.revalidate() 
+0

是的,我已经尝试过了,但是当我把这个方法我不断收到新表。例如,如果我添加一个新产品,会出现一个新表;如果我添加另一个新产品,则会出现另一个新表格等等。新表格甚至不适合面板 – Dave

+0

这似乎发生了,因为在createTable方法中添加了新表格,但不删除旧表格。 – Renatols

+0

如何删除旧的? – Dave

0
products.add(newProduct); 

你不应该更新产品TreeSet中。这不会更新TableModel中的数据,所以当然表格不会更新。数据只应包含在TableModel中,并且数据的所有更新都应该直接对TableModel进行。

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

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

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

编辑:

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

我再添新产品出现的另一个新表等

那是因为你的仓库类是使用的FlowLayout一个JPanel,所以当你不断将组件添加到它的面板只是不停生长。

解决方法是不要继续创建新组件。然后在添加新产品时不需要继续创建新的JTable和JScrollPanse。

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

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

+0

他正在建立表格,使用JTable构造函数在其中传递数据表和列表,其合法... – Kuba

+0

表中的数据实际上已更新,因为在将其添加到产品后,我将其保存到文件中TreeSet 。这个应用程序的主要思想是使用TreeSet,所以我不应该使用别的东西 – Dave

0

另一种解决方案也许无痛将是更新后的表的模式复位:

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

这是我应该添加的唯一行吗?因为我试过了,没有改变...... – Dave