Ticket #6797: async.diff

File async.diff, 7.7 KB (added by bastiK, 12 years ago)
  • src/org/openstreetmap/josm/tools/ImageProvider.java

     
    3030import java.util.Collection;
    3131import java.util.HashMap;
    3232import java.util.Map;
     33import java.util.concurrent.Executors;
     34import java.util.concurrent.ExecutorService;
    3335import java.util.regex.Matcher;
    3436import java.util.regex.Pattern;
    3537import java.util.zip.ZipEntry;
     
    107109     */
    108110    private static Map<String, ImageResource> cache = new HashMap<String, ImageResource>();
    109111
     112    private final static ExecutorService imageFetcher = Executors.newSingleThreadExecutor();
     113
     114    public final static int STATUS_IN_BACKGROUND = 0;
     115    public final static int STATUS_FINISHED_EARLY = 1;
     116
     117    public interface ImageCallback {
     118        void finished(ImageIcon result, int status);
     119    }
     120
    110121    /**
    111122     * @param subdir    Subdirectory the image lies in.
    112123     * @param name      The name of the image. If it does not end with '.png' or '.svg',
     
    243254    }
    244255
    245256    /**
     257     * Load the image in a background thread.
     258     *
     259     * There are 2 possible return values:
     260     *  - STATUS_FINISHED_EARLY
     261     *      This means that image is returned directly: The callback will have been called
     262     *      before this method returns.
     263     *  - STATUS_IN_BACKGROUND
     264     *      Image is fetched in the background and callback will be executed at any time.
     265     */
     266    public int getInBackground(final ImageCallback callback) {
     267        if (name.startsWith("http://") || name.startsWith("wiki://")) {
     268            Runnable fetch = new Runnable() {
     269                @Override
     270                public void run() {
     271                    ImageIcon result = get();
     272                    callback.finished(result, STATUS_IN_BACKGROUND);
     273                }
     274            };
     275            imageFetcher.submit(fetch);
     276            return STATUS_IN_BACKGROUND;
     277        } else {
     278            ImageIcon result = get();
     279            callback.finished(result, STATUS_FINISHED_EARLY);
     280            return STATUS_FINISHED_EARLY;
     281        }
     282    }
     283
     284    /**
    246285     * Return an image from the specified location. Throws a RuntimeException if
    247286     * the image cannot be located.
    248287     *
  • src/org/openstreetmap/josm/gui/mappaint/NodeElemStyle.java

     
    1919import org.openstreetmap.josm.data.osm.visitor.paint.MapPainter;
    2020import org.openstreetmap.josm.gui.mappaint.MapPaintStyles.IconReference;
    2121import org.openstreetmap.josm.gui.mappaint.StyleCache.StyleList;
     22import org.openstreetmap.josm.tools.ImageProvider;
     23import org.openstreetmap.josm.tools.ImageProvider.ImageCallback;
    2224import org.openstreetmap.josm.tools.Pair;
    2325import org.openstreetmap.josm.tools.Utils;
    2426
     
    2931    public MapImage<Image> mapImage;
    3032    public Symbol symbol;
    3133
    32     private ImageIcon disabledIcon;
    33 
    3434    public enum SymbolShape { SQUARE, CIRCLE, TRIANGLE, PENTAGON, HEXAGON, HEPTAGON, OCTAGON, NONAGON, DECAGON }
    3535
    3636    public static class Symbol {
     
    125125        Cascade c = env.mc.getCascade(env.layer);
    126126        Cascade c_def = env.mc.getCascade("default");
    127127
    128         IconReference iconRef = c.get("icon-image", null, IconReference.class);
     128        final IconReference iconRef = c.get("icon-image", null, IconReference.class);
    129129        if (iconRef == null)
    130130            return null;
    131131
     
    144144        int width = widthF == null ? -1 : Math.round(widthF);
    145145        int height = heightF == null ? -1 : Math.round(heightF);
    146146
    147         MapImage<Image> mapImage = new MapImage<Image>(iconRef.iconName, iconRef.source);
     147        final MapImage<Image> mapImage = new MapImage<Image>(iconRef.iconName, iconRef.source);
    148148
    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;
     149        synchronized (mapImage) {
     150            int result = new ImageProvider(iconRef.iconName)
     151                    .setDirs(MapPaintStyles.getIconSourceDirs(iconRef.source))
     152                    .setId("mappaint."+iconRef.source.getPrefName())
     153                    .setArchive(iconRef.source.zipIcons)
     154                    .setWidth(width)
     155                    .setHeight(height)
     156                    .setOptional(true)
     157                    .getInBackground(new ImageCallback() {
     158                        @Override
     159                        public void finished(ImageIcon result, int status) {
     160                                if (status == ImageProvider.STATUS_FINISHED_EARLY) {
     161                                    mapImage.img = result.getImage();
     162                                } else if (status == ImageProvider.STATUS_IN_BACKGROUND) {
     163                                    synchronized (mapImage) {
     164                                        if (result == null) {
     165                                            mapImage.img = MapPaintStyles.getNoIcon_Icon(iconRef.source).getImage();
     166                                            mapImage.alpha = 255;
     167                                        } else {
     168                                            mapImage.img = result.getImage();
     169                                        }
     170                                    }
     171                                    Main.map.mapView.preferenceChanged(null); // otherwise repaint is ignored, because layer hasn't changed
     172                                    Main.map.mapView.repaint();
     173                                }
     174                            }
     175                        }
     176            );
     177           
     178            if (result == ImageProvider.STATUS_FINISHED_EARLY && mapImage.img == null) {
     179                mapImage.img = MapPaintStyles.getNoIcon_Icon(iconRef.source).getImage();
     180                mapImage.alpha = 255;
     181            } else {
     182                mapImage.width = width;
     183                mapImage.height = height;
     184
     185                mapImage.alpha = Math.min(255, Math.max(0, Integer.valueOf(Main.pref.getInteger("mappaint.icon-image-alpha", 255))));
     186                Integer pAlpha = Utils.color_float2int(c.get("icon-opacity", null, float.class));
     187                if (pAlpha != null) {
     188                    mapImage.alpha = pAlpha;
     189                }
    158190            }
    159             mapImage.width = width;
    160             mapImage.height = height;
     191            if (result == ImageProvider.STATUS_IN_BACKGROUND) {
     192                mapImage.img = ImageProvider.get("clock").getImage();
     193            }
    161194        }
    162195        return mapImage;
    163196    }
  • src/org/openstreetmap/josm/gui/mappaint/MapPaintStyles.java

     
    130130                .setOptional(true).get();
    131131    }
    132132
    133     private static List<String> getIconSourceDirs(StyleSource source) {
     133    public static List<String> getIconSourceDirs(StyleSource source) {
    134134        List<String> dirs = new LinkedList<String>();
    135135
    136136        String sourceDir = source.getLocalSourceDir();