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 28 import jakarta.annotation.Nonnull; 29 import java.util.Collection; 30 import java.util.Optional; 31 import java.util.function.Function; 32 import java.nio.file.Path; 33 import javafx.beans.property.BooleanProperty; 34 import javafx.beans.property.DoubleProperty; 35 import javafx.beans.property.IntegerProperty; 36 import javafx.beans.property.LongProperty; 37 import javafx.beans.property.Property; 38 import javafx.scene.Node; 39 import javafx.scene.control.ButtonBase; 40 import javafx.scene.control.ComboBox; 41 import javafx.scene.control.ListView; 42 import javafx.scene.control.MenuItem; 43 import javafx.scene.control.TableView; 44 import javafx.scene.control.TextField; 45 import javafx.scene.control.ToggleButton; 46 import javafx.scene.control.TreeTableView; 47 import javafx.scene.control.TreeView; 48 import javafx.scene.layout.GridPane; 49 import javafx.scene.layout.Pane; 50 import javafx.stage.Window; 51 import it.tidalwave.ui.core.role.Visibility; 52 import it.tidalwave.ui.javafx.role.CustomGraphicProvider; 53 import it.tidalwave.util.ui.UserNotification; 54 import it.tidalwave.util.ui.UserNotificationWithFeedback; 55 import it.tidalwave.ui.core.BoundProperty; 56 import it.tidalwave.ui.core.role.PresentationModel; 57 import it.tidalwave.ui.core.role.UserAction; 58 59 /*************************************************************************************************************************************************************** 60 * 61 * @author Fabrizio Giudici 62 * 63 **************************************************************************************************************************************************************/ 64 public interface JavaFXBinder 65 { 66 /*********************************************************************************************************************************************************** 67 * Sets the main window. This operation must be performed before any other method is called. This operation is 68 * automatically performed by the SteelBlue runtime. 69 * 70 * @param window the main window 71 **********************************************************************************************************************************************************/ 72 public void setMainWindow (@Nonnull Window window); 73 74 /*********************************************************************************************************************************************************** 75 * Binds a button to a {@link UserAction}. The following roles o the action are used: 76 * 77 * <ul> 78 * <li>Displayable: to set the label of the button</li> 79 * </ul> 80 * 81 * The action is used as a callback when the button is pressed; invoked in a thread provided by the binder executor. 82 * The {@code enabled} property of the {@code UserAction} is bound, negated, to the {@code disabled} property of the 83 * button. 84 * 85 * @param button the button 86 * @param action the action 87 **********************************************************************************************************************************************************/ 88 public void bind (@Nonnull ButtonBase button, @Nonnull UserAction action); 89 90 /*********************************************************************************************************************************************************** 91 * Binds a menu item to a {@link UserAction}. The following roles o the action are used: 92 * 93 * <ul> 94 * <li>Displayable: to set the label of the menu item</li> 95 * </ul> 96 * 97 * The action is used as a callback when the button is pressed; invoked in a thread provided by the binder executor. 98 * The {@code enabled} property of the {@code UserAction} is bound, negated, to the {@code disabled} property of the 99 * menu item. 100 * 101 * @param menuItem the menu item 102 * @param action the action 103 **********************************************************************************************************************************************************/ 104 public void bind (@Nonnull MenuItem menuItem, @Nonnull UserAction action); 105 106 /*********************************************************************************************************************************************************** 107 * Binds a {@link TableView} to a {@link PresentationModel} and an optional callback. 108 * 109 * The {@code PresentationModel} is used to populate the table. The following roles are used: 110 * 111 * <ul> 112 * <li>A {@link it.tidalwave.role.SimpleComposite} provides children {@code PresentationModel}s for each row.</li> 113 * <li>In each row, an {@link it.tidalwave.role.Aggregate<PresentationModel>} is used to provide the {@code PresentationModel}s for 114 * each column.</li> 115 * <li>A {@link it.tidalwave.ui.core.role.Displayable} (optional) is used to provide the text to render for each item.</li> 116 * <li>A {@link CustomGraphicProvider} (optional) is used to provide the graphics to render for each item.</li> 117 * <li>A {@link it.tidalwave.ui.core.role.Styleable} (optional) is used to provide the rendering style for each item.</li> 118 * <li>A {@link it.tidalwave.ui.core.role.UserActionProvider} (optional) is used to provide the actions for creating a context menu; 119 * the default action is also bound to the double click or SPACE gesture.</li> 120 * </ul> 121 * 122 * The process of populating data is performed in background threads, so this method quickly returns also in case 123 * of large amount of data. 124 * The initialization callback is called in the JavaFX thread when data population has been completed. 125 * 126 * @since 1.0-ALPHA-13 127 * @param tableView the {@code TablewView} 128 * @param pm the {@code PresentationModel} 129 * @param initCallback the callback 130 **********************************************************************************************************************************************************/ 131 public void bind (@Nonnull TableView<PresentationModel> tableView, 132 @Nonnull PresentationModel pm, 133 @Nonnull Optional<Runnable> initCallback); 134 135 /*********************************************************************************************************************************************************** 136 * Binds a {@link TableView} to a {@link PresentationModel} and a callback. 137 * See {@link #bind(javafx.scene.control.TableView, it.tidalwave.ui.core.role.PresentationModel, java.util.Optional)}. 138 * 139 * The process of populating data is performed in background threads, so this method quickly returns also in case 140 * of large amount of data. 141 * The initialization callback is called in the JavaFX thread when data population has been completed. 142 * 143 * @param tableView the {@code TablewView} 144 * @param pm the {@code PresentationModel} 145 * @param initCallback the callback 146 **********************************************************************************************************************************************************/ 147 public default void bind (@Nonnull final TableView<PresentationModel> tableView, 148 @Nonnull final PresentationModel pm, 149 @Nonnull final Runnable initCallback) 150 { 151 bind(tableView, pm, Optional.of(initCallback)); 152 } 153 154 /*********************************************************************************************************************************************************** 155 * Binds a {@link TableView} to a {@link PresentationModel}. 156 * See {@link #bind(javafx.scene.control.TableView, it.tidalwave.ui.core.role.PresentationModel, java.util.Optional)}. 157 * 158 * @since 1.0-ALPHA-13 159 * @param tableView the {@code TablewView} 160 * @param pm the {@code PresentationModel} 161 **********************************************************************************************************************************************************/ 162 public default void bind (@Nonnull final TableView<PresentationModel> tableView, 163 @Nonnull final PresentationModel pm) 164 { 165 bind(tableView, pm, Optional.empty()); 166 } 167 168 /*********************************************************************************************************************************************************** 169 * Binds a {@link TreeView} to a {@link PresentationModel} and a callback. 170 * 171 * The {@code PresentationModel} is used to populate the table. The following roles are used: 172 * 173 * <ul> 174 * <li>A {@link it.tidalwave.role.SimpleComposite} provides children {@code PresentationModel}s for each row.</li> 175 * <li>In each row, an {@link it.tidalwave.role.Aggregate<PresentationModel>} is used to provide the {@code PresentationModel}s for 176 * each column.</li> 177 * <li>A {@link it.tidalwave.ui.core.role.Displayable} (optional) is used to provide the text to render for each item.</li> 178 * <li>A {@link CustomGraphicProvider} (optional) is used to provide the graphics to render for each item.</li> 179 * <li>A {@link it.tidalwave.ui.core.role.Styleable} (optional) is used to provide the rendering style for each item.</li> 180 * <li>A {@link it.tidalwave.ui.core.role.UserActionProvider} (optional) is used to provide the actions for creating a context menu; 181 * the default action is also bound to the double click or SPACE gesture.</li> 182 * <li>A {@link Visibility} (optional) is used to decide whether the root node should be visible or not.</li> 183 * </ul> 184 * 185 * The process of populating data is performed in background threads, so this method quickly returns also in case 186 * of large amount of data. 187 * The initialization callback is called in the JavaFX thread when data population has been completed. 188 * 189 * @param treeView the {@code TreeView} 190 * @param pm the {@code PresentationModel} 191 * @param initCallback the callback 192 **********************************************************************************************************************************************************/ 193 public void bind (@Nonnull TreeView<PresentationModel> treeView, 194 @Nonnull PresentationModel pm, 195 @Nonnull Optional<Runnable> initCallback); 196 197 /*********************************************************************************************************************************************************** 198 * Binds a {@link TableView} to a {@link PresentationModel} and a callback. 199 * See {@link #bind(javafx.scene.control.TreeView, it.tidalwave.ui.core.role.PresentationModel, java.util.Optional)}. 200 * 201 * @since 1.0-ALPHA-13 202 * @param treeView the {@code TreeView} 203 * @param pm the {@code PresentationModel} 204 * @param initCallback the callback 205 **********************************************************************************************************************************************************/ 206 public default void bind (@Nonnull final TreeView<PresentationModel> treeView, 207 @Nonnull final PresentationModel pm, 208 @Nonnull final Runnable initCallback) 209 { 210 bind(treeView, pm, Optional.of(initCallback)); 211 } 212 213 /*********************************************************************************************************************************************************** 214 * Binds a {@link TableView} to a {@link PresentationModel}. 215 * See {@link #bind(javafx.scene.control.TableView, it.tidalwave.ui.core.role.PresentationModel, java.util.Optional)} 216 * 217 * @since 1.0-ALPHA-13 218 * @param treeView the {@code TreeView} 219 * @param pm the {@code PresentationModel} 220 **********************************************************************************************************************************************************/ 221 public default void bind (@Nonnull final TreeView<PresentationModel> treeView, 222 @Nonnull final PresentationModel pm) 223 { 224 bind(treeView, pm, Optional.empty()); 225 } 226 227 /*********************************************************************************************************************************************************** 228 * Binds a {@link TreeTableView} to a {@link PresentationModel} and a callback. 229 * 230 * The {@code PresentationModel} is used to populate the table. The following roles are used: 231 * 232 * <ul> 233 * <li>A {@link it.tidalwave.role.SimpleComposite} provides children {@code PresentationModel}s for each row.</li> 234 * <li>In each row, an {@link it.tidalwave.role.Aggregate<PresentationModel>} is used to provide the {@code PresentationModel}s for 235 * each column.</li> 236 * <li>A {@link it.tidalwave.ui.core.role.Displayable} (optional) is used to provide the text to render for each item.</li> 237 * <li>A {@link CustomGraphicProvider} (optional) is used to provide the graphics to render for each item.</li> 238 * <li>A {@link it.tidalwave.ui.core.role.Styleable} (optional) is used to provide the rendering style for each item.</li> 239 * <li>A {@link it.tidalwave.ui.core.role.UserActionProvider} (optional) is used to provide the actions for creating a context menu; 240 * the default action is also bound to the double click or SPACE gesture.</li> 241 * <li>A {@link Visibility} (optional) is used to decide whether the root node should be visible or not.</li> 242 * </ul> 243 * 244 * The process of populating data is performed in background threads, so this method quickly returns also in case 245 * of large amount of data. 246 * The initialization callback is called in the JavaFX thread when data population has been completed. 247 * 248 * @param treeTableView the {@code TreeTableView} 249 * @param pm the {@code PresentationModel} 250 * @param initCallback the callback 251 **********************************************************************************************************************************************************/ 252 public void bind (@Nonnull TreeTableView<PresentationModel> treeTableView, 253 @Nonnull PresentationModel pm, 254 @Nonnull Optional<Runnable> initCallback); 255 256 /*********************************************************************************************************************************************************** 257 * Binds a {@link TreeTableView} to a {@link PresentationModel} and a callback. 258 * See {@link #bind(javafx.scene.control.TreeTableView, it.tidalwave.ui.core.role.PresentationModel, java.util.Optional)}. 259 * 260 * @since 1.0-ALPHA-13 261 * @param treeTableView the {@code TreeTableView} 262 * @param pm the {@code PresentationModel} 263 * @param initCallback the callback 264 **********************************************************************************************************************************************************/ 265 public default void bind (@Nonnull final TreeTableView<PresentationModel> treeTableView, 266 @Nonnull final PresentationModel pm, 267 @Nonnull final Runnable initCallback) 268 { 269 bind(treeTableView, pm, Optional.of(initCallback)); 270 } 271 272 /*********************************************************************************************************************************************************** 273 * Binds a {@link TreeTableView} to a {@link PresentationModel}. 274 * See {@link #bind(javafx.scene.control.TreeTableView, it.tidalwave.ui.core.role.PresentationModel, java.util.Optional)}. 275 * 276 * @since 1.0-ALPHA-13 277 * @param treeTableView the {@code TreeTableView} 278 * @param pm the {@code PresentationModel} 279 **********************************************************************************************************************************************************/ 280 public default void bind (@Nonnull final TreeTableView<PresentationModel> treeTableView, 281 @Nonnull final PresentationModel pm) 282 { 283 bind(treeTableView, pm, Optional.empty()); 284 } 285 286 /*********************************************************************************************************************************************************** 287 * Binds a {@link ListView} to a {@link PresentationModel} and an optional callback. 288 * 289 * The {@code PresentationModel} is used to populate the table. The following roles are used: 290 * 291 * <ul> 292 * <li>A {@link it.tidalwave.role.SimpleComposite} provides children {@code PresentationModel}s for each row.</li> 293 * <li>In each row, an {@link it.tidalwave.role.Aggregate<PresentationModel>} is used to provide the {@code PresentationModel}s for 294 * each column.</li> 295 * <li>A {@link it.tidalwave.ui.core.role.Displayable} (optional) is used to provide the text to render for each item.</li> 296 * <li>A {@link CustomGraphicProvider} (optional) is used to provide the graphics to render for each item.</li> 297 * <li>A {@link it.tidalwave.ui.core.role.Styleable} (optional) is used to provide the rendering style for each item.</li> 298 * <li>A {@link it.tidalwave.ui.core.role.UserActionProvider} (optional) is used to provide the actions for creating a context menu; 299 * the default action is also bound to the double click or SPACE gesture.</li> 300 * </ul> 301 * 302 * The process of populating data is performed in background threads, so this method quickly returns also in case 303 * of large amount of data. 304 * The initialization callback is called in the JavaFX thread when data population has been completed. 305 * 306 * @param listView the {@code ListView} 307 * @param pm the {@code PresentationModel} 308 * @param initCallback the callback 309 **********************************************************************************************************************************************************/ 310 public void bind (@Nonnull ListView<PresentationModel> listView, 311 @Nonnull PresentationModel pm, 312 @Nonnull Optional<Runnable> initCallback); 313 314 /*********************************************************************************************************************************************************** 315 * Binds a {@link ListView} to a {@link PresentationModel} and a callback. 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 * @param initCallback the callback 322 **********************************************************************************************************************************************************/ 323 public default void bind (@Nonnull final ListView<PresentationModel> listView, 324 @Nonnull final PresentationModel pm, 325 @Nonnull final Runnable initCallback) 326 { 327 bind(listView, pm, Optional.of(initCallback)); 328 } 329 330 /*********************************************************************************************************************************************************** 331 * Binds a {@link ComboBox} to a {@link PresentationModel}. 332 * See {@link #bind(javafx.scene.control.ListView, it.tidalwave.ui.core.role.PresentationModel, java.util.Optional)}. 333 * 334 * @since 1.0-ALPHA-13 335 * @param listView the {@code ListView} 336 * @param pm the {@code PresentationModel} 337 **********************************************************************************************************************************************************/ 338 public default void bind (@Nonnull final ListView<PresentationModel> listView, 339 @Nonnull final PresentationModel pm) 340 { 341 bind(listView, pm, Optional.empty()); 342 } 343 344 /*********************************************************************************************************************************************************** 345 * Binds a {@link ComboBox} to a {@link PresentationModel} and an optional callback. 346 * 347 * The {@code PresentationModel} is used to populate the table. The following roles are used: 348 * 349 * <ul> 350 * <li>A {@link it.tidalwave.role.SimpleComposite} provides children {@code PresentationModel}s for each row.</li> 351 * <li>In each row, an {@link it.tidalwave.role.Aggregate<PresentationModel>} is used to provide the {@code PresentationModel}s for 352 * each column.</li> 353 * <li>A {@link it.tidalwave.ui.core.role.Displayable} (optional) is used to provide the text to render for each item.</li> 354 * <li>A {@link CustomGraphicProvider} (optional) is used to provide the graphics to render for each item.</li> 355 * <li>A {@link it.tidalwave.ui.core.role.Styleable} (optional) is used to provide the rendering style for each item.</li> 356 * <li>A {@link it.tidalwave.ui.core.role.UserActionProvider} (optional) is used to provide the actions for creating a context menu; 357 * the default action is also bound to the double click or SPACE gesture.</li> 358 * </ul> 359 * 360 * The process of populating data is performed in background threads, so this method quickly returns also in case 361 * of large amount of data. 362 * The initialization callback is called in the JavaFX thread when data population has been completed. 363 * 364 * @param comboBox the {@code ComboBox} 365 * @param pm the {@code PresentationModel} 366 * @param initCallback the callback 367 **********************************************************************************************************************************************************/ 368 public void bind (@Nonnull ComboBox<PresentationModel> comboBox, 369 @Nonnull PresentationModel pm, 370 @Nonnull Optional<Runnable> initCallback); 371 372 /*********************************************************************************************************************************************************** 373 * Binds a {@link ComboBox} to a {@link PresentationModel} and a callback. 374 * See {@link #bind(javafx.scene.control.ComboBox, it.tidalwave.ui.core.role.PresentationModel, java.util.Optional)}. 375 * 376 * @since 1.0-ALPHA-13 377 * @param comboBox the {@code ComboBox} 378 * @param pm the {@code PresentationModel} 379 * @param initCallback the callback 380 **********************************************************************************************************************************************************/ 381 public default void bind (@Nonnull final ComboBox<PresentationModel> comboBox, 382 @Nonnull final PresentationModel pm, 383 @Nonnull final Runnable initCallback) 384 { 385 bind(comboBox, pm, Optional.of(initCallback)); 386 } 387 388 /*********************************************************************************************************************************************************** 389 * Binds a {@link ComboBox} to a {@link PresentationModel}. 390 * See {@link #bind(javafx.scene.control.ComboBox, it.tidalwave.ui.core.role.PresentationModel, java.util.Optional)}. 391 * 392 * @since 1.0-ALPHA-13 393 * @param comboBox the {@code ComboBox} 394 * @param pm the {@code PresentationModel} 395 **********************************************************************************************************************************************************/ 396 public default void bind (@Nonnull final ComboBox<PresentationModel> comboBox, 397 @Nonnull final PresentationModel pm) 398 { 399 bind(comboBox, pm, Optional.empty()); 400 } 401 402 /*********************************************************************************************************************************************************** 403 * Given a {@link PresentationModel} that contains a {@link it.tidalwave.role.Composite}, populate the pane with 404 * {@link ToggleButton}s associated to the elements of the {@link it.tidalwave.role.Composite}. Each element is searched for the 405 * following roles: 406 * 407 * <ul> 408 * <li>{@link it.tidalwave.ui.core.role.UserActionProvider} (mandatory) to provide a callback for the button</li> 409 * <li>{@link it.tidalwave.ui.core.role.Displayable} to provide a text for the button</li> 410 * <li>{@link it.tidalwave.ui.core.role.Styleable} to provide a CSS style for the button</li> 411 * </ul> 412 * 413 * The pane must be pre-populated with at least one button, which will be queried for the CSS style. 414 * 415 * @param pane the {@code Pane} 416 * @param pm the {@code PresentationModel} 417 **********************************************************************************************************************************************************/ 418 public void bindToggleButtons (@Nonnull Pane pane, @Nonnull PresentationModel pm); 419 420 /*********************************************************************************************************************************************************** 421 * Deprecated. Merge to bindToggleButtons, passing some arguments for choosing toggle or normal buttons. 422 * 423 * @deprecated 424 **********************************************************************************************************************************************************/ 425 @Deprecated 426 public void bindButtonsInPane (@Nonnull GridPane gridPane, @Nonnull Collection<UserAction> actions); 427 428 /*********************************************************************************************************************************************************** 429 * Binds two properties of different types. 430 * @param <T> the target property type 431 * @param <S> the source property type 432 * @param target the target property 433 * @param source the source property 434 * @param adapter an adapter from one source to the target 435 * @since 2.0-ALPHA-1 436 **********************************************************************************************************************************************************/ 437 public <T, S> void bind (@Nonnull final BoundProperty<? super T> target, 438 @Nonnull final Property<? extends S> source, 439 @Nonnull final Function<S, T> adapter); 440 441 /*********************************************************************************************************************************************************** 442 * Binds two properties of the same type. 443 * @param <T> the property type 444 * @param target the target property 445 * @param source the source property 446 * @since 2.0-ALPHA-1 447 **********************************************************************************************************************************************************/ 448 public default <T> void bind (@Nonnull final BoundProperty<? super T> target, @Nonnull final Property<T> source) 449 { 450 bind(target, source, Function.identity()); 451 } 452 453 /*********************************************************************************************************************************************************** 454 * Bidirectionally binds two properties of different types. 455 * @param <T> the former property type 456 * @param <S> the latter property type 457 * @param property1 the former property 458 * @param property2 the latter property 459 * @param adapter an adapter from one type to the other 460 * @param reverseAdapter the reverse adapter 461 * @since 2.0-ALPHA-1 462 **********************************************************************************************************************************************************/ 463 public <T, S> void bindBidirectionally (@Nonnull final BoundProperty<? super T> property1, 464 @Nonnull final Property<S> property2, 465 @Nonnull final Function<? super S, T> adapter, 466 @Nonnull final Function<? super T, ? extends S> reverseAdapter); 467 468 /*********************************************************************************************************************************************************** 469 * {@inheritDoc} 470 **********************************************************************************************************************************************************/ 471 public default <T> void bindBidirectionally (@Nonnull final BoundProperty<? super T> property1, @Nonnull final Property<T> property2) 472 { 473 bindBidirectionally(property1, property2, Function.identity(), Function.identity()); 474 } 475 476 /*********************************************************************************************************************************************************** 477 * Bidirectionally binds two properties. 478 * @param property1 the former property 479 * @param property2 the latter property 480 **********************************************************************************************************************************************************/ 481 public default void bindBidirectionally (@Nonnull final BoundProperty<? super Boolean> property1, @Nonnull final BooleanProperty property2) 482 { 483 bindBidirectionally(property1, property2, a -> a, a -> a); 484 } 485 486 /*********************************************************************************************************************************************************** 487 * Bidirectionally binds two properties. 488 * @param property1 the former property 489 * @param property2 the latter property 490 **********************************************************************************************************************************************************/ 491 public default void bindBidirectionally (@Nonnull final BoundProperty<? super Integer> property1, @Nonnull final IntegerProperty property2) 492 { 493 bindBidirectionally(property1, property2, Number::intValue, a -> a); 494 } 495 496 /*********************************************************************************************************************************************************** 497 * Bidirectionally binds two properties. 498 * @param property1 the former property 499 * @param property2 the latter property 500 **********************************************************************************************************************************************************/ 501 public default void bindBidirectionally (@Nonnull final BoundProperty<? super Long> property1, @Nonnull final LongProperty property2) 502 { 503 bindBidirectionally(property1, property2, Number::longValue, a -> a); 504 } 505 506 /*********************************************************************************************************************************************************** 507 * Bidirectionally binds two properties. 508 * @param property1 the former property 509 * @param property2 the latter property 510 **********************************************************************************************************************************************************/ 511 public default void bindBidirectionally (@Nonnull final BoundProperty<? super Double> property1, @Nonnull final DoubleProperty property2) 512 { 513 bindBidirectionally(property1, property2, Number::doubleValue, a -> a); 514 } 515 516 /*********************************************************************************************************************************************************** 517 * 518 **********************************************************************************************************************************************************/ 519 public void bindBidirectionally (@Nonnull TextField textField, 520 @Nonnull BoundProperty<String> textProperty, 521 @Nonnull BoundProperty<Boolean> validProperty); 522 523 /*********************************************************************************************************************************************************** 524 * Shows a modal dialog with the given content and provides feedback by means of the given notification. 525 * 526 * @param notification the object notifying whether the operation is confirmed or cancelled 527 * @since 1.1-ALPHA-6 528 **********************************************************************************************************************************************************/ 529 public default void showInModalDialog (@Nonnull final UserNotification notification) 530 { 531 showInModalDialog(UserNotificationWithFeedback.notificationWithFeedback() 532 .withCaption(notification.getCaption()) 533 .withText(notification.getText())); 534 } 535 536 /*********************************************************************************************************************************************************** 537 * Shows a modal dialog with the given content and provides feedback by means of the given notification. 538 * 539 * @param node the dialog content 540 * @param notification the object notifying whether the operation is confirmed or cancelled 541 **********************************************************************************************************************************************************/ 542 public void showInModalDialog (@Nonnull UserNotificationWithFeedback notification, 543 @Nonnull Optional<Node> node); 544 545 // FIXME: use a Builder, merge with the above 546 public default void showInModalDialog (@Nonnull final Node node, 547 @Nonnull final UserNotificationWithFeedback notification, 548 @Nonnull final BoundProperty<Boolean> valid) 549 { 550 showInModalDialog(notification, Optional.of(node)); 551 } 552 553 @Deprecated 554 public default void showInModalDialog (@Nonnull final Node node, 555 @Nonnull final UserNotificationWithFeedback notification) 556 { 557 showInModalDialog(notification, Optional.of(node)); 558 } 559 560 public default void showInModalDialog (@Nonnull final UserNotificationWithFeedback notification) 561 { 562 showInModalDialog(notification, Optional.empty()); 563 } 564 565 /*********************************************************************************************************************************************************** 566 * Opens the FileChooser for selecting a file. The outcome of the operation (confirmed or cancelled) will be 567 * notified to the given notification object. The selected file will be set to the given bound property, which can 568 * be also used to set the default value rendered on the FileChooser. 569 * 570 * @param notification the object notifying whether the operation is confirmed or cancelled 571 * @param selectedFile the property containing the selected file 572 **********************************************************************************************************************************************************/ 573 public void openFileChooserFor (@Nonnull UserNotificationWithFeedback notification, 574 @Nonnull BoundProperty<Path> selectedFile); 575 576 /*********************************************************************************************************************************************************** 577 * Opens the FileChooser for selecting a folder. The outcome of the operation (confirmed or cancelled) will be 578 * notified to the given notification object. The selected folder will be set to the given bound property, which can 579 * be also used to set the default value rendered on the FileChooser. 580 * 581 * @param notification the object notifying whether the operation is confirmed or cancelled 582 * @param selectedFolder the property containing the selected folder 583 **********************************************************************************************************************************************************/ 584 public void openDirectoryChooserFor (@Nonnull UserNotificationWithFeedback notification, 585 @Nonnull BoundProperty<Path> selectedFolder); 586 }