JTable повторяющиеся значения в строке
У меня есть JTable
заполненный пользовательским DataModel
(вставленный ниже), и когда я вызываю метод JTable
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> data; public CollectionDataModel() { data = new ArrayList<ArrayList>(); } @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 row = new ArrayList(); for(Property p : i.getProperties().values()) { row.add(p.toString()); } data.add(row); } fireTableDataChanged(); } }
- Показать столбец столбца при перетаскивании столбца
- Java и GUI - Где ActionListeners принадлежат в соответствии с шаблоном MVC?
- Ключевые привязки и ключевые слушатели в Java
- Как создать пользовательский компонент Swing
- Цвет кнопок Java Swing
- SwingWorker, Thread.sleep () или javax.swing.timer? Мне нужно «вставить паузу»,
- Терминал Java Linux в JPanel
- Как сделать перемещение изображения во время прослушивания нажатия клавиши на Java.
- Изменение цвета ячеек Java JTable
- как обращаться с плохим выбором файла для отображения изображения в качелях
- Самый простой способ установить изображение в качестве фона JPanel
- Путаница обнаружения столкновений прямоугольника Java
- Сортировка строк по столбцам в JTable
Вот полный пример, который может оказаться полезным. Поскольку образец Map
не поддаётся модификации, я отсылаю вас к примеру @ mKorbel о том, как переопределить 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 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(); } }); } }
Вы можете попытаться внести изменения в заполнение более атомарным.
public void populate(Collection c) { ArrayList> data2 = new ArrayList>(); for(Item i : c.getItems()) { ArrayList row = new ArrayList (); for(Property p : i.getProperties().values()) { row.add(p.toString()); } data2.add(row); } data = data2; fireTableDataChanged(); }
Я предполагаю, что populate
вызывается снова до завершения предыдущего вызова. И, вероятно, c
изменяется во время его итерации.
1) ваша TableModel
не завершена, я пропустил там много или необходимые методы для JTable's
JTable, начиная с TableHeader
и т. Д.
2), так как есть много AbstactTableModels на основе HashMap, я бы предложил вернуть тип массивов, реализованный в API напрямую
Vector> data; String[][] or Object[][]
вместо
ArrayList> data;
простые объяснения состоят в том, что XxxList возвращает столбец, а Vector или String [] возвращает строку
3) Я бы предложил использовать DefaultTableModel
напрямую, тогда вам не придется решать дубликаты или пропущенные столбцы / строки