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