summaryrefslogtreecommitdiffstats
path: root/src/main/java/org/openslx/util/ResourceLoader.java
blob: 7f829fc029e2b0b93f2e9d9b91204d959e79eff3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
package org.openslx.util;

import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.InputStream;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

import javax.swing.Icon;
import javax.swing.ImageIcon;

import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;

/**
 * Helper class for loading resources.
 * This should be error safe loaders with a fall back in case the
 * requested resource can't be found, or isn't of the expected type.
 */
public class ResourceLoader
{

	/**
	 * Logger for this class
	 */
	private final static Logger LOGGER = Logger.getLogger( ResourceLoader.class );

	/**
	 * Load the given resource as an ImageIcon.
	 * This is guaranteed to never throw an Exception and always return
	 * an ImageIcon. If the requested resource could not be loaded,
	 * an icon is generated, containing an error message. If even that
	 * fails, an empty icon is returned.
	 *
	 * @param path Resource path to load
	 * @param description Icon description
	 * @return ImageIcon instance
	 */
	public static ImageIcon getIcon( String path, String description )
	{
		URL url = ResourceLoader.class.getResource( path );
		if ( url == null ) {
			LOGGER.error( "Resource not found: " + path );
		} else {
			try {
				return new ImageIcon( url, description );
			} catch ( Exception e ) {
				LOGGER.error( "Resource not loadable: " + path );
			}
		}
		// If we reach here loading failed, create image containing error
		// message
		try {
			return errorIcon( "Invalid Resource: " + path );
		} catch ( Throwable t ) {
			return new ImageIcon();
		}
	}

	public static Icon getIcon( String path, String description, int maxHeight, Component context )
	{
		ImageIcon icon = getIcon( path, description );
		return getScaledIcon( icon, maxHeight, context );
	}

	/**
	 * Load the given resource as an ImageIcon.
	 * This is guaranteed to never throw an Exception and always return
	 * an ImageIcon. If the requested resource could not be loaded,
	 * an icon is generated, containing an error message. If even that
	 * fails, an empty icon is returned.
	 *
	 * @param path Resource path to load
	 * @return ImageIcon instance
	 */
	public static ImageIcon getIcon( String path )
	{
		return getIcon( path, path );
	}

	/**
	 * Helper that will create an icon with given text.
	 *
	 * @param errorText Text to render to icon
	 * @return the icon
	 */
	private static ImageIcon errorIcon( String errorText )
	{
		Font font = new Font( "Tahoma", Font.PLAIN, 20 );

		// get dimensions of text
		FontRenderContext frc = new FontRenderContext( null, true, true );
		Rectangle2D bounds = font.getStringBounds( errorText, frc );
		int w = (int)bounds.getWidth();
		int h = (int)bounds.getHeight();

		// create a BufferedImage object
		BufferedImage image = new BufferedImage( w, h, BufferedImage.TYPE_INT_RGB );
		Graphics2D g = image.createGraphics();

		// set color and other parameters
		g.setColor( Color.WHITE );
		g.fillRect( 0, 0, w, h );
		g.setColor( Color.RED );
		g.setFont( font );

		g.drawString( errorText, (float)bounds.getX(), (float) -bounds.getY() );

		g.dispose();
		return new ImageIcon( image, "ERROR" );
	}

	/**
	 * Tries to load the given resource treating it as a text file
	 *
	 * @param path Resource path to load
	 * @return content of the loaded resource as String
	 */
	public static String getTextFile( String path )
	{
		String fileContent = null;
		try ( InputStream stream = ResourceLoader.class.getResourceAsStream( path ) ) {
			fileContent = IOUtils.toString( stream, StandardCharsets.UTF_8 );
		} catch ( Exception e ) {
			LOGGER.error( "IO error while trying to load resource '" + path + "'. See trace: ", e );
		}

		if ( fileContent != null ) {
			return fileContent;
		} else {
			return "Resource '" + path + "' not found.";
		}
	}

	public static InputStream getStream( String path )
	{
		return ResourceLoader.class.getResourceAsStream( path );
	}

	private static final Map<Icon, ImageIcon> iconCache = new HashMap<>();

	public static Icon getScaledIcon( Icon icon, int height, Component context )
	{
		if ( icon == null )
			return null;
		ImageIcon cached = iconCache.get( icon );
		if ( cached != null && cached.getIconHeight() == height )
			return cached;
		// Generate?
		float iHeight = icon.getIconHeight();
		float tHeight = height;
		if ( iHeight <= tHeight )
			return icon; // Small enough
		// Scale down:
		BufferedImage image = new BufferedImage( icon.getIconWidth(), icon.getIconHeight(),
				BufferedImage.TYPE_INT_ARGB );
		Graphics2D g = image.createGraphics();
		g.setRenderingHint( RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY );
		g.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );
		icon.paintIcon( context, g, 0, 0 );
		ImageIcon scaledIcon = new ImageIcon( image.getScaledInstance(
				(int) ( icon.getIconWidth() * ( tHeight / iHeight ) ), (int) ( tHeight ), Image.SCALE_SMOOTH ) );
		iconCache.put( icon, scaledIcon );
		return scaledIcon;
	}

}