JavaFX 2按钮大小填充宽度和宽度相同?

在Java FX 2.2中工作。 场景的水平宽度是固定的,但在编译时是未知的。 我想在一个完全填充场景中的水平空间的水平行中放置2个或更多按钮,每个按钮的宽度完全相同。 按钮数随程序状态动态变化。 什么程序片段可以实现这一目标?

来自HBox javadoc的代码几乎可以满足您的需求,除了“按钮本身根据按钮中包含的文本大小不同 – 更宽的文本会导致更宽的按钮”。

HBox hbox = new HBox(); Button button1 = new Button("Add"); Button button2 = new Button("Remove"); HBox.setHgrow(button1, Priority.ALWAYS); HBox.setHgrow(button2, Priority.ALWAYS); button1.setMaxWidth(Double.MAX_VALUE); button2.setMaxWidth(Double.MAX_VALUE); hbox.getChildren().addAll(button1, button2); 

通过创建基于HBox的自定义布局窗格并覆盖它的布局方法,您可以准确获得所描述的行为。

 import javafx.application.Application; import javafx.collections.ObservableList; import javafx.event.*; import javafx.scene.*; import javafx.scene.control.Button; import javafx.scene.layout.*; import javafx.stage.Stage; // displays equal width buttons which fill a layout region's width. // http://stackoverflow.com/questions/12830402/javafx-2-buttons-size-fill-width-and-are-each-same-width public class HorizontallyTiledButtons extends Application { public static void main(String[] args) { launch(args); } @Override public void start(Stage stage) { final Button addButton = new Button("Add"); final Button removeButton = new Button("Remove"); final Button extraButton = new Button("The wizard of Frobozz is watching"); final ButtonBar buttonBar = new ButtonBar(5, addButton, removeButton); addButton.setOnAction(new EventHandler() { @Override public void handle(ActionEvent event) { buttonBar.addButton(extraButton); } }); removeButton.setOnAction(new EventHandler() { @Override public void handle(ActionEvent event) { buttonBar.removeButton(extraButton); } }); VBox layout = new VBox(10); layout.getChildren().addAll(buttonBar); layout.setStyle("-fx-background-color: cornsilk; -fx-padding: 10;"); stage.setScene(new Scene(layout)); stage.setWidth(800); stage.show(); } class ButtonBar extends HBox { ButtonBar(double spacing, Button... buttons) { super(spacing); getChildren().addAll(buttons); for (Button b: buttons) { HBox.setHgrow(b, Priority.ALWAYS); b.setMaxWidth(Double.MAX_VALUE); } } public void addButton(Button button) { HBox.setHgrow(button, Priority.ALWAYS); button.setMaxWidth(Double.MAX_VALUE); ObservableList buttons = getChildren(); if (!buttons.contains(button)) { buttons.add(button); } } public void removeButton(Button button) { getChildren().remove(button); } @Override protected void layoutChildren() { double minPrefWidth = calculatePrefChildWidth(); for (Node n: getChildren()) { if (n instanceof Button) { ((Button) n).setMinWidth(minPrefWidth); } } super.layoutChildren(); } private double calculatePrefChildWidth() { double minPrefWidth = 0; for (Node n: getChildren()) { minPrefWidth = Math.max(minPrefWidth, n.prefWidth(-1)); } return minPrefWidth; } } } 

示例程序输出: twobuttonsthreebuttons

有点属性绑定的清洁解决方案:

  HBox buttonLayout = new HBox(); buttonLayout.getChildren().add(button1); buttonLayout.getChildren().add(button2); int btnCount = buttonLayout.getChildren().size(); button1.prefWidthProperty().bind(buttonLayout.widthProperty().divide(btnCount)); button2.prefWidthProperty().bind(buttonLayout.widthProperty().divide(btnCount));