001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.dialogs.properties; 003 004import static org.openstreetmap.josm.tools.I18n.marktr; 005import static org.openstreetmap.josm.tools.I18n.tr; 006import static org.openstreetmap.josm.tools.I18n.trn; 007 008import java.awt.Color; 009import java.awt.Component; 010import java.awt.Font; 011import java.util.Map; 012import java.util.Objects; 013 014import javax.swing.JLabel; 015import javax.swing.JTable; 016import javax.swing.UIDefaults; 017import javax.swing.table.DefaultTableCellRenderer; 018 019import org.openstreetmap.josm.Main; 020import org.openstreetmap.josm.data.osm.OsmPrimitive; 021 022/** 023 * Cell renderer of tags table. 024 * @since 6314 025 */ 026public class PropertiesCellRenderer extends DefaultTableCellRenderer { 027 028 private void setColors(Component c, String key, boolean isSelected) { 029 UIDefaults defaults = javax.swing.UIManager.getDefaults(); 030 if (OsmPrimitive.getDiscardableKeys().contains(key)) { 031 if (isSelected) { 032 c.setForeground(Main.pref.getColor(marktr("Discardable key: selection Foreground"), Color.GRAY)); 033 c.setBackground(Main.pref.getColor(marktr("Discardable key: selection Background"), 034 defaults.getColor("Table.selectionBackground"))); 035 } else { 036 c.setForeground(Main.pref.getColor(marktr("Discardable key: foreground"), Color.GRAY)); 037 c.setBackground(Main.pref.getColor(marktr("Discardable key: background"), defaults.getColor("Table.background"))); 038 } 039 } else { 040 c.setForeground(defaults.getColor("Table."+(isSelected ? "selectionF" : "f")+"oreground")); 041 c.setBackground(defaults.getColor("Table."+(isSelected ? "selectionB" : "b")+"ackground")); 042 } 043 } 044 045 @Override 046 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { 047 Component c = super.getTableCellRendererComponent(table, value, isSelected, false, row, column); 048 if (value == null) 049 return this; 050 if (c instanceof JLabel) { 051 String str = null; 052 if (value instanceof String) { 053 str = (String) value; 054 } else if (value instanceof Map<?, ?>) { 055 Map<?, ?> v = (Map<?, ?>) value; 056 if (v.size() != 1) { // Multiple values: give user a short summary of the values 057 Integer blankCount; 058 Integer otherCount; 059 if (v.get("") == null) { 060 blankCount = 0; 061 otherCount = v.size(); 062 } else { 063 blankCount = (Integer) v.get(""); 064 otherCount = v.size()-1; 065 } 066 StringBuilder sb = new StringBuilder("<"); 067 if (otherCount == 1) { 068 for (Map.Entry<?, ?> entry : v.entrySet()) { // Find the non-blank value in the map 069 if (!Objects.equals(entry.getKey(), "")) { 070 /* I18n: properties display partial string joined with comma, frst is count, second is value */ 071 sb.append(tr("{0} ''{1}''", entry.getValue().toString(), entry.getKey())); 072 } 073 } 074 } else { 075 /* I18n: properties display partial string joined with comma */ 076 sb.append(trn("{0} different", "{0} different", otherCount, otherCount)); 077 } 078 if (blankCount > 0) { 079 /* I18n: properties display partial string joined with comma */ 080 sb.append(trn(", {0} unset", ", {0} unset", blankCount, blankCount)); 081 } 082 sb.append('>'); 083 str = sb.toString(); 084 c.setFont(c.getFont().deriveFont(Font.ITALIC)); 085 086 } else { // One value: display the value 087 final Map.Entry<?, ?> entry = v.entrySet().iterator().next(); 088 str = (String) entry.getKey(); 089 } 090 } 091 ((JLabel) c).putClientProperty("html.disable", Boolean.TRUE); // Fix #8730 092 ((JLabel) c).setText(str); 093 if (Main.pref.getBoolean("display.discardable-keys", false)) { 094 String key = null; 095 if (column == 0) { 096 key = str; 097 } else if (column == 1) { 098 Object value0 = table.getModel().getValueAt(row, 0); 099 if (value0 instanceof String) { 100 key = (String) value0; 101 } 102 } 103 setColors(c, key, isSelected); 104 } 105 } 106 return c; 107 } 108}