All Downloads are FREE. Search and download functionalities are using the official Maven repository.

tornadofx.control.Fieldset Maven / Gradle / Ivy

package tornadofx.control;

import javafx.beans.DefaultProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.ListChangeListener;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;

import java.util.stream.Stream;

import static javafx.scene.layout.Priority.SOMETIMES;

@SuppressWarnings("unused")
@DefaultProperty("children")
public class Fieldset extends VBox {
	private SimpleStringProperty text = new SimpleStringProperty();
	private ObjectProperty inputGrow = new SimpleObjectProperty<>(SOMETIMES);

	public Fieldset(String text) {
		this();
		setText(text);
	}

	public Field field(String text, Node... inputs) {
		Field field = new Field(text, inputs);
		getChildren().add(field);
		return field;
	}

	public Field field() {
		Field field = new Field();
		getChildren().add(field);
		return field;
	}

	public Field field(Node... inputs) {
		Field field = new Field(null, inputs);
		getChildren().add(field);
		return field;
	}

	public Fieldset() {
		getStyleClass().add("fieldset");

		// Add legend label when text is populated
		textProperty().addListener((observable, oldValue, newValue) -> {
			if (newValue != null) addLegend();
		});

		// Make sure input children gets the configured HBox.hgrow property
		getChildren().addListener((ListChangeListener) c -> {
			while (c.next()) {
				if (c.wasAdded()) {
					c.getAddedSubList().stream().filter(added -> added instanceof Field).forEach(added -> {
						Field field = (Field) added;

						// Configure hgrow for current children
						for (Node input : field.getInputContainer().getChildren())
							configureHgrow(input);

						// Add listener to support inputs added later
						field.getInputContainer().getChildren().addListener((ListChangeListener) c1 -> {
							while (c1.next()) if (c1.wasAdded()) c1.getAddedSubList().forEach(this::configureHgrow);
						});
					});
				}
			}
		});

		// Change HGrow for unconfigured children when inputGrow changes
		inputGrowProperty().addListener((observable, oldValue, newValue) -> {
			getChildren().stream().filter(c -> c instanceof Field).forEach(c -> {
				Field field = (Field) c;
				field.getInputContainer().getChildren().forEach(this::configureHgrow);
			});
		});
	}

	private void addLegend() {
		Label legend = new Label();
		legend.textProperty().bind(textProperty());
		legend.getStyleClass().add("legend");
		getChildren().add(0, legend);
	}

	private void configureHgrow(Node input) {
		HBox.setHgrow(input, getInputGrow());
	}

	public Form getForm() {
		return (Form) getParent();
	}

	Stream getFields() {
		return getChildren().stream()
			.filter(c -> c instanceof Field)
			.map(c -> (Field) c);
	}

	public Priority getInputGrow() {
		return inputGrow.get();
	}

	public ObjectProperty inputGrowProperty() {
		return inputGrow;
	}

	public void setInputGrow(Priority inputGrow) {
		this.inputGrow.set(inputGrow);
	}

	public String getText() {
		return text.get();
	}

	public SimpleStringProperty textProperty() {
		return text;
	}

	public void setText(String text) {
		this.text.set(text);
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy