org.springframework.ide.eclipse.boot.dash.views.RunStateImages.java Source code

Java tutorial

Introduction

Here is the source code for org.springframework.ide.eclipse.boot.dash.views.RunStateImages.java

Source

/*******************************************************************************
 * Copyright (c) 2015 Pivotal, Inc.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Pivotal, Inc. - initial API and implementation
 *******************************************************************************/
package org.springframework.ide.eclipse.boot.dash.views;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.DecorationOverlayIcon;
import org.eclipse.jface.viewers.IDecoration;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
import org.eclipse.swt.widgets.Display;
import org.springframework.ide.eclipse.boot.dash.model.RunState;

/**
 * @author Kris De Volder
 */
public class RunStateImages {

    private Map<Object, Image[]> animations = new HashMap<Object, Image[]>();

    public synchronized Image[] getAnimation(RunState state) throws Exception {
        Image[] anim = animations.get(state);
        if (anim == null) {
            String url = state.getImageUrl();
            animations.put(state, anim = createAnimation(url));
        }
        return anim;
    }

    private Image[] createAnimation(String urlString) throws Exception {
        ImageLoader loader = new ImageLoader();
        InputStream input = null;
        ClassLoader cl = this.getClass().getClassLoader();

        // For a png there might be animation frames to load (ImageLoader cannot
        // pull out frames for an animated png)
        // Given an input url of the form "foo.png" this will search
        // for "foo_1.png", "foo_2.png" etc, until it can find no more frames
        int dot = urlString.lastIndexOf('.');
        String prefix = urlString.substring(0, dot);
        String suffix = urlString.substring(dot + 1);

        List<Image> images = new ArrayList<Image>();
        int count = 1;
        while ((input = cl.getResourceAsStream(prefix + "_" + Integer.toString(count++) + "." + suffix)) != null) {
            ImageData[] data = loader.load(input);
            for (ImageData idata : data) {
                images.add(new Image(Display.getDefault(), idata));
            }
        }
        if (images.size() != 0) {
            // Animation frames were found, return them
            return images.toArray(new Image[images.size()]);
        }

        // Just load it in the regular way, this route does cope
        // with animated gifs
        input = cl.getResourceAsStream(urlString);
        try {
            ImageData[] data = loader.load(input);
            Image[] imgs = new Image[data.length];
            for (int i = 0; i < imgs.length; i++) {
                imgs[i] = new Image(Display.getDefault(), data[i]);
            }
            return imgs;
        } finally {
            input.close();
        }
    }

    public synchronized Image[] getDecoratedImages(final RunState state, final ImageDescriptor descriptor,
            final int position) throws Exception {
        Image[] images = getAnimation(state);
        if (descriptor == null) {
            return images;
        } else {
            Object key = Arrays.<Object>asList(state, descriptor, position);
            Image[] decoratedImages = animations.get(key);
            if (decoratedImages == null) {
                decoratedImages = Arrays.copyOf(images, images.length);
                for (int i = 0; i < decoratedImages.length; i++) {
                    decoratedImages[i] = new DecorationOverlayIcon(decoratedImages[i], descriptor,
                            IDecoration.BOTTOM_RIGHT).createImage(decoratedImages[i].getDevice());
                }
                animations.put(key, decoratedImages);
            }
            return decoratedImages;
        }
    }

    void dispose() {
        if (animations != null) {
            for (Image[] anim : animations.values()) {
                if (anim != null) {
                    for (Image image : anim) {
                        image.dispose();
                    }
                }
            }
            animations = null;
        }
    }

}