001package jmri.jmrit.roster;
002
003import java.awt.Graphics;
004import java.awt.geom.AffineTransform;
005import java.awt.image.AffineTransformOp;
006import java.awt.image.BufferedImage;
007import java.util.HashMap;
008
009import javax.swing.ImageIcon;
010
011import jmri.InstanceManagerAutoDefault;
012
013/**
014 * Generate and cache icons at a given height. A managed instance will generate
015 * icons for a default height, while unmanaged instances can be created to
016 * generate icons at different heights.
017 * <hr>
018 * This file is part of JMRI.
019 * <p>
020 * JMRI is free software; you can redistribute it and/or modify it under the
021 * terms of version 2 of the GNU General Public License as published by the Free
022 * Software Foundation. See the "COPYING" file for a copy of this license.
023 * <p>
024 * JMRI is distributed in the hope that it will be useful, but WITHOUT ANY
025 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
026 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
027 *
028 * @author Lionel Jeanson Copyright (C) 2009
029 */
030public class RosterIconFactory implements InstanceManagerAutoDefault {
031
032    private final int iconHeight;
033    HashMap<String, ImageIcon> icons = new HashMap<>();
034
035    public RosterIconFactory(int h) {
036        iconHeight = h;
037    }
038
039    public RosterIconFactory() {
040        iconHeight = 19; // OS X, because of Apple look'n feel constraints, ComboBox cannot be higher than this 19pixels
041    }
042
043    public ImageIcon getIcon(String id) {
044        if (id == null) {
045            return null;
046        }
047        RosterEntry re = Roster.getDefault().entryFromTitle(id);
048        if (re == null) {
049            return null;
050        }
051        return getIcon(re);
052    }
053    
054    public ImageIcon getReversedIcon(String id) {
055        if (id == null) {
056            return null;
057        }
058        RosterEntry re = Roster.getDefault().entryFromTitle(id);
059        if (re == null) {
060            return null;
061        }
062        return getReversedIcon(re);
063    }
064
065    public ImageIcon getIcon(RosterEntry re) {
066        if ((re == null) || (re.getIconPath() == null)) {
067            return null;
068        }
069
070        ImageIcon icon = icons.get(re.getIconPath());
071        if (icon == null) {
072            icon = new ImageIcon(re.getIconPath(), re.getId());
073            /* icon can not be null
074             if (icon==null)
075             return null;
076             */
077            icon.setImage(icon.getImage().getScaledInstance(-1, iconHeight, java.awt.Image.SCALE_FAST));
078            icons.put(re.getIconPath(), icon);
079        }
080        return icon;
081    }
082    
083    public ImageIcon getReversedIcon(RosterEntry re) {
084        if ((re == null) || (re.getIconPath() == null)) {
085            return null;
086        }
087
088        ImageIcon revicon = icons.get("rev_"+re.getIconPath());
089        if (revicon == null) {
090            ImageIcon icon = getIcon(re);
091            if (icon==null) {
092                return null;
093            }
094            // Flip the image horizontally
095            AffineTransform tx = AffineTransform.getScaleInstance(-1, 1);
096            tx.translate(-icon.getImage().getWidth(null), 0);
097            AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
098            BufferedImage bi = new BufferedImage( icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB);
099            Graphics g = bi.createGraphics();
100            icon.paintIcon(null, g, 0,0);
101            g.dispose();            
102            revicon = new ImageIcon();
103            revicon.setImage(op.filter( bi, null).getScaledInstance(-1, iconHeight, java.awt.Image.SCALE_FAST));
104            icons.put("rev_"+re.getIconPath(), revicon);
105        }
106        return revicon;
107    }
108}