/** * Retries to recover the upload operation from an exception which was thrown because an uploaded * primitive was already deleted on the server. * * @param e the exception throw by the API * @param monitor a progress monitor * @throws OsmTransferException thrown if we can't recover from the exception */ protected void recoverFromGoneOnServer(OsmApiPrimitiveGoneException e, ProgressMonitor monitor) throws OsmTransferException { if (!e.isKnownPrimitive()) throw e; OsmPrimitive p = layer.data.getPrimitiveById(e.getPrimitiveId(), e.getPrimitiveType()); if (p == null) throw e; if (p.isDeleted()) { // we tried to delete an already deleted primitive. // System.out.println( tr( "Warning: object ''{0}'' is already deleted on the server. Skipping this object and retrying to upload.", p.getDisplayName(DefaultNameFormatter.getInstance()))); monitor.appendLogMessage( tr( "Object ''{0}'' is already deleted. Skipping object in upload.", p.getDisplayName(DefaultNameFormatter.getInstance()))); processedPrimitives.addAll(writer.getProcessedPrimitives()); processedPrimitives.add(p); toUpload.removeProcessed(processedPrimitives); return; } // exception was thrown because we tried to *update* an already deleted // primitive. We can't resolve this automatically. Re-throw exception, // a conflict is going to be created later. throw e; }
private void checkNodes() { DataSet dataSet = getDataSet(); if (dataSet != null) { Node[] nodes = this.nodes; for (Node n : nodes) { if (n.getDataSet() != dataSet) throw new DataIntegrityProblemException( "Nodes in way must be in the same dataset", tr("Nodes in way must be in the same dataset")); if (n.isDeleted()) throw new DataIntegrityProblemException( "Deleted node referenced: " + toString(), "<html>" + tr( "Deleted node referenced by {0}", DefaultNameFormatter.getInstance().formatAsHtmlUnorderedList(this)) + "</html>"); } if (Main.pref.getBoolean("debug.checkNullCoor", true)) { for (Node n : nodes) { if (n.isVisible() && !n.isIncomplete() && !n.isLatLonKnown()) throw new DataIntegrityProblemException( "Complete visible node with null coordinates: " + toString(), "<html>" + tr( "Complete node {0} with null coordinates in way {1}", DefaultNameFormatter.getInstance().formatAsHtmlUnorderedList(n), DefaultNameFormatter.getInstance().formatAsHtmlUnorderedList(this)) + "</html>"); } } } }
/** * Inform a non-expert user about what relation membership conflict resolution means. * * @param primitives The primitives to be combined * @param parentRelations The parent relations of the primitives * @throws UserCancelException If the user cancels the dialog. */ protected static void informAboutRelationMembershipConflicts( final Collection<? extends OsmPrimitive> primitives, final Set<Relation> parentRelations) throws UserCancelException { /* I18n: object count < 2 is not possible */ String msg = trn( "You are about to combine {1} object, " + "which is part of {0} relation:<br/>{2}" + "Combining these objects may break this relation. If you are unsure, please cancel this operation.<br/>" + "If you want to continue, you are shown a dialog to decide how to adapt the relation.<br/><br/>" + "Do you want to continue?", "You are about to combine {1} objects, " + "which are part of {0} relations:<br/>{2}" + "Combining these objects may break these relations. If you are unsure, please cancel this operation.<br/>" + "If you want to continue, you are shown a dialog to decide how to adapt the relations.<br/><br/>" + "Do you want to continue?", parentRelations.size(), parentRelations.size(), primitives.size(), DefaultNameFormatter.getInstance().formatAsHtmlUnorderedList(parentRelations, 20)); if (!ConditionalOptionPaneUtil.showConfirmationDialog( "combine_tags", Main.parent, "<html>" + msg + "</html>", tr("Combine confirmation"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_OPTION)) { throw new UserCancelException(); } }
/** * Retries to recover the upload operation from an exception which was thrown because an uploaded * primitive was already deleted on the server. * * @param e the exception throw by the API * @param monitor a progress monitor * @throws OsmTransferException if we can't recover from the exception */ protected void recoverFromGoneOnServer(OsmApiPrimitiveGoneException e, ProgressMonitor monitor) throws OsmTransferException { if (!e.isKnownPrimitive()) throw e; OsmPrimitive p = layer.data.getPrimitiveById(e.getPrimitiveId(), e.getPrimitiveType()); if (p == null) throw e; if (p.isDeleted()) { // we tried to delete an already deleted primitive. final String msg; final String displayName = p.getDisplayName(DefaultNameFormatter.getInstance()); if (p instanceof Node) { msg = tr("Node ''{0}'' is already deleted. Skipping object in upload.", displayName); } else if (p instanceof Way) { msg = tr("Way ''{0}'' is already deleted. Skipping object in upload.", displayName); } else if (p instanceof Relation) { msg = tr("Relation ''{0}'' is already deleted. Skipping object in upload.", displayName); } else { msg = tr("Object ''{0}'' is already deleted. Skipping object in upload.", displayName); } monitor.appendLogMessage(msg); Main.warn(msg); processedPrimitives.addAll(writer.getProcessedPrimitives()); processedPrimitives.add(p); toUpload.removeProcessed(processedPrimitives); return; } // exception was thrown because we tried to *update* an already deleted // primitive. We can't resolve this automatically. Re-throw exception, // a conflict is going to be created later. throw e; }
private static boolean confirmRelationDeletion(Collection<Relation> relations) { JPanel msg = new JPanel(new GridBagLayout()); msg.add( new JMultilineLabel( "<html>" + trn( "You are about to delete {0} relation: {1}" + "<br/>" + "This step is rarely necessary and cannot be undone easily after being uploaded to the server." + "<br/>" + "Do you really want to delete?", "You are about to delete {0} relations: {1}" + "<br/>" + "This step is rarely necessary and cannot be undone easily after being uploaded to the server." + "<br/>" + "Do you really want to delete?", relations.size(), relations.size(), DefaultNameFormatter.getInstance().formatAsHtmlUnorderedList(relations, 20)) + "</html>")); return ConditionalOptionPaneUtil.showConfirmationDialog( "delete_relations", Main.parent, msg, tr("Delete relation?"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_OPTION); }
/** * Internal method that stuffs information into the rendering component provided that it's a kind * of JLabel. * * @param def the rendering component * @param value the HistoryOsmPrimtive to render * @return the modified rendering component */ private Component renderer(Component def, HistoryOsmPrimitive value) { if (value != null && def instanceof JLabel) { ((JLabel) def).setText(value.getDisplayName(DefaultNameFormatter.getInstance())); ((JLabel) def).setIcon(ImageProvider.get(value.getType())); ((JLabel) def).setToolTipText(formatter.buildDefaultToolTip(value)); } return def; }
protected void updateTitle() { if (targetPrimitive == null) { setTitle(tr("Conflicts when combining primitives")); return; } if (targetPrimitive instanceof Way) { setTitle( tr( "Conflicts when combining ways - combined way is ''{0}''", targetPrimitive.getDisplayName(DefaultNameFormatter.getInstance()))); helpAction.setHelpTopic(ht("/Action/CombineWay#ResolvingConflicts")); getRootPane().putClientProperty("help", ht("/Action/CombineWay#ResolvingConflicts")); } else if (targetPrimitive instanceof Node) { setTitle( tr( "Conflicts when merging nodes - target node is ''{0}''", targetPrimitive.getDisplayName(DefaultNameFormatter.getInstance()))); helpAction.setHelpTopic(ht("/Action/MergeNodes#ResolvingConflicts")); getRootPane().putClientProperty("help", ht("/Action/MergeNodes#ResolvingConflicts")); } }
@Override public Object getCorrectionValueAt(int rowIndex, int colIndex) { RoleCorrection roleCorrection = getCorrections().get(rowIndex); switch (colIndex) { case 0: return roleCorrection.relation.getDisplayName(DefaultNameFormatter.getInstance()); case 1: return roleCorrection.member.getRole(); case 2: return roleCorrection.newRole; } return null; }
@Override protected void realRun() throws SAXException, IOException, OsmTransferException { try { Stack<OsmPrimitive> toCheck = new Stack<OsmPrimitive>(); toCheck.addAll(getPrimitivesToCheckForParents()); Set<OsmPrimitive> checked = new HashSet<OsmPrimitive>(); while (!toCheck.isEmpty()) { if (canceled) return; OsmPrimitive current = toCheck.pop(); synchronized (this) { reader = new OsmServerBackreferenceReader(current); } getProgressMonitor() .subTask( tr( "Reading parents of ''{0}''", current.getDisplayName(DefaultNameFormatter.getInstance()))); DataSet ds = reader.parseOsm(getProgressMonitor().createSubTaskMonitor(1, false)); synchronized (this) { reader = null; } checked.add(current); getProgressMonitor().subTask(tr("Checking for deleted parents in the local dataset")); for (OsmPrimitive p : ds.allPrimitives()) { if (canceled) return; OsmPrimitive myDeletedParent = layer.data.getPrimitiveById(p); // our local dataset includes a deleted parent of a primitive we want // to delete. Include this parent in the collection of uploaded primitives // if (myDeletedParent != null && myDeletedParent.isDeleted()) { if (!toUpload.contains(myDeletedParent)) { toUpload.add(myDeletedParent); } if (!checked.contains(myDeletedParent)) { toCheck.push(myDeletedParent); } } } } } catch (Exception e) { if (canceled) // ignore exception return; lastException = e; } }
@Override public String getDescriptionText() { String msg; switch (OsmPrimitiveType.from(osm)) { case NODE: msg = marktr("Add node {0}"); break; case WAY: msg = marktr("Add way {0}"); break; case RELATION: msg = marktr("Add relation {0}"); break; default: /* should not happen */ msg = ""; break; } return tr(msg, osm.getDisplayName(DefaultNameFormatter.getInstance())); }
@Override public String getDescriptionText() { if (toDelete.size() == 1) { OsmPrimitive primitive = toDelete.iterator().next(); String msg = ""; switch (OsmPrimitiveType.from(primitive)) { case NODE: msg = marktr("Delete node {0}"); break; case WAY: msg = marktr("Delete way {0}"); break; case RELATION: msg = marktr("Delete relation {0}"); break; } return tr(msg, primitive.getDisplayName(DefaultNameFormatter.getInstance())); } else { Set<OsmPrimitiveType> typesToDelete = getTypesToDelete(); String msg = ""; if (typesToDelete.size() > 1) { msg = trn("Delete {0} object", "Delete {0} objects", toDelete.size(), toDelete.size()); } else { OsmPrimitiveType t = typesToDelete.iterator().next(); switch (t) { case NODE: msg = trn("Delete {0} node", "Delete {0} nodes", toDelete.size(), toDelete.size()); break; case WAY: msg = trn("Delete {0} way", "Delete {0} ways", toDelete.size(), toDelete.size()); break; case RELATION: msg = trn( "Delete {0} relation", "Delete {0} relations", toDelete.size(), toDelete.size()); break; } } return msg; } }
/** * Renderer that renders the objects from an OsmPrimitive as data. * * <p>Can be used in lists and tables. * * @author imi * @author Frederik Ramm <*****@*****.**> */ public class OsmPrimitivRenderer implements ListCellRenderer, TableCellRenderer { private DefaultNameFormatter formatter = DefaultNameFormatter.getInstance(); /** Default list cell renderer - delegate for ListCellRenderer operation */ private DefaultListCellRenderer defaultListCellRenderer = new DefaultListCellRenderer(); /** Default table cell renderer - delegate for TableCellRenderer operation */ private DefaultTableCellRenderer defaultTableCellRenderer = new DefaultTableCellRenderer(); /** Adapter method supporting the ListCellRenderer interface. */ @Override public Component getListCellRendererComponent( JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { Component def = defaultListCellRenderer.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus); return renderer(def, (OsmPrimitive) value); } /** Adapter method supporting the TableCellRenderer interface. */ @Override public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { Component def = defaultTableCellRenderer.getTableCellRendererComponent( table, value, isSelected, hasFocus, row, column); if (value instanceof OsmPrimitive) return renderer(def, (OsmPrimitive) value); else if (value instanceof HistoryOsmPrimitive) return renderer(def, (HistoryOsmPrimitive) value); else return def; } /** * Internal method that stuffs information into the rendering component provided that it's a kind * of JLabel. * * @param def the rendering component * @param value the OsmPrimtive to render * @return the modified rendering component */ private Component renderer(Component def, OsmPrimitive value) { if (value != null && def instanceof JLabel) { ((JLabel) def).setText(getComponentText(value)); ImageIcon icon = ImageProvider.get(value.getDisplayType()); if (icon != null) { ((JLabel) def).setIcon(icon); } else { Main.warn("Null icon for " + value.getDisplayType()); } ((JLabel) def).setToolTipText(getComponentToolTipText(value)); } return def; } /** * Internal method that stuffs information into the rendering component provided that it's a kind * of JLabel. * * @param def the rendering component * @param value the HistoryOsmPrimtive to render * @return the modified rendering component */ private Component renderer(Component def, HistoryOsmPrimitive value) { if (value != null && def instanceof JLabel) { ((JLabel) def).setText(value.getDisplayName(DefaultNameFormatter.getInstance())); ((JLabel) def).setIcon(ImageProvider.get(value.getType())); ((JLabel) def).setToolTipText(formatter.buildDefaultToolTip(value)); } return def; } /** Can be overridden to customize the Text */ protected String getComponentText(OsmPrimitive value) { return value.getDisplayName(DefaultNameFormatter.getInstance()); } /** Can be overridden to customize the ToolTipText */ protected String getComponentToolTipText(OsmPrimitive value) { return formatter.buildDefaultToolTip(value); } }
public RecentRelationsMenuItem(Relation relation) { super(relation.getDisplayName(DefaultNameFormatter.getInstance())); this.relation = relation; addActionListener(this); }
protected Collection<Command> applyCorrections( Map<OsmPrimitive, List<TagCorrection>> tagCorrectionsMap, Map<OsmPrimitive, List<RoleCorrection>> roleCorrectionMap, String description) throws UserCancelException { if (!tagCorrectionsMap.isEmpty() || !roleCorrectionMap.isEmpty()) { Collection<Command> commands = new ArrayList<Command>(); Map<OsmPrimitive, TagCorrectionTable> tagTableMap = new HashMap<OsmPrimitive, TagCorrectionTable>(); Map<OsmPrimitive, RoleCorrectionTable> roleTableMap = new HashMap<OsmPrimitive, RoleCorrectionTable>(); final JPanel p = new JPanel(new GridBagLayout()); final JMultilineLabel label1 = new JMultilineLabel(description); label1.setMaxWidth(600); p.add(label1, GBC.eop().anchor(GBC.CENTER)); final JMultilineLabel label2 = new JMultilineLabel(tr("Please select which changes you want to apply.")); label2.setMaxWidth(600); p.add(label2, GBC.eop().anchor(GBC.CENTER)); for (Entry<OsmPrimitive, List<TagCorrection>> entry : tagCorrectionsMap.entrySet()) { final OsmPrimitive primitive = entry.getKey(); final List<TagCorrection> tagCorrections = entry.getValue(); if (tagCorrections.isEmpty()) { continue; } final JLabel propertiesLabel = new JLabel(tr("Tags of ")); p.add(propertiesLabel, GBC.std()); final JLabel primitiveLabel = new JLabel( primitive.getDisplayName(DefaultNameFormatter.getInstance()) + ":", ImageProvider.get(primitive.getDisplayType()), JLabel.LEFT); p.add(primitiveLabel, GBC.eol()); final TagCorrectionTable table = new TagCorrectionTable(tagCorrections); final JScrollPane scrollPane = new JScrollPane(table); p.add(scrollPane, GBC.eop().fill(GBC.HORIZONTAL)); tagTableMap.put(primitive, table); } for (Entry<OsmPrimitive, List<RoleCorrection>> entry : roleCorrectionMap.entrySet()) { final OsmPrimitive primitive = entry.getKey(); final List<RoleCorrection> roleCorrections = entry.getValue(); if (roleCorrections.isEmpty()) { continue; } final JLabel rolesLabel = new JLabel(tr("Roles in relations referring to")); p.add(rolesLabel, GBC.std()); final JLabel primitiveLabel = new JLabel( primitive.getDisplayName(DefaultNameFormatter.getInstance()), ImageProvider.get(primitive.getDisplayType()), JLabel.LEFT); p.add(primitiveLabel, GBC.eol()); final RoleCorrectionTable table = new RoleCorrectionTable(roleCorrections); final JScrollPane scrollPane = new JScrollPane(table); p.add(scrollPane, GBC.eop().fill(GBC.HORIZONTAL)); roleTableMap.put(primitive, table); } int answer = JOptionPane.showOptionDialog( Main.parent, p, tr("Automatic tag correction"), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, null, applicationOptions, applicationOptions[0]); if (answer == JOptionPane.YES_OPTION) { for (Entry<OsmPrimitive, List<TagCorrection>> entry : tagCorrectionsMap.entrySet()) { List<TagCorrection> tagCorrections = entry.getValue(); OsmPrimitive primitive = entry.getKey(); // create the clone OsmPrimitive clone = null; if (primitive instanceof Way) { clone = new Way((Way) primitive); } else if (primitive instanceof Node) { clone = new Node((Node) primitive); } else if (primitive instanceof Relation) { clone = new Relation((Relation) primitive); } else throw new AssertionError(); // use this structure to remember keys that have been set already so that // they're not dropped by a later step Set<String> keysChanged = new HashSet<String>(); // apply all changes to this clone for (int i = 0; i < tagCorrections.size(); i++) { if (tagTableMap.get(primitive).getCorrectionTableModel().getApply(i)) { TagCorrection tagCorrection = tagCorrections.get(i); if (tagCorrection.isKeyChanged() && !keysChanged.contains(tagCorrection.oldKey)) { clone.remove(tagCorrection.oldKey); } clone.put(tagCorrection.newKey, tagCorrection.newValue); keysChanged.add(tagCorrection.newKey); } } // save the clone if (!keysChanged.isEmpty()) { commands.add(new ChangeCommand(primitive, clone)); } } for (Entry<OsmPrimitive, List<RoleCorrection>> entry : roleCorrectionMap.entrySet()) { OsmPrimitive primitive = entry.getKey(); List<RoleCorrection> roleCorrections = entry.getValue(); for (int i = 0; i < roleCorrections.size(); i++) { RoleCorrection roleCorrection = roleCorrections.get(i); if (roleTableMap.get(primitive).getCorrectionTableModel().getApply(i)) { commands.add( new ChangeRelationMemberRoleCommand( roleCorrection.relation, roleCorrection.position, roleCorrection.newRole)); } } } } else if (answer != JOptionPane.NO_OPTION) throw new UserCancelException(); return commands; } return Collections.emptyList(); }
/** Can be overridden to customize the Text */ protected String getComponentText(OsmPrimitive value) { return value.getDisplayName(DefaultNameFormatter.getInstance()); }
static SplitWayResult doSplitWay( OsmDataLayer layer, Way way, Way wayToKeep, List<Way> newWays, List<OsmPrimitive> newSelection) { Collection<Command> commandList = new ArrayList<>(newWays.size()); Collection<String> nowarnroles = Main.pref.getCollection( "way.split.roles.nowarn", Arrays.asList( "outer", "inner", "forward", "backward", "north", "south", "east", "west")); // Change the original way final Way changedWay = new Way(way); changedWay.setNodes(wayToKeep.getNodes()); commandList.add(new ChangeCommand(way, changedWay)); if (!newSelection.contains(way)) { newSelection.add(way); } newWays.remove(wayToKeep); for (Way wayToAdd : newWays) { commandList.add(new AddCommand(layer, wayToAdd)); newSelection.add(wayToAdd); } boolean warnmerole = false; boolean warnme = false; // now copy all relations to new way also for (Relation r : OsmPrimitive.getFilteredList(way.getReferrers(), Relation.class)) { if (!r.isUsable()) { continue; } Relation c = null; String type = r.get("type"); if (type == null) { type = ""; } int i_c = 0, i_r = 0; List<RelationMember> relationMembers = r.getMembers(); for (RelationMember rm : relationMembers) { if (rm.isWay() && rm.getMember() == way) { boolean insert = true; if ("restriction".equals(type)) { /* this code assumes the restriction is correct. No real error checking done */ String role = rm.getRole(); if ("from".equals(role) || "to".equals(role)) { OsmPrimitive via = null; for (RelationMember rmv : r.getMembers()) { if ("via".equals(rmv.getRole())) { via = rmv.getMember(); } } List<Node> nodes = new ArrayList<>(); if (via != null) { if (via instanceof Node) { nodes.add((Node) via); } else if (via instanceof Way) { nodes.add(((Way) via).lastNode()); nodes.add(((Way) via).firstNode()); } } Way res = null; for (Node n : nodes) { if (changedWay.isFirstLastNode(n)) { res = way; } } if (res == null) { for (Way wayToAdd : newWays) { for (Node n : nodes) { if (wayToAdd.isFirstLastNode(n)) { res = wayToAdd; } } } if (res != null) { if (c == null) { c = new Relation(r); } c.addMember(new RelationMember(role, res)); c.removeMembersFor(way); insert = false; } } else { insert = false; } } else if (!"via".equals(role)) { warnme = true; } } else if (!("route".equals(type)) && !("multipolygon".equals(type))) { warnme = true; } if (c == null) { c = new Relation(r); } if (insert) { if (rm.hasRole() && !nowarnroles.contains(rm.getRole())) { warnmerole = true; } Boolean backwards = null; int k = 1; while (i_r - k >= 0 || i_r + k < relationMembers.size()) { if ((i_r - k >= 0) && relationMembers.get(i_r - k).isWay()) { Way w = relationMembers.get(i_r - k).getWay(); if ((w.lastNode() == way.firstNode()) || w.firstNode() == way.firstNode()) { backwards = Boolean.FALSE; } else if ((w.firstNode() == way.lastNode()) || w.lastNode() == way.lastNode()) { backwards = Boolean.TRUE; } break; } if ((i_r + k < relationMembers.size()) && relationMembers.get(i_r + k).isWay()) { Way w = relationMembers.get(i_r + k).getWay(); if ((w.lastNode() == way.firstNode()) || w.firstNode() == way.firstNode()) { backwards = Boolean.TRUE; } else if ((w.firstNode() == way.lastNode()) || w.lastNode() == way.lastNode()) { backwards = Boolean.FALSE; } break; } k++; } int j = i_c; for (Way wayToAdd : newWays) { RelationMember em = new RelationMember(rm.getRole(), wayToAdd); j++; if ((backwards != null) && backwards) { c.addMember(i_c, em); } else { c.addMember(j, em); } } i_c = j; } } i_c++; i_r++; } if (c != null) { commandList.add(new ChangeCommand(layer, r, c)); } } if (warnmerole) { new Notification( tr( "A role based relation membership was copied to all new ways.<br>You should verify this and correct it when necessary.")) .setIcon(JOptionPane.WARNING_MESSAGE) .show(); } else if (warnme) { new Notification( tr( "A relation membership was copied to all new ways.<br>You should verify this and correct it when necessary.")) .setIcon(JOptionPane.WARNING_MESSAGE) .show(); } return new SplitWayResult( new SequenceCommand( /* for correct i18n of plural forms - see #9110 */ trn( "Split way {0} into {1} part", "Split way {0} into {1} parts", newWays.size(), way.getDisplayName(DefaultNameFormatter.getInstance()), newWays.size()), commandList), newSelection, way, newWays); }
protected void renderPrimitive(RelationMember member) { String displayName = member.getMember().getDisplayName(DefaultNameFormatter.getInstance()); setText(displayName); setToolTipText(DefaultNameFormatter.getInstance().buildDefaultToolTip(member.getMember())); setIcon(ImageProvider.get(member.getDisplayType())); }
/** * Renderer that renders the objects from an OsmPrimitive as data. * * <p>Can be used in lists and tables. * * @author imi * @author Frederik Ramm */ public class OsmPrimitivRenderer implements ListCellRenderer<OsmPrimitive>, TableCellRenderer { private final DefaultNameFormatter formatter = DefaultNameFormatter.getInstance(); /** Default list cell renderer - delegate for ListCellRenderer operation */ private final DefaultListCellRenderer defaultListCellRenderer = new DefaultListCellRenderer(); /** Default table cell renderer - delegate for TableCellRenderer operation */ private final DefaultTableCellRenderer defaultTableCellRenderer = new DefaultTableCellRenderer(); /** Adapter method supporting the ListCellRenderer interface. */ @Override public Component getListCellRendererComponent( JList<? extends OsmPrimitive> list, OsmPrimitive value, int index, boolean isSelected, boolean cellHasFocus) { Component def = defaultListCellRenderer.getListCellRendererComponent( list, null, index, isSelected, cellHasFocus); return renderer(def, value, list.getModel().getSize() > 1000); } /** Adapter method supporting the TableCellRenderer interface. */ @Override public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { Component def = defaultTableCellRenderer.getTableCellRendererComponent( table, value, isSelected, hasFocus, row, column); if (value instanceof OsmPrimitive) return renderer(def, (OsmPrimitive) value, table.getModel().getRowCount() > 1000); else if (value instanceof HistoryOsmPrimitive) return renderer(def, (HistoryOsmPrimitive) value); else return def; } /** * Internal method that stuffs information into the rendering component provided that it's a kind * of JLabel. * * @param def the rendering component * @param value the OsmPrimitive to render * @param fast whether the icons should be loaded fast since many items are being displayed * @return the modified rendering component */ private Component renderer(Component def, OsmPrimitive value, boolean fast) { if (value != null && def instanceof JLabel) { ((JLabel) def).setText(getComponentText(value)); final ImageIcon icon = fast ? ImageProvider.get(value.getType()) : ImageProvider.getPadded( value, // Height of component no yet known, assume the default 16px. ImageProvider.ImageSizes.SMALLICON.getImageDimension()); if (icon != null) { ((JLabel) def).setIcon(icon); } else { Main.warn("Null icon for " + value.getDisplayType()); } ((JLabel) def).setToolTipText(getComponentToolTipText(value)); } return def; } /** * Internal method that stuffs information into the rendering component provided that it's a kind * of JLabel. * * @param def the rendering component * @param value the HistoryOsmPrimitive to render * @return the modified rendering component */ private Component renderer(Component def, HistoryOsmPrimitive value) { if (value != null && def instanceof JLabel) { ((JLabel) def).setText(value.getDisplayName(DefaultNameFormatter.getInstance())); ((JLabel) def).setIcon(ImageProvider.get(value.getType())); ((JLabel) def).setToolTipText(formatter.buildDefaultToolTip(value)); } return def; } /** * Returns the text representing an OSM primitive in a component. Can be overridden to customize * the text * * @param value OSM primitive * @return text representing the OSM primitive */ protected String getComponentText(OsmPrimitive value) { return value.getDisplayName(DefaultNameFormatter.getInstance()); } /** * Returns the text representing an OSM primitive in a tooltip. Can be overridden to customize the * ToolTipText * * @param value OSM primitive * @return text representing the OSM primitive */ protected String getComponentToolTipText(OsmPrimitive value) { return formatter.buildDefaultToolTip(value); } }