001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one
003 *  or more contributor license agreements.  See the NOTICE file
004 *  distributed with this work for additional information
005 *  regarding copyright ownership.  The ASF licenses this file
006 *  to you under the Apache License, Version 2.0 (the
007 *  "License"); you may not use this file except in compliance
008 *  with the License.  You may obtain a copy of the License at
009 *
010 *        http://www.apache.org/licenses/LICENSE-2.0
011 *
012 *  Unless required by applicable law or agreed to in writing,
013 *  software distributed under the License is distributed on an
014 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *  KIND, either express or implied.  See the License for the
016 *  specific language governing permissions and limitations
017 *  under the License.
018 */
019
020package org.apache.isis.core.runtime.imageloader;
021
022import java.awt.Canvas;
023import java.awt.Image;
024import java.awt.MediaTracker;
025
026import org.slf4j.Logger;
027import org.slf4j.LoggerFactory;
028
029/**
030 * Many icons are based on the same image, but in different sizes and possibly
031 * different colours. The ImageTemplate class loads and holds them image, and
032 * can provide it clients with the full sized images or scaled images.
033 */
034public class TemplateImageImpl implements TemplateImage {
035    private final static Logger LOG = LoggerFactory.getLogger(TemplateImageImpl.class);
036
037    /**
038     * Factory method.
039     */
040    public static TemplateImageImpl create(final java.awt.Image image) {
041        if (image == null) {
042            return null;
043        }
044        return new TemplateImageImpl(image);
045
046    }
047
048    private final Image image;
049    private final MediaTracker mt = new MediaTracker(new Canvas());
050
051    private TemplateImageImpl(final Image image) {
052        if (image == null) {
053            throw new NullPointerException();
054        }
055        this.image = image;
056    }
057
058    @Override
059    public Image getImage() {
060        return image;
061    }
062
063    @Override
064    public Image getIcon(final int height) {
065        Image iconImage;
066
067        if (height == image.getHeight(null)) {
068            return image;
069        }
070
071        iconImage = image.getScaledInstance(-1, height, java.awt.Image.SCALE_SMOOTH);
072
073        if (iconImage != null) {
074            mt.addImage(iconImage, 0);
075
076            try {
077                mt.waitForAll();
078            } catch (final Exception e) {
079                // TODO: tidy up this horrid code.
080                e.printStackTrace();
081            }
082
083            if (mt.isErrorAny()) {
084                LOG.error("failed to create scaled image: " + iconImage + " " + mt.getErrorsAny()[0]);
085                mt.removeImage(iconImage);
086                iconImage = null;
087            } else {
088                mt.removeImage(iconImage);
089                if (LOG.isDebugEnabled()) {
090                    LOG.debug("image " + iconImage + " scaled to " + height);
091                }
092            }
093        }
094
095        if (iconImage == null) {
096            throw new RuntimeException("no icon image!");
097        } else {
098            if (iconImage.getWidth(null) == -1) {
099                throw new RuntimeException("scaled image! " + iconImage.toString());
100            }
101        }
102
103        return iconImage;
104    }
105}