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

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

fix #14353 - robustness to systems not defining standard Java UI color constants

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