2016-09-29 54 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的核心。 –