行中的JTable重复值

时间:2012-02-03 17:40:49

标签: java swing jtable

我有JTable填充了自定义DataModel(粘贴在下方),当我调用populate()方法时,出现以填充表格重复数据 - 每一行都反复填充相同的值。然而,仔细检查(通过简单地println()'数据'字段),数据模型没有错 - 它以我期望的格式保存正确的数据。是什么给了什么?

import java.util.ArrayList;    
import javax.swing.table.AbstractTableModel;

@SuppressWarnings("serial") // we don't expect this app to ever use serialized classes.  EVER.
public class CollectionDataModel extends AbstractTableModel {
    private ArrayList<ArrayList<String>> data;

    public CollectionDataModel() {
        data = new ArrayList<ArrayList<String>>();
    }

    @Override
    public int getColumnCount() {
        if(data.isEmpty()) return 0;
        return data.get(0).size();
    }

    @Override
    public int getRowCount() {
        return data.size();
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        if(rowIndex > getRowCount()) return null;
        if(columnIndex > getColumnCount()) return null;
        return data.get(rowIndex).get(columnIndex);
    }

    public void populate(Collection c) {
        data.clear();
        for(Item i : c.getItems()) {
            ArrayList<String> row = new ArrayList<String>();
            for(Property p : i.getProperties().values()) {
                row.add(p.toString());
            }
            data.add(row);
        }
        fireTableDataChanged();
    }

}

3 个答案:

答案 0 :(得分:10)

这是一个可能有用的完整示例。由于示例Map是不可修改的,因此我会向您推荐@ mKorbel的example,了解如何覆盖isCellEditable()setValueAt()

import java.awt.EventQueue;
import java.awt.GridLayout;
import java.util.Map;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;

/** @see https://stackoverflow.com/questions/9132987 */
public class EnvTableTest extends JPanel {

    public EnvTableTest() {
        this.setLayout(new GridLayout());
        this.add(new JScrollPane(new JTable(new EnvDataModel())));
    }

    private static class EnvDataModel extends AbstractTableModel {

        private Map<String, String> data = System.getenv();
        private String[] keys;

        public EnvDataModel() {
            keys = data.keySet().toArray(new String[data.size()]);
        }

        @Override
        public String getColumnName(int col) {
            if (col == 0) {
                return "Key";
            } else {
                return "Value";
            }
        }

        @Override
        public int getColumnCount() {
            return 2;
        }

        @Override
        public int getRowCount() {
            return data.size();
        }

        @Override
        public Object getValueAt(int row, int col) {
            if (col == 0) {
                return keys[row];
            } else {
                return data.get(keys[row]);
            }
        }
    }

    private void display() {
        JFrame f = new JFrame("EnvTableTest");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(this);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new EnvTableTest().display();
            }
        });
    }
}

答案 1 :(得分:3)

您可以尝试更改填充更多原子。

public void populate(Collection c) {
    ArrayList<ArrayList<String>> data2 = new  ArrayList<ArrayList<String>>();
    for(Item i : c.getItems()) {
        ArrayList<String> row = new ArrayList<String>();
        for(Property p : i.getProperties().values()) {
            row.add(p.toString());
        }
        data2.add(row);
    }
    data = data2;
    fireTableDataChanged();
}

我猜测在populate之前的呼叫结束之前再次调用populate。可能c在迭代期间发生了变化。

答案 2 :(得分:2)

1)您的TableModel未完成,我错过了JTable's生命周期的许多或必需的方法,从TableHeader等开始。

2)因为有很多基于HashMap的AbstactTableModel,我建议直接返回在API中实现的数组类型

Vector<Vector<Object or String>> data; 

String[][] or Object[][] 

而不是

ArrayList<ArrayList<String>> data;

简单的解释是XxxList returs列和Vector或String []返回Row

3)我建议直接使用DefaultTableModel然后你永远不需要解决重复或错过列/行