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.spi.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}