source: josm/trunk/src/org/openstreetmap/josm/gui/tagging/presets/items/MultiSelect.java@ 17639

Last change on this file since 17639 was 17639, checked in by simon04, 3 years ago

see #18949 - Tagging presets: trigger value_template="..." from <combo> and <multiselect> changes

File size: 4.1 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.tagging.presets.items;
3
4import java.awt.Dimension;
5import java.util.Arrays;
6import java.util.List;
7import java.util.Set;
8import java.util.TreeSet;
9
10import javax.swing.JList;
11import javax.swing.JPanel;
12import javax.swing.JScrollPane;
13import javax.swing.ListCellRenderer;
14import javax.swing.ListModel;
15
16import org.openstreetmap.josm.data.osm.Tag;
17import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItemGuiSupport;
18import org.openstreetmap.josm.tools.GBC;
19
20/**
21 * Multi-select list type.
22 */
23public class MultiSelect extends ComboMultiSelect {
24
25 /**
26 * Number of rows to display (positive integer, optional).
27 */
28 public short rows; // NOSONAR
29
30 protected ConcatenatingJList list;
31
32 @Override
33 protected void addToPanelAnchor(JPanel p, String def, TaggingPresetItemGuiSupport support) {
34 list = new ConcatenatingJList(delimiter, presetListEntries.toArray(new PresetListEntry[0]));
35 component = list;
36 ListCellRenderer<PresetListEntry> renderer = getListCellRenderer();
37 list.setCellRenderer(renderer);
38 list.setSelectedItem(getItemToSelect(def, support, true));
39 JScrollPane sp = new JScrollPane(list);
40 // if a number of rows has been specified in the preset,
41 // modify preferred height of scroll pane to match that row count.
42 if (rows > 0) {
43 double height = renderer.getListCellRendererComponent(list,
44 new PresetListEntry("x"), 0, false, false).getPreferredSize().getHeight() * rows;
45 sp.setPreferredSize(new Dimension((int) sp.getPreferredSize().getWidth(), (int) height));
46 }
47 list.addListSelectionListener(l -> support.fireItemValueModified(this, key, getSelectedValue()));
48 p.add(sp, GBC.eol().fill(GBC.HORIZONTAL));
49 }
50
51 @Override
52 protected Object getSelectedItem() {
53 return list.getSelectedItem();
54 }
55
56 @Override
57 public void addCommands(List<Tag> changedTags) {
58 // Do not create any commands if list has been disabled because of an unknown value (fix #8605)
59 if (list.isEnabled()) {
60 super.addCommands(changedTags);
61 }
62 }
63
64 /**
65 * Class that allows list values to be assigned and retrieved as a comma-delimited
66 * string (extracted from TaggingPreset)
67 */
68 private static class ConcatenatingJList extends JList<PresetListEntry> {
69 private final char delimiter;
70
71 protected ConcatenatingJList(char del, PresetListEntry... o) {
72 super(o);
73 delimiter = del;
74 }
75
76 public void setSelectedItem(Object o) {
77 if (o == null) {
78 clearSelection();
79 } else {
80 String s = o.toString();
81 Set<String> parts = new TreeSet<>(Arrays.asList(s.split(String.valueOf(delimiter), -1)));
82 ListModel<PresetListEntry> lm = getModel();
83 int[] intParts = new int[lm.getSize()];
84 int j = 0;
85 for (int i = 0; i < lm.getSize(); i++) {
86 final String value = lm.getElementAt(i).value;
87 if (parts.contains(value)) {
88 intParts[j++] = i;
89 parts.remove(value);
90 }
91 }
92 setSelectedIndices(Arrays.copyOf(intParts, j));
93 // check if we have actually managed to represent the full
94 // value with our presets. if not, cop out; we will not offer
95 // a selection list that threatens to ruin the value.
96 setEnabled(parts.isEmpty());
97 }
98 }
99
100 public String getSelectedItem() {
101 ListModel<PresetListEntry> lm = getModel();
102 int[] si = getSelectedIndices();
103 StringBuilder builder = new StringBuilder();
104 for (int i = 0; i < si.length; i++) {
105 if (i > 0) {
106 builder.append(delimiter);
107 }
108 builder.append(lm.getElementAt(si[i]).value);
109 }
110 return builder.toString();
111 }
112 }
113}
Note: See TracBrowser for help on using the repository browser.