This site requires JavaScript, please enable it in your browser!
Greenfoot back
Zamoht
Zamoht wrote ...

2013/7/14

GreenfootImage and labels

Zamoht Zamoht

2013/7/14

#
As I see it, the best way to center a text in an image is to use the "GreenfootImage(java.lang.String string, int size, java.awt.Color foreground, java.awt.Color background)" constructor of the GreenfootImage. Now what if I want to center a text, but with a different font? I know I could approximate the size of the label or hardcode the size of every letter from the font with a constant font size. So I guess my real question is how hard would it be to create a GreenfootImage constructor, which would look something like this: "GreenfootImage(java.lang.String string, Font font, java.awt.Color foreground, java.awt.Color background)" I guess it's not that easy since the Greenfoot Team hasn't created it yet or is there an other reason?
danpost danpost

2013/7/14

#
To your first question 'if I want to center a text, but with a different font?': you will need to use the drawString method on a GreenfootImage to draw a string with a different font because you would need to set that font (using the GreenfootImage constructor to create a text image does not give you a chance to change the font before drawing the string on the image). You would be able to determine the width of the string if using a MONOSPACED font. Determining the width of the text image would otherwise be very involved. This may be your answer to why 'the Greenfoot Team hasn't created it yet'. Or, more probably, because this is a basic learning site and doing that would be beyond the scope of what they are intending as the purpose for this site.
Zamoht Zamoht

2013/7/14

#
Thanks for the answer. It's not that I really need another font I was just wondering. I think I have only one thing left to ask, how does the drawString method work if you don't know the width of the text image? Or (something I haven't checked) does the drawString only work with monospaced fonts? If not, how does the method place the letters (if it's possible to answer this question)?
danpost danpost

2013/7/14

#
You just have to have an image wide enough to draw the string on. The int parameters in the method signature are the offset from the top-left corner of the image to draw on to where the bottom-left of the string will be drawn. I am not sure if there are methods to get the width of the drawn string. You may have to scan the image and look for the text color starting from the right and going left to figure out the endpoint at which the string was drawn. I have, so far, avoided going that route by either using drawString with a MONOSPACE font or using the aforementioned GreenfootImage constructor using the default font. Looking at the Font API, it appears you need to get a FontMetrics object of the font and then use it to get the width of the string to draw.
Font font = getBackground().getFont();
FontMetrics fm = new FontMetrics(font);
String string = "abcdefg";
int stringWidth = fm.stringWidth(string);
The above was not tested and is not exactly the code you need. However, I believe the code illustrates what steps you need to take (I hope, as again, I have not tried this before). Of course, you will have to import java.awt.Font and java.awt.FontMetrics.
Zamoht Zamoht

2013/7/14

#
Once again thanks for the answer. And thanks for finding the FontMetrics class, I think I will test it when I get time for that.
Zamoht Zamoht

2013/7/15

#
Okay It doesn't seem like this is possible.. To initialize a FontMetrics object you need a Graphics object which is obtained from a Component(3x superclass of the Applet class) object. Please tell me if I'm wrong, but I guess that if I was able to get the Applet object my Greenfoot project is running on (if Greenfoot uses the Applet class) the code would look like this: applet.getFontMetrics(Font font); or applet.getGraphics().getFontMetrics(Font font); Or isn't it as simple as that?
danpost danpost

2013/7/15

#
Found a trail on using Graphics. Basic code in constructor of world follows:
import greenfoot.*;
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.awt.font.FontRenderContext;

public class AnyWorld extends World
{
    public AnyWorld()
    {
        super(600, 400, 1);
        Font font = new Font("Serif", Font.PLAIN, 36);
        GreenfootImage g = getBackground();
        g.setFont(font);
        String condString = "Partly cloudy and humid";
        String tempString = "Temperature: 65 degrees";
        FontRenderContext frc = ((Graphics2D)g.getAwtImage().createGraphics()).getFontRenderContext();
        Rectangle2D boundsTemp = font.getStringBounds(tempString, frc);
        Rectangle2D boundsCond = font.getStringBounds(condString, frc);
        int tempWidth = (int)boundsTemp.getWidth();
        int condWidth = (int)boundsCond.getWidth();
        int strHeight = (int)boundsTemp.getHeight();
        g.setColor(Color.red);
        g.drawString(tempString, (getWidth()-tempWidth)/2, (getHeight()-strHeight)/2);
        g.drawString(condString, (getWidth()-condWidth)/2, (getHeight()+strHeight)/2);
    }
}
Zamoht Zamoht

2013/7/15

#
Thanks for the help and quick response. I think I will code a class for working with centering text and upload it to the gallery. All "creds" to you of course, I will put your name on the class and the scenario since you did all the hard work :) Once again I want to thank you and I hope this is okay with you.
danpost danpost

2013/7/15

#
I do not wish any credit for this as the basic idea behind the code was found in the WeatherWizard applet within the Java tutorials.
Zamoht Zamoht

2013/7/17

#
Ups already uploaded it with your name. Well I can change the description of the scenario, but you are still in the @author as: @author Zamoht (help from danpost) I guess that's okay with you.
danpost danpost

2013/7/23

#
Getting back to the drawString method, I am sure it would not be difficult to change the return type to int and have it return the baseline length of the string drawn. But, as I said before, I doubt the Greenfoot team would agree to do something like that.
You need to login to post a reply.