JavaFXBinder.java

  1. /*
  2.  * *************************************************************************************************************************************************************
  3.  *
  4.  * SteelBlue: DCI User Interfaces
  5.  * http://tidalwave.it/projects/steelblue
  6.  *
  7.  * Copyright (C) 2015 - 2025 by Tidalwave s.a.s. (http://tidalwave.it)
  8.  *
  9.  * *************************************************************************************************************************************************************
  10.  *
  11.  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
  12.  * You may obtain a copy of the License at
  13.  *
  14.  *     http://www.apache.org/licenses/LICENSE-2.0
  15.  *
  16.  * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  17.  * CONDITIONS OF ANY KIND, either express or implied.  See the License for the specific language governing permissions and limitations under the License.
  18.  *
  19.  * *************************************************************************************************************************************************************
  20.  *
  21.  * git clone https://bitbucket.org/tidalwave/steelblue-src
  22.  * git clone https://github.com/tidalwave-it/steelblue-src
  23.  *
  24.  * *************************************************************************************************************************************************************
  25.  */
  26. package it.tidalwave.ui.javafx;

  27. import jakarta.annotation.Nonnull;
  28. import java.util.Collection;
  29. import java.util.Optional;
  30. import java.util.function.Function;
  31. import java.nio.file.Path;
  32. import javafx.beans.property.BooleanProperty;
  33. import javafx.beans.property.DoubleProperty;
  34. import javafx.beans.property.IntegerProperty;
  35. import javafx.beans.property.LongProperty;
  36. import javafx.beans.property.Property;
  37. import javafx.scene.Node;
  38. import javafx.scene.control.ButtonBase;
  39. import javafx.scene.control.ComboBox;
  40. import javafx.scene.control.ListView;
  41. import javafx.scene.control.MenuItem;
  42. import javafx.scene.control.TableView;
  43. import javafx.scene.control.TextField;
  44. import javafx.scene.control.ToggleButton;
  45. import javafx.scene.control.TreeTableView;
  46. import javafx.scene.control.TreeView;
  47. import javafx.scene.layout.GridPane;
  48. import javafx.scene.layout.Pane;
  49. import javafx.stage.Window;
  50. import it.tidalwave.ui.core.BoundProperty;
  51. import it.tidalwave.ui.core.UserNotification;
  52. import it.tidalwave.ui.core.UserNotificationWithFeedback;
  53. import it.tidalwave.ui.core.role.PresentationModel;
  54. import it.tidalwave.ui.core.role.UserAction;
  55. import it.tidalwave.ui.core.role.Visibility;
  56. import it.tidalwave.ui.javafx.role.CustomGraphicProvider;

  57. /***************************************************************************************************************************************************************
  58.  *
  59.  * @author  Fabrizio Giudici
  60.  *
  61.  **************************************************************************************************************************************************************/
  62. public interface JavaFXBinder
  63.   {
  64.     /***********************************************************************************************************************************************************
  65.      * Sets the main window. This operation must be performed before any other method is called. This operation is automatically performed by the SteelBlue
  66.      * runtime.
  67.      * @param   window      the main window
  68.      **********************************************************************************************************************************************************/
  69.     public void setMainWindow (@Nonnull Window window);

  70.     /***********************************************************************************************************************************************************
  71.      * Binds a button to a {@link UserAction}. The following roles o the action are used:
  72.      * <ul>
  73.      * <li>Displayable: to set the label of the button</li>
  74.      * </ul>
  75.      * The action is used as a callback when the button is pressed; invoked in a thread provided by the binder executor. The {@code enabled} property of the
  76.      * {@code UserAction} is bound, negated, to the {@code disabled} property of the button.
  77.      * @param   button      the button
  78.      * @param   action      the action
  79.      **********************************************************************************************************************************************************/
  80.     public void bind (@Nonnull ButtonBase button, @Nonnull UserAction action);

  81.     /***********************************************************************************************************************************************************
  82.      * Binds a menu item to a {@link UserAction}. The following roles o the action are used:
  83.      * <ul>
  84.      * <li>Displayable: to set the label of the menu item</li>
  85.      * </ul>
  86.      * The action is used as a callback when the button is pressed; invoked in a thread provided by the binder executor. The {@code enabled} property of the
  87.      * {@code UserAction} is bound, negated, to the {@code disabled} property of the menu item.
  88.      * @param   menuItem    the menu item
  89.      * @param   action      the action
  90.      **********************************************************************************************************************************************************/
  91.     public void bind (@Nonnull MenuItem menuItem, @Nonnull UserAction action);

  92.     /***********************************************************************************************************************************************************
  93.      * Binds a {@link TableView} to a {@link PresentationModel} and an optional callback. The {@code PresentationModel} is used to populate the table. The
  94.      * following roles are used:
  95.      * <ul>
  96.      * <li>A {@link it.tidalwave.role.SimpleComposite} provides children {@code PresentationModel}s for each row.</li>
  97.      * <li>In each row, an {@link it.tidalwave.role.Aggregate<PresentationModel>} is used to provide the {@code PresentationModel}s for
  98.      *     each column.</li>
  99.      * <li>A {@link it.tidalwave.ui.core.role.Displayable} (optional) is used to provide the text to render for each item.</li>
  100.      * <li>A {@link CustomGraphicProvider} (optional) is used to provide the graphics to render for each item.</li>
  101.      * <li>A {@link it.tidalwave.ui.core.role.Styleable} (optional) is used to provide the rendering style for each item.</li>
  102.      * <li>A {@link it.tidalwave.ui.core.role.UserActionProvider} (optional) is used to provide the actions for creating a context menu;
  103.      *     the default action is also bound to the double click or SPACE gesture.</li>
  104.      * </ul>
  105.      * The process of populating data is performed in background threads, so this method quickly returns also in case of large amount of data. The
  106.      * initialization callback is called in the JavaFX thread when data population has been completed.
  107.      * @param   tableView       the {@code TablewView}
  108.      * @param   pm              the {@code PresentationModel}
  109.      * @param   initCallback    the callback
  110.      * @since   1.0-ALPHA-13
  111.      **********************************************************************************************************************************************************/
  112.     public void bind (@Nonnull TableView<PresentationModel> tableView, @Nonnull PresentationModel pm, @Nonnull Optional<Runnable> initCallback);

  113.     /***********************************************************************************************************************************************************
  114.      * Binds a {@link TableView} to a {@link PresentationModel} and a callback. See {@link #bind(javafx.scene.control.TableView,
  115.      * it.tidalwave.ui.core.role.PresentationModel, java.util.Optional)}. The process of populating data is performed in background threads, so this method
  116.      * quickly returns also in case of large amount of data. The initialization callback is called in the JavaFX thread when data population has been completed.
  117.      * @param   tableView       the {@code TablewView}
  118.      * @param   pm              the {@code PresentationModel}
  119.      * @param   initCallback    the callback
  120.      **********************************************************************************************************************************************************/
  121.     public default void bind (@Nonnull final TableView<PresentationModel> tableView, @Nonnull final PresentationModel pm, @Nonnull final Runnable initCallback)
  122.       {
  123.         bind(tableView, pm, Optional.of(initCallback));
  124.       }

  125.     /***********************************************************************************************************************************************************
  126.      * Binds a {@link TableView} to a {@link PresentationModel}. See {@link #bind(javafx.scene.control.TableView, it.tidalwave.ui.core.role.PresentationModel,
  127.      * java.util.Optional)}.
  128.      * @param   tableView       the {@code TablewView}
  129.      * @param   pm              the {@code PresentationModel}
  130.      * @since   1.0-ALPHA-13
  131.      **********************************************************************************************************************************************************/
  132.     public default void bind (@Nonnull final TableView<PresentationModel> tableView, @Nonnull final PresentationModel pm)
  133.       {
  134.         bind(tableView, pm, Optional.empty());
  135.       }

  136.     /***********************************************************************************************************************************************************
  137.      * Binds a {@link TreeView} to a {@link PresentationModel} and a callback. The {@code PresentationModel} is used to populate the table. The following roles
  138.      * are used:
  139.      * <ul>
  140.      * <li>A {@link it.tidalwave.role.SimpleComposite} provides children {@code PresentationModel}s for each row.</li>
  141.      * <li>In each row, an {@link it.tidalwave.role.Aggregate<PresentationModel>} is used to provide the {@code PresentationModel}s for
  142.      *     each column.</li>
  143.      * <li>A {@link it.tidalwave.ui.core.role.Displayable} (optional) is used to provide the text to render for each item.</li>
  144.      * <li>A {@link CustomGraphicProvider} (optional) is used to provide the graphics to render for each item.</li>
  145.      * <li>A {@link it.tidalwave.ui.core.role.Styleable} (optional) is used to provide the rendering style for each item.</li>
  146.      * <li>A {@link it.tidalwave.ui.core.role.UserActionProvider} (optional) is used to provide the actions for creating a context menu;
  147.      *     the default action is also bound to the double click or SPACE gesture.</li>
  148.      * <li>A {@link Visibility} (optional) is used to decide whether the root node should be visible or not.</li>
  149.      * </ul>
  150.      * The process of populating data is performed in background threads, so this method quickly returns also in case  of large amount of data. The
  151.      * initialization callback is called in the JavaFX thread when data population has been completed.
  152.      * @param   treeView        the {@code TreeView}
  153.      * @param   pm              the {@code PresentationModel}
  154.      * @param   initCallback    the callback
  155.      **********************************************************************************************************************************************************/
  156.     public void bind (@Nonnull TreeView<PresentationModel> treeView, @Nonnull PresentationModel pm, @Nonnull Optional<Runnable> initCallback);

  157.     /***********************************************************************************************************************************************************
  158.      * Binds a {@link TableView} to a {@link PresentationModel} and a callback. See {@link #bind(javafx.scene.control.TreeView,
  159.      * it.tidalwave.ui.core.role.PresentationModel, java.util.Optional)}.
  160.      * @param   treeView        the {@code TreeView}
  161.      * @param   pm              the {@code PresentationModel}
  162.      * @param   initCallback    the callback
  163.      * @since   1.0-ALPHA-13
  164.      **********************************************************************************************************************************************************/
  165.     public default void bind (@Nonnull final TreeView<PresentationModel> treeView, @Nonnull final PresentationModel pm, @Nonnull final Runnable initCallback)
  166.       {
  167.         bind(treeView, pm, Optional.of(initCallback));
  168.       }

  169.     /***********************************************************************************************************************************************************
  170.      * Binds a {@link TableView} to a {@link PresentationModel}. See {@link #bind(javafx.scene.control.TableView, it.tidalwave.ui.core.role.PresentationModel,
  171.      * java.util.Optional)}
  172.      * @param   treeView        the {@code TreeView}
  173.      * @param   pm              the {@code PresentationModel}
  174.      * @since   1.0-ALPHA-13
  175.      **********************************************************************************************************************************************************/
  176.     public default void bind (@Nonnull final TreeView<PresentationModel> treeView, @Nonnull final PresentationModel pm)
  177.       {
  178.         bind(treeView, pm, Optional.empty());
  179.       }

  180.     /***********************************************************************************************************************************************************
  181.      * Binds a {@link TreeTableView} to a {@link PresentationModel} and a callback. The {@code PresentationModel} is used to populate the table. The following
  182.      * roles are used:
  183.      * <ul>
  184.      * <li>A {@link it.tidalwave.role.SimpleComposite} provides children {@code PresentationModel}s for each row.</li>
  185.      * <li>In each row, an {@link it.tidalwave.role.Aggregate<PresentationModel>} is used to provide the {@code PresentationModel}s for
  186.      *     each column.</li>
  187.      * <li>A {@link it.tidalwave.ui.core.role.Displayable} (optional) is used to provide the text to render for each item.</li>
  188.      * <li>A {@link CustomGraphicProvider} (optional) is used to provide the graphics to render for each item.</li>
  189.      * <li>A {@link it.tidalwave.ui.core.role.Styleable} (optional) is used to provide the rendering style for each item.</li>
  190.      * <li>A {@link it.tidalwave.ui.core.role.UserActionProvider} (optional) is used to provide the actions for creating a context menu;
  191.      *     the default action is also bound to the double click or SPACE gesture.</li>
  192.      * <li>A {@link Visibility} (optional) is used to decide whether the root node should be visible or not.</li>
  193.      * </ul>
  194.      * The process of populating data is performed in background threads, so this method quickly returns also in case of large amount of data. The
  195.      * initialization callback is called in the JavaFX thread when data population has been completed.
  196.      * @param   treeTableView   the {@code TreeTableView}
  197.      * @param   pm              the {@code PresentationModel}
  198.      * @param   initCallback    the callback
  199.      **********************************************************************************************************************************************************/
  200.     public void bind (@Nonnull TreeTableView<PresentationModel> treeTableView, @Nonnull PresentationModel pm, @Nonnull Optional<Runnable> initCallback);

  201.     /***********************************************************************************************************************************************************
  202.      * Binds a {@link TreeTableView} to a {@link PresentationModel} and a callback. See {@link #bind(javafx.scene.control.TreeTableView,
  203.      * it.tidalwave.ui.core.role.PresentationModel, java.util.Optional)}.
  204.      * @param   treeTableView   the {@code TreeTableView}
  205.      * @param   pm              the {@code PresentationModel}
  206.      * @param   initCallback    the callback
  207.      * @since   1.0-ALPHA-13
  208.      **********************************************************************************************************************************************************/
  209.     public default void bind (@Nonnull final TreeTableView<PresentationModel> treeTableView,
  210.                               @Nonnull final PresentationModel pm,
  211.                               @Nonnull final Runnable initCallback)
  212.       {
  213.         bind(treeTableView, pm, Optional.of(initCallback));
  214.       }

  215.     /***********************************************************************************************************************************************************
  216.      * Binds a {@link TreeTableView} to a {@link PresentationModel}. See {@link #bind(javafx.scene.control.TreeTableView,
  217.      * it.tidalwave.ui.core.role.PresentationModel, java.util.Optional)}.
  218.      * @param   treeTableView   the {@code TreeTableView}
  219.      * @param   pm              the {@code PresentationModel}
  220.      * @since   1.0-ALPHA-13
  221.      **********************************************************************************************************************************************************/
  222.     public default void bind (@Nonnull final TreeTableView<PresentationModel> treeTableView, @Nonnull final PresentationModel pm)
  223.       {
  224.         bind(treeTableView, pm, Optional.empty());
  225.       }

  226.     /***********************************************************************************************************************************************************
  227.      * Binds a {@link ListView} to a {@link PresentationModel} and an optional callback. The {@code PresentationModel} is used to populate the table. The
  228.      * following roles are used:
  229.      * <ul>
  230.      * <li>A {@link it.tidalwave.role.SimpleComposite} provides children {@code PresentationModel}s for each row.</li>
  231.      * <li>In each row, an {@link it.tidalwave.role.Aggregate<PresentationModel>} is used to provide the {@code PresentationModel}s for
  232.      *     each column.</li>
  233.      * <li>A {@link it.tidalwave.ui.core.role.Displayable} (optional) is used to provide the text to render for each item.</li>
  234.      * <li>A {@link CustomGraphicProvider} (optional) is used to provide the graphics to render for each item.</li>
  235.      * <li>A {@link it.tidalwave.ui.core.role.Styleable} (optional) is used to provide the rendering style for each item.</li>
  236.      * <li>A {@link it.tidalwave.ui.core.role.UserActionProvider} (optional) is used to provide the actions for creating a context menu;
  237.      *     the default action is also bound to the double click or SPACE gesture.</li>
  238.      * </ul>
  239.      * The process of populating data is performed in background threads, so this method quickly returns also in case of large amount of data. The
  240.      * initialization callback is called in the JavaFX thread when data population has been completed.
  241.      * @param   listView        the {@code ListView}
  242.      * @param   pm              the {@code PresentationModel}
  243.      * @param   initCallback    the callback
  244.      **********************************************************************************************************************************************************/
  245.     public void bind (@Nonnull ListView<PresentationModel> listView, @Nonnull PresentationModel pm, @Nonnull Optional<Runnable> initCallback);

  246.     /***********************************************************************************************************************************************************
  247.      * Binds a {@link ListView} to a {@link PresentationModel} and a callback. See {@link #bind(javafx.scene.control.ListView,
  248.      * it.tidalwave.ui.core.role.PresentationModel, java.util.Optional)}.
  249.      * @param   listView        the {@code ListView}
  250.      * @param   pm              the {@code PresentationModel}
  251.      * @param   initCallback    the callback
  252.      * @since   1.0-ALPHA-13
  253.      **********************************************************************************************************************************************************/
  254.     public default void bind (@Nonnull final ListView<PresentationModel> listView, @Nonnull final PresentationModel pm, @Nonnull final Runnable initCallback)
  255.       {
  256.         bind(listView, pm, Optional.of(initCallback));
  257.       }

  258.     /***********************************************************************************************************************************************************
  259.      * Binds a {@link ComboBox} to a {@link PresentationModel}. See {@link #bind(javafx.scene.control.ListView, it.tidalwave.ui.core.role.PresentationModel,
  260.      * java.util.Optional)}.
  261.      * @param   listView        the {@code ListView}
  262.      * @param   pm              the {@code PresentationModel}
  263.      * @since   1.0-ALPHA-13
  264.      **********************************************************************************************************************************************************/
  265.     public default void bind (@Nonnull final ListView<PresentationModel> listView, @Nonnull final PresentationModel pm)
  266.       {
  267.         bind(listView, pm, Optional.empty());
  268.       }

  269.     /***********************************************************************************************************************************************************
  270.      * Binds a {@link ComboBox} to a {@link PresentationModel} and an optional callback. The {@code PresentationModel} is used to populate the table. The
  271.      * following roles are used:
  272.      * <ul>
  273.      * <li>A {@link it.tidalwave.role.SimpleComposite} provides children {@code PresentationModel}s for each row.</li>
  274.      * <li>In each row, an {@link it.tidalwave.role.Aggregate<PresentationModel>} is used to provide the {@code PresentationModel}s for
  275.      *     each column.</li>
  276.      * <li>A {@link it.tidalwave.ui.core.role.Displayable} (optional) is used to provide the text to render for each item.</li>
  277.      * <li>A {@link CustomGraphicProvider} (optional) is used to provide the graphics to render for each item.</li>
  278.      * <li>A {@link it.tidalwave.ui.core.role.Styleable} (optional) is used to provide the rendering style for each item.</li>
  279.      * <li>A {@link it.tidalwave.ui.core.role.UserActionProvider} (optional) is used to provide the actions for creating a context menu;
  280.      *     the default action is also bound to the double click or SPACE gesture.</li>
  281.      * </ul>
  282.      * The process of populating data is performed in background threads, so this method quickly returns also in case of large amount of data. The
  283.      * initialization callback is called in the JavaFX thread when data population has been completed.
  284.      * @param   comboBox        the {@code ComboBox}
  285.      * @param   pm              the {@code PresentationModel}
  286.      * @param   initCallback    the callback
  287.      **********************************************************************************************************************************************************/
  288.     public void bind (@Nonnull ComboBox<PresentationModel> comboBox, @Nonnull PresentationModel pm, @Nonnull Optional<Runnable> initCallback);

  289.     /***********************************************************************************************************************************************************
  290.      * Binds a {@link ComboBox} to a {@link PresentationModel} and a callback. See {@link #bind(javafx.scene.control.ComboBox,
  291.      * it.tidalwave.ui.core.role.PresentationModel, java.util.Optional)}.
  292.      * @param   comboBox        the {@code ComboBox}
  293.      * @param   pm              the {@code PresentationModel}
  294.      * @param   initCallback    the callback
  295.      * @since   1.0-ALPHA-13
  296.      **********************************************************************************************************************************************************/
  297.     public default void bind (@Nonnull final ComboBox<PresentationModel> comboBox, @Nonnull final PresentationModel pm, @Nonnull final Runnable initCallback)
  298.       {
  299.         bind(comboBox, pm, Optional.of(initCallback));
  300.       }

  301.     /***********************************************************************************************************************************************************
  302.      * Binds a {@link ComboBox} to a {@link PresentationModel}. See {@link #bind(javafx.scene.control.ComboBox, it.tidalwave.ui.core.role.PresentationModel,
  303.      * java.util.Optional)}.
  304.      * @param   comboBox        the {@code ComboBox}
  305.      * @param   pm              the {@code PresentationModel}
  306.      * @since   1.0-ALPHA-13
  307.      **********************************************************************************************************************************************************/
  308.     public default void bind (@Nonnull final ComboBox<PresentationModel> comboBox, @Nonnull final PresentationModel pm)
  309.       {
  310.         bind(comboBox, pm, Optional.empty());
  311.       }

  312.     /***********************************************************************************************************************************************************
  313.      * Given a {@link PresentationModel} that contains a {@link it.tidalwave.role.Composite}, populate the pane with {@link ToggleButton}s associated to the
  314.      * elements of the {@link it.tidalwave.role.Composite}. Each element is searched for the following roles:
  315.      * <ul>
  316.      * <li>{@link it.tidalwave.ui.core.role.UserActionProvider} (mandatory) to provide a callback for the button</li>
  317.      * <li>{@link it.tidalwave.ui.core.role.Displayable} to provide a text for the button</li>
  318.      * <li>{@link it.tidalwave.ui.core.role.Styleable} to provide a CSS style for the button</li>
  319.      * </ul>
  320.      * The pane must be pre-populated with at least one button, which will be queried for the CSS style.
  321.      * @param   pane        the {@code Pane}
  322.      * @param   pm          the {@code PresentationModel}
  323.      **********************************************************************************************************************************************************/
  324.     public void bindToggleButtons (@Nonnull Pane pane, @Nonnull PresentationModel pm);

  325.     /***********************************************************************************************************************************************************
  326.      * Deprecated. Merge to bindToggleButtons, passing some arguments for choosing toggle or normal buttons.
  327.      * @deprecated
  328.      **********************************************************************************************************************************************************/
  329.     @Deprecated
  330.     public void bindButtonsInPane (@Nonnull GridPane gridPane, @Nonnull Collection<UserAction> actions);

  331.     /***********************************************************************************************************************************************************
  332.      * Binds two properties of different types.
  333.      * @param   <T>             the target property type
  334.      * @param   <S>             the source property type
  335.      * @param   target          the target property
  336.      * @param   source          the source property
  337.      * @param   adapter         an adapter from one source to the target
  338.      * @since   2.0-ALPHA-1
  339.      **********************************************************************************************************************************************************/
  340.     public <T, S> void bind (@Nonnull final BoundProperty<? super T> target, @Nonnull final Property<? extends S> source, @Nonnull final Function<S, T> adapter);

  341.     /***********************************************************************************************************************************************************
  342.      * Binds two properties of the same type.
  343.      * @param   <T>             the property type
  344.      * @param   target          the target property
  345.      * @param   source          the source property
  346.      * @since   2.0-ALPHA-1
  347.      **********************************************************************************************************************************************************/
  348.     public default <T> void bind (@Nonnull final BoundProperty<? super T> target, @Nonnull final Property<T> source)
  349.       {
  350.         bind(target, source, Function.identity());
  351.       }

  352.     /***********************************************************************************************************************************************************
  353.      * Bidirectionally binds two properties of different types.
  354.      * @param   <T>             the former property type
  355.      * @param   <S>             the latter property type
  356.      * @param   property1       the former property
  357.      * @param   property2       the latter property
  358.      * @param   adapter         an adapter from one type to the other
  359.      * @param   reverseAdapter  the reverse adapter
  360.      * @since   2.0-ALPHA-1
  361.      **********************************************************************************************************************************************************/
  362.     public <T, S> void bindBidirectionally (@Nonnull final BoundProperty<? super T> property1,
  363.                                             @Nonnull final Property<S> property2,
  364.                                             @Nonnull final Function<? super S, T> adapter,
  365.                                             @Nonnull final Function<? super T, ? extends S> reverseAdapter);

  366.     /***********************************************************************************************************************************************************
  367.      * {@inheritDoc}
  368.      **********************************************************************************************************************************************************/
  369.     public default <T> void bindBidirectionally (@Nonnull final BoundProperty<? super T> property1, @Nonnull final Property<T> property2)
  370.       {
  371.         bindBidirectionally(property1, property2, Function.identity(), Function.identity());
  372.       }

  373.     /***********************************************************************************************************************************************************
  374.      * Bidirectionally binds two properties.
  375.      * @param   property1   the former property
  376.      * @param   property2   the latter property
  377.      **********************************************************************************************************************************************************/
  378.     public default void bindBidirectionally (@Nonnull final BoundProperty<? super Boolean> property1, @Nonnull final BooleanProperty property2)
  379.       {
  380.         bindBidirectionally(property1, property2, a -> a, a -> a);
  381.       }

  382.     /***********************************************************************************************************************************************************
  383.      * Bidirectionally binds two properties.
  384.      * @param   property1   the former property
  385.      * @param   property2   the latter property
  386.      **********************************************************************************************************************************************************/
  387.     public default void bindBidirectionally (@Nonnull final BoundProperty<? super Integer> property1, @Nonnull final IntegerProperty property2)
  388.       {
  389.         bindBidirectionally(property1, property2, Number::intValue, a -> a);
  390.       }

  391.     /***********************************************************************************************************************************************************
  392.      * Bidirectionally binds two properties.
  393.      * @param   property1   the former property
  394.      * @param   property2   the latter property
  395.      **********************************************************************************************************************************************************/
  396.     public default void bindBidirectionally (@Nonnull final BoundProperty<? super Long> property1, @Nonnull final LongProperty property2)
  397.       {
  398.         bindBidirectionally(property1, property2, Number::longValue, a -> a);
  399.       }

  400.     /***********************************************************************************************************************************************************
  401.      * Bidirectionally binds two properties.
  402.      * @param   property1   the former property
  403.      * @param   property2   the latter property
  404.      **********************************************************************************************************************************************************/
  405.     public default void bindBidirectionally (@Nonnull final BoundProperty<? super Double> property1, @Nonnull final DoubleProperty property2)
  406.       {
  407.         bindBidirectionally(property1, property2, Number::doubleValue, a -> a);
  408.       }

  409.     /***********************************************************************************************************************************************************
  410.      *
  411.      **********************************************************************************************************************************************************/
  412.     public void bindBidirectionally (@Nonnull TextField textField, @Nonnull BoundProperty<String> textProperty,  @Nonnull BoundProperty<Boolean> validProperty);

  413.     /***********************************************************************************************************************************************************
  414.      * Shows a modal dialog with the given content and provides feedback by means of the given notification.
  415.      * @param   notification  the object notifying whether the operation is confirmed or cancelled
  416.      * @since   1.1-ALPHA-6
  417.      **********************************************************************************************************************************************************/
  418.     public default void showInModalDialog (@Nonnull final UserNotification notification)
  419.       {
  420.         showInModalDialog(UserNotificationWithFeedback.notificationWithFeedback()
  421.                                                       .withCaption(notification.getCaption())
  422.                                                       .withText(notification.getText()));
  423.       }

  424.     /***********************************************************************************************************************************************************
  425.      * Shows a modal dialog with the given content and provides feedback by means of the given notification.
  426.      * @param  node          the dialog content
  427.      * @param  notification  the object notifying whether the operation is confirmed or cancelled
  428.      **********************************************************************************************************************************************************/
  429.     public void showInModalDialog (@Nonnull UserNotificationWithFeedback notification, @Nonnull Optional<Node> node);

  430.     // FIXME: use a Builder, merge with the above
  431.     public default void showInModalDialog (@Nonnull final Node node,
  432.                                            @Nonnull final UserNotificationWithFeedback notification,
  433.                                            @Nonnull final BoundProperty<Boolean> valid)
  434.       {
  435.         showInModalDialog(notification, Optional.of(node));
  436.       }

  437.     @Deprecated
  438.     public default void showInModalDialog (@Nonnull final Node node, @Nonnull final UserNotificationWithFeedback notification)
  439.       {
  440.         showInModalDialog(notification, Optional.of(node));
  441.       }

  442.     public default void showInModalDialog (@Nonnull final UserNotificationWithFeedback notification)
  443.       {
  444.         showInModalDialog(notification, Optional.empty());
  445.       }

  446.     /***********************************************************************************************************************************************************
  447.      * Opens the FileChooser for selecting a file. The outcome of the operation (confirmed or cancelled) will be notified to the given notification object. The
  448.      * selected file will be set to the given bound property, which can be also used to set the default value rendered on the FileChooser.
  449.      * @param  notification  the object notifying whether the operation is confirmed or cancelled
  450.      * @param  selectedFile  the property containing the selected file
  451.      **********************************************************************************************************************************************************/
  452.     public void openFileChooserFor (@Nonnull UserNotificationWithFeedback notification, @Nonnull BoundProperty<Path> selectedFile);

  453.     /***********************************************************************************************************************************************************
  454.      * Opens the FileChooser for selecting a folder. The outcome of the operation (confirmed or cancelled) will be notified to the given notification object.
  455.      * The selected folder will be set to the given bound property, which can be also used to set the default value rendered on the FileChooser.
  456.      * @param  notification    the object notifying whether the operation is confirmed or cancelled
  457.      * @param  selectedFolder  the property containing the selected folder
  458.      **********************************************************************************************************************************************************/
  459.     public void openDirectoryChooserFor (@Nonnull UserNotificationWithFeedback notification, @Nonnull BoundProperty<Path> selectedFolder);
  460.   }