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.role.Visibility;
  51. import it.tidalwave.ui.javafx.role.CustomGraphicProvider;
  52. import it.tidalwave.ui.core.UserNotification;
  53. import it.tidalwave.ui.core.UserNotificationWithFeedback;
  54. import it.tidalwave.ui.core.BoundProperty;
  55. import it.tidalwave.ui.core.role.PresentationModel;
  56. import it.tidalwave.ui.core.role.UserAction;

  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
  66.      * automatically performed by the SteelBlue runtime.
  67.      *
  68.      * @param   window      the main window
  69.      **********************************************************************************************************************************************************/
  70.     public void setMainWindow (@Nonnull Window window);

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

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

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

  129.     /***********************************************************************************************************************************************************
  130.      * Binds a {@link TableView} to a {@link PresentationModel} and a callback.
  131.      * See {@link #bind(javafx.scene.control.TableView, it.tidalwave.ui.core.role.PresentationModel, java.util.Optional)}.
  132.      *
  133.      * The process of populating data is performed in background threads, so this method quickly returns also in case
  134.      * of large amount of data.
  135.      * The initialization callback is called in the JavaFX thread when data population has been completed.
  136.      *
  137.      * @param   tableView       the {@code TablewView}
  138.      * @param   pm              the {@code PresentationModel}
  139.      * @param   initCallback    the callback
  140.      **********************************************************************************************************************************************************/
  141.     public default void bind (@Nonnull final TableView<PresentationModel> tableView,
  142.                               @Nonnull final PresentationModel pm,
  143.                               @Nonnull final Runnable initCallback)
  144.       {
  145.         bind(tableView, pm, Optional.of(initCallback));
  146.       }

  147.     /***********************************************************************************************************************************************************
  148.      * Binds a {@link TableView} to a {@link PresentationModel}.
  149.      * See {@link #bind(javafx.scene.control.TableView, it.tidalwave.ui.core.role.PresentationModel, java.util.Optional)}.
  150.      *
  151.      * @since   1.0-ALPHA-13
  152.      * @param   tableView       the {@code TablewView}
  153.      * @param   pm              the {@code PresentationModel}
  154.      **********************************************************************************************************************************************************/
  155.     public default void bind (@Nonnull final TableView<PresentationModel> tableView,
  156.                               @Nonnull final PresentationModel pm)
  157.       {
  158.         bind(tableView, pm, Optional.empty());
  159.       }

  160.     /***********************************************************************************************************************************************************
  161.      * Binds a {@link TreeView} to a {@link PresentationModel} and a callback.
  162.      *
  163.      * The {@code PresentationModel} is used to populate the table. The following roles are used:
  164.      *
  165.      * <ul>
  166.      * <li>A {@link it.tidalwave.role.SimpleComposite} provides children {@code PresentationModel}s for each row.</li>
  167.      * <li>In each row, an {@link it.tidalwave.role.Aggregate<PresentationModel>} is used to provide the {@code PresentationModel}s for
  168.      *     each column.</li>
  169.      * <li>A {@link it.tidalwave.ui.core.role.Displayable} (optional) is used to provide the text to render for each item.</li>
  170.      * <li>A {@link CustomGraphicProvider} (optional) is used to provide the graphics to render for each item.</li>
  171.      * <li>A {@link it.tidalwave.ui.core.role.Styleable} (optional) is used to provide the rendering style for each item.</li>
  172.      * <li>A {@link it.tidalwave.ui.core.role.UserActionProvider} (optional) is used to provide the actions for creating a context menu;
  173.      *     the default action is also bound to the double click or SPACE gesture.</li>
  174.      * <li>A {@link Visibility} (optional) is used to decide whether the root node should be visible or not.</li>
  175.      * </ul>
  176.      *
  177.      * The process of populating data is performed in background threads, so this method quickly returns also in case
  178.      * of large amount of data.
  179.      * The initialization callback is called in the JavaFX thread when data population has been completed.
  180.      *
  181.      * @param   treeView        the {@code TreeView}
  182.      * @param   pm              the {@code PresentationModel}
  183.      * @param   initCallback    the callback
  184.      **********************************************************************************************************************************************************/
  185.     public void bind (@Nonnull TreeView<PresentationModel> treeView,
  186.                       @Nonnull PresentationModel pm,
  187.                       @Nonnull Optional<Runnable> initCallback);

  188.     /***********************************************************************************************************************************************************
  189.      * Binds a {@link TableView} to a {@link PresentationModel} and a callback.
  190.      * See {@link #bind(javafx.scene.control.TreeView, it.tidalwave.ui.core.role.PresentationModel, java.util.Optional)}.
  191.      *
  192.      * @since   1.0-ALPHA-13
  193.      * @param   treeView        the {@code TreeView}
  194.      * @param   pm              the {@code PresentationModel}
  195.      * @param   initCallback    the callback
  196.      **********************************************************************************************************************************************************/
  197.     public default void bind (@Nonnull final TreeView<PresentationModel> treeView,
  198.                               @Nonnull final PresentationModel pm,
  199.                               @Nonnull final Runnable initCallback)
  200.       {
  201.         bind(treeView, pm, Optional.of(initCallback));
  202.       }

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

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

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

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

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

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

  314.     /***********************************************************************************************************************************************************
  315.      * Binds a {@link ComboBox} to a {@link PresentationModel}.
  316.      * See {@link #bind(javafx.scene.control.ListView, it.tidalwave.ui.core.role.PresentationModel, java.util.Optional)}.
  317.      *
  318.      * @since   1.0-ALPHA-13
  319.      * @param   listView        the {@code ListView}
  320.      * @param   pm              the {@code PresentationModel}
  321.      **********************************************************************************************************************************************************/
  322.     public default void bind (@Nonnull final ListView<PresentationModel> listView,
  323.                               @Nonnull final PresentationModel pm)
  324.       {
  325.         bind(listView, pm, Optional.empty());
  326.       }

  327.     /***********************************************************************************************************************************************************
  328.      * Binds a {@link ComboBox} to a {@link PresentationModel} and an optional callback.
  329.      *
  330.      * The {@code PresentationModel} is used to populate the table. The following roles are used:
  331.      *
  332.      * <ul>
  333.      * <li>A {@link it.tidalwave.role.SimpleComposite} provides children {@code PresentationModel}s for each row.</li>
  334.      * <li>In each row, an {@link it.tidalwave.role.Aggregate<PresentationModel>} is used to provide the {@code PresentationModel}s for
  335.      *     each column.</li>
  336.      * <li>A {@link it.tidalwave.ui.core.role.Displayable} (optional) is used to provide the text to render for each item.</li>
  337.      * <li>A {@link CustomGraphicProvider} (optional) is used to provide the graphics to render for each item.</li>
  338.      * <li>A {@link it.tidalwave.ui.core.role.Styleable} (optional) is used to provide the rendering style for each item.</li>
  339.      * <li>A {@link it.tidalwave.ui.core.role.UserActionProvider} (optional) is used to provide the actions for creating a context menu;
  340.      *     the default action is also bound to the double click or SPACE gesture.</li>
  341.      * </ul>
  342.      *
  343.      * The process of populating data is performed in background threads, so this method quickly returns also in case
  344.      * of large amount of data.
  345.      * The initialization callback is called in the JavaFX thread when data population has been completed.
  346.      *
  347.      * @param   comboBox        the {@code ComboBox}
  348.      * @param   pm              the {@code PresentationModel}
  349.      * @param   initCallback    the callback
  350.      **********************************************************************************************************************************************************/
  351.     public void bind (@Nonnull ComboBox<PresentationModel> comboBox,
  352.                       @Nonnull PresentationModel pm,
  353.                       @Nonnull Optional<Runnable> initCallback);

  354.     /***********************************************************************************************************************************************************
  355.      * Binds a {@link ComboBox} to a {@link PresentationModel} and a callback.
  356.      * See {@link #bind(javafx.scene.control.ComboBox, it.tidalwave.ui.core.role.PresentationModel, java.util.Optional)}.
  357.      *
  358.      * @since   1.0-ALPHA-13
  359.      * @param   comboBox        the {@code ComboBox}
  360.      * @param   pm              the {@code PresentationModel}
  361.      * @param   initCallback    the callback
  362.      **********************************************************************************************************************************************************/
  363.     public default void bind (@Nonnull final ComboBox<PresentationModel> comboBox,
  364.                               @Nonnull final PresentationModel pm,
  365.                               @Nonnull final Runnable initCallback)
  366.       {
  367.         bind(comboBox, pm, Optional.of(initCallback));
  368.       }

  369.     /***********************************************************************************************************************************************************
  370.      * Binds a {@link ComboBox} to a {@link PresentationModel}.
  371.      * See {@link #bind(javafx.scene.control.ComboBox, it.tidalwave.ui.core.role.PresentationModel, java.util.Optional)}.
  372.      *
  373.      * @since   1.0-ALPHA-13
  374.      * @param   comboBox        the {@code ComboBox}
  375.      * @param   pm              the {@code PresentationModel}
  376.      **********************************************************************************************************************************************************/
  377.     public default void bind (@Nonnull final ComboBox<PresentationModel> comboBox,
  378.                               @Nonnull final PresentationModel pm)
  379.       {
  380.         bind(comboBox, pm, Optional.empty());
  381.       }

  382.     /***********************************************************************************************************************************************************
  383.      * Given a {@link PresentationModel} that contains a {@link it.tidalwave.role.Composite}, populate the pane with
  384.      * {@link ToggleButton}s associated to the elements of the {@link it.tidalwave.role.Composite}. Each element is searched for the
  385.      * following roles:
  386.      *
  387.      * <ul>
  388.      * <li>{@link it.tidalwave.ui.core.role.UserActionProvider} (mandatory) to provide a callback for the button</li>
  389.      * <li>{@link it.tidalwave.ui.core.role.Displayable} to provide a text for the button</li>
  390.      * <li>{@link it.tidalwave.ui.core.role.Styleable} to provide a CSS style for the button</li>
  391.      * </ul>
  392.      *
  393.      * The pane must be pre-populated with at least one button, which will be queried for the CSS style.
  394.      *
  395.      * @param   pane        the {@code Pane}
  396.      * @param   pm          the {@code PresentationModel}
  397.      **********************************************************************************************************************************************************/
  398.     public void bindToggleButtons (@Nonnull Pane pane, @Nonnull PresentationModel pm);

  399.     /***********************************************************************************************************************************************************
  400.      * Deprecated. Merge to bindToggleButtons, passing some arguments for choosing toggle or normal buttons.
  401.      *
  402.      * @deprecated
  403.      **********************************************************************************************************************************************************/
  404.     @Deprecated
  405.     public void bindButtonsInPane (@Nonnull GridPane gridPane, @Nonnull Collection<UserAction> actions);

  406.     /***********************************************************************************************************************************************************
  407.      * Binds two properties of different types.
  408.      * @param   <T>             the target property type
  409.      * @param   <S>             the source property type
  410.      * @param   target          the target property
  411.      * @param   source          the source property
  412.      * @param   adapter         an adapter from one source to the target
  413.      * @since   2.0-ALPHA-1
  414.      **********************************************************************************************************************************************************/
  415.     public <T, S> void bind (@Nonnull final BoundProperty<? super T> target,
  416.                              @Nonnull final Property<? extends S> source,
  417.                              @Nonnull final Function<S, T> adapter);

  418.     /***********************************************************************************************************************************************************
  419.      * Binds two properties of the same type.
  420.      * @param   <T>             the property type
  421.      * @param   target          the target property
  422.      * @param   source          the source property
  423.      * @since   2.0-ALPHA-1
  424.      **********************************************************************************************************************************************************/
  425.     public default <T> void bind (@Nonnull final BoundProperty<? super T> target, @Nonnull final Property<T> source)
  426.       {
  427.         bind(target, source, Function.identity());
  428.       }

  429.     /***********************************************************************************************************************************************************
  430.      * Bidirectionally binds two properties of different types.
  431.      * @param   <T>             the former property type
  432.      * @param   <S>             the latter property type
  433.      * @param   property1       the former property
  434.      * @param   property2       the latter property
  435.      * @param   adapter         an adapter from one type to the other
  436.      * @param   reverseAdapter  the reverse adapter
  437.      * @since   2.0-ALPHA-1
  438.      **********************************************************************************************************************************************************/
  439.     public <T, S> void bindBidirectionally (@Nonnull final BoundProperty<? super T> property1,
  440.                                             @Nonnull final Property<S> property2,
  441.                                             @Nonnull final Function<? super S, T> adapter,
  442.                                             @Nonnull final Function<? super T, ? extends S> reverseAdapter);

  443.     /***********************************************************************************************************************************************************
  444.      * {@inheritDoc}
  445.      **********************************************************************************************************************************************************/
  446.     public default <T> void bindBidirectionally (@Nonnull final BoundProperty<? super T> property1, @Nonnull final Property<T> property2)
  447.       {
  448.         bindBidirectionally(property1, property2, Function.identity(), Function.identity());
  449.       }

  450.     /***********************************************************************************************************************************************************
  451.      * Bidirectionally binds two properties.
  452.      * @param   property1   the former property
  453.      * @param   property2   the latter property
  454.      **********************************************************************************************************************************************************/
  455.     public default void bindBidirectionally (@Nonnull final BoundProperty<? super Boolean> property1, @Nonnull final BooleanProperty property2)
  456.       {
  457.         bindBidirectionally(property1, property2, a -> a, a -> a);
  458.       }

  459.     /***********************************************************************************************************************************************************
  460.      * Bidirectionally binds two properties.
  461.      * @param   property1   the former property
  462.      * @param   property2   the latter property
  463.      **********************************************************************************************************************************************************/
  464.     public default void bindBidirectionally (@Nonnull final BoundProperty<? super Integer> property1, @Nonnull final IntegerProperty property2)
  465.       {
  466.         bindBidirectionally(property1, property2, Number::intValue, a -> a);
  467.       }

  468.     /***********************************************************************************************************************************************************
  469.      * Bidirectionally binds two properties.
  470.      * @param   property1   the former property
  471.      * @param   property2   the latter property
  472.      **********************************************************************************************************************************************************/
  473.     public default void bindBidirectionally (@Nonnull final BoundProperty<? super Long> property1, @Nonnull final LongProperty property2)
  474.       {
  475.         bindBidirectionally(property1, property2, Number::longValue, a -> a);
  476.       }

  477.     /***********************************************************************************************************************************************************
  478.      * Bidirectionally binds two properties.
  479.      * @param   property1   the former property
  480.      * @param   property2   the latter property
  481.      **********************************************************************************************************************************************************/
  482.     public default void bindBidirectionally (@Nonnull final BoundProperty<? super Double> property1, @Nonnull final DoubleProperty property2)
  483.       {
  484.         bindBidirectionally(property1, property2, Number::doubleValue, a -> a);
  485.       }

  486.     /***********************************************************************************************************************************************************
  487.      *
  488.      **********************************************************************************************************************************************************/
  489.     public void bindBidirectionally (@Nonnull TextField textField,
  490.                                      @Nonnull BoundProperty<String> textProperty,
  491.                                      @Nonnull BoundProperty<Boolean> validProperty);

  492.     /***********************************************************************************************************************************************************
  493.      * Shows a modal dialog with the given content and provides feedback by means of the given notification.
  494.      *
  495.      * @param   notification  the object notifying whether the operation is confirmed or cancelled
  496.      * @since   1.1-ALPHA-6
  497.      **********************************************************************************************************************************************************/
  498.     public default void showInModalDialog (@Nonnull final UserNotification notification)
  499.       {
  500.         showInModalDialog(UserNotificationWithFeedback.notificationWithFeedback()
  501.                                                       .withCaption(notification.getCaption())
  502.                                                       .withText(notification.getText()));
  503.       }

  504.     /***********************************************************************************************************************************************************
  505.      * Shows a modal dialog with the given content and provides feedback by means of the given notification.
  506.      *
  507.      * @param  node          the dialog content
  508.      * @param  notification  the object notifying whether the operation is confirmed or cancelled
  509.      **********************************************************************************************************************************************************/
  510.     public void showInModalDialog (@Nonnull UserNotificationWithFeedback notification,
  511.                                    @Nonnull Optional<Node> node);

  512.     // FIXME: use a Builder, merge with the above
  513.     public default void showInModalDialog (@Nonnull final Node node,
  514.                                            @Nonnull final UserNotificationWithFeedback notification,
  515.                                            @Nonnull final BoundProperty<Boolean> valid)
  516.       {
  517.         showInModalDialog(notification, Optional.of(node));
  518.       }

  519.     @Deprecated
  520.     public default void showInModalDialog (@Nonnull final Node node,
  521.                                            @Nonnull final UserNotificationWithFeedback notification)
  522.       {
  523.         showInModalDialog(notification, Optional.of(node));
  524.       }

  525.     public default void showInModalDialog (@Nonnull final UserNotificationWithFeedback notification)
  526.       {
  527.         showInModalDialog(notification, Optional.empty());
  528.       }

  529.     /***********************************************************************************************************************************************************
  530.      * Opens the FileChooser for selecting a file. The outcome of the operation (confirmed or cancelled) will be
  531.      * notified to the given notification object. The selected file will be set to the given bound property, which can
  532.      * be also used to set the default value rendered on the FileChooser.
  533.      *
  534.      * @param  notification  the object notifying whether the operation is confirmed or cancelled
  535.      * @param  selectedFile  the property containing the selected file
  536.      **********************************************************************************************************************************************************/
  537.     public void openFileChooserFor (@Nonnull UserNotificationWithFeedback notification,
  538.                                     @Nonnull BoundProperty<Path> selectedFile);

  539.     /***********************************************************************************************************************************************************
  540.      * Opens the FileChooser for selecting a folder. The outcome of the operation (confirmed or cancelled) will be
  541.      * notified to the given notification object. The selected folder will be set to the given bound property, which can
  542.      * be also used to set the default value rendered on the FileChooser.
  543.      *
  544.      * @param  notification    the object notifying whether the operation is confirmed or cancelled
  545.      * @param  selectedFolder  the property containing the selected folder
  546.      **********************************************************************************************************************************************************/
  547.     public void openDirectoryChooserFor (@Nonnull UserNotificationWithFeedback notification,
  548.                                          @Nonnull BoundProperty<Path> selectedFolder);
  549.   }