I'm writing java code for a game and when creating the health bars I saw an exception that confused me greatly. The code and stack is below:
Code:
package com.teamanubiz.pixelhero;
import java.awt.Graphics;
import java.awt.Image;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import com.teamanubiz.gameapi.gfx.Sprite;
public class GUIRenderLayer {
public void renderStatBar(GUIPosition pos, Graphics g, int health, int maxHealth, int mana, int maxMana) {
Sprite healthBar = null;
try {
healthBar = new Sprite(ImageIO.read(new File("res\\gui\\bar.png")));
} catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
healthBar.crop(0, 0, 128, 32);
healthBar.scale(256, 32);
Sprite manaBar = null;
try {
manaBar = new Sprite(ImageIO.read(new File("res\\gui\\bar.png")));
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
manaBar.crop(0, 32, 128, 32);
manaBar.scale(265, 16);
Sprite temp = null;
try {
temp = new Sprite(ImageIO.read(new File("res\\gui\\bar.png")));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
temp.crop(0, 64, 128, 32);
temp.scale(256, 32);
Sprite emptyHealth = new Sprite(temp.getCurrent());
temp.scale(256, 16);
Sprite emptyMana = new Sprite(temp.getCurrent());
if (pos == GUIPosition.BOTTOM) {
double percent_h = health / maxHealth;
double percent_m = mana / maxMana;
healthBar.crop(0, 0, (int) ((int) 256 * percent_h), 32);
manaBar.crop(0, 0, (int) ((int) 256 * percent_m), 16);
g.drawImage(emptyMana.getCurrent(), 100, 464, null);
g.drawImage(emptyHealth.getCurrent(), 100, 432, null);
g.drawImage(healthBar.getCurrent(), 100, 432, null);
g.drawImage(manaBar.getCurrent(), 100, 464, null);
}
}
}
This class is referencing a custom library containing the class Sprite
. It for some reason says that I am trying to cast a ToolkitImage
to a BufferedImage
in the below method of Sprite.java.
public void crop(int xOffset, int yOffset, int width, int height) {
BufferedImage temp = (BufferedImage) source;
temp = temp.getSubimage(xOffset, yOffset, width, height);
source = temp;
}
The variable source
is an instance of an Image
that is a field in Sprite.java
The stack below claims I am creating a ToolkitImage
despite the fact new ImageIcon("res\\gui\\bar.png").getImage()
returns only an Image
. I do not convert the Image
to a ToolkitImage
ever in the code. This makes it extremely confusing.
Stacktrace:
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: sun.awt.image.ToolkitImage cannot be cast to java.awt.image.BufferedImage
at com.teamanubiz.gameapi.gfx.Sprite.crop(Sprite.java:48)
at com.teamanubiz.pixelhero.GUIRenderLayer.renderStatBar(GUIRenderLayer.java:55)
at com.teamanubiz.pixelhero.GameWindow.tick(GameWindow.java:14)
at com.teamanubiz.gameapi.Display.paint(Display.java:95)
at javax.swing.RepaintManager$4.run(Unknown Source)
at javax.swing.RepaintManager$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.prePaintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.access$1300(Unknown Source)
at javax.swing.RepaintManager$ProcessingRunnable.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$400(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: sun.awt.image.ToolkitImage cannot be cast to java.awt.image.BufferedImage
at com.teamanubiz.gameapi.gfx.Sprite.crop(Sprite.java:48)
at com.teamanubiz.pixelhero.GUIRenderLayer.renderStatBar(GUIRenderLayer.java:55)
at com.teamanubiz.pixelhero.GameWindow.tick(GameWindow.java:14)
at com.teamanubiz.gameapi.Display.paint(Display.java:95)
at javax.swing.RepaintManager$4.run(Unknown Source)
at javax.swing.RepaintManager$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.prePaintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.access$1300(Unknown Source)
at javax.swing.RepaintManager$ProcessingRunnable.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$400(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: sun.awt.image.ToolkitImage cannot be cast to java.awt.image.BufferedImage
at com.teamanubiz.gameapi.gfx.Sprite.crop(Sprite.java:48)
at com.teamanubiz.pixelhero.GUIRenderLayer.renderStatBar(GUIRenderLayer.java:55)
at com.teamanubiz.pixelhero.GameWindow.tick(GameWindow.java:14)
at com.teamanubiz.gameapi.Display.paint(Display.java:95)
at javax.swing.RepaintManager$4.run(Unknown Source)
at javax.swing.RepaintManager$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.prePaintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.access$1300(Unknown Source)
at javax.swing.RepaintManager$ProcessingRunnable.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$400(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
No you don't "convert" the Image to a ToolKitImage, but that's what the JVM is giving you when you call
new ImageIcon("res\\gui\\bar.png").getImage()
, and not a BufferedImage. The ImageIcon API states thatgetImage()
returns an object of Image type, but does not specify what type of Image. Since Image is an interface, you know that there must be some concrete type underlying the returned Image object. If you need a BufferedImage you could one, and draw this Image into it.Myself, I wouldn't even use an ImageIcon here if I wanted a BufferedImage, but rather would use
ImageIO.read(...)
which returns a BufferedImage.So....
BufferedImage
is a type ofImage
, butImage
is not a typeBufferedImage
, you could, for example, castBufferedImage
to anImage
.Instead of using
ImageIcon
to load the image, useImageIO.read
, which returns aBufferedImage
So instead of...
Nb:
ImageIcon
delegates the actual loading of the image toToolkit
and wraps it in a Icon interfaceUse something like...