diff --git a/src/test/java/net/synedra/validatorfx/demo/WeakListenerDemo.java b/src/test/java/net/synedra/validatorfx/demo/WeakListenerDemo.java new file mode 100644 index 0000000..352f95e --- /dev/null +++ b/src/test/java/net/synedra/validatorfx/demo/WeakListenerDemo.java @@ -0,0 +1,79 @@ +package net.synedra.validatorfx.demo; + +import javafx.application.Application; +import javafx.beans.binding.Bindings; +import javafx.beans.value.ObservableIntegerValue; +import javafx.event.ActionEvent; +import javafx.geometry.Insets; +import javafx.geometry.Pos; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.control.RadioButton; +import javafx.scene.control.ToggleGroup; +import javafx.scene.layout.GridPane; +import javafx.stage.Stage; + +/** WeakListenerDemo shows why weak listeners are required in ValidatorFX. + * @author r.lichtenberger@synedra.com + */ +public class WeakListenerDemo extends Application { + + private WeakListenerDemoForm form; + private GridPane grid; + private RadioButton odd; + private RadioButton even; + private ToggleGroup togglegroup; // this contains the "global" property our check will depend on ... + private ObservableIntegerValue allowedModulus; + + @Override + public void start(Stage primaryStage) throws Exception { + grid = createGrid(); + + Button showFormButton = new Button("Show form"); + showFormButton.setOnAction(this::showNewForm); + grid.add(showFormButton, 0, 0); + + togglegroup = new ToggleGroup(); + + odd = new RadioButton("Odd"); + odd.setToggleGroup(togglegroup); + grid.add(odd, 1, 0); + + even = new RadioButton("Even"); + even.setToggleGroup(togglegroup); + grid.add(even, 2, 0); + + togglegroup.selectToggle(odd); + + allowedModulus = Bindings.createIntegerBinding(() -> { + return togglegroup.getSelectedToggle() == odd ? 1 : 0; + }, togglegroup.selectedToggleProperty()); + + Scene scene = new Scene(grid); + primaryStage.setScene(scene); + primaryStage.show(); + } + + private void showNewForm(ActionEvent e) { + if (form != null) { + grid.getChildren().remove(form.getPresentation()); + } + form = new WeakListenerDemoForm(allowedModulus); + grid.add(form.getPresentation(), 0, 1, 2, 1); + } + + private GridPane createGrid() { + GridPane grid = new GridPane(); + grid.setAlignment(Pos.TOP_LEFT); + grid.setHgap(10); + grid.setVgap(10); + grid.setPadding(new Insets(25, 25, 25, 25)); + grid.setMinSize(600, 400); + return grid; + } + + + public static void main(String[] args) { + launch(); + } +} diff --git a/src/test/java/net/synedra/validatorfx/demo/WeakListenerDemoForm.java b/src/test/java/net/synedra/validatorfx/demo/WeakListenerDemoForm.java new file mode 100644 index 0000000..92dda67 --- /dev/null +++ b/src/test/java/net/synedra/validatorfx/demo/WeakListenerDemoForm.java @@ -0,0 +1,36 @@ +package net.synedra.validatorfx.demo; + +import javafx.beans.value.ObservableIntegerValue; +import javafx.geometry.Insets; +import javafx.scene.Node; +import javafx.scene.control.TextField; +import javafx.scene.layout.VBox; +import net.synedra.validatorfx.Validator; + +/** This class simulates a (very simple) form that contains a validator and a check. + * The expectation is that if no reference to a WeakListenerDemoForm instance exists, it will be garbage collected. + */ +class WeakListenerDemoForm { + private Validator validator = new Validator(); + private TextField textField = new TextField(); + WeakListenerDemoForm(ObservableIntegerValue allowedModulus) { + VBox.setMargin(textField, new Insets(5)); + validator.createCheck() + .dependsOn("username", textField.textProperty()) + .dependsOn("allowedModulus", allowedModulus) + .withMethod(c -> { + String userName = c.get("username"); + int allowed = c.get("allowedModulus"); + if (userName.length() % 2 != allowed) { + c.error("Please use " + (allowed == 0 ? "even" : "odd") + " number of letters."); + } + }) + .decorates(textField) + .immediate(); + ; + } + + Node getPresentation() { + return textField; + } +} \ No newline at end of file