source: josm/trunk/src/org/openstreetmap/josm/gui/dialogs/properties/PropertiesCellRenderer.java@ 11553

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

refactor handling of null values - use Java 8 Optional where possible

  • Property svn:eol-style set to native
File size: 6.6 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.dialogs.properties;
3
4import static org.openstreetmap.josm.tools.I18n.marktr;
5import static org.openstreetmap.josm.tools.I18n.tr;
6import static org.openstreetmap.josm.tools.I18n.trn;
7
8import java.awt.Color;
9import java.awt.Component;
10import java.awt.Font;
11import java.util.Collection;
12import java.util.Map;
13import java.util.Objects;
14import java.util.Optional;
15import java.util.concurrent.CopyOnWriteArrayList;
16
17import javax.swing.JLabel;
18import javax.swing.JTable;
19import javax.swing.UIManager;
20import javax.swing.table.DefaultTableCellRenderer;
21import javax.swing.table.TableCellRenderer;
22
23import org.openstreetmap.josm.data.osm.OsmPrimitive;
24import org.openstreetmap.josm.data.preferences.BooleanProperty;
25import org.openstreetmap.josm.data.preferences.CachingProperty;
26import org.openstreetmap.josm.data.preferences.ColorProperty;
27
28/**
29 * Cell renderer of tags table.
30 * @since 6314
31 */
32public class PropertiesCellRenderer extends DefaultTableCellRenderer {
33
34 private static final CachingProperty<Color> SELECTED_FG
35 = new ColorProperty(marktr("Discardable key: selection Foreground"), Color.GRAY).cached();
36 private static final CachingProperty<Color> SELECTED_BG;
37 private static final CachingProperty<Color> NORMAL_FG
38 = new ColorProperty(marktr("Discardable key: foreground"), Color.GRAY).cached();
39 private static final CachingProperty<Color> NORMAL_BG;
40 private static final CachingProperty<Boolean> DISCARDABLE
41 = new BooleanProperty("display.discardable-keys", false).cached();
42
43 static {
44 SELECTED_BG = new ColorProperty(marktr("Discardable key: selection Background"),
45 Optional.ofNullable(UIManager.getColor("Table.selectionBackground")).orElse(Color.BLUE)).cached();
46 NORMAL_BG = new ColorProperty(marktr("Discardable key: background"),
47 Optional.ofNullable(UIManager.getColor("Table.background")).orElse(Color.WHITE)).cached();
48 }
49
50 private final Collection<TableCellRenderer> customRenderer = new CopyOnWriteArrayList<>();
51
52 private static void setColors(Component c, String key, boolean isSelected) {
53
54 if (OsmPrimitive.getDiscardableKeys().contains(key)) {
55 c.setForeground((isSelected ? SELECTED_FG : NORMAL_FG).get());
56 c.setBackground((isSelected ? SELECTED_BG : NORMAL_BG).get());
57 } else {
58 c.setForeground(UIManager.getColor("Table."+(isSelected ? "selectionF" : "f")+"oreground"));
59 c.setBackground(UIManager.getColor("Table."+(isSelected ? "selectionB" : "b")+"ackground"));
60 }
61 }
62
63 @Override
64 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
65 for (TableCellRenderer renderer : customRenderer) {
66 final Component component = renderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
67 if (component != null) {
68 return component;
69 }
70 }
71 if (value == null)
72 return this;
73 Component c = super.getTableCellRendererComponent(table, value, isSelected, false, row, column);
74 if (c instanceof JLabel) {
75 String str = null;
76 if (value instanceof String) {
77 str = (String) value;
78 } else if (value instanceof Map<?, ?>) {
79 Map<?, ?> v = (Map<?, ?>) value;
80 if (v.size() != 1) { // Multiple values: give user a short summary of the values
81 Integer blankCount;
82 Integer otherCount;
83 if (v.get("") == null) {
84 blankCount = 0;
85 otherCount = v.size();
86 } else {
87 blankCount = (Integer) v.get("");
88 otherCount = v.size()-1;
89 }
90 StringBuilder sb = new StringBuilder("<");
91 if (otherCount == 1) {
92 // Find the non-blank value in the map
93 v.entrySet().stream().filter(entry -> !Objects.equals(entry.getKey(), ""))
94 /* I18n: properties display partial string joined with comma, first is count, second is value */
95 .findAny().ifPresent(entry -> sb.append(tr("{0} ''{1}''", entry.getValue().toString(), entry.getKey())));
96 } else {
97 /* I18n: properties display partial string joined with comma */
98 sb.append(trn("{0} different", "{0} different", otherCount, otherCount));
99 }
100 if (blankCount > 0) {
101 /* I18n: properties display partial string joined with comma */
102 sb.append(trn(", {0} unset", ", {0} unset", blankCount, blankCount));
103 }
104 sb.append('>');
105 str = sb.toString();
106 c.setFont(c.getFont().deriveFont(Font.ITALIC));
107
108 } else { // One value: display the value
109 final Map.Entry<?, ?> entry = v.entrySet().iterator().next();
110 str = (String) entry.getKey();
111 }
112 }
113 ((JLabel) c).putClientProperty("html.disable", Boolean.TRUE); // Fix #8730
114 ((JLabel) c).setText(str);
115 if (DISCARDABLE.get()) {
116 String key = null;
117 if (column == 0) {
118 key = str;
119 } else if (column == 1) {
120 Object value0 = table.getModel().getValueAt(row, 0);
121 if (value0 instanceof String) {
122 key = (String) value0;
123 }
124 }
125 setColors(c, key, isSelected);
126 }
127 }
128 return c;
129 }
130
131 /**
132 * Adds a custom table cell renderer to render cells of the tags table.
133 *
134 * If the renderer is not capable performing a {@link TableCellRenderer#getTableCellRendererComponent},
135 * it should return {@code null} to fall back to the
136 * {@link PropertiesCellRenderer#getTableCellRendererComponent default implementation}.
137 * @param renderer the renderer to add
138 * @since 9149
139 */
140 public void addCustomRenderer(TableCellRenderer renderer) {
141 customRenderer.add(renderer);
142 }
143
144 /**
145 * Removes a custom table cell renderer.
146 * @param renderer the renderer to remove
147 * @since 9149
148 */
149 public void removeCustomRenderer(TableCellRenderer renderer) {
150 customRenderer.remove(renderer);
151 }
152}
Note: See TracBrowser for help on using the repository browser.