[英]Scaling a button's text automatically with the button in JavaFX
我在JavaFX中制作了一个按钮网格。
当我调整内部带有网格的窗口的大小时,按钮也会在网格内重新调整大小。
问题在于这些按钮上的文本不会随它们调整大小:它始终保持相同的大小,因此当按钮变大时,按钮上会有很多空白,然后中间,看起来很糟糕。
我希望文本与这些按钮一起自动调整大小以适合空白区域,以便当整个用户界面变大时,按钮上的文本也变大。
我该怎么做?
我尝试将CSS样式表中的-fx-font-size
设置为百分比值,但是它的工作方式似乎与网站不同:文本不会按其容器的百分比缩放,而是按百分比缩放一些预定义的文本大小。
编辑
这不是重复的! 停止将每个问题标记为重复! 如果已回答,那么我一开始就不会要求它!
从我的角度来看,第一个线程是关于有人想要设置新创建的按钮的文本大小/样式以说明其容器的当前大小等情况的。这不是我所需要的,因为我希望当这些按钮以某种方式在其容器内调整大小时, 已经创建的按钮也能自动调整其文本大小。
另一个主题是使用预设的字体大小缩放文本以及根容器/窗口。 这也与我需要的有所不同,因为我不希望文本使用window缩放,而是使用按钮本身的大小缩放。 它必须以某种方式缩放:始终适合按钮的大小。 您知道:文本保持不变,但是会拉伸以使其始终适合按钮的内部(带有少量填充,而不是文本周围的巨大空白区域)。
按钮的大小决定了文本的大小,而不是窗口或容器等的大小,它需要由按钮本身自动完成(内置按钮或子类按钮),而不是通过其包含的容器手动遍历所有这些按钮并更新其文本大小(这样做是愚蠢的方式)。
就像链接的问题一样,这有点像hack:但是请考虑缩放按钮内的文本节点,而不是更改字体大小。 这似乎工作正常:
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);
}
}
另一种获得类似效果的方法可以是com.sun.javafx.scene.control.skin.ButtonSkin
子类,并从皮肤的父级重写layoutLabelInArea(double x, double y, double w, double h, Pos alignment)
方法( LabeledSkinBase
)。 然后,您可以显式地将更新的外观分配给按钮(通过CSS或Java API调用)。
这样做将需要com.sun
API的子类,该子类可能会在后续的JavaFX版本中更改而不会另行通知。 而且layoutLabelInArea
操作相当复杂,因此更改布局逻辑可能会有些棘手。 当然,在这种特殊情况下,James建议将基于侦听器的文本重新缩放操作应用于layout bounds属性的建议更为简单。
我不一定要提倡这种方法,而只是提供一条可以创建的路径,该路径可以满足您的目标:“按钮的大小决定了文本的大小,而不是窗口或容器的大小。其他事情,则需要按钮本身自动完成”。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.