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 ListSettingTableModel model;
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        model = new ListSettingTableModel(setting.getValue());
041        setContent(build(), false);
042    }
043
044    @Override
045    public List<String> getData() {
046        return new ArrayList<>(Utils.filter(model.getData(), new Predicate<String>() {
047            @Override
048            public boolean evaluate(String object) {
049                return object != null && !object.isEmpty();
050            }
051        }));
052    }
053
054    @Override
055    protected final JPanel build() {
056        JPanel p = new JPanel(new GridBagLayout());
057        p.add(new JLabel(tr("Key: {0}", entry.getKey())), GBC.eol().insets(0, 0, 5, 0));
058        JTable table = new JTable(model);
059        table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
060        table.setTableHeader(null);
061
062        DefaultCellEditor editor = new DefaultCellEditor(new JosmTextField());
063        editor.setClickCountToStart(1);
064        table.setDefaultEditor(table.getColumnClass(0), editor);
065
066        JScrollPane pane = new JScrollPane(table);
067        p.add(pane, GBC.eol().insets(5, 10, 0, 0).fill());
068        return p;
069    }
070
071    static class ListSettingTableModel extends AbstractTableModel {
072
073        private final List<String> data;
074
075        ListSettingTableModel(List<String> orig) {
076            if (orig != null) {
077                data = new ArrayList<>(orig);
078            } else {
079                data = new ArrayList<>();
080            }
081        }
082
083        public List<String> getData() {
084            return data;
085        }
086
087        @Override
088        public int getRowCount() {
089            return data.size() + 1;
090        }
091
092        @Override
093        public int getColumnCount() {
094            return 1;
095        }
096
097        @Override
098        public Object getValueAt(int row, int column) {
099            return data.size() == row ? "" : data.get(row);
100        }
101
102        @Override
103        public void setValueAt(Object o, int row, int column) {
104            String s = (String) o;
105            if (row == data.size()) {
106                data.add(s);
107                fireTableRowsInserted(row+1, row+1);
108            } else {
109                data.set(row, s);
110            }
111            fireTableCellUpdated(row, column);
112        }
113
114        @Override
115        public boolean isCellEditable(int row, int column) {
116            return true;
117        }
118    }
119}