问题描述
我在设置文字大小时遇到麻烦。尽管我找到了一种here的计算方法,但是如本示例所示,计算仍然不准确。
import java.awt.Toolkit;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class TextHeight extends javafx.application.Application {
@Override
public void start(Stage stage) {
var text = new Text("EXAMPLE");
var fontSize = 100 * Toolkit.getDefaultToolkit().getScreenResolution() / 72.0;
text.setFont(Font.loadFont(getClass().getResourceAsstream("GT Pressura Mono Regular Regular.ttf"),fontSize));
text.setFill(Color.BLUE);
text.setX(0);
text.setY(100);
var pane = new Pane(text,new Rectangle(500,10,100));
stage.setScene(new Scene(pane,600,120));
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
我现在根本不想解决文本的位置。只是字体的高度不是100px,而是大约94px。
尺寸计算是否存在问题?还是和字体有关? (我下载了here)还是问题出在其他地方?
请帮助
谢谢
解决方法
正如评论中指出的那样(链接指向真正出色的字体度量讨论),字体的大小不是大写字母的高度。
可能(我想看看其他建议),实现所需目标的最佳方法是定义一个自定义Region
来保存您的文本节点,该文本节点将覆盖{{1 }},以便调整字体大小,以使高度适合区域的大小。
一些实施说明:
-
layoutChildren()
确定如何测量文本的边界。默认值为Text.setBoundsType()
,该范围基于字体的度量标准,而不是实际呈现的文本。我认为您在这里想要的是LOGICAL
范围。 - 此实现的内容偏向垂直;表示宽度取决于高度。一旦知道了高度,就可以计算出字体大小,并根据文本的宽度计算出首选宽度。
这在一定程度上是受限制的(没有多行文本等),但是如果您想要更复杂的内容,应该为您提供一个起点。
VISUAL
这是一个示例,该示例通过将文本窗格的高度固定为public class TextPane extends Region {
private final Text text ;
public TextPane(Text text) {
this.text = text ;
getChildren().add(text);
}
@Override
protected void layoutChildren() {
adjustFontSize(getHeight());
text.setY(getHeight());
text.setX(0);
}
private void adjustFontSize(double height) {
double textHeight = text.getBoundsInLocal().getHeight();
if (Math.abs(height - textHeight) > 1) {
Font currentFont = text.getFont() ;
double fontSize = currentFont.getSize() ;
text.setFont(Font.font(currentFont.getFamily(),height * fontSize / textHeight));
}
}
@Override
protected double computePrefWidth(double height) {
adjustFontSize(height);
return text.getBoundsInLocal().getWidth();
}
@Override
public Orientation getContentBias() {
return Orientation.VERTICAL;
}
}
来实现您想要的工作:
100
如果文本具有下降的字形(例如,如果将public class TextHeight extends javafx.application.Application {
@Override
public void start(Stage stage) {
Text text = new Text("EXAMPLE");
text.setBoundsType(TextBoundsType.VISUAL);
text.setTextOrigin(VPos.BOTTOM);
text.setFill(Color.BLUE);
TextPane textPane = new TextPane(text);
textPane.setMinHeight(100);
textPane.setMaxHeight(100);
Pane root = new Pane(textPane,new Rectangle(620,10,100));
stage.setScene(new Scene(root,700,120));
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
更改为"EXAMPLE"
,因此"Example"
下降到基线以下),则文本的总高度将包括下降:
这是一个使用文本窗格作为根节点的示例(因此,其大小始终与场景相同)。更改窗口大小将导致文本自动更新以垂直填充场景:
p