Changeset 5054 in josm


Ignore:
Timestamp:
2012-03-08T12:11:38+01:00 (12 years ago)
Author:
bastiK
Message:

see #6797: load map images in background, in case they are loaded over a network. Show temporary image in the meantime.

Location:
trunk/src/org/openstreetmap/josm
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPainter.java

    r5045 r5054  
    2222import java.awt.geom.Point2D;
    2323import java.awt.geom.Rectangle2D;
    24 import java.awt.image.BufferedImage;
    2524import java.util.Arrays;
    2625import java.util.Collection;
     
    738737         *
    739738         */
     739        Rectangle box = bs.getBox();
    740740        if (bs.hAlign == HorizontalTextAlignment.RIGHT) {
    741             x += bs.box.x + bs.box.width + 2;
     741            x += box.x + box.width + 2;
    742742        } else {
    743743            FontRenderContext frc = g.getFontRenderContext();
     
    747747                x -= textWidth / 2;
    748748            } else if (bs.hAlign == HorizontalTextAlignment.LEFT) {
    749                 x -= - bs.box.x + 4 + textWidth;
     749                x -= - box.x + 4 + textWidth;
    750750            } else throw new AssertionError();
    751751        }
    752752
    753753        if (bs.vAlign == VerticalTextAlignment.BOTTOM) {
    754             y += bs.box.y + bs.box.height;
     754            y += box.y + box.height;
    755755        } else {
    756756            FontRenderContext frc = g.getFontRenderContext();
    757757            LineMetrics metrics = text.font.getLineMetrics(s, frc);
    758758            if (bs.vAlign == VerticalTextAlignment.ABOVE) {
    759                 y -= - bs.box.y + metrics.getDescent();
     759                y -= - box.y + metrics.getDescent();
    760760            } else if (bs.vAlign == VerticalTextAlignment.TOP) {
    761                 y -= - bs.box.y - metrics.getAscent();
     761                y -= - box.y - metrics.getAscent();
    762762            } else if (bs.vAlign == VerticalTextAlignment.CENTER) {
    763763                y += (metrics.getAscent() - metrics.getDescent()) / 2;
    764764            } else if (bs.vAlign == VerticalTextAlignment.BELOW) {
    765                 y += bs.box.y + bs.box.height + metrics.getAscent() + 2;
     765                y += box.y + box.height + metrics.getAscent() + 2;
    766766            } else throw new AssertionError();
    767767        }
     
    803803    }
    804804
    805     public void drawArea(Way w, Color color, MapImage<BufferedImage> fillImage, TextElement text) {
     805    public void drawArea(Way w, Color color, MapImage fillImage, TextElement text) {
    806806        drawArea(w, getPath(w), color, fillImage, text);
    807807    }
    808808
    809     protected void drawArea(OsmPrimitive osm, Path2D.Double path, Color color, MapImage<BufferedImage> fillImage, TextElement text) {
     809    protected void drawArea(OsmPrimitive osm, Path2D.Double path, Color color, MapImage fillImage, TextElement text) {
    810810
    811811        Shape area = path.createTransformedShape(nc.getAffineTransform());
     
    816816                g.fill(area);
    817817            } else {
    818                 TexturePaint texture = new TexturePaint(fillImage.img,
     818                TexturePaint texture = new TexturePaint(fillImage.getImage(),
    819819                        //                        new Rectangle(polygon.xpoints[0], polygon.ypoints[0], fillImage.getWidth(), fillImage.getHeight()));
    820                         new Rectangle(0, 0, fillImage.img.getWidth(null), fillImage.img.getHeight(null)));
     820                        new Rectangle(0, 0, fillImage.getWidth(), fillImage.getHeight()));
    821821                g.setPaint(texture);
    822822                Float alpha = Utils.color_int2float(fillImage.alpha);
     
    873873    }
    874874
    875     public void drawArea(Relation r, Color color, MapImage<BufferedImage> fillImage, TextElement text) {
     875    public void drawArea(Relation r, Color color, MapImage fillImage, TextElement text) {
    876876        Multipolygon multipolygon = MultipolygonCache.getInstance().get(nc, r);
    877877        if (!r.isDisabled() && !multipolygon.getOuterWays().isEmpty()) {
     
    915915    }
    916916
    917     public void drawRestriction(Relation r, MapImage<Image> icon) {
     917    public void drawRestriction(Relation r, MapImage icon) {
    918918        Way fromWay = null;
    919919        Way toWay = null;
     
    10861086        }
    10871087
    1088         drawRestriction(inactive || r.isDisabled() ? icon.getDisabled() : icon.img,
     1088        drawRestriction(inactive || r.isDisabled() ? icon.getDisabled() : icon.getImage(),
    10891089                pVia, vx, vx2, vy, vy2, iconAngle, r.isSelected());
    10901090    }
  • trunk/src/org/openstreetmap/josm/gui/MapView.java

    r4627 r5054  
    460460     * Draw the component.
    461461     */
    462     @Override public void paint(Graphics g) {
     462    @Override public synchronized void paint(Graphics g) {
    463463        if (BugReportExceptionHandler.exceptionHandlingInProgress())
    464464            return;
     
    833833    }
    834834
    835     public void preferenceChanged(PreferenceChangeEvent e) {
     835    public synchronized void preferenceChanged(PreferenceChangeEvent e) {
    836836        paintPreferencesChanged = true;
    837837    }
  • trunk/src/org/openstreetmap/josm/gui/mappaint/AreaElemStyle.java

    r4960 r5054  
    55
    66import java.awt.Color;
    7 import java.awt.image.BufferedImage;
    8 
    9 import javax.swing.ImageIcon;
    107
    118import org.openstreetmap.josm.Main;
     
    2724     */
    2825    public Color color;
    29     public MapImage<BufferedImage> fillImage;
     26    public MapImage fillImage;
    3027    public TextElement text;
    3128
    32     protected AreaElemStyle(Cascade c, Color color, MapImage<BufferedImage> fillImage, TextElement text) {
     29    protected AreaElemStyle(Cascade c, Color color, MapImage fillImage, TextElement text) {
    3330        super(c, -1000f);
    3431        CheckParameterUtil.ensureParameterNotNull(color);
     
    3936
    4037    public static AreaElemStyle create(Cascade c) {
    41         MapImage<BufferedImage> fillImage = null;
     38        MapImage fillImage = null;
    4239        Color color = null;
    4340
    4441        IconReference iconRef = c.get("fill-image", null, IconReference.class);
    4542        if (iconRef != null) {
    46             ImageIcon icon = MapPaintStyles.getIcon(iconRef, -1, -1);
    47             if (icon != null) {
    48                 if (!(icon.getImage() instanceof BufferedImage))
    49                     throw new RuntimeException();
    50                 fillImage = new MapImage<BufferedImage>(iconRef.iconName, iconRef.source);
    51                 fillImage.img = (BufferedImage) icon.getImage();
     43            fillImage = new MapImage(iconRef.iconName, iconRef.source);
     44            fillImage.getImage();
    5245
    53                 color = new Color(fillImage.img.getRGB(
    54                         fillImage.img.getWidth() / 2, fillImage.img.getHeight() / 2)
    55                 );
     46            color = new Color(fillImage.getImage().getRGB(
     47                    fillImage.getWidth() / 2, fillImage.getHeight() / 2)
     48            );
    5649
    57                 fillImage.alpha = Math.min(255, Math.max(0, Integer.valueOf(Main.pref.getInteger("mappaint.fill-image-alpha", 255))));
    58                 Integer pAlpha = Utils.color_float2int(c.get("fill-opacity", null, float.class));
    59                 if (pAlpha != null) {
    60                     fillImage.alpha = pAlpha;
    61                 }
     50            fillImage.alpha = Math.min(255, Math.max(0, Integer.valueOf(Main.pref.getInteger("mappaint.fill-image-alpha", 255))));
     51            Integer pAlpha = Utils.color_float2int(c.get("fill-opacity", null, float.class));
     52            if (pAlpha != null) {
     53                fillImage.alpha = pAlpha;
    6254            }
    6355        } else {
     
    7870            text = TextElement.create(c, PaintColors.AREA_TEXT.get(), true);
    7971        }
    80        
     72
    8173        if (color != null)
    8274            return new AreaElemStyle(c, color, fillImage, text);
  • trunk/src/org/openstreetmap/josm/gui/mappaint/BoxTextElemStyle.java

    r4869 r5054  
    2222    public enum VerticalTextAlignment { ABOVE, TOP, CENTER, BOTTOM, BELOW }
    2323
     24    public static interface BoxProvider {
     25        BoxProviderResult get();
     26    }
     27
     28    public static class BoxProviderResult {
     29        private Rectangle box;
     30        private boolean temporary;
     31
     32        public BoxProviderResult(Rectangle box, boolean temporary) {
     33            this.box = box;
     34            this.temporary = temporary;
     35        }
     36
     37        /**
     38         * The box
     39         */
     40        public Rectangle getBox() {
     41            return box;
     42        }
     43
     44        /**
     45         * True, if the box can change in future calls of the BoxProvider get() method
     46         */
     47        public boolean isTemporary() {
     48            return temporary;
     49        }
     50    }
     51
     52    public static class SimpleBoxProvider implements BoxProvider {
     53        private Rectangle box;
     54
     55        public SimpleBoxProvider(Rectangle box) {
     56            this.box = box;
     57        }
     58
     59        @Override
     60        public BoxProviderResult get() {
     61            return new BoxProviderResult(box, false);
     62        }
     63
     64        @Override
     65        public int hashCode() {
     66            return box.hashCode();
     67        }
     68
     69        @Override
     70        public boolean equals(Object obj) {
     71            if (obj == null || !(obj instanceof BoxProvider))
     72                return false;
     73            final BoxProvider other = (BoxProvider) obj;
     74            BoxProviderResult resultOther = other.get();
     75            if (resultOther.isTemporary()) return false;
     76            return box.equals(resultOther.getBox());
     77        }
     78    }
     79
    2480    public static final Rectangle ZERO_BOX = new Rectangle(0, 0, 0, 0);
    2581
    2682    public TextElement text;
    27     public Rectangle box;
     83    // Either boxProvider or box is not null. If boxProvider is different from
     84    // null, this means, that the box can still change in future, otherwise
     85    // it is fixed.
     86    protected BoxProvider boxProvider;
     87    protected Rectangle box;
    2888    public HorizontalTextAlignment hAlign;
    2989    public VerticalTextAlignment vAlign;
    3090
    31     public BoxTextElemStyle(Cascade c, TextElement text, Rectangle box, HorizontalTextAlignment hAlign, VerticalTextAlignment vAlign) {
     91    public BoxTextElemStyle(Cascade c, TextElement text, BoxProvider boxProvider, Rectangle box, HorizontalTextAlignment hAlign, VerticalTextAlignment vAlign) {
    3292        super(c, 2000f);
    3393        CheckParameterUtil.ensureParameterNotNull(text);
     
    3595        CheckParameterUtil.ensureParameterNotNull(vAlign);
    3696        this.text = text;
     97        this.boxProvider = boxProvider;
    3798        this.box = box == null ? ZERO_BOX : box;
    3899        this.hAlign = hAlign;
     
    40101    }
    41102
     103    public static BoxTextElemStyle create(Environment env, BoxProvider boxProvider) {
     104        return create(env, boxProvider, null);
     105    }
     106
    42107    public static BoxTextElemStyle create(Environment env, Rectangle box) {
     108        return create(env, null, box);
     109    }
     110
     111    public static BoxTextElemStyle create(Environment env, BoxProvider boxProvider, Rectangle box) {
    43112        initDefaultParameters();
    44113        Cascade c = env.mc.getCascade(env.layer);
     
    74143        }
    75144
    76         return new BoxTextElemStyle(c, text, box, hAlign, vAlign);
     145        return new BoxTextElemStyle(c, text, boxProvider, box, hAlign, vAlign);
     146    }
     147
     148    public Rectangle getBox() {
     149        if (boxProvider != null) {
     150            BoxProviderResult result = boxProvider.get();
     151            if (!result.isTemporary()) {
     152                box = result.getBox();
     153                boxProvider = null;
     154            }
     155            return result.getBox();
     156        }
     157        return box;
    77158    }
    78159
     
    84165        Node n = new Node();
    85166        n.put("name", "dummy");
    86         SIMPLE_NODE_TEXT_ELEMSTYLE = create(new Environment(n, mc, "default", null), NodeElemStyle.SIMPLE_NODE_ELEMSTYLE.getBox());
     167        SIMPLE_NODE_TEXT_ELEMSTYLE = create(new Environment(n, mc, "default", null), NodeElemStyle.SIMPLE_NODE_ELEMSTYLE.getBoxProvider());
    87168        if (SIMPLE_NODE_TEXT_ELEMSTYLE == null) throw new AssertionError();
    88169    }
     
    113194            return false;
    114195        final BoxTextElemStyle other = (BoxTextElemStyle) obj;
    115         return text.equals(other.text) &&
    116                 box.equals(other.box) &&
    117                 hAlign == other.hAlign &&
    118                 vAlign == other.vAlign;
     196        if (!text.equals(other.text)) return false;
     197        if (boxProvider != null) {
     198            if (!boxProvider.equals(other.boxProvider)) return false;
     199        } else if (other.boxProvider != null) {
     200            return false;
     201        } else {
     202            if (!box.equals(other.box)) return false;
     203        }
     204        if (hAlign != other.hAlign) return false;
     205        if (vAlign != other.vAlign) return false;
     206        return true;
    119207    }
    120208
     
    123211        int hash = super.hashCode();
    124212        hash = 97 * hash + text.hashCode();
    125         hash = 97 * hash + box.hashCode();
     213        if (boxProvider != null) {
     214            hash = 97 * hash + boxProvider.hashCode();
     215        } else {
     216            hash = 97 * hash + box.hashCode();
     217        }
    126218        hash = 97 * hash + hAlign.hashCode();
    127219        hash = 97 * hash + vAlign.hashCode();
  • trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java

    r4682 r5054  
    2929    private boolean defaultNodes, defaultLines;
    3030    private int defaultNodesIdx, defaultLinesIdx;
    31    
     31
    3232    public ElemStyles()
    3333    {
     
    317317                if (nodeStyle != null) {
    318318                    sl.add(nodeStyle);
    319                     addIfNotNull(sl, BoxTextElemStyle.create(env, nodeStyle.getBox()));
     319                    addIfNotNull(sl, BoxTextElemStyle.create(env, nodeStyle.getBoxProvider()));
    320320                } else {
    321                     addIfNotNull(sl, BoxTextElemStyle.create(env, NodeElemStyle.SIMPLE_NODE_ELEMSTYLE.getBox()));
     321                    addIfNotNull(sl, BoxTextElemStyle.create(env, NodeElemStyle.SIMPLE_NODE_ELEMSTYLE.getBoxProvider()));
    322322                }
    323323            } else if (osm instanceof Relation) {
  • trunk/src/org/openstreetmap/josm/gui/mappaint/LinePatternElemStyle.java

    r4822 r5054  
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.gui.mappaint;
    3 
    4 import java.awt.Image;
    5 
    6 import javax.swing.ImageIcon;
    73
    84import org.openstreetmap.josm.data.osm.OsmPrimitive;
     
    1713public class LinePatternElemStyle extends ElemStyle {
    1814
    19     public MapImage<Image> pattern;
     15    public MapImage pattern;
    2016
    21     public LinePatternElemStyle(Cascade c, MapImage<Image> pattern) {
     17    public LinePatternElemStyle(Cascade c, MapImage pattern) {
    2218        super(c, -1f);
    2319        this.pattern = pattern;
     
    3026        if (iconRef == null)
    3127            return null;
    32         ImageIcon icon = MapPaintStyles.getIcon(iconRef, -1, -1);
    33         if (icon == null)
    34             return null;
    35         MapImage<Image> pattern = new MapImage<Image>(iconRef.iconName, iconRef.source);
    36         pattern.img = icon.getImage();
     28        MapImage pattern = new MapImage(iconRef.iconName, iconRef.source);
    3729        return new LinePatternElemStyle(c, pattern);
    3830    }
     
    4133    public void paintPrimitive(OsmPrimitive primitive, MapPaintSettings paintSettings, MapPainter painter, boolean selected, boolean member) {
    4234        Way w = (Way)primitive;
    43         painter.drawLinePattern(w, pattern.img);
     35        painter.drawLinePattern(w, pattern.getImage());
    4436    }
    4537
  • trunk/src/org/openstreetmap/josm/gui/mappaint/MapImage.java

    r4823 r5054  
    33
    44import static org.openstreetmap.josm.tools.Utils.equal;
     5
    56import java.awt.Image;
     7import java.awt.Rectangle;
     8import java.awt.image.BufferedImage;
    69
    710import javax.swing.GrayFilter;
    811import javax.swing.ImageIcon;
    912
    10 public class MapImage<I extends Image> {
     13import org.openstreetmap.josm.Main;
     14import org.openstreetmap.josm.gui.mappaint.BoxTextElemStyle.BoxProvider;
     15import org.openstreetmap.josm.gui.mappaint.BoxTextElemStyle.BoxProviderResult;
     16import org.openstreetmap.josm.tools.ImageProvider;
     17import org.openstreetmap.josm.tools.ImageProvider.ImageCallback;
     18import org.openstreetmap.josm.tools.Utils;
     19
     20public class MapImage {
    1121    /**
    1222     * ImageIcon can chage while the image is loading.
    1323     */
    14     public I img;
    15 
    16     public int alpha = 255;
     24    private BufferedImage img;
    1725
    1826    /**
    19      * The 4 following fields are only used to check for equality.
     27     * The 5 following fields are only used to check for equality.
    2028     */
     29    public int alpha = 255;
    2130    public String name;
    2231    public StyleSource source;
     
    2433    public int height = -1;
    2534
     35    private boolean temporary;
    2636    private Image disabledImg;
    2737
     
    3747    }
    3848
    39     // img changes when image is fully loaded and can't be used for equality check.
     49    public BufferedImage getImage() {
     50        if (img != null)
     51            return img;
     52        temporary = false;
     53        new ImageProvider(name)
     54                .setDirs(MapPaintStyles.getIconSourceDirs(source))
     55                .setId("mappaint."+source.getPrefName())
     56                .setArchive(source.zipIcons)
     57                .setWidth(width)
     58                .setHeight(height)
     59                .setOptional(true)
     60                .getInBackground(new ImageCallback() {
     61                    @Override
     62                    public void finished(ImageIcon result) {
     63                        synchronized (MapImage.this) {
     64                            if (result == null) {
     65                                img = (BufferedImage) MapPaintStyles.getNoIcon_Icon(source).getImage();
     66                            } else {
     67                                img = (BufferedImage) result.getImage();
     68                            }
     69                            if (temporary) {
     70                                Main.map.mapView.preferenceChanged(null); // otherwise repaint is ignored, because layer hasn't changed
     71                                Main.map.mapView.repaint();
     72                            }
     73                            temporary = false;
     74                        }
     75                    }
     76                }
     77        );
     78        synchronized (this) {
     79            if (img == null) {
     80                img = (BufferedImage) ImageProvider.get("clock").getImage();
     81                temporary = true;
     82            }
     83        }
     84        return img;
     85    }
     86
     87    public int getWidth() {
     88        return getImage().getWidth(null);
     89    }
     90
     91    public int getHeight() {
     92        return getImage().getHeight(null);
     93    }
     94
     95    public float getAlphaFloat() {
     96        return Utils.color_int2float(alpha);
     97    }
     98
     99    /**
     100     * Returns true, if image is not completely loaded and getImage() returns a temporary image.
     101     */
     102    public boolean isTemporary() {
     103        return temporary;
     104    }
     105
     106    protected class MapImageBoxProvider implements BoxProvider {
     107        @Override
     108        public BoxProviderResult get() {
     109            return new BoxProviderResult(box(), temporary);
     110        }
     111
     112        private Rectangle box() {
     113            int w = getWidth(), h = getHeight();
     114            return new Rectangle(-w/2, -h/2, w, h);
     115        }
     116
     117        private MapImage getParent() {
     118            return MapImage.this;
     119        }
     120
     121        @Override
     122        public int hashCode() {
     123            return MapImage.this.hashCode();
     124        }
     125
     126        @Override
     127        public boolean equals(Object obj) {
     128            if (obj == null || !(obj instanceof BoxProvider))
     129                return false;
     130            if (obj instanceof MapImageBoxProvider) {
     131                MapImageBoxProvider other = (MapImageBoxProvider) obj;
     132                return MapImage.this.equals(other.getParent());
     133            } else if (temporary) {
     134                return false;
     135            } else {
     136                final BoxProvider other = (BoxProvider) obj;
     137                BoxProviderResult resultOther = other.get();
     138                if (resultOther.isTemporary()) return false;
     139                return box().equals(resultOther.getBox());
     140            }
     141        }
     142    }
     143
     144    public BoxProvider getBoxProvider() {
     145        return new MapImageBoxProvider();
     146    }
     147
    40148    @Override
    41149    public boolean equals(Object obj) {
     
    43151            return false;
    44152        final MapImage other = (MapImage) obj;
     153        // img changes when image is fully loaded and can't be used for equality check.
    45154        return  alpha == other.alpha &&
    46155                equal(name, other.name) &&
  • trunk/src/org/openstreetmap/josm/gui/mappaint/MapPaintStyles.java

    r4968 r5054  
    119119    }
    120120
    121     private static List<String> getIconSourceDirs(StyleSource source) {
     121    public static List<String> getIconSourceDirs(StyleSource source) {
    122122        List<String> dirs = new LinkedList<String>();
    123123
  • trunk/src/org/openstreetmap/josm/gui/mappaint/NodeElemStyle.java

    r4822 r5054  
    66import java.awt.BasicStroke;
    77import java.awt.Color;
    8 import java.awt.Image;
    98import java.awt.Rectangle;
    109import java.awt.Stroke;
    11 
    12 import javax.swing.ImageIcon;
    1310
    1411import org.openstreetmap.josm.Main;
     
    2017import org.openstreetmap.josm.gui.mappaint.MapPaintStyles.IconReference;
    2118import org.openstreetmap.josm.gui.mappaint.StyleCache.StyleList;
     19import org.openstreetmap.josm.gui.mappaint.BoxTextElemStyle.BoxProvider;
     20import org.openstreetmap.josm.gui.mappaint.BoxTextElemStyle.SimpleBoxProvider;
    2221import org.openstreetmap.josm.tools.Pair;
    2322import org.openstreetmap.josm.tools.Utils;
     
    2726 */
    2827public class NodeElemStyle extends ElemStyle {
    29     public MapImage<Image> mapImage;
     28    public MapImage mapImage;
    3029    public Symbol symbol;
    31 
    32     private ImageIcon disabledIcon;
    3330
    3431    public enum SymbolShape { SQUARE, CIRCLE, TRIANGLE, PENTAGON, HEXAGON, HEPTAGON, OCTAGON, NONAGON, DECAGON }
     
    9592    public static final StyleList DEFAULT_NODE_STYLELIST_TEXT = new StyleList(NodeElemStyle.SIMPLE_NODE_ELEMSTYLE, BoxTextElemStyle.SIMPLE_NODE_TEXT_ELEMSTYLE);
    9693
    97     protected NodeElemStyle(Cascade c, MapImage<Image> mapImage, Symbol symbol) {
     94    protected NodeElemStyle(Cascade c, MapImage mapImage, Symbol symbol) {
    9895        super(c, 1000f);
    9996        this.mapImage = mapImage;
     
    108105        Cascade c = env.mc.getCascade(env.layer);
    109106
    110         MapImage<Image> mapImage = createIcon(env);
     107        MapImage mapImage = createIcon(env);
    111108        Symbol symbol = null;
    112109        if (mapImage == null) {
     
    122119    }
    123120
    124     private static MapImage<Image> createIcon(Environment env) {
     121    private static MapImage createIcon(Environment env) {
    125122        Cascade c = env.mc.getCascade(env.layer);
    126123        Cascade c_def = env.mc.getCascade("default");
    127124
    128         IconReference iconRef = c.get("icon-image", null, IconReference.class);
     125        final IconReference iconRef = c.get("icon-image", null, IconReference.class);
    129126        if (iconRef == null)
    130127            return null;
     
    145142        int height = heightF == null ? -1 : Math.round(heightF);
    146143
    147         MapImage<Image> mapImage = new MapImage<Image>(iconRef.iconName, iconRef.source);
    148 
    149         ImageIcon icon = MapPaintStyles.getIcon(iconRef, width, height);
    150         if (icon == null) {
    151             mapImage.img = MapPaintStyles.getNoIcon_Icon(iconRef.source).getImage();
    152         } else {
    153             mapImage.img = icon.getImage();
    154             mapImage.alpha = Math.min(255, Math.max(0, Integer.valueOf(Main.pref.getInteger("mappaint.icon-image-alpha", 255))));
    155             Integer pAlpha = Utils.color_float2int(c.get("icon-opacity", null, float.class));
    156             if (pAlpha != null) {
    157                 mapImage.alpha = pAlpha;
    158             }
    159             mapImage.width = width;
    160             mapImage.height = height;
     144        final MapImage mapImage = new MapImage(iconRef.iconName, iconRef.source);
     145
     146        mapImage.width = width;
     147        mapImage.height = height;
     148
     149        mapImage.alpha = Math.min(255, Math.max(0, Integer.valueOf(Main.pref.getInteger("mappaint.icon-image-alpha", 255))));
     150        Integer pAlpha = Utils.color_float2int(c.get("icon-opacity", null, float.class));
     151        if (pAlpha != null) {
     152            mapImage.alpha = pAlpha;
    161153        }
    162154        return mapImage;
     
    243235            Node n = (Node) primitive;
    244236            if (mapImage != null && painter.isShowIcons()) {
    245                 painter.drawNodeIcon(n, (painter.isInactiveMode() || n.isDisabled()) ? mapImage.getDisabled() : mapImage.img,
     237                painter.drawNodeIcon(n, (painter.isInactiveMode() || n.isDisabled()) ? mapImage.getDisabled() : mapImage.getImage(),
    246238                        Utils.color_int2float(mapImage.alpha), selected, member);
    247239            } else if (symbol != null) {
     
    309301    }
    310302
    311     public Rectangle getBox() {
     303    public BoxProvider getBoxProvider() {
    312304        if (mapImage != null) {
    313             int w = mapImage.img.getWidth(null), h = mapImage.img.getHeight(null);
    314             return new Rectangle(-w/2, -h/2, w, h);
     305            return mapImage.getBoxProvider();
    315306        } else if (symbol != null) {
    316             return new Rectangle(-symbol.size/2, -symbol.size/2, symbol.size, symbol.size);
     307            return new SimpleBoxProvider(new Rectangle(-symbol.size/2, -symbol.size/2, symbol.size, symbol.size));
    317308        } else {
    318309            // This is only executed once, so no performance concerns.
     
    324315                    Main.pref.getInteger("mappaint.node.tagged-size", 3)
    325316            );
    326             return new Rectangle(-size/2, -size/2, size, size);
     317            return new SimpleBoxProvider(new Rectangle(-size/2, -size/2, size, size));
    327318        }
    328319    }
  • trunk/src/org/openstreetmap/josm/tools/ImageProvider.java

    r5033 r5054  
    3232import java.util.HashMap;
    3333import java.util.Map;
     34import java.util.concurrent.Executors;
     35import java.util.concurrent.ExecutorService;
    3436import java.util.regex.Matcher;
    3537import java.util.regex.Pattern;
     
    104106    private static Map<String, ImageResource> cache = new HashMap<String, ImageResource>();
    105107
     108    private final static ExecutorService imageFetcher = Executors.newSingleThreadExecutor();
     109
     110    public interface ImageCallback {
     111        void finished(ImageIcon result);
     112    }
     113
    106114    /**
    107115     * @param subdir    Subdirectory the image lies in.
     
    256264        else
    257265            return ir.getImageIcon(new Dimension(width, height));
     266    }
     267
     268    /**
     269     * Load the image in a background thread.
     270     *
     271     * This method returns immediately and runs the image request
     272     * asynchronously.
     273     *
     274     * @param callback is called, when the image is ready. This can happen
     275     * before the call to getInBackground returns or it may be invoked some
     276     * time (seconds) later.
     277     * If no image is available, a null value is returned to callback (just
     278     * like ImageProvider.get).
     279     */
     280    public void getInBackground(final ImageCallback callback) {
     281        if (name.startsWith("http://") || name.startsWith("wiki://")) {
     282            Runnable fetch = new Runnable() {
     283                @Override
     284                public void run() {
     285                    ImageIcon result = get();
     286                    callback.finished(result);
     287                }
     288            };
     289            imageFetcher.submit(fetch);
     290        } else {
     291            ImageIcon result = get();
     292            callback.finished(result);
     293        }
    258294    }
    259295
Note: See TracChangeset for help on using the changeset viewer.