JavaFX:为什么我的HBox孩子有时会重叠?

时间:2017-03-17 10:28:37

标签: java user-interface javafx

我有这个非常奇怪的问题。让我试着解释一下:

My Image

我创建了一个名为NumberPicker的类,其基本构思取自here。我们的想法是扩展HBox,将Label放入其中,将另一个VBox放入其中Button。最后,它应该如下所示:(见我的图像上的(1))

这是我的代码:

public class NumberPicker extends HBox {

    private Label label = null;
    private VBox vBox = null;
    private Button incrementButton = null, decrementButton = null;

    private String valueFormatString;
    private Number value;
    private Number stepWidth;
    private boolean isFloat = false;

    public Number getValue() {
        return value;
    }

    public NumberPicker(Number startValue, Number stepWidth, String valueFormatString) {
        super();

        this.valueFormatString = valueFormatString;
        value = startValue;
        this.stepWidth = stepWidth;

        if (value instanceof Float) {
            isFloat = true;
        }
    }

    public void init() {
        label = new Label();
        label.setFont(Font.font(20));
        label.setText(String.format(valueFormatString, value));

        vBox = new VBox();

        //partially taken from https://dzone.com/articles/javafx-numbertextfield-and
        int ARROW_SIZE = 4;

        Path arrowUp = new Path();
        arrowUp.getElements().addAll(new MoveTo(-ARROW_SIZE, 0), new LineTo(ARROW_SIZE, 0),
                new LineTo(0, -ARROW_SIZE), new LineTo(-ARROW_SIZE, 0));
        arrowUp.setMouseTransparent(true);

        Path arrowDown = new Path();
        arrowDown.getElements().addAll(new MoveTo(-ARROW_SIZE, 0), new LineTo(ARROW_SIZE, 0),
                new LineTo(0, ARROW_SIZE), new LineTo(-ARROW_SIZE, 0));
        arrowDown.setMouseTransparent(true);

        NumberBinding buttonHeight = label.heightProperty().divide(2);

        incrementButton = new Button();
        incrementButton.prefWidthProperty().bind(label.heightProperty());
        incrementButton.minWidthProperty().bind(label.heightProperty());
        incrementButton.maxHeightProperty().bind(buttonHeight);
        incrementButton.prefHeightProperty().bind(buttonHeight);
        incrementButton.minHeightProperty().bind(buttonHeight);
        incrementButton.setOnAction(handler);

        StackPane incPane = new StackPane();
        incPane.getChildren().addAll(incrementButton, arrowUp);
        incPane.setAlignment(Pos.CENTER);

        decrementButton = new Button();
        decrementButton.prefWidthProperty().bind(label.heightProperty());
        decrementButton.minWidthProperty().bind(label.heightProperty());
        decrementButton.maxHeightProperty().bind(buttonHeight);
        decrementButton.prefHeightProperty().bind(buttonHeight);
        decrementButton.minHeightProperty().bind(buttonHeight);
        decrementButton.setOnAction(handler);

        StackPane decPane = new StackPane();
        decPane.getChildren().addAll(decrementButton, arrowDown);
        decPane.setAlignment(Pos.CENTER);

        vBox.getChildren().addAll(incPane, decPane);

        setAlignment(Pos.CENTER);
        getChildren().addAll(label, vBox);
    }

    private EventHandler<ActionEvent> handler = (ActionEvent event) -> {
        if (event.getSource() == incrementButton) {
            if (isFloat) {
                value = value.floatValue() + stepWidth.floatValue();
            } else {
                value = value.intValue() + stepWidth.intValue();
            }
        } else {
            if (isFloat) {
                value = value.floatValue() - stepWidth.floatValue();
            } else {
                value = value.intValue() - stepWidth.intValue();
            }
        }
        if (isFloat) {
            label.setText(String.format(valueFormatString, value.floatValue()));
        } else {
            label.setText(String.format(valueFormatString, value.intValue()));
        }
    };

}

所以关于这一点的是,如果我创建一个HBox并填写如下:

    HBox pickers = new HBox();
    NumberPicker np1 = new NumberPicker(1, 1, "%d");
    np1.init();
    Label label = new Label("TEST");
    NumberPicker np2 = new NumberPicker(1, 1, "%d");
    np2.init();
    pickers.getChildren().addAll(np1, label, np2);

结果如下:(见“我的形象”上的(2))

这对我来说真的很奇怪。第一个NumberPicker看起来不错,第二个没有。它更奇怪:如果我使用Button中的NumberPicker,则Button向右跳一点,看起来像另一个,正确NumberPicker :(见(3)在我的形象上)

我不知道问题是什么。我试着用ScenicView进行分析,它给了我以下信息:

NumberPicker: prefWidth 22,00
    Label: prefWidth 10,78
    VBox: prefWidth 30,00

这告诉我NumberPicker的计算prefWidth应该是41,因为它的子宽度总和大约为41,但实际值为22.一旦我点击{{ 1}} Button值更改为41。

有人可以帮我解决这个问题吗?我显然希望prefWidth看起来很好(如我的图像中的(3)),而不必先点击按钮。

顺便说一下。抱歉图像的奇怪之处。因此,我不允许发布超过2个名称低于10的链接

0 个答案:

没有答案