2016-09-29 57 views
0

我創建的JTable與包含在一個ArrayList的數據,然後添加JTable中JScrollPane中無法更新JTable中的信息

ArrayList<Product> stock = new ArrayList<Product>(s); 

    String[] col = {"Nombre", "Cantidad", "Descripci\u00F3n", "Contenido"}; 
    DefaultTableModel tableModel = new DefaultTableModel(col,0); 
    JTable table = new JTable(tableModel); 

    Collections.sort(stock, new Comparator<Product>() { 
     public int compare(Product p1, Product p2) { 
      return p1.getNombre().compareTo(p2.getNombre()); 
     } 
    }); 

    for (int i = 0; i < stock.size(); i++){ 
     String nombre = stock.get(i).getNombre(); 
     String cantidad = stock.get(i).getCantidad(); 
     String descripcion = stock.get(i).getDescripcion(); 
     String contenido = stock.get(i).getContenido(); 
     Object[] data = {nombre, cantidad, descripcion, contenido}; 
     tableModel.addRow(data); 
    } 

    table.getColumnModel().getColumn(0).setPreferredWidth(width*3/18); 
    table.getColumnModel().getColumn(1).setPreferredWidth(width/9); 
    table.getColumnModel().getColumn(2).setPreferredWidth(width*8/18); 
    table.getColumnModel().getColumn(3).setPreferredWidth(width/9); 
    frame.getContentPane().setLayout(new BorderLayout(0, 0)); 
    table.getTableHeader().setFont(new Font("Arial", Font.BOLD, f)); 
    table.setFont(new Font("Arial", Font.PLAIN, f)); 
    table.setBounds(1, 1, width*8/9, height); 
    table.setRowHeight(height/30); 
    table.setEnabled(false); 

    DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer(); 
    centerRenderer.setHorizontalAlignment(JLabel.CENTER); 
    for(int i = 0; i<4; i++){ 
     table.getColumnModel().getColumn(i).setCellRenderer(centerRenderer); 
    } 

    JScrollPane sp = new JScrollPane(table); 
    frame.getContentPane().add(sp, BorderLayout.CENTER); 

然後通過一個JButton我修改的ArrayList內容,然後告訴TableModel的是已經作了修改,然後重新驗證()和重繪()JTable中

JButton btnVender = new JButton("Vender"); 
    btnVender.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      String n = JOptionPane.showInputDialog("Qué producto quieres vender?"); 
      int x=1; 
      for(Product p : stock){ 
       if(p.getNombre().equals(n)){ 
        x=0; 
        String numero = JOptionPane.showInputDialog("Cuántos quieres vender?"); 
        int num = Integer.parseInt(numero); 
        p.decrementar(num); 
        tableModel.fireTableDataChanged(); 
        table.revalidate(); 
        table.repaint(); 
        break;     
       } 
      } 
      if(x==1){ 
       JOptionPane.showMessageDialog(null, "No existe ese producto"); 
      } 
     } 
    }); 

的問題是,JTable中不會更新,但信息的確ArrayList中變化

回答

2

JTable的數據不在ArrayList中,而是駐留在表模型本身中。底線:不要更新ArrayList,而是更新表模型本身,這裏是DefaultTableModel,然後您的JTable應該顯示新數據。幸運的是,這應該很容易做到,因爲表格模型的方法允許您使用getValueAt(...)提取數據,如果需要添加新行,則使用setValueAt(...)以及addRow(...)更新其單元格中的值。

請注意,如果您通過DefaultTableModel進行更改,則不需要直接調用fireTableDataChanged(),事實上,您不應該調用此方法 - 這是模型的責任。同樣,您不需要revalidate()repaint()您的JTable。

請查看DefaultTableModel API瞭解血淋淋的細節。

另一方面,如果您絕對需要使用ArrayList作爲JTable的數據核心,那麼您不應該使用DefaultTableModel,而應該通過擴展AbstractTableModel並使用ArrayList作爲其數據核心來創建自己的TableModel。如果你這樣做,那麼在改變模型的狀態之後,你的模型的代碼應該注意調用適當的fire...(...)方法。

+0

謝謝,我不得不改變ArrayList中的值,因爲它們內部的對象是序列化和反序列化的,但是使用setValueAt()更改表中的值有效。 – ErickQ

+0

@ErickQ:不客氣,但如果您創建並使用並行數據集合(ArrayList和TableModel),則會冒險。如果這是我的問題,我會創建方法來序列化和反序列化我的模型的數據核,這可以通過'getDataVector()'獲得,或者使用ArrayList作爲AbstractTableModel的核心。 –