001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.widgets;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.awt.BorderLayout;
007import java.awt.Dimension;
008import java.awt.GridBagLayout;
009import java.awt.event.ActionEvent;
010import java.awt.event.ActionListener;
011import java.util.ArrayList;
012import java.util.List;
013
014import javax.swing.DefaultListModel;
015import javax.swing.JButton;
016import javax.swing.JList;
017import javax.swing.JOptionPane;
018import javax.swing.JPanel;
019import javax.swing.JScrollPane;
020
021import org.openstreetmap.josm.Main;
022import org.openstreetmap.josm.tools.GBC;
023
024/**
025 * A {@link JList} containing items, and {@link JButton}s to add/edit/delete items.
026 */
027public class EditableList extends JPanel {
028
029    public final String title;
030    public final JList<String> sourcesList = new JList<>(new DefaultListModel<String>());
031    public final JButton addSrcButton = new JButton(tr("Add"));
032    public final JButton editSrcButton = new JButton(tr("Edit"));
033    public final JButton deleteSrcButton = new JButton(tr("Delete"));
034
035    /**
036     * Constructs a new {@code EditableList}.
037     * @param title The title displayed in input dialog
038     */
039    public EditableList(String title) {
040        this.title = title;
041        build();
042    }
043
044    protected final void build() {
045
046        setLayout(new BorderLayout());
047
048        addSrcButton.addActionListener(new ActionListener() {
049            @Override
050            public void actionPerformed(ActionEvent e) {
051                String source = JOptionPane.showInputDialog(
052                        Main.parent,
053                        title,
054                        title,
055                        JOptionPane.QUESTION_MESSAGE);
056                if (source != null) {
057                    ((DefaultListModel<String>) sourcesList.getModel()).addElement(source);
058                }
059                sourcesList.clearSelection();
060            }
061        });
062
063        editSrcButton.addActionListener(new ActionListener() {
064            @Override
065            public void actionPerformed(ActionEvent e) {
066                int row = sourcesList.getSelectedIndex();
067                if (row == -1 && sourcesList.getModel().getSize() == 1) {
068                    sourcesList.setSelectedIndex(0);
069                    row = 0;
070                }
071                if (row == -1) {
072                    if (sourcesList.getModel().getSize() == 0) {
073                        String source = JOptionPane.showInputDialog(Main.parent, title, title, JOptionPane.QUESTION_MESSAGE);
074                        if (source != null) {
075                            ((DefaultListModel<String>) sourcesList.getModel()).addElement(source);
076                        }
077                    } else {
078                        JOptionPane.showMessageDialog(
079                                Main.parent,
080                                tr("Please select the row to edit."),
081                                tr("Information"),
082                                JOptionPane.INFORMATION_MESSAGE
083                        );
084                    }
085                } else {
086                    String source = (String) JOptionPane.showInputDialog(Main.parent,
087                            title,
088                            title,
089                            JOptionPane.QUESTION_MESSAGE, null, null,
090                            sourcesList.getSelectedValue());
091                    if (source != null) {
092                        ((DefaultListModel<String>) sourcesList.getModel()).setElementAt(source, row);
093                    }
094                }
095                sourcesList.clearSelection();
096            }
097        });
098
099        deleteSrcButton.addActionListener(new ActionListener() {
100            @Override
101            public void actionPerformed(ActionEvent e) {
102                if (sourcesList.getSelectedIndex() == -1) {
103                    JOptionPane.showMessageDialog(Main.parent, tr("Please select the row to delete."), tr("Information"),
104                            JOptionPane.QUESTION_MESSAGE);
105                } else {
106                    ((DefaultListModel<String>) sourcesList.getModel()).remove(sourcesList.getSelectedIndex());
107                }
108            }
109        });
110        sourcesList.setMinimumSize(new Dimension(300, 50));
111        sourcesList.setVisibleRowCount(3);
112
113        addSrcButton.setToolTipText(tr("Add a new source to the list."));
114        editSrcButton.setToolTipText(tr("Edit the selected source."));
115        deleteSrcButton.setToolTipText(tr("Delete the selected source from the list."));
116
117        final JPanel buttonPanel = new JPanel(new GridBagLayout());
118        buttonPanel.add(addSrcButton, GBC.std().insets(0, 5, 0, 0));
119        buttonPanel.add(editSrcButton, GBC.std().insets(5, 5, 5, 0));
120        buttonPanel.add(deleteSrcButton, GBC.std().insets(0, 5, 0, 0));
121
122        add(new JScrollPane(sourcesList), BorderLayout.CENTER);
123        add(buttonPanel, BorderLayout.SOUTH);
124        setPreferredSize(new Dimension(300, 50 + (int) buttonPanel.getPreferredSize().getHeight()));
125
126    }
127
128    public void setItems(final Iterable<String> items) {
129        for (String source : items) {
130            ((DefaultListModel<String>) sourcesList.getModel()).addElement(source);
131        }
132    }
133
134    public List<String> getItems() {
135        final List<String> items = new ArrayList<>(sourcesList.getModel().getSize());
136        for (int i = 0; i < sourcesList.getModel().getSize(); ++i) {
137            items.add(sourcesList.getModel().getElementAt(i));
138        }
139        return items;
140    }
141
142    @Override
143    public void setEnabled(boolean enabled) {
144        sourcesList.setEnabled(enabled);
145        addSrcButton.setEnabled(enabled);
146        editSrcButton.setEnabled(enabled);
147        deleteSrcButton.setEnabled(enabled);
148    }
149}