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