This works real nice, and the framerate is better as well.
/*
* Created on Dec 2, 2004
*
*/
package game;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.Image;
import java.awt.Transparency;
import java.awt.geom.Rectangle2D;
/**
* @author Jeremy
*
*/
public class FloatingMessage {
protected String message;
protected int x;
protected int y;
protected int vY = -3;
protected boolean markedForRemoval = false;
protected Image intermediateImage;
protected static Font font = new Font("Arial",Font.BOLD,11);
public FloatingMessage(String m, int x, int y){
message = m;
this.x = x;
this.y = y;
}
public void paintComponent(Graphics2D g) {
if (intermediateImage == null) {
// First, measure the size of the text
Rectangle2D rect = g.getFontMetrics().getStringBounds(message, g);
int imageW = (int)(rect.getWidth() - rect.getX() + 2);
int imageH = (int)(rect.getHeight() - rect.getY());
// We must also account for text "descent" in determining where to draw string in image
int descent = (int)(g.getFontMetrics().getDescent() + .5f);
// Now, create the intermediate image
GraphicsConfiguration gc = g.getDeviceConfiguration();
intermediateImage = gc.createCompatibleImage(imageW, imageH, Transparency.BITMASK);
// And render the transparent background and the text into the image
Graphics2D gImg = (Graphics2D)intermediateImage.getGraphics();
gImg.setComposite(AlphaComposite.Src);
gImg.setColor(new Color(0,0,0,0));
gImg.fillRect(0, 0, imageW, imageH);
renderText(gImg, 0, imageH - descent);
gImg.dispose();
}
g.drawImage(intermediateImage, x, y,null);
}
public void renderText(Graphics g, int x, int y) {
g.setColor(Color.WHITE);
g.setFont(font);
g.drawString(message, x, y);
}
public static void createFloatingMessage(Stage stage, String m, int x, int y){
FloatingMessage fm = new FloatingMessage(m,x,y);
stage.addFloatingMessage(fm);
}
public void setMessage(String m){
message = m;
}
public String getMessage(){
return message;
}
public void setX(int i){
x = i;
}
public int getX(){
return x;
}
public void setY(int i){
y = i;
}
public int getY(){
return y;
}
/**
* Am I going to be deleted?
* @return true or false
*/
public boolean isMarkedForRemoval(){
return markedForRemoval;
}
public void move(){
y+=vY;
if(y < 0){
remove();
}
}
public void remove(){
markedForRemoval = true;
}
}
In my main class I just call these subroutines when I need them.
public void paintFloatingMessages(Graphics2D g){
FloatingMessage fm;
for(int i=0; i<messages.size(); i++){
fm = (FloatingMessage)messages.get(i);
fm.paintComponent(g);
}
}
public void updateFloatingMessages(){
FloatingMessage fm;
for(int i=0; i<messages.size(); i++){
fm = (FloatingMessage)messages.get(i);
if(fm.isMarkedForRemoval()){
messages.remove(i);
}
fm.move();
}
}