javafx自动resize和button填充

我正在尝试使用Javafx进行布局的屏幕键盘。 我正在使用场景生成器来制作FXML文件。

<?xml version="1.0" encoding="UTF-8"?> <?import java.lang.*?> <?import java.util.*?> <?import javafx.geometry.*?> <?import javafx.scene.control.*?> <?import javafx.scene.layout.*?> <?import javafx.scene.paint.*?> <?import javafx.scene.text.*?> <AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="186.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2"> <children> <VBox layoutX="0.0" layoutY="0.0" prefHeight="186.0" prefWidth="600.0" rotate="0.0" spacing="2.0"> <children> <HBox minHeight="33.0" prefHeight="33.0" prefWidth="600.0" spacing="2.0"> <children> <Label maxWidth="-Infinity" prefHeight="33.0" prefWidth="35.0" text="Milk" textAlignment="CENTER" /> <Label maxWidth="-Infinity" prefHeight="33.0" text="Mister" /> <Label maxWidth="-Infinity" prefHeight="35.0" text="Minimum" /> </children> <padding> <Insets left="5.0" /> </padding> </HBox> <HBox prefHeight="29.0" prefWidth="600.0"> <children> <Button minWidth="29.0" mnemonicParsing="false" prefHeight="27.0" prefWidth="29.0" text="Esc" textAlignment="CENTER" underline="false"> <font> <Font size="9.0" /> </font> </Button> <Button mnemonicParsing="false" text="`" textAlignment="CENTER" /> <Button mnemonicParsing="false" text="1" /> <Button mnemonicParsing="false" text="2" /> <Button mnemonicParsing="false" text="3" /> <Button mnemonicParsing="false" text="4" /> <Button mnemonicParsing="false" text="5" /> <Button mnemonicParsing="false" text="6" /> <Button mnemonicParsing="false" text="7" /> <Button mnemonicParsing="false" text="9" /> <Button mnemonicParsing="false" text="0" /> <Button mnemonicParsing="false" text="-" /> <Button mnemonicParsing="false" text="=" /> <Button mnemonicParsing="false" text="Backspace" /> </children> </HBox> <HBox prefHeight="57.0" prefWidth="600.0"> <children> <VBox minHeight="50.0" prefHeight="78.0" prefWidth="505.0" HBox.hgrow="ALWAYS"> <children> <HBox prefHeight="29.0" prefWidth="-1.0"> <children> <Button mnemonicParsing="false" prefHeight="27.0" text="Tab" /> <Button mnemonicParsing="false" text="q" /> <Button mnemonicParsing="false" text="w" /> <Button mnemonicParsing="false" text="e" /> <Button mnemonicParsing="false" text="r" /> <Button mnemonicParsing="false" text="t" /> <Button mnemonicParsing="false" text="y" /> <Button mnemonicParsing="false" text="u" /> <Button mnemonicParsing="false" text="i" /> <Button mnemonicParsing="false" text="o" /> <Button mnemonicParsing="false" text="p" /> <Button mnemonicParsing="false" text="[" /> <Button mnemonicParsing="false" text="]" /> </children> </HBox> <HBox minHeight="-1.0" prefHeight="28.0" prefWidth="-1.0"> <children> <Button mnemonicParsing="false" prefWidth="71.0" text="Caps" /> <Button mnemonicParsing="false" text="a" /> <Button mnemonicParsing="false" text="s" /> <Button mnemonicParsing="false" text="d" /> <Button mnemonicParsing="false" text="f" /> <Button mnemonicParsing="false" text="g" /> <Button mnemonicParsing="false" text="h" /> <Button mnemonicParsing="false" text="j" /> <Button mnemonicParsing="false" text="k" /> <Button mnemonicParsing="false" text="l" /> <Button mnemonicParsing="false" text=";" /> <Button mnemonicParsing="false" text="'" /> <Button mnemonicParsing="false" text="\\" /> </children> </HBox> </children> </VBox> <Button mnemonicParsing="false" prefHeight="57.0" prefWidth="132.0" text="Enter" /> </children> </HBox> <HBox prefHeight="27.000099999997474" prefWidth="600.0"> <children> <Button mnemonicParsing="false" prefWidth="85.0" text="Shift" /> <Button mnemonicParsing="false" text="z" /> <Button mnemonicParsing="false" text="x" /> <Button mnemonicParsing="false" text="c" /> <Button mnemonicParsing="false" text="v" /> <Button mnemonicParsing="false" text="b" /> <Button mnemonicParsing="false" text="n" /> <Button mnemonicParsing="false" text="m" /> <Button mnemonicParsing="false" text="," /> <Button mnemonicParsing="false" text="." /> <Button mnemonicParsing="false" text="/" /> <Button mnemonicParsing="false" text="^" /> <Button mnemonicParsing="false" prefWidth="56.0" text="Shift" /> <Button mnemonicParsing="false" text="Del" /> </children> </HBox> <HBox prefHeight="29.0" prefWidth="600.0" VBox.vgrow="ALWAYS"> <children> <Button mnemonicParsing="false" text="Fn" /> <Button mnemonicParsing="false" text="Ctrl"> <HBox.margin> <Insets /> </HBox.margin> </Button> <Button mnemonicParsing="false" text="Win" /> <Button mnemonicParsing="false" text="Alt" /> <Button mnemonicParsing="false" prefWidth="105.0" text="Space" HBox.hgrow="ALWAYS" /> <Button mnemonicParsing="false" text="Alt" /> <Button mnemonicParsing="false" prefWidth="-1.0" text="Ctrl" textAlignment="LEFT" /> <Button mnemonicParsing="false" text="&lt;" /> <Button mnemonicParsing="false" text="v" /> <Button mnemonicParsing="false" text="&gt;" /> <Button mnemonicParsing="false" text="Menu" /> </children> </HBox> </children> </VBox> </children> </AnchorPane> 

看起来像这样:

在这里输入图像描述

但是当窗口resize时,内容不会。 我想要button来获得/失去大小,直到它适合窗口。 打开了黑色和Vgrow没有奏效。

而我无法find如何设置button上的填充。 我想让Ctrl这样的button变小而不丢失文本。

根据字体大小来确定尺寸

对于您的特定情况,请尝试调整用于虚拟键盘的父级布局容器的字体大小( -fx-font-size ),而不是尝试使用填充或其他布局约束来调整button-fx-font-size 。 如果您增加字体大小,button将自动更改他们的首选大小,以匹配这个较大的大小,再加上所有的文本将自动呈现和适合的首选大小,并显示在build议填充布局的字体大小(这可能是你想要的)。

button大小调整规则

基本上可以调整button的规则是:

  1. 从button中删除maxSize约束, button.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE) 。 这是必需的,因为button的默认约束是其最大大小是其首选大小,所以它不会自动增长以填充可用空间。
  2. 获取button的首选大小是你想要的大小。 当你在做一个屏幕键盘时,一种方法是增加或减less字体大小,然后button自动resize。
  3. 如果你想在button中额外的填充,你可以在CSS中使用-fx-padding或者在代码中使用button.setPadding(new Insets(...))
  4. 将button放在可resize的父级中。
  5. 确保resize的父母实际上resize(像StackPane将自动resize,以填补可用区域,我不使用AnchorPane非常多,所以我不熟悉其调整行为)。

为了更好地理解JavaFX中的布局pipe理,我build议使用JavaFX 2.0演示文稿查看过去的JavaOne 界面布局 。

可调整的button网格示例

如果您希望继续尝试创build自己的实现,则此示例颜色select器可能会有所帮助。 颜色select实现基于可resize的可resize的button的网格,因此,当您更改颜色选取器网格的可用区域时,网格中的网格和button会展开或收缩。 颜色select器的代码不是基于FXML的,也不是直接实现你想要的键盘,但是当你在你的问题中提问时,它确实演示了button自动调整的大小。

chooserlargechoosersmall

考虑使用JavaFX虚拟键盘

JavaFX已经有一个内置的虚拟键盘 。 内置键盘没有官方支持和logging的公共API,不保证在Java版本之间维护。 但是,使用内置的虚拟键盘可能仍然是比尝试创build自己的虚拟键盘更好的方法。 创build一个高质量的通用虚拟键盘是一项相当艰巨的任务(IMO)。

嵌入式键盘

在Oracle JavaFX论坛上有关于这个主题的一些讨论。

JavaFX是开源的,所以即使不直接使用内置的虚拟键盘,也可以查看JavaFX源代码 ,看看它是如何实现的。

示例虚拟键盘代码

演示在“桌面”环境中使用内置JavaFX虚拟键盘的示例代码。

 import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.control.TextField; import javafx.scene.layout.StackPane; import javafx.stage.Stage; public class EmbeddedSample extends Application { @Override public void start(Stage stage) { stage.setScene(new Scene(new StackPane(new TextField("xyzzy")), 200, 100)); stage.getScene().setOnMouseClicked(e -> stage.hide()); stage.show(); } public static void main(String[] args) { launch(args); } } 

像这样运行示例代码:

 java -Dcom.sun.javafx.virtualKeyboard=javafx -Dcom.sun.javafx.touch=true EmbeddedSample 

示例虚拟键盘代码基于字体大小resize

keyslargerkeyssmall

keyboard.css

 .key { -fx-base: antiquewhite; } .key-row { -fx-spacing: 0.333333em; } .keyboard { -fx-spacing: 0.333333em; -fx-padding: 0.333333em; -fx-font-family: monospace; } 

ResizableKeyboardSample.java

 import javafx.application.Application; import javafx.beans.property.*; import javafx.geometry.*; import javafx.scene.Node; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.layout.*; import javafx.scene.text.Font; import javafx.stage.Stage; public class ResizableKeyboardSample extends Application { public static void main(String[] args) throws Exception { launch(args); } String[] chars = { "qwertyuiop", "asdfghjkl", "zxcvbnm" }; public void start(final Stage stage) throws Exception { Keyboard keyboard = new Keyboard(); VBox layout = new VBox(20); layout.setPadding(new Insets(10)); layout.getChildren().setAll( createControls(keyboard), keyboard ); Scene scene = new Scene(layout, 1000, 400); scene.getStylesheets().add( getClass().getResource( "keyboard.css" ).toExternalForm() ); stage.setScene(scene); stage.show(); } private Node createControls(Keyboard keyboard) { Slider fontSize = new Slider(8, 40, Font.getDefault().getSize()); keyboard.fontSizeProperty().bind(fontSize.valueProperty()); fontSize.setShowTickLabels(true); fontSize.setShowTickMarks(true); fontSize.setMajorTickUnit(2); fontSize.setMinorTickCount(0); Label typedData = new Label(); keyboard.lastKeyTextProperty().addListener((observable, oldText, newText) -> typedData.setText(typedData.getText() + newText) ); VBox layout = new VBox(10); layout.getChildren().setAll( new Label("Keyboard Size"), fontSize, typedData ); layout.setMinSize(VBox.USE_PREF_SIZE, VBox.USE_PREF_SIZE); return layout; } class Keyboard extends VBox { private DoubleProperty fontSize = new SimpleDoubleProperty(Font.getDefault().getSize()); public double getFontSize() { return fontSize.get(); } public DoubleProperty fontSizeProperty() { return fontSize; } public void setFontSize(double fontSize) { this.fontSize.set(fontSize); } private ReadOnlyStringWrapper lastKeyText = new ReadOnlyStringWrapper(); public String getLastKeyText() { return lastKeyText.get(); } public ReadOnlyStringProperty lastKeyTextProperty() { return lastKeyText.getReadOnlyProperty(); } public Keyboard() { setAlignment(Pos.BOTTOM_CENTER); setMinSize(VBox.USE_PREF_SIZE, VBox.USE_PREF_SIZE); getStyleClass().add("keyboard"); onFontSizeChange(fontSize.getValue()); fontSize.addListener((observable, oldValue, newValue) -> onFontSizeChange(newValue) ); for (String row: chars) { HBox keyRow = new HBox(); keyRow.getStyleClass().add("key-row"); keyRow.setAlignment(Pos.CENTER); for (char c: row.toCharArray()) { KeyButton key = new KeyButton(Character.toString(c)); keyRow.getChildren().add(key); } getChildren().add(keyRow); } } private void onFontSizeChange(Number newValue) { setStyle("-fx-font-size: " + newValue + "px;"); } class KeyButton extends Button { public KeyButton(String text) { super(text); getStyleClass().add("key"); setMinSize(Button.USE_PREF_SIZE, Button.USE_PREF_SIZE); setMaxSize(Button.USE_PREF_SIZE, Button.USE_PREF_SIZE); setOnAction(event -> lastKeyText.set(text)); } } } }