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.Dimension; 007import java.awt.GridBagLayout; 008import java.util.ArrayList; 009import java.util.List; 010 011import javax.swing.DefaultCellEditor; 012import javax.swing.JComponent; 013import javax.swing.JLabel; 014import javax.swing.JPanel; 015import javax.swing.JScrollPane; 016import javax.swing.JTable; 017import javax.swing.table.AbstractTableModel; 018 019import org.openstreetmap.josm.data.Preferences.ListSetting; 020import org.openstreetmap.josm.gui.ExtendedDialog; 021import org.openstreetmap.josm.gui.widgets.JosmTextField; 022import org.openstreetmap.josm.tools.GBC; 023import org.openstreetmap.josm.tools.Predicate; 024import org.openstreetmap.josm.tools.Utils; 025import org.openstreetmap.josm.tools.WindowGeometry; 026 027/** 028 * Editor for List preference entries. 029 */ 030public class ListEditor extends ExtendedDialog { 031 032 private List<String> data; 033 private transient PrefEntry entry; 034 035 /** 036 * Constructs a new {@code ListEditor}. 037 * @param gui The parent component 038 */ 039 public ListEditor(final JComponent gui, PrefEntry entry, ListSetting setting) { 040 super(gui, tr("Change list setting"), new String[] {tr("OK"), tr("Cancel")}); 041 this.entry = entry; 042 List<String> orig = setting.getValue(); 043 if (orig != null) { 044 data = new ArrayList<>(orig); 045 } else { 046 data = new ArrayList<>(); 047 } 048 setButtonIcons(new String[] {"ok.png", "cancel.png"}); 049 setRememberWindowGeometry(getClass().getName() + ".geometry", WindowGeometry.centerInWindow(gui, new Dimension(300, 350))); 050 setContent(build(), false); 051 } 052 053 /** 054 * Returns the list of values. 055 * @return The list of values. 056 */ 057 public List<String> getData() { 058 return new ArrayList<>(Utils.filter(data, new Predicate<String>() { 059 @Override 060 public boolean evaluate(String object) { 061 return object != null && !object.isEmpty(); 062 } 063 })); 064 } 065 066 protected final JPanel build() { 067 JPanel p = new JPanel(new GridBagLayout()); 068 p.add(new JLabel(tr("Key: {0}", entry.getKey())), GBC.eol().insets(0, 0, 5, 0)); 069 ListSettingTableModel listModel = new ListSettingTableModel(); 070 JTable table = new JTable(listModel); 071 table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE); 072 table.setTableHeader(null); 073 074 DefaultCellEditor editor = new DefaultCellEditor(new JosmTextField()); 075 editor.setClickCountToStart(1); 076 table.setDefaultEditor(table.getColumnClass(0), editor); 077 078 JScrollPane pane = new JScrollPane(table); 079 p.add(pane, GBC.eol().insets(5, 10, 0, 0).fill()); 080 return p; 081 } 082 083 class ListSettingTableModel extends AbstractTableModel { 084 085 public List<String> getData() { 086 return data; 087 } 088 089 @Override 090 public int getRowCount() { 091 return data.size() + 1; 092 } 093 094 @Override 095 public int getColumnCount() { 096 return 1; 097 } 098 099 @Override 100 public Object getValueAt(int row, int column) { 101 return data.size() == row ? "" : data.get(row); 102 } 103 104 @Override 105 public void setValueAt(Object o, int row, int column) { 106 String s = (String) o; 107 if (row == data.size()) { 108 data.add(s); 109 fireTableRowsInserted(row+1, row+1); 110 } else { 111 data.set(row, s); 112 } 113 fireTableCellUpdated(row, column); 114 } 115 116 @Override 117 public boolean isCellEditable(int row, int column) { 118 return true; 119 } 120 } 121}