【问题标题】:Can't update JTable's info无法更新 JTable 的信息
【发布时间】:2017-02-08 02:43:14
【问题描述】:

我使用 ArrayList 中包含的数据创建 JTable,然后将 JTable 添加到 JScrollPane

    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 已经进行了更改,然后 revalidate() 和 repaint() 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 中的信息确实发生了变化

【问题讨论】:

    标签: java swing arraylist jtable


    【解决方案1】:

    JTable 的数据不保存在 ArrayList 中,而是驻留在表模型本身中。底线:不要更新 ArrayList 而是更新表模型本身,这里是 DefaultTableModel,然后您的 JTable 应该显示新数据。幸运的是,这应该很容易做到,因为表格模型的方法允许您使用 getValueAt(...) 提取数据,并在需要添加新行时使用 setValueAt(...)addRow(...) 更新其单元格中的值。

    请注意,如果您通过 DefaultTableModel 进行更改,则无需直接调用fireTableDataChanged(),实际上您不应该调用此方法——这是模型的责任。同样,您的 JTable 也无需 revalidate()repaint()

    请查看DefaultTableModel API 了解详细信息。

    另一方面,如果您绝对需要使用 ArrayList 作为 JTable 的数据核心,那么您不应该使用 DefaultTableModel 而是通过扩展 AbstractTableModel 并使用您的 ArrayList 作为其数据核心来创建自己的 TableModel。如果您这样做,那么您的模型代码应该注意在更改模型状态后调用适当的fire...(...) 方法。

    【讨论】:

    • 谢谢,我必须更改 ArrayList 中的值,因为其中的对象是序列化和反序列化的,但是使用 setValueAt() 从表中更改值是有效的。
    • @ErickQ:不客气,但如果您正在创建和使用并行数据集合(ArrayList 和 TableModel),您将面临危险。如果这是我的问题,我会创建方法来序列化和反序列化模型的数据核,可以通过getDataVector() 获得,或者使用 ArrayList 作为 AbstractTableModel 的核。
    猜你喜欢
    • 2012-07-02
    • 1970-01-01
    • 2021-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多