使用Java FX 2.2。场景的水平宽度是固定的,但在编译时是未知的。我想在一个完全填充场景中的水平空间的水平行中放置2个或更多按钮,每个按钮的宽度完全相同。按钮数随程序状态动态变化。什么程序片段可以实现这一目标?
答案 0 :(得分:11)
来自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<ActionEvent>() {
@Override public void handle(ActionEvent event) {
buttonBar.addButton(extraButton);
}
});
removeButton.setOnAction(new EventHandler<ActionEvent>() {
@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<Node> 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;
}
}
}
示例程序输出:
答案 1 :(得分:10)
带有属性绑定的清洁解决方案:
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));