JTable duplicate values in row

前端 未结 3 1059
春和景丽
春和景丽 2020-11-21 13:43

I have a JTable populated with a custom DataModel (pasted below) and when I call the populate() method, it appears to populat

相关标签:
3条回答
  • 2020-11-21 14:07

    Here's a complete example that may prove helpful. As the sample Map is unmodifiable, I refer you to @mKorbel's example on how to override isCellEditable() and 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();
                }
            });
        }
    }
    
    0 讨论(0)
  • 2020-11-21 14:08

    1) your TableModel is un_completed, I miss there lots or required methods for JTable's life_cycle, starting with TableHeader etc.

    2) since there are lots of AbstactTableModels based on HashMap, I'd suggest to return arrays type implemented in API directly

    Vector<Vector<Object or String>> data; 
    
    String[][] or Object[][] 
    

    instead of

    ArrayList<ArrayList<String>> data;
    

    simple explanations is that XxxList returs column and Vector or String[] returns Row

    3) I'd suggest to use DefaultTableModel directly then you'll never need to solve duplicates or missed column/row

    0 讨论(0)
  • 2020-11-21 14:20

    You could try to make the changes of populate more atomic.

    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();
    }
    

    I am guessing that populate is called again before a prior populate call finished. And probably c is changed during its iteration.

    0 讨论(0)
提交回复
热议问题