I want to center a block of text in a rectangle. I am currently using the PDFont.getStringWidth method for centering horizontally. However, I do not see a corresponding PDFont.getStringHeight method. Is there a way to get the height of a string, taking into account descenders? I see the getHeight method, but that would only work for a single character, and sounds like it would be expensive to call for a long string.
Related
I'm trying to display text inside a rectangle which I have the dimensions of (x, y, width, and height). However, if the text's length is long enough to the point where the text would leak outside the rectangle, I want to instead display as many characters as possible in a single line, followed by ellipses (...). I am aware that I can use the Graphics.getFontMetrics().stringWidth(text) to get the width the text would occupy in pixels. I could use this method by looping through, adding a character at a time to the string that would be displayed and checking if its width exceeds the rectangle's width. However, this feels inefficient.
As such, I want to know if there is a better/efficient way of doing this.
Actually i am trying to display the line number and coloumn number the user is currently typing in a JTextArea . My question is how can i convert CaretEvent.getDot() to rectangular coordinates so that i can achieve this ? Or is there any other method ?
Perhaps you're looking to use the JTextArea method, public Rectangle modelToView(int location). Actually this is a method from JTextArea's parent class, JTextComponent, and can help translate an int location in the document to the current rectangle location in the GUI itself, relative to the text component.
i am trying to display the line number and coloumn number the user is currently typing in a JTextArea
Check out Text Utilities. It provides methods like:
getColumnAtCaret(...)
getLineAtCaret(...)
So I have this situation:
I have a JList that displays a bunch of Strings.
However, these strings are really long and JList is really narrow. Meaning the strings won't fit.
What I want to do is make each entry to have two rows, like this:
|Word word word |
|word word wor...|
It would do wordWrap for the first row, and then finish the secon't row by cutting the rest of the string and appeinging the three dots to what is left in a way maximum space is filled.
It doesn't really matter what I do, the important thing is that I have to use FontMetrics to measure all this stuff so I can make it work. And that's the catch.
Until whole getListCellRendererComponent(...) method is executed, the component will not be painted, thus having no graphics, thus making any font measurement impossible.
How do I get around it?
P.S. I need to use the JLabel for the visuals.
the component will not be painted, thus having no graphics, thus making any font measurement impossible.
You don't need the Graphics to use the FontMetrics.
See Left Dot Renderer which is used for a JTable, but the concepts should be the same for a list renderer as well.
You need to use JLabels? It'd be a lot easier to have getListCellRendererComponent() return a JTextArea whose height has been set to 2 lines and which has setLineWrap() and setWrapStyleWord() both set to true. Make the JTextArea uneditable, and it'll look like a 2-line JLabel.
From an xml file, I'm given a width, height and id. All of them can and do vary very quickly. Now, I'm asked to draw a rectangle using the width and height (an easy task), and place the id at its center. The id must not overflow out of the rectangle it's contained it.
For single-character strings, this is also easy - set the font size to the height, play a bit with the x position maybe, and it's centered. The problem is when it's multi-character strings.
So given a width and height and a string, how can you determine what font-size the string should appear in? Assume you have every bit of information you need on the rectangle you're drawing the string in.
[Edit]: I'm using the Graphics 2D class to draw everything.
Start with selecting a Font at your preferred (i.e. maximum) size.
Grab the FontRenderContext from your Graphics2D object using getFontRenderContext.
Use getStringBounds() on the Font to be rendered to get a Rectangle2D object for the specific String to be rendered. That object describes the final size of the String using that Font
Check if the size specified by that Rectangle2D is small enough.
4a. If it is small enough, you're done. Use the last Font you've checked.
4b. If it is too big, use Font.derive() to produce a smaller version of the Font and continue to use that and loop back to 3.
Don't quite have the time to give you a full working example, but here are a couple pointers that should get you going in the right direction. The graphics object you are using to draw with has a getFontMetrics() method, one of the methods on FontMetrics is stringWidth(String str) which gives you the width of a string in the current Font.
If the width is too big for your rectangle set the Font on the Graphics object to the same font just with a smaller size until it fits.
To horizontally center a string in a container (learned long ago in typing class in high school):
(rectangleWidth / 2) - (stringWidth / 2)
http://download.oracle.com/javase/1.5.0/docs/api/java/awt/FontMetrics.html
To create a Font with a smaller size, something like:
Font font = graphics.getFont();
Font smallerFont = font.derive(font.getSize() - 1);
graphics.setFont(smallerFont);
Hope this gets you going in the right direction.
I would recommend for this problem to remove as many unknowns as possible. In this case, the problem chiefly is that font characters can vary in width... well most. That's why I would use a good monospace font like courier new for the ID, that way you know what the width of each character is, you know the width of your rectangle and you know the number of characters in your string. You can simply reduce the pixel size of each character will till your string fits the available width.
Example, if the width of each character is 12px and you have 10 characters in your ID, then you need 120px to fit everything in. If you only have 80px available, it's simple math 80/10 = 8px font-size (reduce half a pixel for padding if you want.
Just my suggestion.
I'm creating a graphical timeline out of an excel document and I need to have small tags of the name of the event next to the marker for that event. Some of these are easy and are right justified but others are left justified and I need to figure out their width so that I can properly offset them.
window.drawString("7/4-Fourth of July",horizontalIndex-Offset,verticalIndex);
Currently I'm averaging the pixel width using an average of both font sizes 10 and 32, but this doesn't really cut it. Can someone help me get the exact offset?
This thread explains how to do it:
Calculate the display width of a string in Java
You should first get the font metrics, and then ask the metrics how wide a certain string is.
from a java.awt.Graphics object, you can call getFontMetrics. the FontMetrics object has a getStringBounds method that does what you need.
here's the documentation
and another good alternative is SwingUtilities#computeStringWidth(FontMetrics fm, String str)
As a (read: my ;-) general rule, never use the Graphics-level drawString methods. Instead, use a JLabel/CellRendererPane pair to "stamp" the text onto whatever component.
The advantages
anti-alias is handled automagically
size calculations are done in the labels' bowels, so positioning calculations dont require any low-level methods but simply based on the labels' prefSize
TextLayout, shown here, is another alternative.