这是一个受内部 api 启发的 hack。
JavaFX 使用com.sun.javafx.scene.control.skin.Utils
类来进行各种基于文本的计算。这还包括计算溢出文本到多少原始文本以及在哪里显示省略号文本等。
对于未包装和非多行标签文本,此类中仅使用了 3 种方法:
static String computeClippedText(Font font, String text, double width, OverrunStyle type, String ellipsisString)
static double computeTextWidth(Font font, String text, double wrappingWidth) {...}
static int computeTruncationIndex(Font font, String text, double width) {...}
由于这个类是一个内部 api,我只是将这 3 个方法(以及必要的类变量)复制到我自己的 Utils 类中并用作:
@Override
public void start( Stage primaryStage )
{
final Label label = new Label( "Lorem Ipsum is simply dummy long text of the printing and typesetting industry" );
label.setFont( Font.font( 10 ) );
System.out.println( "originalText = " + label.getText() );
Platform.runLater( () ->
{
Double fontSize = label.getFont().getSize();
String clippedText = Utils.computeClippedText( label.getFont(), label.getText(), label.getWidth(), label.getTextOverrun(), label.getEllipsisString() );
Font newFont = label.getFont();
while ( !label.getText().equals( clippedText ) && fontSize > 0.5 )
{
System.out.println( "fontSize = " + fontSize + ", clippedText = " + clippedText );
fontSize = fontSize - 0.05;
newFont = Font.font( label.getFont().getFamily(), fontSize );
clippedText = Utils.computeClippedText( newFont, label.getText(), label.getWidth(), label.getTextOverrun(), label.getEllipsisString() );
}
label.setFont( newFont );
} );
Scene scene = new Scene( new VBox(label), 350, 200 );
primaryStage.setScene( scene );
primaryStage.show();
}
根据您的要求,您可以computeClippedText()
进一步简化逻辑并提高方法的计算时间。