source: josm/trunk/src/org/openstreetmap/josm/gui/preferences/advanced/PreferencesTable.java@ 12279

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

sonar - squid:S3878 - Arrays should not be created for varargs parameters

  • Property svn:eol-style set to native
File size: 14.6 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.preferences.advanced;
3
4import static org.openstreetmap.josm.tools.I18n.marktr;
5import static org.openstreetmap.josm.tools.I18n.tr;
6
7import java.awt.Color;
8import java.awt.Component;
9import java.awt.Font;
10import java.awt.GraphicsEnvironment;
11import java.awt.GridBagLayout;
12import java.awt.event.MouseAdapter;
13import java.awt.event.MouseEvent;
14import java.util.ArrayList;
15import java.util.List;
16import java.util.Map;
17import java.util.Objects;
18
19import javax.swing.ButtonGroup;
20import javax.swing.DefaultCellEditor;
21import javax.swing.JComponent;
22import javax.swing.JLabel;
23import javax.swing.JOptionPane;
24import javax.swing.JPanel;
25import javax.swing.JRadioButton;
26import javax.swing.JTable;
27import javax.swing.UIManager;
28import javax.swing.table.DefaultTableCellRenderer;
29import javax.swing.table.DefaultTableModel;
30
31import org.openstreetmap.josm.data.preferences.ColorProperty;
32import org.openstreetmap.josm.data.preferences.ListListSetting;
33import org.openstreetmap.josm.data.preferences.ListSetting;
34import org.openstreetmap.josm.data.preferences.MapListSetting;
35import org.openstreetmap.josm.data.preferences.Setting;
36import org.openstreetmap.josm.data.preferences.StringSetting;
37import org.openstreetmap.josm.gui.ExtendedDialog;
38import org.openstreetmap.josm.gui.util.GuiHelper;
39import org.openstreetmap.josm.gui.widgets.JosmTextField;
40import org.openstreetmap.josm.tools.GBC;
41
42/**
43 * Component for editing list of preferences as a table.
44 * @since 6021
45 */
46public class PreferencesTable extends JTable {
47 private final AllSettingsTableModel model;
48 private final transient List<PrefEntry> displayData;
49
50 /**
51 * Constructs a new {@code PreferencesTable}.
52 * @param displayData The list of preferences entries to display
53 */
54 public PreferencesTable(List<PrefEntry> displayData) {
55 this.displayData = displayData;
56 model = new AllSettingsTableModel();
57 setModel(model);
58 putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
59 getColumnModel().getColumn(1).setCellRenderer(new SettingCellRenderer());
60 getColumnModel().getColumn(1).setCellEditor(new SettingCellEditor());
61
62 addMouseListener(new MouseAdapter() {
63 @Override public void mouseClicked(MouseEvent e) {
64 if (e.getClickCount() == 2) {
65 editPreference(PreferencesTable.this);
66 }
67 }
68 });
69 }
70
71 /**
72 * This method should be called when displayed data was changed form external code
73 */
74 public void fireDataChanged() {
75 model.fireTableDataChanged();
76 }
77
78 /**
79 * The list of currently selected rows
80 * @return newly created list of PrefEntry
81 */
82 public List<PrefEntry> getSelectedItems() {
83 List<PrefEntry> entries = new ArrayList<>();
84 for (int row : getSelectedRows()) {
85 PrefEntry p = (PrefEntry) model.getValueAt(row, -1);
86 entries.add(p);
87 }
88 return entries;
89 }
90
91 /**
92 * Call this to edit selected row in preferences table
93 * @param gui - parent component for messagebox
94 * @return true if editing was actually performed during this call
95 */
96 public boolean editPreference(final JComponent gui) {
97 if (getSelectedRowCount() != 1) {
98 if (!GraphicsEnvironment.isHeadless()) {
99 JOptionPane.showMessageDialog(
100 gui,
101 tr("Please select the row to edit."),
102 tr("Warning"),
103 JOptionPane.WARNING_MESSAGE
104 );
105 }
106 return false;
107 }
108 final PrefEntry e = (PrefEntry) model.getValueAt(getSelectedRow(), 1);
109 Setting<?> stg = e.getValue();
110 boolean ok = false;
111 if (stg instanceof StringSetting) {
112 editCellAt(getSelectedRow(), 1);
113 Component editor = getEditorComponent();
114 if (editor != null) {
115 editor.requestFocus();
116 }
117 } else if (stg instanceof ListSetting) {
118 ok = doEditList(gui, e, (ListSetting) stg);
119 } else if (stg instanceof ListListSetting) {
120 ok = doEditListList(gui, e, (ListListSetting) stg);
121 } else if (stg instanceof MapListSetting) {
122 ok = doEditMapList(gui, e, (MapListSetting) stg);
123 }
124 return ok;
125 }
126
127 private static boolean doEditList(final JComponent gui, final PrefEntry e, ListSetting lSetting) {
128 ListEditor lEditor = new ListEditor(gui, e, lSetting);
129 lEditor.showDialog();
130 if (lEditor.getValue() == 1) {
131 List<String> data = lEditor.getData();
132 if (!lSetting.equalVal(data)) {
133 e.setValue(new ListSetting(data));
134 return true;
135 }
136 }
137 return false;
138 }
139
140 private static boolean doEditListList(final JComponent gui, final PrefEntry e, ListListSetting llSetting) {
141 ListListEditor llEditor = new ListListEditor(gui, e, llSetting);
142 llEditor.showDialog();
143 if (llEditor.getValue() == 1) {
144 List<List<String>> data = llEditor.getData();
145 if (!llSetting.equalVal(data)) {
146 e.setValue(new ListListSetting(data));
147 return true;
148 }
149 }
150 return false;
151 }
152
153 private static boolean doEditMapList(final JComponent gui, final PrefEntry e, MapListSetting mlSetting) {
154 MapListEditor mlEditor = new MapListEditor(gui, e, mlSetting);
155 mlEditor.showDialog();
156 if (mlEditor.getValue() == 1) {
157 List<Map<String, String>> data = mlEditor.getData();
158 if (!mlSetting.equalVal(data)) {
159 e.setValue(new MapListSetting(data));
160 return true;
161 }
162 }
163 return false;
164 }
165
166 /**
167 * Add new preference to the table
168 * @param gui - parent component for asking dialogs
169 * @return newly created entry or null if adding was cancelled
170 */
171 public PrefEntry addPreference(final JComponent gui) {
172 JPanel p = new JPanel(new GridBagLayout());
173 p.add(new JLabel(tr("Key")), GBC.std().insets(0, 0, 5, 0));
174 JosmTextField tkey = new JosmTextField("", 50);
175 p.add(tkey, GBC.eop().insets(5, 0, 0, 0).fill(GBC.HORIZONTAL));
176
177 p.add(new JLabel(tr("Select Setting Type:")), GBC.eol().insets(5, 15, 5, 0));
178
179 JRadioButton rbString = new JRadioButton(tr("Simple"));
180 JRadioButton rbList = new JRadioButton(tr("List"));
181 JRadioButton rbListList = new JRadioButton(tr("List of lists"));
182 JRadioButton rbMapList = new JRadioButton(tr("List of maps"));
183
184 ButtonGroup group = new ButtonGroup();
185 group.add(rbString);
186 group.add(rbList);
187 group.add(rbListList);
188 group.add(rbMapList);
189
190 p.add(rbString, GBC.eol());
191 p.add(rbList, GBC.eol());
192 p.add(rbListList, GBC.eol());
193 p.add(rbMapList, GBC.eol());
194
195 rbString.setSelected(true);
196
197 PrefEntry pe = null;
198 boolean ok = false;
199 if (!GraphicsEnvironment.isHeadless() && askAddSetting(gui, p)) {
200 if (rbString.isSelected()) {
201 StringSetting sSetting = new StringSetting(null);
202 pe = new PrefEntry(tkey.getText(), sSetting, sSetting, false);
203 ok = doAddSimple(gui, pe, sSetting);
204 } else if (rbList.isSelected()) {
205 ListSetting lSetting = new ListSetting(null);
206 pe = new PrefEntry(tkey.getText(), lSetting, lSetting, false);
207 ok = doAddList(gui, pe, lSetting);
208 } else if (rbListList.isSelected()) {
209 ListListSetting llSetting = new ListListSetting(null);
210 pe = new PrefEntry(tkey.getText(), llSetting, llSetting, false);
211 ok = doAddListList(gui, pe, llSetting);
212 } else if (rbMapList.isSelected()) {
213 MapListSetting mlSetting = new MapListSetting(null);
214 pe = new PrefEntry(tkey.getText(), mlSetting, mlSetting, false);
215 ok = doAddMapList(gui, pe, mlSetting);
216 }
217 }
218 return ok ? pe : null;
219 }
220
221 private static boolean askAddSetting(JComponent gui, JPanel p) {
222 return new ExtendedDialog(gui, tr("Add setting"), tr("OK"), tr("Cancel"))
223 .setContent(p).setButtonIcons("ok.png", "cancel.png").showDialog().getValue() == 1;
224 }
225
226 private static boolean doAddSimple(final JComponent gui, PrefEntry pe, StringSetting sSetting) {
227 StringEditor sEditor = new StringEditor(gui, pe, sSetting);
228 sEditor.showDialog();
229 if (sEditor.getValue() == 1) {
230 String data = sEditor.getData();
231 if (!Objects.equals(sSetting.getValue(), data)) {
232 pe.setValue(new StringSetting(data));
233 return true;
234 }
235 }
236 return false;
237 }
238
239 private static boolean doAddList(final JComponent gui, PrefEntry pe, ListSetting lSetting) {
240 ListEditor lEditor = new ListEditor(gui, pe, lSetting);
241 lEditor.showDialog();
242 if (lEditor.getValue() == 1) {
243 List<String> data = lEditor.getData();
244 if (!lSetting.equalVal(data)) {
245 pe.setValue(new ListSetting(data));
246 return true;
247 }
248 }
249 return false;
250 }
251
252 private static boolean doAddListList(final JComponent gui, PrefEntry pe, ListListSetting llSetting) {
253 ListListEditor llEditor = new ListListEditor(gui, pe, llSetting);
254 llEditor.showDialog();
255 if (llEditor.getValue() == 1) {
256 List<List<String>> data = llEditor.getData();
257 if (!llSetting.equalVal(data)) {
258 pe.setValue(new ListListSetting(data));
259 return true;
260 }
261 }
262 return false;
263 }
264
265 private static boolean doAddMapList(final JComponent gui, PrefEntry pe, MapListSetting mlSetting) {
266 MapListEditor mlEditor = new MapListEditor(gui, pe, mlSetting);
267 mlEditor.showDialog();
268 if (mlEditor.getValue() == 1) {
269 List<Map<String, String>> data = mlEditor.getData();
270 if (!mlSetting.equalVal(data)) {
271 pe.setValue(new MapListSetting(data));
272 return true;
273 }
274 }
275 return false;
276 }
277
278 /**
279 * Reset selected preferences to their default values
280 * @param gui - parent component to display warning messages
281 */
282 public void resetPreferences(final JComponent gui) {
283 if (getSelectedRowCount() == 0) {
284 if (!GraphicsEnvironment.isHeadless()) {
285 JOptionPane.showMessageDialog(
286 gui,
287 tr("Please select the row to delete."),
288 tr("Warning"),
289 JOptionPane.WARNING_MESSAGE
290 );
291 }
292 return;
293 }
294 for (int row : getSelectedRows()) {
295 PrefEntry e = displayData.get(row);
296 e.reset();
297 }
298 fireDataChanged();
299 }
300
301 final class AllSettingsTableModel extends DefaultTableModel {
302
303 AllSettingsTableModel() {
304 setColumnIdentifiers(new String[]{tr("Key"), tr("Value")});
305 }
306
307 @Override
308 public boolean isCellEditable(int row, int column) {
309 return column == 1 && (displayData.get(row).getValue() instanceof StringSetting);
310 }
311
312 @Override
313 public int getRowCount() {
314 return displayData.size();
315 }
316
317 @Override
318 public Object getValueAt(int row, int column) {
319 if (column == 0)
320 return displayData.get(row).getKey();
321 else
322 return displayData.get(row);
323 }
324
325 @Override
326 public void setValueAt(Object o, int row, int column) {
327 PrefEntry pe = displayData.get(row);
328 String s = (String) o;
329 if (!s.equals(pe.getValue().getValue())) {
330 pe.setValue(new StringSetting(s));
331 fireTableCellUpdated(row, column);
332 }
333 }
334 }
335
336 static final class SettingCellRenderer extends DefaultTableCellRenderer {
337 private final Color backgroundColor = UIManager.getColor("Table.background");
338 private final Color changedColor = new ColorProperty(
339 marktr("Advanced Background: Changed"),
340 new Color(200, 255, 200)).get();
341 private final Color nonDefaultColor = new ColorProperty(
342 marktr("Advanced Background: NonDefault"),
343 new Color(255, 255, 200)).get();
344
345 @Override
346 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
347 if (value == null)
348 return this;
349 PrefEntry pe = (PrefEntry) value;
350 Setting<?> setting = pe.getValue();
351 Object val = setting.getValue();
352 String display = val != null ? val.toString() : "<html><i>&lt;"+tr("unset")+"&gt;</i></html>";
353
354 JLabel label = (JLabel) super.getTableCellRendererComponent(table,
355 display, isSelected, hasFocus, row, column);
356
357 GuiHelper.setBackgroundReadable(label, backgroundColor);
358 if (pe.isChanged()) {
359 GuiHelper.setBackgroundReadable(label, changedColor);
360 } else if (!pe.isDefault()) {
361 GuiHelper.setBackgroundReadable(label, nonDefaultColor);
362 }
363
364 if (!pe.isDefault()) {
365 label.setFont(label.getFont().deriveFont(Font.BOLD));
366 }
367 val = pe.getDefaultValue().getValue();
368 if (val != null) {
369 if (pe.isDefault()) {
370 label.setToolTipText(tr("Current value is default."));
371 } else {
372 label.setToolTipText(tr("Default value is ''{0}''.", val));
373 }
374 } else {
375 label.setToolTipText(tr("Default value currently unknown (setting has not been used yet)."));
376 }
377 return label;
378 }
379 }
380
381 static final class SettingCellEditor extends DefaultCellEditor {
382 SettingCellEditor() {
383 super(new JosmTextField());
384 }
385
386 @Override
387 public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
388 PrefEntry pe = (PrefEntry) value;
389 StringSetting stg = (StringSetting) pe.getValue();
390 String s = stg.getValue() == null ? "" : stg.getValue();
391 return super.getTableCellEditorComponent(table, s, isSelected, row, column);
392 }
393 }
394}
Note: See TracBrowser for help on using the repository browser.