source: josm/trunk/src/org/openstreetmap/josm/gui/preferences/advanced/MapListEditor.java@ 6890

Last change on this file since 6890 was 6890, checked in by Don-vip, 10 years ago

fix some Sonar issues (Constructor Calls Overridable Method)

  • Property svn:eol-style set to native
File size: 8.8 KB
Line 
1// License: GPL. See LICENSE file for details.
2package org.openstreetmap.josm.gui.preferences.advanced;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.Dimension;
7import java.awt.GridBagLayout;
8import java.awt.event.ActionEvent;
9import java.util.ArrayList;
10import java.util.Arrays;
11import java.util.Collections;
12import java.util.LinkedHashMap;
13import java.util.List;
14import java.util.Map;
15import java.util.Map.Entry;
16
17import javax.swing.AbstractAction;
18import javax.swing.AbstractListModel;
19import javax.swing.DefaultCellEditor;
20import javax.swing.JComponent;
21import javax.swing.JLabel;
22import javax.swing.JList;
23import javax.swing.JPanel;
24import javax.swing.JScrollPane;
25import javax.swing.JTable;
26import javax.swing.JToolBar;
27import javax.swing.event.ListSelectionEvent;
28import javax.swing.event.ListSelectionListener;
29import javax.swing.table.AbstractTableModel;
30import javax.swing.table.TableCellEditor;
31
32import org.openstreetmap.josm.data.Preferences.MapListSetting;
33import org.openstreetmap.josm.gui.ExtendedDialog;
34import org.openstreetmap.josm.gui.widgets.JosmTextField;
35import org.openstreetmap.josm.tools.GBC;
36import org.openstreetmap.josm.tools.ImageProvider;
37import org.openstreetmap.josm.tools.WindowGeometry;
38
39/**
40 * Editor for List of Maps preference entries.
41 */
42public class MapListEditor extends ExtendedDialog {
43
44 EntryListModel entryModel;
45 PrefEntry entry;
46
47 JList entryList;
48 JTable table;
49 MapTableModel tableModel;
50
51 List<List<String>> dataKeys;
52 List<List<String>> dataValues;
53 Integer entryIdx;
54
55 public MapListEditor(JComponent gui, PrefEntry entry, MapListSetting setting) {
56 super(gui, tr("Change list of maps setting"), new String[] {tr("OK"), tr("Cancel")});
57 this.entry = entry;
58 List<Map<String, String>> orig = setting.getValue();
59
60 dataKeys = new ArrayList<List<String>>();
61 dataValues = new ArrayList<List<String>>();
62 if (orig != null) {
63 for (Map<String, String> m : orig) {
64 List<String> keys = new ArrayList<String>();
65 List<String> values = new ArrayList<String>();
66 for (Entry<String, String> e : m.entrySet()) {
67 keys.add(e.getKey());
68 values.add(e.getValue());
69 }
70 dataKeys.add(keys);
71 dataValues.add(values);
72 }
73 }
74 setButtonIcons(new String[] {"ok.png", "cancel.png"});
75 setRememberWindowGeometry(getClass().getName() + ".geometry", WindowGeometry.centerInWindow(gui, new Dimension(500, 350)));
76 setContent(build(), false);
77 }
78
79 /**
80 * Returns the data.
81 * @return the preference data
82 */
83 public List<Map<String,String>> getData() {
84 List<Map<String,String>> data = new ArrayList<Map<String,String>>();
85 for (int i=0; i < dataKeys.size(); ++i) {
86 Map<String,String> m = new LinkedHashMap<String, String>();
87 for (int j=0; j < dataKeys.get(i).size(); ++j) {
88 m.put(dataKeys.get(i).get(j), dataValues.get(i).get(j));
89 }
90 data.add(m);
91 }
92 return data;
93 }
94
95 protected final JPanel build() {
96 JPanel p = new JPanel(new GridBagLayout());
97 p.add(new JLabel(tr("Key: {0}", entry.getKey())), GBC.std(0,0).span(2).weight(1, 0).insets(0,0,5,10));
98
99 JPanel left = new JPanel(new GridBagLayout());
100
101 entryModel = new EntryListModel();
102 entryList = new JList(entryModel);
103 entryList.getSelectionModel().addListSelectionListener(new EntryListener());
104 JScrollPane scroll = new JScrollPane(entryList);
105 left.add(scroll, GBC.eol().fill());
106
107 JToolBar sideButtonTB = new JToolBar(JToolBar.HORIZONTAL);
108 sideButtonTB.setBorderPainted(false);
109 sideButtonTB.setOpaque(false);
110 sideButtonTB.add(new NewEntryAction());
111 RemoveEntryAction removeEntryAction = new RemoveEntryAction();
112 entryList.getSelectionModel().addListSelectionListener(removeEntryAction);
113 sideButtonTB.add(removeEntryAction);
114 left.add(sideButtonTB, GBC.eol());
115
116 left.setPreferredSize(new Dimension(80, 0));
117
118 p.add(left, GBC.std(0,1).fill().weight(0.3, 1.0));
119
120 tableModel = new MapTableModel();
121 table = new JTable(tableModel);
122 table.putClientProperty("terminateEditOnFocusLost", true);
123 table.getTableHeader().getColumnModel().getColumn(0).setHeaderValue(tr("Key"));
124 table.getTableHeader().getColumnModel().getColumn(1).setHeaderValue(tr("Value"));
125 DefaultCellEditor editor = new DefaultCellEditor(new JosmTextField());
126 editor.setClickCountToStart(1);
127 table.setDefaultEditor(table.getColumnClass(0), editor);
128
129 JScrollPane pane = new JScrollPane(table);
130 pane.setPreferredSize(new Dimension(140, 0));
131 p.add(pane, GBC.std(1,1).insets(5,0,0,0).fill().weight(0.7, 1.0));
132 return p;
133 }
134
135 class EntryListModel extends AbstractListModel {
136 @Override
137 public Object getElementAt(int index) {
138 return tr("Entry {0}", index+1);
139 }
140
141 @Override
142 public int getSize() {
143 return dataKeys.size();
144 }
145
146 public void add() {
147 dataKeys.add(new ArrayList<String>());
148 dataValues.add(new ArrayList<String>());
149 fireIntervalAdded(this, getSize() - 1, getSize() - 1);
150 }
151
152 public void remove(int idx) {
153 dataKeys.remove(idx);
154 dataValues.remove(idx);
155 fireIntervalRemoved(this, idx, idx);
156 }
157 }
158
159 class NewEntryAction extends AbstractAction {
160 public NewEntryAction() {
161 putValue(NAME, tr("New"));
162 putValue(SHORT_DESCRIPTION, tr("add entry"));
163 putValue(SMALL_ICON, ImageProvider.get("dialogs", "add"));
164 }
165
166 @Override
167 public void actionPerformed(ActionEvent evt) {
168 entryModel.add();
169 }
170 }
171
172 class RemoveEntryAction extends AbstractAction implements ListSelectionListener {
173 public RemoveEntryAction() {
174 putValue(NAME, tr("Remove"));
175 putValue(SHORT_DESCRIPTION, tr("Remove the selected entry"));
176 putValue(SMALL_ICON, ImageProvider.get("dialogs", "delete"));
177 updateEnabledState();
178 }
179
180 protected final void updateEnabledState() {
181 setEnabled(entryList.getSelectedIndices().length == 1);
182 }
183
184 @Override
185 public void valueChanged(ListSelectionEvent e) {
186 updateEnabledState();
187 }
188
189 @Override
190 public void actionPerformed(ActionEvent e) {
191 int idx = entryList.getSelectedIndices()[0];
192 entryModel.remove(idx);
193 }
194 }
195
196 class EntryListener implements ListSelectionListener {
197 @Override
198 public void valueChanged(ListSelectionEvent e) {
199 TableCellEditor editor = table.getCellEditor();
200 if (editor != null) {
201 ((DefaultCellEditor) editor).stopCellEditing();
202 }
203 if (entryList.getSelectedIndices().length != 1) {
204 entryIdx = null;
205 table.setEnabled(false);
206 } else {
207 entryIdx = entryList.getSelectedIndices()[0];
208 table.setEnabled(true);
209 }
210 tableModel.fireTableDataChanged();
211 }
212 }
213
214 class MapTableModel extends AbstractTableModel {
215 @SuppressWarnings("unchecked")
216 private List<List<String>> data() {
217 if (entryIdx == null) return Collections.emptyList();
218 return Arrays.asList(dataKeys.get(entryIdx), dataValues.get(entryIdx));
219 }
220
221 private int size() {
222 if (entryIdx == null) return 0;
223 return dataKeys.get(entryIdx).size();
224 }
225
226 @Override
227 public int getRowCount() {
228 return entryIdx == null ? 0 : size() + 1;
229 }
230
231 @Override
232 public int getColumnCount() {
233 return 2;
234 }
235
236 @Override
237 public String getColumnName(int column) {
238 return column == 0 ? tr("Key") : tr("Value");
239 }
240
241 @Override
242 public Object getValueAt(int row, int column) {
243 return size() == row ? "" : data().get(column).get(row);
244 }
245
246 @Override
247 public void setValueAt(Object o, int row, int column) {
248 String s = (String) o;
249 if (row == size()) {
250 data().get(0).add("");
251 data().get(1).add("");
252 data().get(column).set(row, s);
253 fireTableRowsInserted(row+1, row+1);
254 } else {
255 data().get(column).set(row, s);
256 fireTableCellUpdated(row, column);
257 }
258 }
259
260 @Override
261 public boolean isCellEditable(int row, int column) {
262 return true;
263 }
264 }
265
266}
Note: See TracBrowser for help on using the repository browser.