在JavaFX中,有没有办法在同一文本行中使用两种不同的字体大小?

在JavaFX中,有没有办法在同一文本行中使用两种不同的字体大小?,java,javafx,text,formatting,eclipse-neon,Java,Javafx,Text,Formatting,Eclipse Neon,我正在用Java制作一个windows运行的移动概念股票市场游戏,它是JavaFX库,我希望在玩家当前余额的右下角有货币形式(在我的例子中是美元)。这样做的关键是,每当玩家在游戏中获得1000美元的倍数时,玩家的余额就会变大,这意味着持有玩家余额的字符串也会变大。这会导致应用程序中字符串“USD”的固定位置与播放器的当前余额重叠 我试着简单地强迫程序在数字增加1000倍时移动“USD”符号。然而,这似乎效率很低,我敢打赌,有一种更简单的方法可以做到这一点 double balance =

我正在用Java制作一个windows运行的移动概念股票市场游戏,它是JavaFX库,我希望在玩家当前余额的右下角有货币形式(在我的例子中是美元)。这样做的关键是,每当玩家在游戏中获得1000美元的倍数时,玩家的余额就会变大,这意味着持有玩家余额的字符串也会变大。这会导致应用程序中字符串“USD”的固定位置与播放器的当前余额重叠

我试着简单地强迫程序在数字增加1000倍时移动“USD”符号。然而,这似乎效率很低,我敢打赌,有一种更简单的方法可以做到这一点

    double balance = 12313.00;

    DecimalFormat decimalFormat = new DecimalFormat("#,###");
    String numberAsString = decimalFormat.format(balance);

    Text balanceText = new Text("$" + (numberAsString));
    balanceText.setFont(Font.font("Modernist", 72));
    balanceText.setFill(Color.web("77e6b3"));
    balanceText.setLayoutX(25);
    balanceText.setLayoutY(250);

    Text currencyText = new Text("USD");
    currencyText.setFont(Font.font("Modernist", 36));
    currencyText.setFill(Color.web("77e6b3"));
    currencyText.setLayoutX(275);
    currencyText.setLayoutY(250);

不要试图手动设置
文本
节点的X/Y坐标,而应该利用许多内置函数

通过在JavaFX中混合不同的布局窗格,可以轻松构建非常复杂的UI布局。每个
窗格
都可以独立设置样式和配置,每个窗格应用不同的布局“规则”

我建议通过阅读上面的链接来更好地了解可用的内容,但对于您的问题,我在下面提供了一个完整的示例


基本上,我们使用的是一个
HBox
,以水平方向保持玩家的余额和货币名称。由于我们的玩家货币有一个完全独立的
标签
,当我们增加该
标签
的值或字体大小时,界面的其余部分不受影响(意味着货币类型可以保持相同的大小)


结果:


注意:有许多额外的格式和样式选项可供选择,以确保您的布局符合预期。您需要通读JavaDocs或查找其他教程以了解更多信息。这个答案只是为了说明许多可能的解决方案之一

可以使用渲染器以多种字体、大小、样式和颜色呈现富文本:

示例代码

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.VPos;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.*;
import javafx.scene.text.TextFlow;
import javafx.stage.Stage;

import java.text.DecimalFormat;

public class MoMoney extends Application {
    @Override
    public void start(Stage stage) throws Exception {
        double balance = 12313.00;

        DecimalFormat decimalFormat = new DecimalFormat("#,###");
        String numberAsString = decimalFormat.format(balance);

        Text balanceText = new Text("$" + (numberAsString));
        balanceText.setFont(Font.font("Modernist", 72));
        balanceText.setFill(Color.web("77e6b3"));

        Text currencyText = new Text("USD");
        currencyText.setTextOrigin(VPos.TOP);
        currencyText.setFont(Font.font("Modernist", 36));
        currencyText.setFill(Color.web("77e6b3"));

        TextFlow flow = new TextFlow(balanceText, currencyText);
        flow.setMinSize(TextFlow.USE_PREF_SIZE, TextFlow.USE_PREF_SIZE);

        VBox layout = new VBox(flow);
        layout.setPadding(new Insets(10));

        stage.setScene(new Scene(layout));
        stage.getScene().setFill(Color.rgb(35, 39, 50));
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }
}
JavaDoc说明

来自上面链接的JavaDoc的TextFlow说明:

TextFlow是一种特殊的布局,设计用于布局富文本。它可用于在单个文本流中布局多个文本节点。TextFlow使用文本及其内部每个文本节点的字体加上自身的宽度和文本对齐方式来确定每个子节点的位置

实施意见

默认情况下,如果没有足够的空间渲染所有文本,TextFlow会将文本换行,因此我将TextFlow的最小大小设置为其首选大小以防止出现这种情况

TextFlow可以使用标准的基于宽度的对齐设置(如左对齐、右对齐、对齐等)对齐文本。但是,TextFlow无法垂直对齐文本,例如生成上标值。还有其他限制,例如使文本可选择用于复制和粘贴或编辑文本。所以,看看它,试着看看它是否适合你的目的,如果没有,那么考虑下面提到的其他替代机制。

替代方法

其他有效的方法包括:

  • 使用带有约束的布局容器来控制布局(如Zephyr的回答和这个相关问题:)
  • 嵌入用于呈现CSS格式html的
  • 使用第三方库,如

  • 如果我理解正确,您可能需要查看不同的JavaFX布局窗格选项(
    VBox
    HBox
    Stackpane
    ,等等)。如果将玩家的余额保存在与“USD”字符串分开的容器中,则无论余额文本增长多少,都可以强制它们永不重叠。但是,如果没有关于您的问题的更多详细信息,就不可能给出确切的答案。除非您使用的是图形或动画,否则我认为您应该尽可能避免使用
    .setLayoutX()
    .setlayoutY()
    。让JavaFX容器为您处理布局。为常规UI控件设置绝对位置几乎总是会导致布局问题。您可能不应该使用文本,而应该使用标签。
    import javafx.application.Application;
    import javafx.geometry.Insets;
    import javafx.geometry.VPos;
    import javafx.scene.Scene;
    import javafx.scene.layout.VBox;
    import javafx.scene.paint.Color;
    import javafx.scene.text.*;
    import javafx.scene.text.TextFlow;
    import javafx.stage.Stage;
    
    import java.text.DecimalFormat;
    
    public class MoMoney extends Application {
        @Override
        public void start(Stage stage) throws Exception {
            double balance = 12313.00;
    
            DecimalFormat decimalFormat = new DecimalFormat("#,###");
            String numberAsString = decimalFormat.format(balance);
    
            Text balanceText = new Text("$" + (numberAsString));
            balanceText.setFont(Font.font("Modernist", 72));
            balanceText.setFill(Color.web("77e6b3"));
    
            Text currencyText = new Text("USD");
            currencyText.setTextOrigin(VPos.TOP);
            currencyText.setFont(Font.font("Modernist", 36));
            currencyText.setFill(Color.web("77e6b3"));
    
            TextFlow flow = new TextFlow(balanceText, currencyText);
            flow.setMinSize(TextFlow.USE_PREF_SIZE, TextFlow.USE_PREF_SIZE);
    
            VBox layout = new VBox(flow);
            layout.setPadding(new Insets(10));
    
            stage.setScene(new Scene(layout));
            stage.getScene().setFill(Color.rgb(35, 39, 50));
            stage.show();
        }
    
        public static void main(String[] args) {
            launch();
        }
    }