Ticket #6797: async.diff

File async.diff, 7.7 KB (added by bastiK, 16 months 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();