How: Change the icon in the window and taskbar.

Started by Labrasones, July 27, 2011, 20:19:45

Previous topic - Next topic

Labrasones

I'm making a game for windows systems, (vista and 7 are the targets), and I'd like to have my own icon in the window and taskbar. I'm still realy new to java, and all the posts I could find on this topic deal with byte buffers without give an explination on how to use them. So I'd like to ask if anyone can give me a walkthrough on how to setup a code to display a custom icon in the window? Espcially what libraries to import.

CodeBunny

LWJGL already supports this, see Display.setIcon(ByteBuffer[]).

Basically, load the image with the standard Java2D methods (probably ImageIO.read()), convert its rastered data to a bytebuffer, and use that bytebuffer.

Labrasones

It's the bytebuffers that I do know how to use. Do you ave any tutorials or reference materials you could point me to for those?

CodeBunny

Here's a convenience class I made that I use for my LWJGL games:

/*****************************************************************************
 * A convenience class for loading icons from images.
 * 
 * Icons loaded from this class are formatted to fit within the required
 * dimension (16x16, 32x32, or 128x128). If the source image is larger than the
 * target dimension, it is shrunk down to the minimum size that will fit. If it
 * is smaller, then it is only scaled up if the new scale can be a per-pixel
 * linear scale (i.e., x2, x3, x4, etc). In both cases, the image's width/height
 * ratio is kept the same as the source image.
 * 
 * @author Chris Molini
 *****************************************************************************/
public class IconLoader
{
	/*************************************************************************
	 * Loads an icon in ByteBuffer form.
	 * 
	 * @param filepath
	 *            The location of the Image to use as an icon.
	 * 
	 * @return An array of ByteBuffers containing the pixel data for the icon in
	 *         varying sizes.
	 *************************************************************************/
	public static ByteBuffer[] load(String filepath)
	{
		return load(new SystemLoader(filepath));
	}

	/*************************************************************************
	 * Loads an icon in ByteBuffer form.
	 * 
	 * @param loader
	 *            A Loader pointing to the image.
	 * 
	 * @return An array of ByteBuffers containing the pixel data for the icon in
	 *         various sizes (as recommended by the OS).
	 *************************************************************************/
	public static ByteBuffer[] load(Loader loader)
	{
		BufferedImage image = null;
		try
		{
			image = ImageIO.read(loader.url());
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
		ByteBuffer[] buffers = null;
		String OS = System.getProperty("os.name").toUpperCase();
		if(OS.contains("WIN"))
		{
			buffers = new ByteBuffer[2];
			buffers[0] = loadInstance(image, 16);
			buffers[1] = loadInstance(image, 32);
		}
		else if(OS.contains("MAC"))
		{
			buffers = new ByteBuffer[1];
			buffers[0] = loadInstance(image, 128);
		}
		else
		{
			buffers = new ByteBuffer[1];
			buffers[0] = loadInstance(image, 32);
		}
		return buffers;
	}

	/*************************************************************************
	 * Copies the supplied image into a square icon at the indicated size.
	 * 
	 * @param image
	 *            The image to place onto the icon.
	 * @param dimension
	 *            The desired size of the icon.
	 * 
	 * @return A ByteBuffer of pixel data at the indicated size.
	 *************************************************************************/
	private static ByteBuffer loadInstance(BufferedImage image, int dimension)
	{
		BufferedImage scaledIcon = new BufferedImage(dimension, dimension,
				BufferedImage.TYPE_INT_ARGB_PRE);
		Graphics2D g = scaledIcon.createGraphics();
		double ratio = getIconRatio(image, scaledIcon);
		double width = image.getWidth() * ratio;
		double height = image.getHeight() * ratio;
		g.drawImage(image, (int) ((scaledIcon.getWidth() - width) / 2),
				(int) ((scaledIcon.getHeight() - height) / 2), (int) (width),
				(int) (height), null);
		g.dispose();

		return convertToByteBuffer(scaledIcon);
	}

	/*************************************************************************
	 * Gets the width/height ratio of the icon. This is meant to simplify
	 * scaling the icon to a new dimension.
	 * 
	 * @param src
	 *            The base image that will be placed onto the icon.
	 * @param icon
	 *            The icon that will have the image placed on it.
	 * 
	 * @return The amount to scale the source image to fit it onto the icon
	 *         appropriately.
	 *************************************************************************/
	private static double getIconRatio(BufferedImage src, BufferedImage icon)
	{
		double ratio = 1;
		if (src.getWidth() > icon.getWidth())
			ratio = (double) (icon.getWidth()) / src.getWidth();
		else
			ratio = (int) (icon.getWidth() / src.getWidth());
		if (src.getHeight() > icon.getHeight())
		{
			double r2 = (double) (icon.getHeight()) / src.getHeight();
			if (r2 < ratio)
				ratio = r2;
		}
		else
		{
			double r2 = (int) (icon.getHeight() / src.getHeight());
			if (r2 < ratio)
				ratio = r2;
		}
		return ratio;
	}

	/*************************************************************************
	 * Converts a BufferedImage into a ByteBuffer of pixel data.
	 * 
	 * @param image
	 *            The image to convert.
	 * 
	 * @return A ByteBuffer that contains the pixel data of the supplied image.
	 *************************************************************************/
	public static ByteBuffer convertToByteBuffer(BufferedImage image)
	{
		byte[] buffer = new byte[image.getWidth() * image.getHeight() * 4];
		int counter = 0;
		for (int i = 0; i < image.getHeight(); i++)
			for (int j = 0; j < image.getWidth(); j++)
			{
				int colorSpace = image.getRGB(j, i);
				buffer[counter + 0] = (byte) ((colorSpace << 8) >> 24);
				buffer[counter + 1] = (byte) ((colorSpace << 16) >> 24);
				buffer[counter + 2] = (byte) ((colorSpace << 24) >> 24);
				buffer[counter + 3] = (byte) (colorSpace >> 24);
				counter += 4;
			}
		return ByteBuffer.wrap(buffer);
	}
}

CodeBunny

The above code is under the New BSD license, btw, so if you want to use it verbatim, give credit to "Chris Molini."

But if just want to see some example code, no need.

Labrasones

Thanks for the example. I'm mostly just looking for learning resources, as the game I'm working on is more a learning opertunity for me. I'll probably learn more from trying to rewrite my own code from your example. I also want to thank you, since you've been extreamly helpfull with all my questions. I couldn't have done anything without your help! I'm sure I'll have more questions before I'm done with this game though. There is so much that I don't know yet  :-\

CodeBunny

Hey, np. That's what this forum is for, and its certainly saved my butt a ton when it comes to bugs and issues.

Good luck with the game.