2015-04-20 4 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.

Для этого вам понадобится пользовательская TableModel, которая может содержать объекты Product.

Отметьте Row Table Model для общей TableModel, которая позволяет хранить пользовательские объекты. Затем код JButtonTableModel.java показывает, как вы можете расширить RowTableModel для поддержки своего настраиваемого объекта.

Затем, когда вы создаете новый продукт, вы просто используете метод addRow (...) только что созданного ProductTableModel.

Edit:

Ответ выше, является правильным решением. Вы не должны хранить две копии данных.

добавить еще один новый продукт появится еще один новый стол и так далее

Это потому, что ваш класс Склад является JPanel, который использует FlowLayout, поэтому, когда вы держите добавления компонентов к ней панель просто держать растет.

Решение не должно создавать новые компоненты. Тогда вам не нужно создавать новые JTable и JScrollPanse при добавлении новых продуктов.

Вместо этого, когда вы создаете класс Warehouse, вы создаете таблицу и ScrollPane. Таблица будет пустой.

Затем, когда вы добавляете продукт в список продуктов, вы можете создать новый DefaultTablModel. Затем вы просто используете метод table.setModel(...) для обновления таблицы. Теперь таблица перекрасит себя новыми данными.

+0

Он строит таблицу позже, с конструктором JTable, где вы передаете данные Таблица таблицы и столбца, ее законная ... – Kuba

+0

Данные в таблице фактически обновляются, потому что я сохраняю ее в файл сразу после того, как я добавлю его в продукты TreeSet , Основная идея этого приложения - использовать TreeSet, поэтому я не должен использовать что-то еще. – Dave

0

Другим решением может быть безболезненным бы сбросить модель таблицы после обновления:

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

Это единственная строка, которую я должен добавить? Потому что я пытался, и никаких изменений ... – Dave

Смежные вопросы