我正在尝试将文本准确地放置在窗格的水平和垂直中心.使用fontmetrics和测试程序,我得到以下结果:
该测试提出了以下问题:
以下是Frank reportSize功能的替代实现:
public void reportSize(String s, Font myFont) {
Text text = new Text(s);
text.setFont(myFont);
Bounds tb = text.getBoundsInLocal();
Rectangle stencil = new Rectangle(
tb.getMinX(), tb.getMinY(), tb.getWidth(), tb.getHeight()
);
Shape intersection = Shape.intersect(text, stencil);
Bounds ib = intersection.getBoundsInLocal();
System.out.println(
"Text size: " + ib.getWidth() + ", " + ib.getHeight()
);
}
Run Code Online (Sandbox Code Playgroud)
此实现使用形状交集来确定渲染形状的边界框的大小,没有空格.该实现不依赖com.sun于Java 9+中的用户应用程序代码可能无法直接访问的包类.
经过一番实验后,我想出了这个解决方案:
这是生成它的代码:
public void getBoundingBox(String s, Font myFont) {
final FontMetrics fm = Toolkit.getToolkit().getFontLoader().getFontMetrics(myFont);
final Canvas canvas = new Canvas(fm.computeStringWidth(s), fm.getAscent() + fm.getDescent());
final GraphicsContext gc = canvas.getGraphicsContext2D();
gc.setFill(Color.RED); // Just an abitrary color
gc.setTextBaseline(VPos.TOP); // This saves having to scan the bottom
gc.setFont(myFont);
gc.fillText(s, -fm.getLeading(), 0); // This saves having to scan the left
// Get a snapshot of the canvas
final WritableImage image = canvas.snapshot(null, null);
final PixelReader pr = image.getPixelReader();
final int h = (int) canvas.getHeight();
final int w = (int) canvas.getWidth();
int x;
int y = 0;
// Scan from the top down until we find a red pixel
boolean found = false;
while (y < h && !found) {
x = 0;
while (x < w && !found) {
found = pr.getColor(x, y).equals(Color.RED);
x++;
}
y++;
}
int yPos = y - 2;
// Scan from right to left until we find a red pixel
x = w;
found = false;
while (x > 0 && !found) {
y = 0;
while (y < h && !found) {
found = pr.getColor(x, y).equals(Color.RED);
y++;
}
x--;
}
int xPos = x + 3;
// Here is a visible representation of the bounding box
Rectangle mask = new Rectangle(0, yPos, xPos, h - yPos);
mask.setFill(Color.rgb(0, 0, 255, 0.25));
root.getChildren().addAll(canvas, mask); // root is a global AnchorPane
System.out.println("The width of the bounding box is " + xPos);
System.out.println("The height of the bounding box is " + (h - yPos));
}
Run Code Online (Sandbox Code Playgroud)
FontMetrics 需要两次导入:
import com.sun.javafx.tk.FontMetrics;
import com.sun.javafx.tk.Toolkit;
Run Code Online (Sandbox Code Playgroud)
并像这样调用边界框:
Font myFont = new Font("Arial", 100.0);
getBoundingBox("Testing", myFont);
Run Code Online (Sandbox Code Playgroud)
它解决了我的问题,我希望这对其他人也有用。