diff --git a/base/src/main/java/atlantafx/base/controls/BehaviorBase.java b/base/src/main/java/atlantafx/base/controls/BehaviorBase.java index 503ebff..81b7f99 100755 --- a/base/src/main/java/atlantafx/base/controls/BehaviorBase.java +++ b/base/src/main/java/atlantafx/base/controls/BehaviorBase.java @@ -1,24 +1,59 @@ -/* SPDX-License-Identifier: MIT */ +/* + * SPDX-License-Identifier: MIT + * + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ package atlantafx.base.controls; import javafx.scene.control.Control; import javafx.scene.control.SkinBase; -public abstract class BehaviorBase> { +/** + * Encapsulates behavior interaction logic for a skin. The main functionality + * in BehaviorBase revolves around infrastructure for resolving events into + * function calls. A BehaviorBase implementation will usually contain logic for + * handling key events based on the host platform, as well as view-specific + * functions for handling mouse and key and other input events. + * + *

Although BehaviorBase is typically used as a base class, it is not abstract and + * several skins instantiate an instance of BehaviorBase directly. + * + *

Note: This is an excerpt of the private Behavior API from the JavaFX codebase. + * It serves as a compatibility layer for implementing certain controls, although it + * can also be useful for new controls. + */ +public class BehaviorBase> { private C control; private S skin; + /** + * Constructor for all BehaviorBase instances. + * + * @param control The control for which this Skin should attach to. + * @param skin The skin used by the control. + */ protected BehaviorBase(C control, S skin) { this.control = control; this.skin = skin; } + /** + * Gets the control associated with this behavior. + * + * @return The control for this behavior. + */ public C getControl() { return control; } + /** + * Gets the skin associated with this behavior. + * + * @return The control for this behavior. + */ public S getSkin() { return skin; } diff --git a/base/src/main/java/atlantafx/base/controls/BehaviorSkinBase.java b/base/src/main/java/atlantafx/base/controls/BehaviorSkinBase.java index bc544aa..5ba8443 100755 --- a/base/src/main/java/atlantafx/base/controls/BehaviorSkinBase.java +++ b/base/src/main/java/atlantafx/base/controls/BehaviorSkinBase.java @@ -1,4 +1,9 @@ -/* SPDX-License-Identifier: MIT */ +/* + * SPDX-License-Identifier: MIT + * + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ package atlantafx.base.controls; @@ -7,21 +12,48 @@ import javafx.beans.value.ObservableValue; import javafx.scene.control.Control; import javafx.scene.control.SkinBase; +/** + * Base implementation class for defining the visual representation of user + * interface controls that need to handle platform events and therefore can take + * advantage of using the Behavior API. + * + *

Note: This is an excerpt of the private Behavior API from the JavaFX codebase. + * It serves as a compatibility layer for implementing certain controls, although it + * can also be useful for new controls. + */ public abstract class BehaviorSkinBase> extends SkinBase { protected B behavior; + /** + * Constructor for all BehaviorSkinBase instances. + * + * @param control The control for which this Skin should attach to. + */ protected BehaviorSkinBase(C control) { super(control); behavior = createDefaultBehavior(); } + /** + * An abstract method for creating the behavior instance to be used by this skin. + */ public abstract B createDefaultBehavior(); + /** + * Gets the control associated with this skin. + * + * @return The control for this Skin. + */ public C getControl() { return getSkinnable(); } + /** + * Gets the behavior associated with this skin. + * + * @return The behavior for this skin. + */ public B getBehavior() { return behavior; } diff --git a/base/src/main/java/atlantafx/base/controls/Breadcrumbs.java b/base/src/main/java/atlantafx/base/controls/Breadcrumbs.java index f9a862e..0ea30fa 100755 --- a/base/src/main/java/atlantafx/base/controls/Breadcrumbs.java +++ b/base/src/main/java/atlantafx/base/controls/Breadcrumbs.java @@ -47,14 +47,21 @@ import javafx.scene.control.Skin; import javafx.scene.control.TreeItem; import javafx.scene.layout.Region; import javafx.util.Callback; +import org.jetbrains.annotations.Nullable; /** - * Represents a bread crumb bar. This control is useful to visualize and navigate + * A bread crumb bar. This control is useful to visualize and navigate * a hierarchical path structure, such as file systems. * - *

A breadcrumbs consist of two types of elements: a button (default is a hyperlink) - * and a divider (default is for Label). You can customize both by providing the - * corresponding control factory. + *

{@code
+ * String[] list = {"Root", "Folder", "file.txt"};
+ * BreadCrumbItem selectedCrumb = Breadcrumbs.buildTreeModel(list);
+ * Breadcrumbs breadcrumbs = new Breadcrumbs<>(selectedCrumb);
+ * }
+ * + *

A breadcrumbs consist of two types of elements: a button (default is + * {@code Hyperlink}) and a divider (default is for {@code Label}). You can + * customize both by providing the corresponding factory. */ @SuppressWarnings("unused") public class Breadcrumbs extends Control { @@ -63,6 +70,7 @@ public class Breadcrumbs extends Control { protected final Callback, ButtonBase> defaultCrumbNodeFactory = item -> new Hyperlink(item.getStringValue()); + protected final Callback, ? extends Node> defaultDividerFactory = item -> item != null && !item.isLast() ? new Label("/") : null; @@ -74,10 +82,12 @@ public class Breadcrumbs extends Control { } /** - * Creates a bread crumb bar with the given BreadCrumbItem as the currently - * selected crumb. + * Creates a bread crumb bar with the given BreadCrumbItem as the + * currently {@link #selectedCrumbProperty()}. + * + * @param selectedCrumb The currently selected crumb. */ - public Breadcrumbs(BreadCrumbItem selectedCrumb) { + public Breadcrumbs(@Nullable BreadCrumbItem selectedCrumb) { getStyleClass().add(DEFAULT_STYLE_CLASS); // breadcrumbs should be the size of its content @@ -100,8 +110,10 @@ public class Breadcrumbs extends Control { } /** - * Construct a tree model from the flat list which then can be set - * as selectedCrumb node to be shown. + * Constructs a tree model from the flat list which then can be set + * as the {@code selectedCrumb} node to be shown. + * + * @param crumbs The flat list of values used to build the tree model */ @SafeVarargs public static BreadCrumbItem buildTreeModel(T... crumbs) { @@ -128,7 +140,8 @@ public class Breadcrumbs extends Control { *

Consider the following hierarchy: * [Root] > [Folder] > [SubFolder] > [file.txt] * - *

To show the above bread crumb bar, you have to set the [file.txt] tree-node as selected crumb. + *

To show the above bread crumb bar, you have to set the [file.txt] + * tree-node as selected crumb. */ public final ObjectProperty> selectedCrumbProperty() { return selectedCrumb; @@ -147,10 +160,9 @@ public class Breadcrumbs extends Control { /** * Enables or disables auto navigation (default is enabled). - * If auto navigation is enabled, it will automatically navigate to the crumb which was - * clicked by the user. - * - * @return a {@link BooleanProperty} + * If auto navigation is enabled, it will automatically navigate to the + * crumb which was clicked by the user, meaning it will set the + * {@link #selectedCrumbProperty()} upon click. */ public final BooleanProperty autoNavigationEnabledProperty() { return autoNavigation; @@ -168,14 +180,15 @@ public class Breadcrumbs extends Control { } /** - * Crumb factory is used to create custom bread crumb instances. - * null is not allowed and will result in a fallback to the default factory. + * The crumb factory is used to create custom bread crumb instances. + * A null value is not allowed and will result in a fallback to the default factory. + *

* - *

BreadCrumbItem<T> specifies the tree item for creating bread crumb. Use - * {@link BreadCrumbItem#isFirst()} and {@link BreadCrumbItem#isLast()} to create bread crumb - * depending on item position. - * - *

ButtonBase stands for resulting bread crumb node. It CAN NOT be null. + *

Use {@link BreadCrumbItem#isFirst()} and {@link BreadCrumbItem#isLast()} to + * create bread crumb depending on item position. */ public final ObjectProperty, ButtonBase>> crumbFactoryProperty() { return crumbFactory; @@ -196,16 +209,19 @@ public class Breadcrumbs extends Control { } /** - * Divider factory is used to create custom divider instances. - * null is not allowed and will result in a fallback to the default factory. + * The divider factory is used to create custom instances of dividers. + * A null value is not allowed and will result in a fallback to the default factory. * - *

BreadCrumbItem<T> specifies the preceding tree item. It can be null, because this way - * you can insert divider before the first bread crumb, which can be used e.g. for creating a Unix path. - * Use {@link BreadCrumbItem#isFirst()} and {@link BreadCrumbItem#isLast()} to create divider - * depending on item position. + *

* - *

? extends Node stands for resulting divider node. It CAN be null, which - * means there will be no divider inserted after the specified bread crumb. + *

Use {@link BreadCrumbItem#isFirst()} and {@link BreadCrumbItem#isLast()} to + * create bread crumb depending on item position. */ public final ObjectProperty, ? extends Node>> dividerFactoryProperty() { return dividerFactory; @@ -226,26 +242,15 @@ public class Breadcrumbs extends Control { } /** - * The EventHandler is called when a user selects a bread crumb. + * Represents the EventHandler that is called when a user selects a bread crumb. */ public final ObjectProperty>> onCrumbActionProperty() { return onCrumbAction; } - /** - * Set a new EventHandler for when a user selects a crumb. - */ - public final void setOnCrumbAction(EventHandler> value) { - onCrumbActionProperty().set(value); - } - - public final EventHandler> getOnCrumbAction() { - return onCrumbActionProperty().get(); - } - protected final ObjectProperty>> onCrumbAction = new ObjectPropertyBase<>() { - @SuppressWarnings({"unchecked", "rawtypes"}) + @SuppressWarnings({ "unchecked", "rawtypes" }) @Override protected void invalidated() { setEventHandler(BreadCrumbActionEvent.CRUMB_ACTION, (EventHandler) (Object) get()); @@ -262,48 +267,79 @@ public class Breadcrumbs extends Control { } }; + public final void setOnCrumbAction(EventHandler> value) { + onCrumbActionProperty().set(value); + } + + public final EventHandler> getOnCrumbAction() { + return onCrumbActionProperty().get(); + } + /////////////////////////////////////////////////////////////////////////// + /** + * {@code BreadCrumbItem} extends {@link TreeItem}, providing support + * for navigating hierarchical structures. + * + * @param The type of the value property within BreadCrumbItem. + */ public static class BreadCrumbItem extends TreeItem { - // setters must not be exposed to user - private boolean first; - private boolean last; + protected boolean first; + protected boolean last; - public BreadCrumbItem(T value) { + /** + * Creates a BreadCrumbItem with the value property set to the provided object. + * + * @param value The object to be stored as the value of this BreadCrumbItem. + */ + public BreadCrumbItem(@Nullable T value) { super(value); } + /** + * Use this method to determine if this item is at the beginning, + * so you can create bread crumbs accordingly. + */ public boolean isFirst() { return first; } - void setFirst(boolean first) { - this.first = first; - } - + /** + * Use this method to determine if this item is at the end, + * so you can create breadcrumbs accordingly. + */ public boolean isLast() { return last; } - void setLast(boolean last) { + /////////////////////////////////////////////////// + // package private // + /////////////////////////////////////////////////// + + protected void setFirst(boolean first) { + this.first = first; + } + + protected void setLast(boolean last) { this.last = last; } - String getStringValue() { + protected String getStringValue() { return getValue() != null ? getValue().toString() : ""; } } /** - * Represents an Event which is fired when a bread crumb was activated. + * An {@code Event} which is fired when a bread crumb was activated. */ public static class BreadCrumbActionEvent extends Event { /** - * The event type that should be listened to by people interested in - * knowing when the {@link Breadcrumbs#selectedCrumbProperty() selected crumb} - * has changed. + * Represents the event type that should be listened to by people who are + * interested in knowing when the selected crumb has changed. This is accomplished + * through listening to the {@link Breadcrumbs#selectedCrumbProperty() selected crumb + * property}. */ public static final EventType> CRUMB_ACTION = new EventType<>("CRUMB_ACTION" + UUID.randomUUID()); @@ -312,6 +348,8 @@ public class Breadcrumbs extends Control { /** * Creates a new event that can subsequently be fired. + * + * @param selectedCrumb The currently selected crumb. */ public BreadCrumbActionEvent(BreadCrumbItem selectedCrumb) { super(CRUMB_ACTION); diff --git a/base/src/main/java/atlantafx/base/controls/BreadcrumbsSkin.java b/base/src/main/java/atlantafx/base/controls/BreadcrumbsSkin.java index 65c1cb1..addc773 100755 --- a/base/src/main/java/atlantafx/base/controls/BreadcrumbsSkin.java +++ b/base/src/main/java/atlantafx/base/controls/BreadcrumbsSkin.java @@ -41,17 +41,23 @@ import javafx.scene.control.ButtonBase; import javafx.scene.control.SkinBase; import javafx.scene.control.TreeItem.TreeModificationEvent; +/** + * The default skin for the {@link Breadcrumbs} control. + */ public class BreadcrumbsSkin extends SkinBase> { protected static final PseudoClass FIRST = PseudoClass.getPseudoClass("first"); protected static final PseudoClass LAST = PseudoClass.getPseudoClass("last"); - protected final EventHandler> treeChildrenModifiedHandler = e -> updateBreadCrumbs(); + protected final EventHandler> treeChildrenModifiedHandler = + e -> updateBreadCrumbs(); public BreadcrumbsSkin(final Breadcrumbs control) { super(control); - control.selectedCrumbProperty().addListener((obs, old, val) -> updateSelectedPath(old, val)); + control.selectedCrumbProperty().addListener( + (obs, old, val) -> updateSelectedPath(old, val) + ); updateSelectedPath(getSkinnable().selectedCrumbProperty().get(), null); } diff --git a/base/src/main/java/atlantafx/base/controls/Calendar.java b/base/src/main/java/atlantafx/base/controls/Calendar.java index 6001fd2..c6a088c 100755 --- a/base/src/main/java/atlantafx/base/controls/Calendar.java +++ b/base/src/main/java/atlantafx/base/controls/Calendar.java @@ -51,22 +51,23 @@ import javafx.scene.control.Control; import javafx.scene.control.DateCell; import javafx.scene.control.Skin; import javafx.util.Callback; +import org.jetbrains.annotations.Nullable; /** - * The DatePicker control allows the user to select a date. The calendar is based on either + * The Calendar control allows the user to select a date. The calendar is based on either * the standard ISO-8601 chronology or any of the other chronology classes defined in the - * java.time.chrono package. + * java.time.chrono package. * - *

The {@link #valueProperty() value} property represents the currently selected - * {@link LocalDate}. The default value is null. - * - *

The {@link #chronologyProperty() chronology} property specifies a calendar system to be used - * for parsing, displaying, and choosing dates. - * - *

The {@link #valueProperty() value} property is always defined in the ISO calendar system, + *

*/ public class Calendar extends Control { @@ -74,7 +75,8 @@ public class Calendar extends Control { protected Chronology lastValidChronology = IsoChronology.INSTANCE; /** - * Creates a default DatePicker instance with a null date value set. + * Creates a default Calendar instance with a null + * date value set. */ public Calendar() { this(null); @@ -105,11 +107,12 @@ public class Calendar extends Control { } /** - * Creates a DatePicker instance and sets the {@link #valueProperty() value} to the given date. + * Creates a Calendar instance and sets the {@link #valueProperty() value} + * to the specified date. * - * @param localDate to be set as the currently selected date in the DatePicker. Can be null. + * @param localDate The date to be set as the currently selected date in the Calendar. */ - public Calendar(LocalDate localDate) { + public Calendar(@Nullable LocalDate localDate) { setValue(localDate); getStyleClass().add(DEFAULT_STYLE_CLASS); } @@ -126,6 +129,13 @@ public class Calendar extends Control { // Properties // /////////////////////////////////////////////////////////////////////////// + /** + * Represents the currently selected {@link LocalDate}. The default value is null. + */ + public ObjectProperty valueProperty() { + return value; + } + private final ObjectProperty value = new SimpleObjectProperty<>(this, "value"); public final LocalDate getValue() { @@ -136,10 +146,6 @@ public class Calendar extends Control { valueProperty().set(value); } - public ObjectProperty valueProperty() { - return value; - } - /** * A custom cell factory can be provided to customize individual day cells * Refer to {@link DateCell} and {@link Cell} for more information on cell factories. @@ -162,8 +168,8 @@ public class Calendar extends Control { } /** - * The calendar system used for parsing, displaying, and choosing dates in the DatePicker - * control. + * The calendar system used for parsing, displaying, and choosing dates in the + * Calendar control. * *

The default is usually {@link IsoChronology} unless provided explicitly * in the {@link Locale} by use of a Locale calendar extension. @@ -176,7 +182,8 @@ public class Calendar extends Control { return chronology; } - private final ObjectProperty chronology = new SimpleObjectProperty<>(this, "chronology", null); + private final ObjectProperty chronology + = new SimpleObjectProperty<>(this, "chronology", null); @SuppressWarnings("CatchAndPrintStackTrace") public final Chronology getChronology() { @@ -199,7 +206,7 @@ public class Calendar extends Control { } /** - * Whether the DatePicker popup should display a column showing week numbers. + * Whether the Calendar should display a column showing week numbers. * *

The default value is specified in a resource bundle, and depends on the country of the * current locale. @@ -238,7 +245,15 @@ public class Calendar extends Control { return showWeekNumbersProperty().getValue(); } - private final ObjectProperty topNode = new SimpleObjectProperty<>(this, "topNode", null); + /** + * Represents the custom node to be placed at the top of the Calendar above the month-year area. + */ + public ObjectProperty topNodeProperty() { + return topNode; + } + + private final ObjectProperty topNode + = new SimpleObjectProperty<>(this, "topNode", null); public final void setTopNode(Node value) { topNode.setValue(value); @@ -248,11 +263,15 @@ public class Calendar extends Control { return topNode.getValue(); } - public ObjectProperty topNodeProperty() { - return topNode; + /** + * Represents the custom node to be placed at the bottom of the Calendar below the day-cell grid. + */ + public ObjectProperty bottomNodeProperty() { + return bottomNode; } - private final ObjectProperty bottomNode = new SimpleObjectProperty<>(this, "bottomNode", null); + private final ObjectProperty bottomNode + = new SimpleObjectProperty<>(this, "bottomNode", null); public final void setBottomNode(Node value) { bottomNode.setValue(value); @@ -262,10 +281,6 @@ public class Calendar extends Control { return bottomNode.getValue(); } - public ObjectProperty bottomNodeProperty() { - return bottomNode; - } - /////////////////////////////////////////////////////////////////////////// // Stylesheet Handling // /////////////////////////////////////////////////////////////////////////// diff --git a/base/src/main/java/atlantafx/base/controls/CalendarBehavior.java b/base/src/main/java/atlantafx/base/controls/CalendarBehavior.java index 6e793a6..2989bfa 100755 --- a/base/src/main/java/atlantafx/base/controls/CalendarBehavior.java +++ b/base/src/main/java/atlantafx/base/controls/CalendarBehavior.java @@ -12,6 +12,9 @@ import java.time.ZoneId; import javafx.scene.input.KeyEvent; import javafx.scene.input.MouseEvent; +/** + * The default behavior for the {@link Calendar} control. + */ public class CalendarBehavior extends BehaviorBase { public CalendarBehavior(Calendar control, CalendarSkin skin) { diff --git a/base/src/main/java/atlantafx/base/controls/CalendarSkin.java b/base/src/main/java/atlantafx/base/controls/CalendarSkin.java index 7cfa1e3..41b4791 100755 --- a/base/src/main/java/atlantafx/base/controls/CalendarSkin.java +++ b/base/src/main/java/atlantafx/base/controls/CalendarSkin.java @@ -73,6 +73,9 @@ import javafx.scene.layout.StackPane; import javafx.scene.layout.VBox; import javafx.util.Callback; +/** + * The default skin for the {@link Calendar} control. + */ public class CalendarSkin extends BehaviorSkinBase { // formatters @@ -100,7 +103,8 @@ public class CalendarSkin extends BehaviorSkinBase { protected DateCell lastFocusedDayCell = null; protected final int daysPerWeek = getDaysPerWeek(); - private final ObjectProperty displayedYearMonth = new SimpleObjectProperty<>(this, "displayedYearMonth"); + private final ObjectProperty displayedYearMonth + = new SimpleObjectProperty<>(this, "displayedYearMonth"); public ObjectProperty displayedYearMonthProperty() { return displayedYearMonth; @@ -113,27 +117,27 @@ public class CalendarSkin extends BehaviorSkinBase { return firstDayOfMonth.get(); } - public CalendarSkin(Calendar datePicker) { - super(datePicker); + public CalendarSkin(Calendar control) { + super(control); createUI(); - registerChangeListener(datePicker.valueProperty(), e -> { - LocalDate date = datePicker.getValue(); + registerChangeListener(control.valueProperty(), e -> { + LocalDate date = control.getValue(); displayedYearMonthProperty().set( date != null ? YearMonth.from(date) : YearMonth.now(ZoneId.systemDefault()) ); updateValues(); - datePicker.fireEvent(new ActionEvent()); + control.fireEvent(new ActionEvent()); }); - registerChangeListener(datePicker.showWeekNumbersProperty(), e -> { + registerChangeListener(control.showWeekNumbersProperty(), e -> { updateGrid(); updateWeekNumberCells(); }); - registerChangeListener(datePicker.topNodeProperty(), e -> { - Node node = datePicker.getTopNode(); + registerChangeListener(control.topNodeProperty(), e -> { + Node node = control.getTopNode(); if (node == null) { rootPane.getChildren().removeIf(c -> c.getStyleClass().contains("top-node")); } else { @@ -144,8 +148,8 @@ public class CalendarSkin extends BehaviorSkinBase { } }); - registerChangeListener(datePicker.bottomNodeProperty(), e -> { - Node node = datePicker.getBottomNode(); + registerChangeListener(control.bottomNodeProperty(), e -> { + Node node = control.getBottomNode(); if (node == null) { rootPane.getChildren().removeIf(c -> c.getStyleClass().contains("bottom-node")); } else { @@ -171,9 +175,7 @@ public class CalendarSkin extends BehaviorSkinBase { } /** - * The primary chronology for display. This may be overridden to be different from the - * DatePicker chronology. For example DatePickerHijrahContent uses ISO as primary and Hijrah - * as a secondary chronology. + * The primary chronology for display. */ public Chronology getPrimaryChronology() { return getControl().getChronology(); diff --git a/base/src/main/java/atlantafx/base/controls/CaptionMenuItem.java b/base/src/main/java/atlantafx/base/controls/CaptionMenuItem.java index ea1bc95..7055512 100644 --- a/base/src/main/java/atlantafx/base/controls/CaptionMenuItem.java +++ b/base/src/main/java/atlantafx/base/controls/CaptionMenuItem.java @@ -2,20 +2,31 @@ package atlantafx.base.controls; +import javafx.beans.NamedArg; import javafx.beans.property.StringProperty; import javafx.scene.control.CustomMenuItem; import javafx.scene.control.Label; +import org.jetbrains.annotations.Nullable; -@SuppressWarnings("unused") +/** + * A MenuItem that is intended to contain a caption for a group of menu items + * that share a common purpose. + */ public class CaptionMenuItem extends CustomMenuItem { protected final Label title = new Label(); + /** + * Creates an empty menu item. + */ public CaptionMenuItem() { this(null); } - public CaptionMenuItem(String text) { + /** + * Creates a CaptionMenuItem with the specified text as the title. + */ + public CaptionMenuItem(@Nullable @NamedArg("text") String text) { super(); setTitle(text); @@ -24,6 +35,13 @@ public class CaptionMenuItem extends CustomMenuItem { getStyleClass().addAll("caption-menu-item"); } + /** + * Contains the title of the menu item. + */ + public StringProperty titleProperty() { + return title.textProperty(); + } + public String getTitle() { return title.getText(); } @@ -31,8 +49,4 @@ public class CaptionMenuItem extends CustomMenuItem { public void setTitle(String text) { title.setText(text); } - - public StringProperty titleProperty() { - return title.textProperty(); - } } diff --git a/base/src/main/java/atlantafx/base/controls/Card.java b/base/src/main/java/atlantafx/base/controls/Card.java index d3d7ff6..7c0b127 100644 --- a/base/src/main/java/atlantafx/base/controls/Card.java +++ b/base/src/main/java/atlantafx/base/controls/Card.java @@ -9,7 +9,7 @@ import javafx.scene.control.Control; import javafx.scene.control.Skin; /** - * Aa versatile container that can used in various contexts such as headings, + * A versatile container that can be used in various contexts, such as headings, * text, dialogs and more. It includes a header to provide a brief overview * or context of the information. The sub-header and body sections provide * more detailed content, while the footer may include additional actions or @@ -17,12 +17,17 @@ import javafx.scene.control.Skin; */ public class Card extends Control { - // Default constructor + /** + * Creates an empty Card. + */ public Card() { super(); getStyleClass().add("card"); } + /** + * {@inheritDoc} + */ @Override protected Skin createDefaultSkin() { return new CardSkin(this); @@ -33,69 +38,69 @@ public class Card extends Control { /////////////////////////////////////////////////////////////////////////// /** - * The property representing the card’s header node. + * Represents the card’s header node. */ + public ObjectProperty headerProperty() { + return header; + } + private final ObjectProperty header = new SimpleObjectProperty<>(this, "header"); public Node getHeader() { return header.get(); } - public ObjectProperty headerProperty() { - return header; - } - public void setHeader(Node header) { this.header.set(header); } /** - * The property representing the card’s sub-header node. + * Represents the card’s sub-header node. */ + public final ObjectProperty subHeaderProperty() { + return subHeader; + } + private final ObjectProperty subHeader = new SimpleObjectProperty<>(this, "subHeader"); public Node getSubHeader() { return subHeader.get(); } - public final ObjectProperty subHeaderProperty() { - return subHeader; - } - public void setSubHeader(Node subHeader) { this.subHeader.set(subHeader); } /** - * The property representing the card’s body node. + * Represents the card’s body node. */ + public ObjectProperty bodyProperty() { + return body; + } + private final ObjectProperty body = new SimpleObjectProperty<>(this, "body"); public Node getBody() { return body.get(); } - public ObjectProperty bodyProperty() { - return body; - } - public void setBody(Node body) { this.body.set(body); } /** - * The property representing the card’s footer node. + * Represents the card’s footer node. */ + public ObjectProperty footerProperty() { + return footer; + } + private final ObjectProperty footer = new SimpleObjectProperty<>(this, "footer"); public Node getFooter() { return footer.get(); } - public ObjectProperty footerProperty() { - return footer; - } - public void setFooter(Node footer) { this.footer.set(footer); } diff --git a/base/src/main/java/atlantafx/base/controls/CardSkin.java b/base/src/main/java/atlantafx/base/controls/CardSkin.java index 435b644..52993a8 100644 --- a/base/src/main/java/atlantafx/base/controls/CardSkin.java +++ b/base/src/main/java/atlantafx/base/controls/CardSkin.java @@ -11,6 +11,9 @@ import javafx.scene.layout.Priority; import javafx.scene.layout.StackPane; import javafx.scene.layout.VBox; +/** + * The default skin for the {@link Card} control. + */ public class CardSkin implements Skin { protected static final PseudoClass HAS_HEADER = PseudoClass.getPseudoClass("has-header"); diff --git a/base/src/main/java/atlantafx/base/controls/CustomTextField.java b/base/src/main/java/atlantafx/base/controls/CustomTextField.java index a96dc0c..61ab406 100755 --- a/base/src/main/java/atlantafx/base/controls/CustomTextField.java +++ b/base/src/main/java/atlantafx/base/controls/CustomTextField.java @@ -36,79 +36,29 @@ import javafx.scene.control.Skin; import javafx.scene.control.TextField; /** - * A base class for people wanting to customize a {@link TextField} to contain nodes - * inside the text field itself, without being on top of the users typed-in text. + * A base class for people wanting to customize a {@link TextField} + * to contain nodes inside the text field itself, without being on top + * of the users typed-in text. */ -@SuppressWarnings("unused") public class CustomTextField extends TextField { /** - * Instantiates a default CustomTextField. + * Creates an empty CustomTextField. */ public CustomTextField() { getStyleClass().add("custom-text-field"); } + /** + * Creates a CustomTextField with initial text content. + * + * @param text A string for text content. + */ public CustomTextField(String text) { this(); setText(text); } - /////////////////////////////////////////////////////////////////////////// - // Properties // - /////////////////////////////////////////////////////////////////////////// - - private final ObjectProperty left = new SimpleObjectProperty<>(this, "left"); - - /** - * Returns an ObjectProperty wrapping the {@link Node} that is placed - * on the left of the text field. - */ - public final ObjectProperty leftProperty() { - return left; - } - - /** - * Returns the {@link Node} that is placed on the left of the text field. - */ - public final Node getLeft() { - return left.get(); - } - - /** - * Sets the {@link Node} that is placed on the left of the text field. - */ - public final void setLeft(Node value) { - left.set(value); - } - - private final ObjectProperty right = new SimpleObjectProperty<>(this, "right"); - - /** - * Property representing the {@link Node} that is placed on the right of the text field. - */ - public final ObjectProperty rightProperty() { - return right; - } - - /** - * Returns the {@link Node} that is placed on the right of the text field. - */ - public final Node getRight() { - return right.get(); - } - - /** - * Sets the {@link Node} that is placed on the right of the text field. - */ - public final void setRight(Node value) { - right.set(value); - } - - /////////////////////////////////////////////////////////////////////////// - // Methods // - /////////////////////////////////////////////////////////////////////////// - /** * {@inheritDoc} */ @@ -126,4 +76,54 @@ public class CustomTextField extends TextField { } }; } + + /////////////////////////////////////////////////////////////////////////// + // Properties // + /////////////////////////////////////////////////////////////////////////// + + /** + * Represents the {@link Node} that is placed on the left of the text field. + */ + public final ObjectProperty leftProperty() { + return left; + } + + private final ObjectProperty left = new SimpleObjectProperty<>(this, "left"); + + /** + * Returns the {@link Node} that is placed on the left of the text field. + */ + public final Node getLeft() { + return left.get(); + } + + /** + * Sets the {@link Node} that is placed on the left of the text field. + */ + public final void setLeft(Node value) { + left.set(value); + } + + /** + * Represents the {@link Node} that is placed on the right of the text field. + */ + public final ObjectProperty rightProperty() { + return right; + } + + private final ObjectProperty right = new SimpleObjectProperty<>(this, "right"); + + /** + * Returns the {@link Node} that is placed on the right of the text field. + */ + public final Node getRight() { + return right.get(); + } + + /** + * Sets the {@link Node} that is placed on the right of the text field. + */ + public final void setRight(Node value) { + right.set(value); + } } diff --git a/base/src/main/java/atlantafx/base/controls/CustomTextFieldSkin.java b/base/src/main/java/atlantafx/base/controls/CustomTextFieldSkin.java index df8131f..5ebb15f 100755 --- a/base/src/main/java/atlantafx/base/controls/CustomTextFieldSkin.java +++ b/base/src/main/java/atlantafx/base/controls/CustomTextFieldSkin.java @@ -38,6 +38,9 @@ import javafx.scene.control.skin.TextFieldSkin; import javafx.scene.layout.StackPane; import javafx.scene.text.HitInfo; +/** + * The default skin for the {@link CustomTextField} control. + */ public abstract class CustomTextFieldSkin extends TextFieldSkin { private static final PseudoClass HAS_NO_SIDE_NODE = PseudoClass.getPseudoClass("no-side-nodes"); diff --git a/base/src/main/java/atlantafx/base/controls/MaskTextField.java b/base/src/main/java/atlantafx/base/controls/MaskTextField.java index 6cdd654..04af786 100644 --- a/base/src/main/java/atlantafx/base/controls/MaskTextField.java +++ b/base/src/main/java/atlantafx/base/controls/MaskTextField.java @@ -29,6 +29,7 @@ package atlantafx.base.controls; import atlantafx.base.util.MaskChar; import atlantafx.base.util.MaskTextFormatter; +import atlantafx.base.util.SimpleMaskChar; import java.util.List; import java.util.Objects; import javafx.beans.NamedArg; @@ -38,9 +39,9 @@ import javafx.beans.property.StringProperty; import org.jetbrains.annotations.Nullable; /** - * This is a convenience wrapper for instantiating a {@link CustomTextField} with a - * {@code MaskTextFormatter}. For additional info refer to the {@link MaskTextFormatter} - * docs. + * A convenience wrapper for instantiating a {@link CustomTextField} with a + * {@code MaskTextFormatter}. For additional info refer to the + * {@link MaskTextFormatter} documentation. */ public class MaskTextField extends CustomTextField { @@ -56,15 +57,35 @@ public class MaskTextField extends CustomTextField { protected final ReadOnlyObjectWrapper formatter = new ReadOnlyObjectWrapper<>(this, "formatter"); + /** + * Creates an empty MaskTextField. + */ public MaskTextField() { super(""); init(); } + /** + * Creates an empty MaskTextField with the specified input mask. + * + *

The input mask is specified as a string that must follow the + * rules described in the {@link MaskTextFormatter} documentation. + * + * @param mask The input mask. + */ public MaskTextField(@NamedArg("mask") String mask) { this("", mask); } + /** + * Creates a MaskTextField with initial text content and the specified input mask. + * + *

The input mask is specified as a string that must follow the + * rules described in the {@link MaskTextFormatter} documentation. + * + * @param text A string for text content. + * @param mask An input mask. + */ private MaskTextField(@NamedArg("text") String text, @NamedArg("mask") String mask) { super(Objects.requireNonNullElse(text, "")); @@ -74,6 +95,15 @@ public class MaskTextField extends CustomTextField { init(); } + /** + * Creates a MaskTextField with initial text content and the specified input mask. + * + *

The input mask is specified as a list of {@code MaskChar}. You can use + * the {@link SimpleMaskChar} as the default implementation. + * + * @param text A string for text content. + * @param mask An input mask. + */ public MaskTextField(String text, List mask) { super(Objects.requireNonNullElse(text, "")); @@ -90,6 +120,18 @@ public class MaskTextField extends CustomTextField { }); } + /////////////////////////////////////////////////////////////////////////// + // Properties // + /////////////////////////////////////////////////////////////////////////// + + /** + * Represents the input mask. + * + *

Note that the MaskTextField allows for specifying the input mask as either a string + * or a list of {@code MaskChar}. These formats cannot be converted to one another. Therefore, + * if the input mask was specified as a list of {@code MaskChar}, this property will return + * null value. + */ public StringProperty maskProperty() { return mask; } diff --git a/base/src/main/java/atlantafx/base/controls/Message.java b/base/src/main/java/atlantafx/base/controls/Message.java index d5f3cdd..0ed39d9 100644 --- a/base/src/main/java/atlantafx/base/controls/Message.java +++ b/base/src/main/java/atlantafx/base/controls/Message.java @@ -12,21 +12,24 @@ import javafx.scene.control.Skin; import org.jetbrains.annotations.Nullable; /** - * The Message is a component for displaying notifications or alerts - * and is specifically designed to grab the user’s attention. - * It is based on the Tile layout and shares its structure. + * A control for displaying banners or alerts that is specifically + * designed to grab the user’s attention. It is based on the {@link Tile} + * layout and shares its structure. */ public class Message extends TileBase { /** - * See {@link Tile#Tile()}. + * Creates an empty Message. */ public Message() { this(null, null, null); } /** - * See {@link Tile#Tile(String, String)}. + * Creates a new Message with an initial title and description. + * + * @param title A string for the title. + * @param description A string for the description. */ public Message(@Nullable @NamedArg("title") String title, @Nullable @NamedArg("description") String description) { @@ -34,7 +37,11 @@ public class Message extends TileBase { } /** - * See {@link Tile#Tile(String, String, Node)}. + * Creates a new Message with an initial title, description and graphic. + * + * @param title A string for the title. + * @param description A string for the description. + * @param graphic A graphic or icon. */ public Message(@Nullable String title, @Nullable String description, @@ -43,6 +50,9 @@ public class Message extends TileBase { getStyleClass().add("message"); } + /** + * {@inheritDoc} + */ @Override protected Skin createDefaultSkin() { return new MessageSkin(this); @@ -53,27 +63,33 @@ public class Message extends TileBase { /////////////////////////////////////////////////////////////////////////// /** - * The property representing the message’s action handler. Setting an action handler - * makes the message interactive or clickable. When a user clicks on the interactive + * Represents the message’s action handler. Setting an action handler makes the + * message interactive (or clickable). When a user clicks on the interactive * message, the specified action handler will be called. */ + public ObjectProperty actionHandlerProperty() { + return actionHandler; + } + private final ObjectProperty actionHandler = new SimpleObjectProperty<>(this, "actionHandler"); public Runnable getActionHandler() { return actionHandler.get(); } - public ObjectProperty actionHandlerProperty() { - return actionHandler; - } - public void setActionHandler(Runnable actionHandler) { this.actionHandler.set(actionHandler); } /** - * The property representing the user specified close handler. + * Represents the user-specified close handler, which is intended to be used to close + * or dismiss the message. When a user clicks on the message's close button, the specified + * close handler will be called. */ + public ObjectProperty> onCloseProperty() { + return onClose; + } + protected final ObjectProperty> onClose = new SimpleObjectProperty<>(this, "onClose"); @@ -81,10 +97,6 @@ public class Message extends TileBase { return onClose.get(); } - public ObjectProperty> onCloseProperty() { - return onClose; - } - public void setOnClose(EventHandler onClose) { this.onClose.set(onClose); } diff --git a/base/src/main/java/atlantafx/base/controls/MessageSkin.java b/base/src/main/java/atlantafx/base/controls/MessageSkin.java index c3c05c7..6eab348 100644 --- a/base/src/main/java/atlantafx/base/controls/MessageSkin.java +++ b/base/src/main/java/atlantafx/base/controls/MessageSkin.java @@ -9,6 +9,9 @@ import javafx.geometry.HPos; import javafx.geometry.VPos; import javafx.scene.layout.StackPane; +/** + * The default skin for the {@link Message} control. + */ public class MessageSkin extends TileSkinBase { protected static final PseudoClass CLOSEABLE = PseudoClass.getPseudoClass("closeable"); diff --git a/base/src/main/java/atlantafx/base/controls/ModalPane.java b/base/src/main/java/atlantafx/base/controls/ModalPane.java index 16bb97d..765a3b1 100755 --- a/base/src/main/java/atlantafx/base/controls/ModalPane.java +++ b/base/src/main/java/atlantafx/base/controls/ModalPane.java @@ -16,53 +16,93 @@ import javafx.geometry.Side; import javafx.scene.Node; import javafx.scene.control.Control; import javafx.scene.control.Skin; +import javafx.stage.Stage; import javafx.util.Duration; import org.jetbrains.annotations.Nullable; /** * A container for displaying application dialogs ot top of the current scene - * without opening a modal {@link javafx.stage.Stage}. It's a translucent (glass) pane - * that can hold arbitrary content as well as animate its appearance.

+ * without opening a modal {@link Stage}. It's a translucent (glass) pane + * that can hold arbitrary content as well as animate its appearance. * *

When {@link #displayProperty()} value is changed the modal pane modifies own * {@link #viewOrderProperty()} value accordingly, thus moving itself on top of the * parent container or vise versa. You can change the target view order value via the - * constructor param. This also means that one must not change modal pane {@link #viewOrderProperty()} - * property manually. + * constructor param. This also means that one must not change the modal pane + * {@link #viewOrderProperty()} property manually. + * + *

Example: + * + *

{@code
+ * ModalPane modalPane = new ModalPane();
+ *
+ * Label content = new Label("Content");
+ * content.setSize(450, 450);
+ *
+ * Button openBtn = new Button("Open");
+ * openBtn.setOnAction(evt -> modalPane.show(content));
+ * }
*/ public class ModalPane extends Control { - protected static final int Z_FRONT = -10; - protected static final int Z_BACK = 10; + /** + * The default value that is set to the modal pane + * when it must be on top of other nodes. + */ + public static final int Z_FRONT = -10; + /** + * The default value that is set to the modal pane + * when it must be below of other nodes. + */ + public static final int Z_BACK = 10; + + /** + * The default animation duration that is applied to the modal content + * when it enters the user view. + */ public static final Duration DEFAULT_DURATION_IN = Duration.millis(200); + + /** + * The default animation duration that is applied to the modal content + * when it leaves the user view. + */ public static final Duration DEFAULT_DURATION_OUT = Duration.millis(100); private final int topViewOrder; /** - * See {@link #ModalPane(int)}. + * Creates a new modal pane with the default {@code topViewOrder} + * property value. */ public ModalPane() { this(Z_FRONT); } /** - * Creates a new modal pane. + * Creates a new modal pane with the specified {@code topViewOrder} property. * - * @param topViewOrder the {@link #viewOrderProperty()} value to be set - * to display the modal pane on top of the parent container. + * @param topViewOrder The {@link #viewOrderProperty()} value to be set in order + * to display the ModalPane on top of the parent container. */ public ModalPane(@NamedArg("topViewOrder") int topViewOrder) { super(); this.topViewOrder = topViewOrder; } + /** + * {@inheritDoc} + */ @Override protected Skin createDefaultSkin() { return new ModalPaneSkin(this); } + /** + * Returns the value of {@link #viewOrderProperty()} to be set in order to display + * the ModalPane on top of its parent container. This is a constructor parameter + * that cannot be changed after the ModalPane has been instantiated. + */ public int getTopViewOrder() { return topViewOrder; } @@ -71,6 +111,13 @@ public class ModalPane extends Control { // Properties // /////////////////////////////////////////////////////////////////////////// + /** + * Specifies the content node to display inside the modal pane. + */ + public ObjectProperty contentProperty() { + return content; + } + protected final ObjectProperty content = new SimpleObjectProperty<>(this, "content", null); public Node getContent() { @@ -82,14 +129,14 @@ public class ModalPane extends Control { } /** - * The content node to display inside the modal pane. + * Indicates whether the modal pane is set to be on top or not. + * When changed, the {@link #viewOrderProperty()} value will be modified accordingly. + * See the {@link #getTopViewOrder()}. */ - public ObjectProperty contentProperty() { - return content; + public BooleanProperty displayProperty() { + return display; } - // ~ - protected final BooleanProperty display = new SimpleBooleanProperty(this, "display", false); public boolean isDisplay() { @@ -101,15 +148,12 @@ public class ModalPane extends Control { } /** - * Whether the modal pane is set to top or not. - * When changed the pane {@link #viewOrderProperty()} value will be modified accordingly. + * Specifies the alignment of the content node. */ - public BooleanProperty displayProperty() { - return display; + public ObjectProperty alignmentProperty() { + return alignment; } - // ~ - protected final ObjectProperty alignment = new SimpleObjectProperty<>(this, "alignment", Pos.CENTER); public Pos getAlignment() { @@ -121,14 +165,13 @@ public class ModalPane extends Control { } /** - * Content alignment. + * The factory that provides a transition to be played on content appearance, + * i.e. when {@link #displayProperty()} is set to 'true'. */ - public ObjectProperty alignmentProperty() { - return alignment; + public ObjectProperty> inTransitionFactoryProperty() { + return inTransitionFactory; } - // ~ - protected final ObjectProperty> inTransitionFactory = new SimpleObjectProperty<>( this, "inTransitionFactory", node -> Animations.zoomIn(node, DEFAULT_DURATION_IN) ); @@ -142,15 +185,13 @@ public class ModalPane extends Control { } /** - * The factory that provides a transition to be played on content appearance, - * i.e. when {@link #displayProperty()} is set to 'true'. + * The factory that provides a transition to be played on content disappearance, + * i.e. when {@link #displayProperty()} is set to 'false'. */ - public ObjectProperty> inTransitionFactoryProperty() { - return inTransitionFactory; + public ObjectProperty> outTransitionFactoryProperty() { + return outTransitionFactory; } - // ~ - protected final ObjectProperty> outTransitionFactory = new SimpleObjectProperty<>( this, "outTransitionFactory", node -> Animations.zoomOut(node, DEFAULT_DURATION_OUT) ); @@ -164,15 +205,16 @@ public class ModalPane extends Control { } /** - * The factory that provides a transition to be played on content disappearance, - * i.e. when {@link #displayProperty()} is set to 'false'. + * Specifies whether the content should be treated as persistent or not. + * + *

By default, the modal pane exits when the ESC button is pressed or when + * the mouse is clicked outside the content area. This property prevents + * this behavior and plays a bouncing animation instead. */ - public ObjectProperty> outTransitionFactoryProperty() { - return outTransitionFactory; + public BooleanProperty persistentProperty() { + return persistent; } - // ~ - protected final BooleanProperty persistent = new SimpleBooleanProperty(this, "persistent", false); public boolean getPersistent() { @@ -183,23 +225,13 @@ public class ModalPane extends Control { this.persistent.set(persistent); } - /** - * Specifies whether content should be treated as persistent or not. - * By default, the modal pane exits when the ESC button is pressed or when - * the mouse is clicked outside the content area. This property prevents - * this behavior and plays bouncing animation instead. - */ - public BooleanProperty persistentProperty() { - return persistent; - } - /////////////////////////////////////////////////////////////////////////// // Public API // /////////////////////////////////////////////////////////////////////////// /** * A convenience method for setting the content of the modal pane content - * and triggering display state at the same time. + * and triggering its display state at the same time. */ public void show(Node node) { // calling show method with no content specified doesn't make any sense @@ -208,6 +240,17 @@ public class ModalPane extends Control { setDisplay(true); } + /** + * A convenience method for clearing the content of the modal pane content + * and triggering its display state at the same time. + */ + public void hide(boolean clear) { + setDisplay(false); + if (clear) { + setContent(null); + } + } + /** * See {@link #hide(boolean)}. */ @@ -216,24 +259,16 @@ public class ModalPane extends Control { } /** - * A convenience method for clearing the content of the modal pane content - * and triggering display state at the same time. + * See {@link #usePredefinedTransitionFactories(Side, Duration, Duration)}. */ - public void hide(boolean clear) { - setDisplay(false); - if (clear) { - setContent(null); - } + public void usePredefinedTransitionFactories(@Nullable Side side) { + usePredefinedTransitionFactories(side, DEFAULT_DURATION_IN, DEFAULT_DURATION_OUT); } /** * Sets the predefined factory for both {@link #inTransitionFactoryProperty()} and * {@link #outTransitionFactoryProperty()} based on content position. */ - public void usePredefinedTransitionFactories(@Nullable Side side) { - usePredefinedTransitionFactories(side, DEFAULT_DURATION_IN, DEFAULT_DURATION_OUT); - } - public void usePredefinedTransitionFactories(@Nullable Side side, @Nullable Duration inDuration, @Nullable Duration outDuration) { diff --git a/base/src/main/java/atlantafx/base/controls/ModalPaneSkin.java b/base/src/main/java/atlantafx/base/controls/ModalPaneSkin.java index fee49ee..878e10c 100644 --- a/base/src/main/java/atlantafx/base/controls/ModalPaneSkin.java +++ b/base/src/main/java/atlantafx/base/controls/ModalPaneSkin.java @@ -22,6 +22,9 @@ import javafx.scene.layout.StackPane; import javafx.util.Duration; import org.jetbrains.annotations.Nullable; +/** + * The default skin for the {@link ModalPane} control. + */ public class ModalPaneSkin extends SkinBase { protected ModalPane control; diff --git a/base/src/main/java/atlantafx/base/controls/Notification.java b/base/src/main/java/atlantafx/base/controls/Notification.java index 0f6dd61..d436c17 100644 --- a/base/src/main/java/atlantafx/base/controls/Notification.java +++ b/base/src/main/java/atlantafx/base/controls/Notification.java @@ -15,6 +15,7 @@ import javafx.event.Event; import javafx.event.EventHandler; import javafx.scene.Node; import javafx.scene.control.Button; +import javafx.scene.control.ButtonBar; import javafx.scene.control.Control; import javafx.scene.control.MenuItem; import javafx.scene.control.Skin; @@ -22,23 +23,34 @@ import javafx.scene.layout.Region; import org.jetbrains.annotations.Nullable; /** - * The Notification control is intended for displaying alerts and messages - * to users as pop-ups. It's customizable with different colors and icons, - * can contain a graphic or image, along with the message and additional actions - * for users to take. The purpose of this control is to immediately notify users - * of significant events and provide them with quick access to related actions without - * interrupting their workflow. + * A control that is intended for displaying notifications to users as pop-ups. + * It is customizable with different colors and icons, can contain a graphic or image, + * along with the message and additional actions for users to take. */ public class Notification extends Control { + /** + * Creates an empty Notification. + */ public Notification() { this(null, null); } + /** + * Creates a Notification with initial message text. + * + * @param message A string for the notification message. + */ public Notification(@Nullable @NamedArg("message") String message) { this(message, null); } + /** + * Creates a Notification with initial message text and graphic. + * + * @param message A string for the notification message. + * @param graphic A graphic or icon. + */ public Notification(@Nullable @NamedArg("message") String message, @Nullable @NamedArg("graphic") Node graphic) { super(); @@ -66,16 +78,16 @@ public class Notification extends Control { * Represents an optional graphical component that can be displayed alongside * the notification message. */ + public ObjectProperty graphicProperty() { + return graphic; + } + private final ObjectProperty graphic = new SimpleObjectProperty<>(this, "graphic"); public Node getGraphic() { return graphic.get(); } - public ObjectProperty graphicProperty() { - return graphic; - } - public void setGraphic(Node graphic) { this.graphic.set(graphic); } @@ -84,16 +96,16 @@ public class Notification extends Control { * Stores a short text message that will be displayed to users when the * notification appears. This property doesn't support the formatted text. */ + public StringProperty messageProperty() { + return message; + } + private final StringProperty message = new SimpleStringProperty(this, "message"); public String getMessage() { return message.get(); } - public StringProperty messageProperty() { - return message; - } - public void setMessage(String message) { this.message.set(message); } @@ -102,8 +114,14 @@ public class Notification extends Control { * Specifies the primary actions associated with this notification. * *

This property is used to store one or more action buttons that will - * be displayed at the bottom of the notification when it appears. + * be displayed at the bottom of the notification when it appears. These + * buttons will be placed inside the {@link ButtonBar} and use the alignment + * that is described in the ButtonBar documentation. */ + public ReadOnlyObjectProperty> primaryActionsProperty() { + return primaryActions.getReadOnlyProperty(); + } + private final ReadOnlyObjectWrapper> primaryActions = new ReadOnlyObjectWrapper<>(this, "primaryActions", FXCollections.observableArrayList()); @@ -111,10 +129,6 @@ public class Notification extends Control { return primaryActions.get(); } - public ReadOnlyObjectProperty> primaryActionsProperty() { - return primaryActions.getReadOnlyProperty(); - } - public void setPrimaryActions(ObservableList