我正在尝试在javafx中创建一个包含一组按钮的自定义窗格。 窗格自动布置按钮,以便它们占用最大允许宽度。
窗格效果很好,我遇到的问题是,当舞台上设置场景时,按钮会布局,但屏幕下方会显示。
我在舞台上所做的任何动作(包括点击另一个窗口并对舞台进行去焦点)都会使它们正确布局。
我无法弄清楚发生了什么。 我想发布正在发生的事情的屏幕截图,问题是当我去截取屏幕时,窗口去焦点,然后条形图正确显示。
public class ButtonBar extends Pane {
//Add to auto generated buttons
protected String buttonPrefix = "F";
protected String buttonSuffix = "";
//Container sizing
protected DoubleProperty prefHeight = new SimpleDoubleProperty();
//Button Sizing
protected DoubleProperty buttonWidth = new SimpleDoubleProperty();
protected DoubleProperty buttonHeight = new SimpleDoubleProperty();
//Button Positioning
protected ArrayList<DoubleProperty> buttonXLocation;
//Static Button sizing
protected double interButtonMargin = 1;
protected double endButtonMargin = 10;
//Store whether initialized
protected boolean initialized = false;
//Listen for change to relayout
InvalidationListener layoutListener;
public int getNumberButtons() {
return numberButtons;
}
public void setNumberButtons(int numberButtons) {
this.numberButtons = numberButtons;
}
//Number of buttons
protected int numberButtons = 12;
protected boolean respectApsectRatio = true;
public ButtonBar() {
this(12);
}
public ButtonBar(List<Button> buttons) {
this.numberButtons = buttons.size();
getChildren().addAll(buttons);
}
public ButtonBar(int numButtons) {
this.numberButtons = numButtons;
for (int i = 0; i < numButtons; i++) {
Button button = new Button(String.valueOf(i + 1));
button.setStyle("-fx-background-radius: 7; -fx-font-size: 30px; -fx-background-color: #ffb366");
getChildren().add(button);
}
}
protected void init() {
buttonXLocation = new ArrayList<DoubleProperty>(numberButtons);
List<Node> children = getChildren();
//Calculate button width minus paddings
buttonWidth.bind(
widthProperty()
.subtract(interButtonMargin * (numberButtons - 1))
.subtract(endButtonMargin * 2)
.divide(numberButtons)
);
if (!respectApsectRatio) {
buttonHeight.bind(heightProperty());
prefHeight.bind(heightProperty());
} else {
buttonHeight.bind(buttonWidth);
prefHeight.bind(buttonHeight);
}
int i = 0;
for (Node n : getChildren()) {
Button b = (Button) n;
DoubleProperty buttonX = new SimpleDoubleProperty();
buttonX.bind(buttonWidth
.multiply(i)
.add(endButtonMargin)
.add(interButtonMargin * i)
);
buttonXLocation.add(i, buttonX);
//Set button text
b.setText(buttonPrefix + b.getText() + buttonSuffix);
i++;
}
setNeedsLayout(true);
this.initialized = true;
layoutListener = new InvalidationListener() {
@Override
public void invalidated(Observable observable) {
setNeedsLayout(true);
layout();
layoutChildren();
}
};
widthProperty().addListener(layoutListener);
heightProperty().addListener(layoutListener);
}
@Override
protected void layoutChildren() {
//Only initialize once
if( !initialized ) init();
super.layoutChildren();
setPrefHeight(prefHeight.doubleValue());
List<Node> buttons = getChildren();
for (int i = 0; i < buttons.size(); i++) {
Button button = (Button) buttons.get(i);
button.setPrefWidth(buttonWidth.doubleValue());
button.setPrefHeight(buttonHeight.doubleValue());
button.setLayoutX(buttonXLocation.get(i).doubleValue());
button.setLayoutY(0);
}
super.layoutChildren();
}`