001 // License: GPL. For details, see LICENSE file. 002 package org.openstreetmap.josm.gui.conflict.pair.relation; 003 004 import java.awt.Color; 005 import java.awt.Component; 006 import java.util.ArrayList; 007 import java.util.Collections; 008 009 import javax.swing.BorderFactory; 010 import javax.swing.JLabel; 011 import javax.swing.JTable; 012 import javax.swing.border.Border; 013 import javax.swing.table.TableCellRenderer; 014 015 import org.openstreetmap.josm.data.osm.Node; 016 import org.openstreetmap.josm.data.osm.OsmPrimitive; 017 import org.openstreetmap.josm.data.osm.RelationMember; 018 import org.openstreetmap.josm.gui.DefaultNameFormatter; 019 import org.openstreetmap.josm.gui.conflict.ConflictColors; 020 import org.openstreetmap.josm.gui.conflict.pair.ListMergeModel; 021 import org.openstreetmap.josm.tools.ImageProvider; 022 023 /** 024 * This is the {@link TableCellRenderer} used in the tables of {@link RelationMemberMerger}. 025 * 026 */ 027 public class RelationMemberTableCellRenderer extends JLabel implements TableCellRenderer { 028 private Border rowNumberBorder = null; 029 030 /** 031 * constructor 032 */ 033 public RelationMemberTableCellRenderer() { 034 setIcon(null); 035 setOpaque(true); 036 rowNumberBorder = BorderFactory.createEmptyBorder(0,4,0,0); 037 } 038 039 public String buildToolTipText(OsmPrimitive primitive) { 040 StringBuilder sb = new StringBuilder(); 041 sb.append("<html>"); 042 sb.append("<strong>id</strong>=") 043 .append(primitive.getId()) 044 .append("<br>"); 045 ArrayList<String> keyList = new ArrayList<String>(primitive.keySet()); 046 Collections.sort(keyList); 047 for (int i = 0; i < keyList.size(); i++) { 048 if (i > 0) { 049 sb.append("<br>"); 050 } 051 String key = keyList.get(i); 052 sb.append("<strong>") 053 .append(key) 054 .append("</strong>") 055 .append("="); 056 String value = primitive.get(key); 057 while(value.length() != 0) { 058 sb.append(value.substring(0,Math.min(50, value.length()))); 059 if (value.length() > 50) { 060 sb.append("<br>"); 061 value = value.substring(50); 062 } else { 063 value = ""; 064 } 065 } 066 } 067 sb.append("</html>"); 068 return sb.toString(); 069 } 070 071 /** 072 * reset the renderer 073 */ 074 protected void reset() { 075 setBackground(ConflictColors.BGCOLOR.get()); 076 setForeground(ConflictColors.FGCOLOR.get()); 077 setBorder(null); 078 setIcon(null); 079 setToolTipText(null); 080 } 081 082 protected void renderBackground(ListMergeModel<Node>.EntriesTableModel model, RelationMember member, int row, int col, boolean isSelected) { 083 Color bgc = ConflictColors.BGCOLOR.get(); 084 if (col == 0) { 085 if (model.getListMergeModel().isFrozen()) { 086 bgc = ConflictColors.BGCOLOR_FROZEN.get(); 087 } else if (model.isParticipatingInCurrentComparePair()) { 088 bgc = ConflictColors.BGCOLOR_PARTICIPAING_IN_COMPARISON.get(); 089 } else if (isSelected) { 090 bgc = ConflictColors.BGCOLOR_SELECTED.get(); 091 } 092 } else { 093 if (model.getListMergeModel().isFrozen()) { 094 bgc = ConflictColors.BGCOLOR_FROZEN.get(); 095 } else if (member == null) { 096 bgc = ConflictColors.BGCOLOR_EMPTY_ROW.get(); 097 } else if (isSelected) { 098 bgc = ConflictColors.BGCOLOR_SELECTED.get(); 099 } else { 100 if (model.isParticipatingInCurrentComparePair()) { 101 if (model.isSamePositionInOppositeList(row)) { 102 bgc = ConflictColors.BGCOLOR_SAME_POSITION_IN_OPPOSITE.get(); 103 } else if (model.isIncludedInOppositeList(row)) { 104 bgc = ConflictColors.BGCOLOR_IN_OPPOSITE.get(); 105 } else { 106 bgc = ConflictColors.BGCOLOR_NOT_IN_OPPOSITE.get(); 107 } 108 } 109 } 110 } 111 setBackground(bgc); 112 } 113 114 protected void renderForeground(ListMergeModel<Node>.EntriesTableModel model, RelationMember member, int row, int col, boolean isSelected) { 115 Color fgc = ConflictColors.FGCOLOR.get(); 116 if (col == 0 && model.isParticipatingInCurrentComparePair() && ! model.getListMergeModel().isFrozen()) { 117 fgc = ConflictColors.FGCOLOR_PARTICIPAING_IN_COMPARISON.get(); 118 } 119 setForeground(fgc); 120 } 121 122 protected void renderRole(RelationMember member) { 123 setText(member.getRole()); 124 setToolTipText(member.getRole()); 125 } 126 127 protected void renderPrimitive(RelationMember member) { 128 String displayName = member.getMember().getDisplayName(DefaultNameFormatter.getInstance()); 129 setText(displayName); 130 setToolTipText(buildToolTipText(member.getMember())); 131 setIcon(ImageProvider.get(member.getDisplayType())); 132 } 133 134 /** 135 * render the row id 136 * @param row the row index 137 * @param isSelected 138 */ 139 protected void renderRowId(int row) { 140 setBorder(rowNumberBorder); 141 setText(Integer.toString(row+1)); 142 } 143 144 protected void renderEmptyRow() { 145 setIcon(null); 146 setBackground(ConflictColors.BGCOLOR_EMPTY_ROW.get()); 147 setText(""); 148 } 149 150 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, 151 int row, int column) { 152 153 RelationMember member = (RelationMember)value; 154 reset(); 155 if (member == null) { 156 renderEmptyRow(); 157 } else { 158 renderBackground(getModel(table), member, row, column, isSelected); 159 renderForeground(getModel(table), member, row, column, isSelected); 160 switch(column) { 161 case 0: 162 renderRowId(row); 163 break; 164 case 1: 165 renderRole(member); 166 break; 167 case 2: 168 renderPrimitive(member); 169 break; 170 default: 171 // should not happen 172 } 173 } 174 return this; 175 } 176 177 /** 178 * replies the model 179 * @param table the table 180 * @return the table model 181 */ 182 @SuppressWarnings("unchecked") 183 protected ListMergeModel<Node>.EntriesTableModel getModel(JTable table) { 184 return (ListMergeModel.EntriesTableModel)table.getModel(); 185 } 186 }