使用JavaFX中的按钮自动缩放按钮的文本

时间:2016-05-04 15:26:36

标签: java button text javafx autoresize

我在JavaFX中创建了一个按钮网格 当我调整窗口内部网格的大小时,按钮也会在网格内调整大小 问题是这些按钮上的文本不会随之调整大小:它始终保持相同的大小,因此当按钮变大时,按钮上会有很多空白区域然后是中间的一个小小的文字,看起来很糟糕 我希望文本能够自动调整大小和这些按钮以适应空白区域,这样当整个用户界面变大时,按钮上的文字也会变大。
我怎么能做到这一点?

我尝试将CS​​S样式表中的-fx-font-size设置为百分比值,但它似乎与网站的工作方式不同:文本不会按其容器的百分比进行缩放,而是一些预定义文本大小的百分比。

修改
这是重复!停止将每个问题标记为重复!如果它已被回答,我不会在第一时间问它!

从我看到的,第一个线程是关于某人想要为新创建的按钮设置文本的大小/样式以考虑其容器的当前大小的情况这不是我需要的,因为我希望已经创建的按钮也可以在这些按钮以某种方式在容器内调整大小时自动调整文本大小。

另一个主题是关于使用预设字体大小缩放文本以及根容器/窗口。这也与我需要的不同,因为我不希望文本使用窗口进行缩放,而是使用按钮本身的大小。它必须以某种方式缩放:始终适合按钮的大小。你知道:文本保持不变,但是伸展以便它总是适合按钮的内部(带有一点填充,而不是文本周围的巨大空白区域)。

按钮的大小用于确定其上的文本大小,而不是窗口或容器或其他内容,它需要由按钮本身自动完成(或者内置的一个或一个子类的),不是通过其包含的容器手动迭代所有这些按钮并更新它们的文本大小(这将是愚蠢的方式)。

2 个答案:

答案 0 :(得分:2)

这就像链接的问题一样,是一种黑客攻击:但考虑缩放按钮内的文本节点而不是改变字体大小。这似乎工作正常:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.stage.Stage;

public class ScaledButtons extends Application {

    @Override
    public void start(Stage primaryStage) {
        GridPane root = new GridPane();
        root.setHgap(5);
        root.setVgap(5);
        for (int i = 1; i <= 9 ; i++) {
            root.add(createScaledButton(Integer.toString(i)), (i-1) % 3, (i-1) / 3);
        }
        root.add(createScaledButton("#"), 0, 3);
        root.add(createScaledButton("0"), 1, 3);
        root.add(createScaledButton("*"), 2, 3);

        primaryStage.setScene(new Scene(root, 250, 400));
        primaryStage.show();
    }

    private Button createScaledButton(String text) {
        Button button = new Button(text);
        GridPane.setFillHeight(button, true);
        GridPane.setFillWidth(button, true);
        GridPane.setHgrow(button, Priority.ALWAYS);
        GridPane.setVgrow(button, Priority.ALWAYS);

        button.layoutBoundsProperty().addListener((obs, oldBounds, newBounds) -> 
            scaleButton(button));

        button.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);

        return button ;
    }

    private void scaleButton(Button button) {
        double w = button.getWidth();
        double h = button.getHeight();

        double bw = button.prefWidth(-1);
        double bh = button.prefHeight(-1);

        if (w == 0 || h == 0 || bw == 0 || bh == 0) return ;

        double hScale = w / bw ;
        double vScale = h / bw ;

        double scale = Math.min(hScale, vScale);

        button.lookup(".text").setScaleX(scale);
        button.lookup(".text").setScaleY(scale);
    }

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

答案 1 :(得分:0)

获得类似效果的另一种方法可能是子类~ $ simctl spawn booted launchctl print system | grep com.apple.springboard.services 0x1c407 M D com.apple.springboard.services ... ~ $ simctl spawn booted launchctl print system | grep com.apple.springboard.services 0x1c407 M A com.apple.springboard.services 并从皮肤的父级(xcrun simctl bootstatus <UDID>)覆盖com.sun.javafx.scene.control.skin.ButtonSkin方法。然后,您可以显式将更新的外观分配给按钮(通过CSS或通过Java API调用)。

这样做需要layoutLabelInArea(double x, double y, double w, double h, Pos alignment) API的子类化,这些API可能会在后续JavaFX版本中发生变化,恕不另行通知。另外LabeledSkinBase的操作相当复杂,因此更改布局逻辑可能有点棘手。当然,在这种特殊情况下,James建议将基于侦听器的文本重新缩放操作应用于布局边界属性更简单。

我不一定提倡这种方法,只是提供一条路径,你可以创建一个满足你的目标的东西:“按钮的大小是确定它上面文本的大小,而不是窗口或容器或其他东西,它需要由按钮本身“。

自动完成