package bluej.utility.javafx;

import bluej.utility.Debug;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.css.CssMetaData;
import javafx.css.SimpleStyleableDoubleProperty;
import javafx.css.Styleable;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.scene.Node;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Region;

import java.util.List;
import java.util.stream.Collectors;


| A VBox that behaves better with respect to sizing its children and | particularly FlowPane children. | | Possibly, this behaviour could be achieve by tweaking VBox in just | the right way. But this class works, and that will do for me. | public class BetterVBox extends Pane{ private final double minWidth; private final DoubleProperty spacingProperty = new SimpleDoubleProperty(0.0); public final DoubleProperty spacingProperty() { return spacingProperty; } public BetterVBox(double minWidth) { this.minWidth = minWidth; } @Override protected void layoutChildren() { final Insets padding = getPadding(); double y = (int)padding.getTop(); final double contentWidth = getWidth() - (int)padding.getLeft() - (int)padding.getRight(); for (Node n : getManagedChildren()) { y += getTopMarginFor(n); double w = Math.min(contentWidth - (int)getLeftMarginFor(n) - (int)getRightMarginFor(n), n.maxWidth(-1)); double h = n.prefHeight(w); n.resizeRelocate((int) padding.getLeft() + (int)getLeftMarginFor(n), y, w, h); y += h + spacingProperty.get() + getBottomMarginFor(n); } } @Override public boolean isResizable() { return true; } @Override protected double computeMinWidth(double height) { return minWidth; } @Override protected double computeMinHeight(double width) { final Insets padding = getPadding(); final double contentWidth = width - (int)padding.getLeft() - (int)padding.getRight(); double reqMin = (getMinHeight() == Region.USE_COMPUTED_SIZE || getMinHeight() == Region.USE_PREF_SIZE) ? 0 : getMinHeight(); return Math.max(reqMin, getManagedChildren().stream().mapToDouble(n -> getTopMarginFor(n) + getBottomMarginFor(n) + n.prefHeight(contentWidth)).sum()) + (int)padding.getTop() + (int)padding.getBottom(); } @Override protected double computePrefWidth(double height) { return 2000.0; } @Override protected double computePrefHeight(double width) { if (width == -1 || width == 2000) { Debug.printCallStack("Problem in BetterVBox: calculating height first, which should not happen -- are you running ScenicView?"); width = 2000; } final Insets padding = getPadding(); final double contentWidth = width - (int)padding.getLeft() - (int)padding.getRight(); double reqMin = (getMinHeight() == Region.USE_COMPUTED_SIZE || getMinHeight() == Region.USE_PREF_SIZE) ? 0 : getMinHeight(); double contentHeight = 0; for (Node n : getManagedChildren()) { contentHeight += getTopMarginFor(n) + getBottomMarginFor(n) + n.prefHeight(contentWidth - getLeftMarginFor(n) - getRightMarginFor(n)); } return Math.max(reqMin, contentHeight) + (int)padding.getTop() + (int)padding.getBottom(); } @Override protected double computeMaxHeight(double width) { return computePrefHeight(width); } @Override protected double computeMaxWidth(double height) { return Double.MAX_VALUE; } @Override public Orientation getContentBias() { return Orientation.HORIZONTAL; } public double getTopMarginFor(Node n) { return 0; } public double getBottomMarginFor(Node n) { return 0; } public double getLeftMarginFor(Node n) { return 0; } public double getRightMarginFor(Node n) { return 0; } }
top, use, map, class BetterVBox

.   spacingProperty
.   BetterVBox
.   layoutChildren
.   isResizable
.   computeMinWidth
.   computeMinHeight
.   computePrefWidth
.   computePrefHeight
.   computeMaxHeight
.   computeMaxWidth
.   getContentBias
.   getTopMarginFor
.   getBottomMarginFor
.   getLeftMarginFor
.   getRightMarginFor




162 neLoCode + 4 LoComm