javafx cambio de tamaño automático y relleno de botón

Estoy intentando hacer un teclado en pantalla con Javafx para el diseño. Estoy usando Scene Builder para hacer el archivo FXML.

              

Que se ve así:

enter image description here

Pero cuando la ventana cambia de tamaño, el contenido no. Quiero que los botones ganen / pierdan tamaño hasta que encaje en la ventana. Activar a Hgrow y Vgrow no funcionó.

Y no puedo encontrar cómo configurar el relleno de los botones. Quiero hacer botones como Ctrl más pequeños sin perder el texto.

Dimensionamiento basado en el tamaño de letra

Para su caso particular, en lugar de intentar cambiar el tamaño de los botones usando relleno o restricciones de diseño adicionales, intente ajustar el tamaño de fuente ( -fx-font-size ) utilizado para el contenedor de diseño principal para su teclado virtual. Si aumenta el tamaño de la fuente, los botones cambiarán automáticamente su tamaño preferido para que coincida con este tamaño más grande, además todo el texto se procesará automáticamente y se ajustará al tamaño preferido y se mostrará en el diseño de relleno sugerido para ese tamaño de fuente ( que es probablemente lo que quieres).

Reglas de cambio de tamaño de botón

Básicamente, las reglas para cambiar el tamaño de un botón son:

  1. Elimine la restricción maxSize del botón, button.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE) . Esto es necesario porque la restricción predeterminada para un botón es que su tamaño máximo es su tamaño preferido, por lo que no crece automáticamente para llenar el espacio disponible.
  2. Obtenga el tamaño preferido del botón para el tamaño que desee. Como está haciendo un teclado en pantalla, una forma de lograr esto es boost o disminuir el tamaño de la fuente, luego el botón se ajustará automáticamente.
  3. Si desea un relleno adicional en un botón, puede usar -fx-padding en CSS o button.setPadding(new Insets(...)) en el código.
  4. Pon el botón en un padre de tamaño variable.
  5. Asegúrate de que el tamaño de los padres se cambie de tamaño (algo así como un StackPane se redimensionará automáticamente para llenar el área disponible, no uso AnchorPane mucho, así que no estoy familiarizado con su comportamiento de cambio de tamaño).

Para comprender mejor la administración del diseño en JavaFX, recomiendo ver un Layout de interfaz JavaOne pasado con la presentación JavaFX 2.0 .

Muestra de cuadrícula de botón redimensionable

Si desea continuar intentando crear su propia implementación, este selector de color de muestra podría ser de ayuda. La implementación de elegir color se basa en una cuadrícula de tamaño variable de botones redimensionables, de modo que al cambiar el área disponible para la cuadrícula de selector de color, tanto la cuadrícula como los botones de la cuadrícula se expanden o contraen. El código para el selector de color no está basado en FXML, ni implementa directamente un teclado que es lo que desea, pero sí muestra el tamaño automático de los botones mientras pregunta en su pregunta.

chooserlargeChoosersmall

Considere usar el teclado virtual JavaFX

JavaFX ya tiene un teclado virtual incorporado . El teclado incorporado no tiene una API pública oficialmente respaldada y documentada, y no se garantiza que se mantenga entre las versiones de Java. Sin embargo, usar el teclado virtual integrado podría ser un mejor enfoque que tratar de crear uno propio. Crear un teclado virtual de propósito general de calidad es una tarea bastante difícil (IMO).

teclado integrado

Existe una discusión sobre este tema en los foros de Oracle JavaFX .

JavaFX es de código abierto, por lo que incluso si no usa el teclado virtual integrado directamente, puede revisar el origen de JavaFX para ver cómo se implementa si lo desea.

Ejemplo de código de teclado virtual

Código de muestra que demuestra el uso del teclado virtual JavaFX incorporado en un entorno de “escritorio”.

 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); } } 

Ejecute el código de ejemplo de esta manera:

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

Ejemplo de código de teclado virtual para cambiar el tamaño según el tamaño de la fuente

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)); } } } }