/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ package net.sourceforge.pmd.util.fxdesigner.util.controls; import static net.sourceforge.pmd.util.fxdesigner.util.reactfx.ReactfxUtil.rewire; import javafx.beans.binding.Bindings; import javafx.beans.binding.DoubleBinding; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.control.ChoiceBox; import javafx.scene.control.Label; import javafx.scene.layout.StackPane; /** * A choicebox that fits the width of the currently displayed item instead * of taking the width of the largest item. * * @author Clément Fournier */ public class DynamicWidthChoicebox<T> extends ChoiceBox<T> { public DynamicWidthChoicebox() { ControlUtil.subscribeOnSkin( this, skin -> { Label label = (Label) skin.getNode().lookup(".label"); StackPane arrow = (StackPane) skin.getNode().lookup(".open-button"); boolean showArrow = !getStyleClass().contains("no-arrow"); label.setAlignment(showArrow ? Pos.CENTER_LEFT : Pos.CENTER); DoubleBinding widthBinding = Bindings.createDoubleBinding( () -> { Insets myInsets = getInsets(); double arrowWidth = showArrow ? arrow.prefWidth(-1) : 0; return myInsets.getLeft() + label.prefWidth(-1) + arrowWidth + myInsets.getRight(); }, label.widthProperty(), this.getSelectionModel().selectedItemProperty(), this.insetsProperty() ); return rewire(this.prefWidthProperty(), widthBinding); } ); } }