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