Java - Changing text size using canvas? - java

I am trying to change the size of the text I am drawing to my canvas. I have searched all the properties that the canvas method holds, but there are no options for text size.
canvas.drawText("TESTTT", 200, 200, colorCyan);
Obviously the text is way too small and the font is ugly :( What can I do?

You can set size to the paint object
colorCyan.setTextSize(40f); // takes a float as the param
http://developer.android.com/reference/android/graphics/Paint.html#setTextSize(float)
public void setTextSize (float textSize)
Added in API level 1 Set the paint's text size. This value must be > 0
Parameters textSize set the paint's text size.

You didn't search too much ;)
Paint paint = new Paint();
paint.setTextSize(...
before drawing if.

Related

How to draw text in world coordinate space?

I'm creating a game in libGDX. I want to create some UI elements (buttons and stuff), because of my app design, I would like to draw them in the world space, as other game objects.
I'm using Freetype generator that generates a bitmap font from true type font files(.ttf). The problem is that the dimension of the font is in pixels.
Orthographic camera that I use to to render the world, has viewport size of approximately 10x10, so when I generate a font at the size of 10, it covers almost whole screen(too big) and also looks very ugly because generated bitmap for the font is too small (too few pixels).
What I want is to create sprite, draw it at same size(world space) and draw text over it, and basicly create a button.
Is there some well established way how to deal with this?
Thanks to clarifying comments, I've came up with the solution.
I took a point at which I wanted to draw the text, projected it to the screen space by my world camera. Then I flipped y axis by:
point.y = viewportHeight - point.y;
Then I unprojected it with ScreenViewport (separate viewport for drawing the text, is uses camera of the size of the screen so 1unit == 1pixel).
Now I can draw text in projection where 1unit = 1pixel, on the point that is at the same place on the screen as previously chosen point in world space.
I also wanted to be able to draw text inside rectangular boundaries. For this I chose another point. At this point text should end. Did the same procedure as with start point, and then calculated width
targetWidth = endpoint.x - startpoint.x;
Then I used GlypthLayout class to get actual width of my text at some(generated) font size.
actualWidth = glyphLayout.width;
And when I scaled font like this
font.getData().setScale(targetWidth / actualWidth);
my font get scaled so drawed text is wide as target width.
But be aware of another problem! When I generate bimap font via FreetypeGenerator with size bigger when approximately 300, some letters don't draw, and are missing. (probably bug).

Java Get Size of Font

I have JFrame with a JTextArea inside of it.
Font font = new Font("monospaced", Font.PLAIN, 14);
textarea.setFont(font);
Since the font is monospaced, all characters are the same width and height.
I'd like to know what this width and height is in pixels.
For this, I could use font.getStringBounds but I have no Graphics context to pass to it. frame.getGraphics() returns null.
How can I find the size of a character? Can it be done without a Graphics instance? I don't want an instance of it anyway. I just want to know how big my characters are.
You can use JFrame#getFontMetrics since one of JFrame's Superclass is Component.
If this does not work, you can also use BufferedImage to get a Graphics object:
BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
You can use the image object to get an instance of Graphics.
FYI, I am using a JFrame/JTextarea to render a text based game, so I'll use this info for scaling the text and getting the dimensions of the window in units of characters
It's probably not the best approach, it would be better to simply use JTextArea#setColumns and JTextArea#setRows which will use the font based information to make determinations about it's preferred size automatically
You can then make use of the LayoutManager APIs and simply call pack on the JFrame which will pack the window around the contents, based on it's preferred size
This will also affect the preferred size of JScrollPane

Get the pixels of a string

While doing some stuff with the drawstring() method, I was wondering if there was a way of to extract a pixel array from a string parameter, so that the return type could fit into a 2d pixel array?
The method also needs to work with sizing and coloring.
I have already managed to draw the string to a graphics parameter that has a pixel listener attached to it, using drawstring() and then simply getting the data from that specific area.
But I was wondering if their is a way to get the pixels without having to draw it?
I want to be able to add effects like waves, 3d rotations and cool particles effects using the pixel engine i have, so to draw and then grab the pixels takes to much update space!
And remember that the string will be scaled, colored and transformed before it is extracted to a pixel array, so drawing the string once wont work.
The act of drawing a string is complex. The text data in the string first has to be decoded into a sequence of glyphs in a given font. These are then rasterized by intersecting lines with the font's curve definitions at the scale your are rendering it. (Actually, with a process called "hinting" this is even more complex.) Once you have rasterized the glyphs you have the array of pixels you can then send to the display device.
What you want to do is to interrupt this process in the middle by transforming the text into a set of curves which are created from the font glyphs. Code like the following will give you the curves:
Graphics graphics;
Font font = new Font("ComicSans", Font.PLAIN, 12);
GlyphVector vector = font.createGlyphVector(graphics.getFontMetrics(font).getFontRenderContext(), "Lorem ipsum");
Shape shape = vector.getOutline();
// transform shape

Adding rendering offset to Frame

The scenario here is as so: I am using a Frame object to do some lower-ish level rendering with AWT (no Swing). The only issue is, Frames, when rendering directly to them, do not account for their borders. So, as we all likely know, rendering a Rectangle at (0,0) does not look like it is doing the right thing. This is because (0,0) is the literal top-left of the Frame.
So the problem is, instead of adding in the Frame insets for everything to be rendered on-screen like so:
//This is within the rendering method in the Frame subclass. A buffer strategy is already created
Graphics2D g = (Graphics2D)bufferStrategy.getDrawGraphics();
g.clearRect(0, 0, getWidth(), getHeight());
g.setColor(Color.WHITE);
Insets insets = this.getInsets();
g.drawString("FPS: " + getFPS(), 100 + insets.left, 100 + insets.top); //<-- Ugh.
g.dispose();
I would like to be able to simply add an offset of sorts to the underlying graphics of the Frame. Is this possible? To be clear, it would be nice to have some functionality like this:
g.setDrawingOrigin(x, y);
With this sort of method, I could get away with murder. I don't know why there wouldn't be one buried somewhere...
NOTE: It is a Frame and not a JFrame, so we lack a content pane to reference. Another thing, it would be nice to avoid adding any other component to the Frame. I am trying to keep this as lightweight as possible (hence, the Frame instead of JFrame. Okay, there isn't much of a difference, but let me have my fun :D).
The method you are looking for is Graphic's translate(int, int).
So you would call,
g.translate(insets.left, insets.top);
One other approach is that instead of drawing to the Frame directly, you can add another component which fits and uses all of the Frame's space, and then do all the drawing in that subcomponent's paint method where x and y are where you expect.
Directly from the JavaDocs...
The size of the frame includes any area designated for the border. The dimensions of the border area may be obtained using the getInsets method, however, since these dimensions are platform-dependent, a valid insets value cannot be obtained until the frame is made displayable by either calling pack or show. Since the border area is included in the overall size of the frame, the border effectively obscures a portion of the frame, constraining the area available for rendering and/or displaying subcomponents to the rectangle which has an upper-left corner location of (insets.left, insets.top), and has a size of width - (insets.left + insets.right) by height - (insets.top + insets.bottom).

ToolTip for own drawings

my java application contains a JPanel on which I draw certain shapes. Now I would like to label these shapes with some kind of tooltips.
Therefore I tried to create my own "Tooltips" by using the drawString, setBackground, setColor method.:
public void drawToolTip(Graphics2D graphics, String text, Point2D position) {
graphics.setBackground(Color.RED);
graphics.setColor(Color.GREEN);
graphics.drawString(text, (float) position.getX(), (float) position.getY());
}
Unfortunately the setBackground method does not seem to work. The text background remains transparent although I set it to red. setColor and drawString just work fine.
My questions are:
What could be the reason that the setBackground method does not work?
Is there a possibility to draw a boarder arround the text without drawRect?
If I want to use "drawRect" method as a substitude to draw the text background and border: How can I make it automatically fit to the written text? Or in other words how can I get the dimensions of a specific text?
Regards Marc
Graphics2D.drawString() does not draw a background by default. You will have to do this yourself.
You can use drawRect() to draw a line border or fillRec() to draw a solid rectangle.
Oracle has a great tutorial on measuring String widths. Essentially, you need to create a java.awt.Font then get its FontMetrics and use that to calculate the width and height of your string.
A simple implementation would involve drawing onto the Graphics object of a JLabel's icon. And then simply adding the tool tip text to the Swing component.
For more information, see How to Use Tool Tips.
You can not change background color the way you expect using graphics.setBackground(..) call. Setting background color in the Graphics2D only affects the clearRect or fillRect kind of calls and not the background color of the Component.
For drawing a rectangle at a location you wish, with specific back ground, you will have to relay on following steps:
Define a rectangle - r
grpahics.setPaint() for background and
graphics.fill(r) graphcis.setPaint() for border and
graphics.draw(r) to draw border
now, comes the difficult part of drawing text in to the rectangle which involves computation of height etc. based on FontMetrics of the font you would set for drawing the text.
I googled and found an example for you here

Categories