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.util.List; 010import java.util.stream.Collectors; 011import java.util.stream.IntStream; 012 013import javax.swing.DefaultListModel; 014import javax.swing.JButton; 015import javax.swing.JList; 016import javax.swing.JOptionPane; 017import javax.swing.JPanel; 018import javax.swing.JScrollPane; 019 020import org.openstreetmap.josm.gui.MainApplication; 021import org.openstreetmap.josm.tools.GBC; 022import org.openstreetmap.josm.tools.Utils; 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 /** 030 * The title displayed in input dialog 031 */ 032 public final String title; 033 /** 034 * The list items 035 */ 036 public final JList<String> sourcesList = new JList<>(new DefaultListModel<String>()); 037 /** 038 * The add button 039 */ 040 public final JButton addSrcButton = new JButton(tr("Add")); 041 /** 042 * The edit button displayed nex to the list 043 */ 044 public final JButton editSrcButton = new JButton(tr("Edit")); 045 /** 046 * The delete button 047 */ 048 public final JButton deleteSrcButton = new JButton(tr("Delete")); 049 050 /** 051 * Constructs a new {@code EditableList}. 052 * @param title The title displayed in input dialog 053 */ 054 public EditableList(String title) { 055 this.title = title; 056 build(); 057 } 058 059 protected final void build() { 060 061 setLayout(new BorderLayout()); 062 063 addSrcButton.addActionListener(e -> { 064 String source = JOptionPane.showInputDialog( 065 MainApplication.getMainFrame(), 066 title, 067 title, 068 JOptionPane.QUESTION_MESSAGE); 069 if (!Utils.isEmpty(source)) { 070 ((DefaultListModel<String>) sourcesList.getModel()).addElement(source); 071 } 072 sourcesList.clearSelection(); 073 }); 074 075 editSrcButton.addActionListener(e -> { 076 int row = sourcesList.getSelectedIndex(); 077 if (row == -1 && sourcesList.getModel().getSize() == 1) { 078 sourcesList.setSelectedIndex(0); 079 row = 0; 080 } 081 if (row == -1) { 082 if (sourcesList.getModel().getSize() == 0) { 083 String source1 = JOptionPane.showInputDialog(MainApplication.getMainFrame(), title, title, JOptionPane.QUESTION_MESSAGE); 084 if (!Utils.isEmpty(source1)) { 085 ((DefaultListModel<String>) sourcesList.getModel()).addElement(source1); 086 } 087 } else { 088 JOptionPane.showMessageDialog( 089 MainApplication.getMainFrame(), 090 tr("Please select the row to edit."), 091 tr("Information"), 092 JOptionPane.INFORMATION_MESSAGE 093 ); 094 } 095 } else { 096 String source2 = (String) JOptionPane.showInputDialog(MainApplication.getMainFrame(), 097 title, 098 title, 099 JOptionPane.QUESTION_MESSAGE, null, null, 100 sourcesList.getSelectedValue()); 101 if (!Utils.isEmpty(source2)) { 102 ((DefaultListModel<String>) sourcesList.getModel()).setElementAt(source2, row); 103 } 104 } 105 sourcesList.clearSelection(); 106 }); 107 108 deleteSrcButton.addActionListener(e -> { 109 if (sourcesList.getSelectedIndex() == -1) { 110 JOptionPane.showMessageDialog(MainApplication.getMainFrame(), tr("Please select the row to delete."), tr("Information"), 111 JOptionPane.QUESTION_MESSAGE); 112 } else { 113 ((DefaultListModel<String>) sourcesList.getModel()).remove(sourcesList.getSelectedIndex()); 114 } 115 }); 116 sourcesList.setMinimumSize(new Dimension(300, 50)); 117 sourcesList.setVisibleRowCount(3); 118 119 addSrcButton.setToolTipText(tr("Add a new source to the list.")); 120 editSrcButton.setToolTipText(tr("Edit the selected source.")); 121 deleteSrcButton.setToolTipText(tr("Delete the selected source from the list.")); 122 123 final JPanel buttonPanel = new JPanel(new GridBagLayout()); 124 buttonPanel.add(addSrcButton, GBC.std().insets(0, 5, 0, 0)); 125 buttonPanel.add(editSrcButton, GBC.std().insets(5, 5, 5, 0)); 126 buttonPanel.add(deleteSrcButton, GBC.std().insets(0, 5, 0, 0)); 127 128 add(new JScrollPane(sourcesList), BorderLayout.CENTER); 129 add(buttonPanel, BorderLayout.SOUTH); 130 setPreferredSize(new Dimension(300, 50 + (int) buttonPanel.getPreferredSize().getHeight())); 131 132 } 133 134 /** 135 * Sets the list items by a given list of strings 136 * @param items The items that should be set 137 */ 138 public void setItems(final Iterable<String> items) { 139 for (String source : items) { 140 ((DefaultListModel<String>) sourcesList.getModel()).addElement(source); 141 } 142 } 143 144 /** 145 * Gets all items that are currently displayed 146 * @return All items as list of strings 147 */ 148 public List<String> getItems() { 149 return IntStream.range(0, sourcesList.getModel().getSize()) 150 .mapToObj(i -> sourcesList.getModel().getElementAt(i)) 151 .collect(Collectors.toList()); 152 } 153 154 @Override 155 public void setEnabled(boolean enabled) { 156 sourcesList.setEnabled(enabled); 157 addSrcButton.setEnabled(enabled); 158 editSrcButton.setEnabled(enabled); 159 deleteSrcButton.setEnabled(enabled); 160 } 161}