001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.history;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.awt.Color;
007import java.awt.Component;
008import java.util.EnumMap;
009import java.util.Map;
010
011import javax.swing.ImageIcon;
012import javax.swing.JLabel;
013import javax.swing.JTable;
014import javax.swing.table.TableCellRenderer;
015
016import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
017import org.openstreetmap.josm.data.osm.RelationMemberData;
018import org.openstreetmap.josm.gui.history.TwoColumnDiff.Item;
019import org.openstreetmap.josm.tools.ImageProvider;
020
021/**
022 * The {@link TableCellRenderer} for a list of relation members in {@link HistoryBrowser}.
023 * @since 1709
024 */
025public class RelationMemberListTableCellRenderer extends JLabel implements TableCellRenderer {
026
027    public static final Color BGCOLOR_EMPTY_ROW = new Color(234, 234, 234);
028    public static final Color BGCOLOR_NOT_IN_OPPOSITE = new Color(255, 197, 197);
029    public static final Color BGCOLOR_IN_OPPOSITE = new Color(255, 234, 213);
030    public static final Color BGCOLOR_SELECTED = new Color(143, 170, 255);
031
032    private transient Map<OsmPrimitiveType, ImageIcon> icons;
033
034    /**
035     * Constructs a new {@code RelationMemberListTableCellRenderer}.
036     */
037    public RelationMemberListTableCellRenderer() {
038        setOpaque(true);
039        icons = new EnumMap<>(OsmPrimitiveType.class);
040        icons.put(OsmPrimitiveType.NODE, ImageProvider.get("data", "node"));
041        icons.put(OsmPrimitiveType.WAY, ImageProvider.get("data", "way"));
042        icons.put(OsmPrimitiveType.RELATION, ImageProvider.get("data", "relation"));
043    }
044
045    protected void renderIcon(RelationMemberData member) {
046        if (member == null) {
047            setIcon(null);
048        } else {
049            setIcon(icons.get(member.getMemberType()));
050        }
051    }
052
053    protected void renderRole(Item diffItem) {
054        String text = "";
055        Color bgColor = diffItem.state.getColor();
056        RelationMemberData member = (RelationMemberData) diffItem.value;
057        text = member == null ? "" : member.getRole();
058        setText(text);
059        setToolTipText(text);
060        setBackground(bgColor);
061    }
062
063    protected void renderPrimitive(Item diffItem) {
064        String text = "";
065        Color bgColor = diffItem.state.getColor();
066        RelationMemberData member = (RelationMemberData) diffItem.value;
067        text = "";
068        if (member != null) {
069            switch(member.getMemberType()) {
070            case NODE: text = tr("Node {0}", member.getMemberId()); break;
071            case WAY: text = tr("Way {0}", member.getMemberId()); break;
072            case RELATION: text = tr("Relation {0}", member.getMemberId()); break;
073            }
074        }
075        setText(text);
076        setToolTipText(text);
077        setBackground(bgColor);
078    }
079
080    // Warning: The model pads with null-rows to match the size of the opposite table. 'value' could be null
081    @Override
082    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
083            int row, int column) {
084
085        Item member = (TwoColumnDiff.Item) value;
086        renderIcon((RelationMemberData) member.value);
087        switch(column) {
088        case 0:
089            renderRole(member);
090            break;
091        case 1:
092            renderPrimitive(member);
093            break;
094        }
095
096        return this;
097    }
098}