001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.preferences.advanced; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005 006import java.awt.GridBagLayout; 007import java.util.ArrayList; 008import java.util.List; 009 010import javax.swing.DefaultCellEditor; 011import javax.swing.JComponent; 012import javax.swing.JLabel; 013import javax.swing.JPanel; 014import javax.swing.JScrollPane; 015import javax.swing.JTable; 016import javax.swing.table.AbstractTableModel; 017 018import org.openstreetmap.josm.data.preferences.ListSetting; 019import org.openstreetmap.josm.gui.widgets.JosmTextField; 020import org.openstreetmap.josm.tools.GBC; 021import org.openstreetmap.josm.tools.SubclassFilteredCollection; 022 023/** 024 * Editor for List preference entries. 025 * @since 4634 026 */ 027public class ListEditor extends AbstractListEditor<String> { 028 029 private final ListSettingTableModel model; 030 031 /** 032 * Constructs a new {@code ListEditor}. 033 * @param gui The parent component 034 * @param entry preference entry 035 * @param setting list setting 036 */ 037 public ListEditor(final JComponent gui, PrefEntry entry, ListSetting setting) { 038 super(gui, tr("Change list setting"), entry); 039 model = new ListSettingTableModel(setting.getValue()); 040 setContent(build(), false); 041 } 042 043 @Override 044 public List<String> getData() { 045 return new ArrayList<>(SubclassFilteredCollection.filter(model.getData(), object -> object != null && !object.isEmpty())); 046 } 047 048 @Override 049 protected final JPanel build() { 050 JPanel p = new JPanel(new GridBagLayout()); 051 p.add(new JLabel(tr("Key: {0}", entry.getKey())), GBC.eol().insets(0, 0, 5, 0)); 052 JTable table = new JTable(model); 053 table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE); 054 table.setTableHeader(null); 055 056 DefaultCellEditor editor = new DefaultCellEditor(new JosmTextField()); 057 editor.setClickCountToStart(1); 058 table.setDefaultEditor(table.getColumnClass(0), editor); 059 060 JScrollPane pane = new JScrollPane(table); 061 p.add(pane, GBC.eol().insets(5, 10, 0, 0).fill()); 062 return p; 063 } 064 065 static class ListSettingTableModel extends AbstractTableModel { 066 067 private final List<String> data; 068 069 ListSettingTableModel(List<String> orig) { 070 if (orig != null) { 071 data = new ArrayList<>(orig); 072 } else { 073 data = new ArrayList<>(); 074 } 075 } 076 077 public List<String> getData() { 078 return data; 079 } 080 081 @Override 082 public int getRowCount() { 083 return data.size() + 1; 084 } 085 086 @Override 087 public int getColumnCount() { 088 return 1; 089 } 090 091 @Override 092 public Object getValueAt(int row, int column) { 093 return data.size() == row ? "" : data.get(row); 094 } 095 096 @Override 097 public void setValueAt(Object o, int row, int column) { 098 String s = (String) o; 099 if (row == data.size()) { 100 data.add(s); 101 fireTableRowsInserted(row+1, row+1); 102 } else { 103 data.set(row, s); 104 } 105 fireTableCellUpdated(row, column); 106 } 107 108 @Override 109 public boolean isCellEditable(int row, int column) { 110 return true; 111 } 112 } 113}