Write a Javadoc for all controls, layouts and utils
This commit is contained in:
parent
750ed00e11
commit
357f31da64
@ -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;
|
package atlantafx.base.controls;
|
||||||
|
|
||||||
import javafx.scene.control.Control;
|
import javafx.scene.control.Control;
|
||||||
import javafx.scene.control.SkinBase;
|
import javafx.scene.control.SkinBase;
|
||||||
|
|
||||||
public abstract class BehaviorBase<C extends Control, S extends SkinBase<C>> {
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* <p>Although BehaviorBase is typically used as a base class, it is not abstract and
|
||||||
|
* several skins instantiate an instance of BehaviorBase directly.
|
||||||
|
*
|
||||||
|
* <p>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<C extends Control, S extends SkinBase<C>> {
|
||||||
|
|
||||||
private C control;
|
private C control;
|
||||||
private S skin;
|
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) {
|
protected BehaviorBase(C control, S skin) {
|
||||||
this.control = control;
|
this.control = control;
|
||||||
this.skin = skin;
|
this.skin = skin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the control associated with this behavior.
|
||||||
|
*
|
||||||
|
* @return The control for this behavior.
|
||||||
|
*/
|
||||||
public C getControl() {
|
public C getControl() {
|
||||||
return control;
|
return control;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the skin associated with this behavior.
|
||||||
|
*
|
||||||
|
* @return The control for this behavior.
|
||||||
|
*/
|
||||||
public S getSkin() {
|
public S getSkin() {
|
||||||
return skin;
|
return skin;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
package atlantafx.base.controls;
|
||||||
|
|
||||||
@ -7,21 +12,48 @@ import javafx.beans.value.ObservableValue;
|
|||||||
import javafx.scene.control.Control;
|
import javafx.scene.control.Control;
|
||||||
import javafx.scene.control.SkinBase;
|
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.
|
||||||
|
*
|
||||||
|
* <p>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<C extends Control, B extends BehaviorBase<C, ?>> extends SkinBase<C> {
|
public abstract class BehaviorSkinBase<C extends Control, B extends BehaviorBase<C, ?>> extends SkinBase<C> {
|
||||||
|
|
||||||
protected B behavior;
|
protected B behavior;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for all BehaviorSkinBase instances.
|
||||||
|
*
|
||||||
|
* @param control The control for which this Skin should attach to.
|
||||||
|
*/
|
||||||
protected BehaviorSkinBase(C control) {
|
protected BehaviorSkinBase(C control) {
|
||||||
super(control);
|
super(control);
|
||||||
behavior = createDefaultBehavior();
|
behavior = createDefaultBehavior();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An abstract method for creating the behavior instance to be used by this skin.
|
||||||
|
*/
|
||||||
public abstract B createDefaultBehavior();
|
public abstract B createDefaultBehavior();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the control associated with this skin.
|
||||||
|
*
|
||||||
|
* @return The control for this Skin.
|
||||||
|
*/
|
||||||
public C getControl() {
|
public C getControl() {
|
||||||
return getSkinnable();
|
return getSkinnable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the behavior associated with this skin.
|
||||||
|
*
|
||||||
|
* @return The behavior for this skin.
|
||||||
|
*/
|
||||||
public B getBehavior() {
|
public B getBehavior() {
|
||||||
return behavior;
|
return behavior;
|
||||||
}
|
}
|
||||||
|
@ -47,14 +47,21 @@ import javafx.scene.control.Skin;
|
|||||||
import javafx.scene.control.TreeItem;
|
import javafx.scene.control.TreeItem;
|
||||||
import javafx.scene.layout.Region;
|
import javafx.scene.layout.Region;
|
||||||
import javafx.util.Callback;
|
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 hierarchical path structure, such as file systems.
|
||||||
*
|
*
|
||||||
* <p>A breadcrumbs consist of two types of elements: a button (default is a hyperlink)
|
* <pre>{@code
|
||||||
* and a divider (default is for Label). You can customize both by providing the
|
* String[] list = {"Root", "Folder", "file.txt"};
|
||||||
* corresponding control factory.
|
* BreadCrumbItem<String> selectedCrumb = Breadcrumbs.buildTreeModel(list);
|
||||||
|
* Breadcrumbs<String> breadcrumbs = new Breadcrumbs<>(selectedCrumb);
|
||||||
|
* }</pre>
|
||||||
|
*
|
||||||
|
* <p>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")
|
@SuppressWarnings("unused")
|
||||||
public class Breadcrumbs<T> extends Control {
|
public class Breadcrumbs<T> extends Control {
|
||||||
@ -63,6 +70,7 @@ public class Breadcrumbs<T> extends Control {
|
|||||||
|
|
||||||
protected final Callback<BreadCrumbItem<T>, ButtonBase> defaultCrumbNodeFactory =
|
protected final Callback<BreadCrumbItem<T>, ButtonBase> defaultCrumbNodeFactory =
|
||||||
item -> new Hyperlink(item.getStringValue());
|
item -> new Hyperlink(item.getStringValue());
|
||||||
|
|
||||||
protected final Callback<BreadCrumbItem<T>, ? extends Node> defaultDividerFactory =
|
protected final Callback<BreadCrumbItem<T>, ? extends Node> defaultDividerFactory =
|
||||||
item -> item != null && !item.isLast() ? new Label("/") : null;
|
item -> item != null && !item.isLast() ? new Label("/") : null;
|
||||||
|
|
||||||
@ -74,10 +82,12 @@ public class Breadcrumbs<T> extends Control {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a bread crumb bar with the given BreadCrumbItem as the currently
|
* Creates a bread crumb bar with the given BreadCrumbItem as the
|
||||||
* selected crumb.
|
* currently {@link #selectedCrumbProperty()}.
|
||||||
|
*
|
||||||
|
* @param selectedCrumb The currently selected crumb.
|
||||||
*/
|
*/
|
||||||
public Breadcrumbs(BreadCrumbItem<T> selectedCrumb) {
|
public Breadcrumbs(@Nullable BreadCrumbItem<T> selectedCrumb) {
|
||||||
getStyleClass().add(DEFAULT_STYLE_CLASS);
|
getStyleClass().add(DEFAULT_STYLE_CLASS);
|
||||||
|
|
||||||
// breadcrumbs should be the size of its content
|
// breadcrumbs should be the size of its content
|
||||||
@ -100,8 +110,10 @@ public class Breadcrumbs<T> extends Control {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a tree model from the flat list which then can be set
|
* Constructs a tree model from the flat list which then can be set
|
||||||
* as selectedCrumb node to be shown.
|
* as the {@code selectedCrumb} node to be shown.
|
||||||
|
*
|
||||||
|
* @param crumbs The flat list of values used to build the tree model
|
||||||
*/
|
*/
|
||||||
@SafeVarargs
|
@SafeVarargs
|
||||||
public static <T> BreadCrumbItem<T> buildTreeModel(T... crumbs) {
|
public static <T> BreadCrumbItem<T> buildTreeModel(T... crumbs) {
|
||||||
@ -128,7 +140,8 @@ public class Breadcrumbs<T> extends Control {
|
|||||||
* <p>Consider the following hierarchy:
|
* <p>Consider the following hierarchy:
|
||||||
* [Root] > [Folder] > [SubFolder] > [file.txt]
|
* [Root] > [Folder] > [SubFolder] > [file.txt]
|
||||||
*
|
*
|
||||||
* <p>To show the above bread crumb bar, you have to set the [file.txt] tree-node as selected crumb.
|
* <p>To show the above bread crumb bar, you have to set the [file.txt]
|
||||||
|
* tree-node as selected crumb.
|
||||||
*/
|
*/
|
||||||
public final ObjectProperty<BreadCrumbItem<T>> selectedCrumbProperty() {
|
public final ObjectProperty<BreadCrumbItem<T>> selectedCrumbProperty() {
|
||||||
return selectedCrumb;
|
return selectedCrumb;
|
||||||
@ -147,10 +160,9 @@ public class Breadcrumbs<T> extends Control {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables or disables auto navigation (default is enabled).
|
* Enables or disables auto navigation (default is enabled).
|
||||||
* If auto navigation is enabled, it will automatically navigate to the crumb which was
|
* If auto navigation is enabled, it will automatically navigate to the
|
||||||
* clicked by the user.
|
* crumb which was clicked by the user, meaning it will set the
|
||||||
*
|
* {@link #selectedCrumbProperty()} upon click.
|
||||||
* @return a {@link BooleanProperty}
|
|
||||||
*/
|
*/
|
||||||
public final BooleanProperty autoNavigationEnabledProperty() {
|
public final BooleanProperty autoNavigationEnabledProperty() {
|
||||||
return autoNavigation;
|
return autoNavigation;
|
||||||
@ -168,14 +180,15 @@ public class Breadcrumbs<T> extends Control {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Crumb factory is used to create custom bread crumb instances.
|
* The crumb factory is used to create custom bread crumb instances.
|
||||||
* <code>null</code> is not allowed and will result in a fallback to the default factory.
|
* A null value is not allowed and will result in a fallback to the default factory.
|
||||||
|
* <ul>
|
||||||
|
* <li><code>BreadCrumbItem<T></code> specifies the tree item for creating bread crumb.</li>
|
||||||
|
* <li><code>ButtonBase</code> stands for resulting bread crumb node.</li>
|
||||||
|
* </ul>
|
||||||
*
|
*
|
||||||
* <p><code>BreadCrumbItem<T></code> specifies the tree item for creating bread crumb. Use
|
* <p>Use {@link BreadCrumbItem#isFirst()} and {@link BreadCrumbItem#isLast()} to
|
||||||
* {@link BreadCrumbItem#isFirst()} and {@link BreadCrumbItem#isLast()} to create bread crumb
|
* create bread crumb depending on item position.
|
||||||
* depending on item position.
|
|
||||||
*
|
|
||||||
* <p><code>ButtonBase</code> stands for resulting bread crumb node. It CAN NOT be <code>null</code>.
|
|
||||||
*/
|
*/
|
||||||
public final ObjectProperty<Callback<BreadCrumbItem<T>, ButtonBase>> crumbFactoryProperty() {
|
public final ObjectProperty<Callback<BreadCrumbItem<T>, ButtonBase>> crumbFactoryProperty() {
|
||||||
return crumbFactory;
|
return crumbFactory;
|
||||||
@ -196,16 +209,19 @@ public class Breadcrumbs<T> extends Control {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Divider factory is used to create custom divider instances.
|
* The divider factory is used to create custom instances of dividers.
|
||||||
* <code>null</code> is not allowed and will result in a fallback to the default factory.
|
* A null value is not allowed and will result in a fallback to the default factory.
|
||||||
*
|
*
|
||||||
* <p><code>BreadCrumbItem<T></code> specifies the preceding tree item. It can be null, because this way
|
* <ul>
|
||||||
* you can insert divider before the first bread crumb, which can be used e.g. for creating a Unix path.
|
* <li><code>BreadCrumbItem<T></code> specifies the preceding tree item.
|
||||||
* Use {@link BreadCrumbItem#isFirst()} and {@link BreadCrumbItem#isLast()} to create divider
|
* It can be null, which allows for inserting a divider before the first bread crumb,
|
||||||
* depending on item position.
|
* such as when creating a Unix path.</li>
|
||||||
|
* <li><code>? extends Node</code> stands for resulting divider node. It can also be null,
|
||||||
|
* indicating that there will be no divider inserted after the specified bread crumb.</li>
|
||||||
|
* </ul>
|
||||||
*
|
*
|
||||||
* <p><code>? extends Node</code> stands for resulting divider node. It CAN be <code>null</code>, which
|
* <p>Use {@link BreadCrumbItem#isFirst()} and {@link BreadCrumbItem#isLast()} to
|
||||||
* means there will be no divider inserted after the specified bread crumb.
|
* create bread crumb depending on item position.
|
||||||
*/
|
*/
|
||||||
public final ObjectProperty<Callback<BreadCrumbItem<T>, ? extends Node>> dividerFactoryProperty() {
|
public final ObjectProperty<Callback<BreadCrumbItem<T>, ? extends Node>> dividerFactoryProperty() {
|
||||||
return dividerFactory;
|
return dividerFactory;
|
||||||
@ -226,26 +242,15 @@ public class Breadcrumbs<T> 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<EventHandler<BreadCrumbActionEvent<T>>> onCrumbActionProperty() {
|
public final ObjectProperty<EventHandler<BreadCrumbActionEvent<T>>> onCrumbActionProperty() {
|
||||||
return onCrumbAction;
|
return onCrumbAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a new EventHandler for when a user selects a crumb.
|
|
||||||
*/
|
|
||||||
public final void setOnCrumbAction(EventHandler<BreadCrumbActionEvent<T>> value) {
|
|
||||||
onCrumbActionProperty().set(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public final EventHandler<BreadCrumbActionEvent<T>> getOnCrumbAction() {
|
|
||||||
return onCrumbActionProperty().get();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected final ObjectProperty<EventHandler<BreadCrumbActionEvent<T>>> onCrumbAction = new ObjectPropertyBase<>() {
|
protected final ObjectProperty<EventHandler<BreadCrumbActionEvent<T>>> onCrumbAction = new ObjectPropertyBase<>() {
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||||
@Override
|
@Override
|
||||||
protected void invalidated() {
|
protected void invalidated() {
|
||||||
setEventHandler(BreadCrumbActionEvent.CRUMB_ACTION, (EventHandler<BreadCrumbActionEvent>) (Object) get());
|
setEventHandler(BreadCrumbActionEvent.CRUMB_ACTION, (EventHandler<BreadCrumbActionEvent>) (Object) get());
|
||||||
@ -262,48 +267,79 @@ public class Breadcrumbs<T> extends Control {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public final void setOnCrumbAction(EventHandler<BreadCrumbActionEvent<T>> value) {
|
||||||
|
onCrumbActionProperty().set(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final EventHandler<BreadCrumbActionEvent<T>> getOnCrumbAction() {
|
||||||
|
return onCrumbActionProperty().get();
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code BreadCrumbItem} extends {@link TreeItem}, providing support
|
||||||
|
* for navigating hierarchical structures.
|
||||||
|
*
|
||||||
|
* @param <T> The type of the value property within BreadCrumbItem.
|
||||||
|
*/
|
||||||
public static class BreadCrumbItem<T> extends TreeItem<T> {
|
public static class BreadCrumbItem<T> extends TreeItem<T> {
|
||||||
|
|
||||||
// setters must not be exposed to user
|
protected boolean first;
|
||||||
private boolean first;
|
protected boolean last;
|
||||||
private 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);
|
super(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use this method to determine if this item is at the beginning,
|
||||||
|
* so you can create bread crumbs accordingly.
|
||||||
|
*/
|
||||||
public boolean isFirst() {
|
public boolean isFirst() {
|
||||||
return first;
|
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() {
|
public boolean isLast() {
|
||||||
return last;
|
return last;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLast(boolean last) {
|
///////////////////////////////////////////////////
|
||||||
|
// package private //
|
||||||
|
///////////////////////////////////////////////////
|
||||||
|
|
||||||
|
protected void setFirst(boolean first) {
|
||||||
|
this.first = first;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setLast(boolean last) {
|
||||||
this.last = last;
|
this.last = last;
|
||||||
}
|
}
|
||||||
|
|
||||||
String getStringValue() {
|
protected String getStringValue() {
|
||||||
return getValue() != null ? getValue().toString() : "";
|
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<T> extends Event {
|
public static class BreadCrumbActionEvent<T> extends Event {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The event type that should be listened to by people interested in
|
* Represents the event type that should be listened to by people who are
|
||||||
* knowing when the {@link Breadcrumbs#selectedCrumbProperty() selected crumb}
|
* interested in knowing when the selected crumb has changed. This is accomplished
|
||||||
* has changed.
|
* through listening to the {@link Breadcrumbs#selectedCrumbProperty() selected crumb
|
||||||
|
* property}.
|
||||||
*/
|
*/
|
||||||
public static final EventType<BreadCrumbActionEvent<?>> CRUMB_ACTION
|
public static final EventType<BreadCrumbActionEvent<?>> CRUMB_ACTION
|
||||||
= new EventType<>("CRUMB_ACTION" + UUID.randomUUID());
|
= new EventType<>("CRUMB_ACTION" + UUID.randomUUID());
|
||||||
@ -312,6 +348,8 @@ public class Breadcrumbs<T> extends Control {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new event that can subsequently be fired.
|
* Creates a new event that can subsequently be fired.
|
||||||
|
*
|
||||||
|
* @param selectedCrumb The currently selected crumb.
|
||||||
*/
|
*/
|
||||||
public BreadCrumbActionEvent(BreadCrumbItem<T> selectedCrumb) {
|
public BreadCrumbActionEvent(BreadCrumbItem<T> selectedCrumb) {
|
||||||
super(CRUMB_ACTION);
|
super(CRUMB_ACTION);
|
||||||
|
@ -41,17 +41,23 @@ import javafx.scene.control.ButtonBase;
|
|||||||
import javafx.scene.control.SkinBase;
|
import javafx.scene.control.SkinBase;
|
||||||
import javafx.scene.control.TreeItem.TreeModificationEvent;
|
import javafx.scene.control.TreeItem.TreeModificationEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default skin for the {@link Breadcrumbs} control.
|
||||||
|
*/
|
||||||
public class BreadcrumbsSkin<T> extends SkinBase<Breadcrumbs<T>> {
|
public class BreadcrumbsSkin<T> extends SkinBase<Breadcrumbs<T>> {
|
||||||
|
|
||||||
protected static final PseudoClass FIRST = PseudoClass.getPseudoClass("first");
|
protected static final PseudoClass FIRST = PseudoClass.getPseudoClass("first");
|
||||||
protected static final PseudoClass LAST = PseudoClass.getPseudoClass("last");
|
protected static final PseudoClass LAST = PseudoClass.getPseudoClass("last");
|
||||||
|
|
||||||
protected final EventHandler<TreeModificationEvent<Object>> treeChildrenModifiedHandler = e -> updateBreadCrumbs();
|
protected final EventHandler<TreeModificationEvent<Object>> treeChildrenModifiedHandler =
|
||||||
|
e -> updateBreadCrumbs();
|
||||||
|
|
||||||
public BreadcrumbsSkin(final Breadcrumbs<T> control) {
|
public BreadcrumbsSkin(final Breadcrumbs<T> control) {
|
||||||
super(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);
|
updateSelectedPath(getSkinnable().selectedCrumbProperty().get(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,22 +51,23 @@ import javafx.scene.control.Control;
|
|||||||
import javafx.scene.control.DateCell;
|
import javafx.scene.control.DateCell;
|
||||||
import javafx.scene.control.Skin;
|
import javafx.scene.control.Skin;
|
||||||
import javafx.util.Callback;
|
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
|
* the standard ISO-8601 chronology or any of the other chronology classes defined in the
|
||||||
* java.time.chrono package.
|
* <code>java.time.chrono</code> package.
|
||||||
*
|
*
|
||||||
* <p>The {@link #valueProperty() value} property represents the currently selected
|
* <ul>
|
||||||
* {@link LocalDate}. The default value is null.
|
* <li>The {@link #valueProperty() value} property represents the currently selected
|
||||||
*
|
* {@link LocalDate}. The default value is null.</li>
|
||||||
* <p>The {@link #chronologyProperty() chronology} property specifies a calendar system to be used
|
* <li>The {@link #chronologyProperty() chronology} property specifies a calendar system to be used
|
||||||
* for parsing, displaying, and choosing dates.
|
* for parsing, displaying, and choosing dates.</li>
|
||||||
*
|
* <li>The {@link #valueProperty() value} property is always defined in the ISO calendar system,
|
||||||
* <p>The {@link #valueProperty() value} property is always defined in the ISO calendar system,
|
|
||||||
* however, so applications based on a different chronology may use the conversion methods
|
* however, so applications based on a different chronology may use the conversion methods
|
||||||
* provided in the {@link java.time.chrono.Chronology} API to get or set the corresponding
|
* provided in the {@link java.time.chrono.Chronology} API to get or set the corresponding
|
||||||
* {@link java.time.chrono.ChronoLocalDate} value.
|
* {@link java.time.chrono.ChronoLocalDate} value.</li>
|
||||||
|
* </ul>
|
||||||
*/
|
*/
|
||||||
public class Calendar extends Control {
|
public class Calendar extends Control {
|
||||||
|
|
||||||
@ -74,7 +75,8 @@ public class Calendar extends Control {
|
|||||||
protected Chronology lastValidChronology = IsoChronology.INSTANCE;
|
protected Chronology lastValidChronology = IsoChronology.INSTANCE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a default DatePicker instance with a <code>null</code> date value set.
|
* Creates a default Calendar instance with a <code>null</code>
|
||||||
|
* date value set.
|
||||||
*/
|
*/
|
||||||
public Calendar() {
|
public Calendar() {
|
||||||
this(null);
|
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);
|
setValue(localDate);
|
||||||
getStyleClass().add(DEFAULT_STYLE_CLASS);
|
getStyleClass().add(DEFAULT_STYLE_CLASS);
|
||||||
}
|
}
|
||||||
@ -126,6 +129,13 @@ public class Calendar extends Control {
|
|||||||
// Properties //
|
// Properties //
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the currently selected {@link LocalDate}. The default value is null.
|
||||||
|
*/
|
||||||
|
public ObjectProperty<LocalDate> valueProperty() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
private final ObjectProperty<LocalDate> value = new SimpleObjectProperty<>(this, "value");
|
private final ObjectProperty<LocalDate> value = new SimpleObjectProperty<>(this, "value");
|
||||||
|
|
||||||
public final LocalDate getValue() {
|
public final LocalDate getValue() {
|
||||||
@ -136,10 +146,6 @@ public class Calendar extends Control {
|
|||||||
valueProperty().set(value);
|
valueProperty().set(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObjectProperty<LocalDate> valueProperty() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A custom cell factory can be provided to customize individual day cells
|
* 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.
|
* 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
|
* The calendar system used for parsing, displaying, and choosing dates in the
|
||||||
* control.
|
* Calendar control.
|
||||||
*
|
*
|
||||||
* <p>The default is usually {@link IsoChronology} unless provided explicitly
|
* <p>The default is usually {@link IsoChronology} unless provided explicitly
|
||||||
* in the {@link Locale} by use of a Locale calendar extension.
|
* in the {@link Locale} by use of a Locale calendar extension.
|
||||||
@ -176,7 +182,8 @@ public class Calendar extends Control {
|
|||||||
return chronology;
|
return chronology;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ObjectProperty<Chronology> chronology = new SimpleObjectProperty<>(this, "chronology", null);
|
private final ObjectProperty<Chronology> chronology
|
||||||
|
= new SimpleObjectProperty<>(this, "chronology", null);
|
||||||
|
|
||||||
@SuppressWarnings("CatchAndPrintStackTrace")
|
@SuppressWarnings("CatchAndPrintStackTrace")
|
||||||
public final Chronology getChronology() {
|
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.
|
||||||
*
|
*
|
||||||
* <p>The default value is specified in a resource bundle, and depends on the country of the
|
* <p>The default value is specified in a resource bundle, and depends on the country of the
|
||||||
* current locale.
|
* current locale.
|
||||||
@ -238,7 +245,15 @@ public class Calendar extends Control {
|
|||||||
return showWeekNumbersProperty().getValue();
|
return showWeekNumbersProperty().getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ObjectProperty<Node> 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<Node> topNodeProperty() {
|
||||||
|
return topNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final ObjectProperty<Node> topNode
|
||||||
|
= new SimpleObjectProperty<>(this, "topNode", null);
|
||||||
|
|
||||||
public final void setTopNode(Node value) {
|
public final void setTopNode(Node value) {
|
||||||
topNode.setValue(value);
|
topNode.setValue(value);
|
||||||
@ -248,11 +263,15 @@ public class Calendar extends Control {
|
|||||||
return topNode.getValue();
|
return topNode.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObjectProperty<Node> topNodeProperty() {
|
/**
|
||||||
return topNode;
|
* Represents the custom node to be placed at the bottom of the Calendar below the day-cell grid.
|
||||||
|
*/
|
||||||
|
public ObjectProperty<Node> bottomNodeProperty() {
|
||||||
|
return bottomNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ObjectProperty<Node> bottomNode = new SimpleObjectProperty<>(this, "bottomNode", null);
|
private final ObjectProperty<Node> bottomNode
|
||||||
|
= new SimpleObjectProperty<>(this, "bottomNode", null);
|
||||||
|
|
||||||
public final void setBottomNode(Node value) {
|
public final void setBottomNode(Node value) {
|
||||||
bottomNode.setValue(value);
|
bottomNode.setValue(value);
|
||||||
@ -262,10 +281,6 @@ public class Calendar extends Control {
|
|||||||
return bottomNode.getValue();
|
return bottomNode.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObjectProperty<Node> bottomNodeProperty() {
|
|
||||||
return bottomNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Stylesheet Handling //
|
// Stylesheet Handling //
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -12,6 +12,9 @@ import java.time.ZoneId;
|
|||||||
import javafx.scene.input.KeyEvent;
|
import javafx.scene.input.KeyEvent;
|
||||||
import javafx.scene.input.MouseEvent;
|
import javafx.scene.input.MouseEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default behavior for the {@link Calendar} control.
|
||||||
|
*/
|
||||||
public class CalendarBehavior extends BehaviorBase<Calendar, CalendarSkin> {
|
public class CalendarBehavior extends BehaviorBase<Calendar, CalendarSkin> {
|
||||||
|
|
||||||
public CalendarBehavior(Calendar control, CalendarSkin skin) {
|
public CalendarBehavior(Calendar control, CalendarSkin skin) {
|
||||||
|
@ -73,6 +73,9 @@ import javafx.scene.layout.StackPane;
|
|||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
import javafx.util.Callback;
|
import javafx.util.Callback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default skin for the {@link Calendar} control.
|
||||||
|
*/
|
||||||
public class CalendarSkin extends BehaviorSkinBase<Calendar, CalendarBehavior> {
|
public class CalendarSkin extends BehaviorSkinBase<Calendar, CalendarBehavior> {
|
||||||
|
|
||||||
// formatters
|
// formatters
|
||||||
@ -100,7 +103,8 @@ public class CalendarSkin extends BehaviorSkinBase<Calendar, CalendarBehavior> {
|
|||||||
protected DateCell lastFocusedDayCell = null;
|
protected DateCell lastFocusedDayCell = null;
|
||||||
protected final int daysPerWeek = getDaysPerWeek();
|
protected final int daysPerWeek = getDaysPerWeek();
|
||||||
|
|
||||||
private final ObjectProperty<YearMonth> displayedYearMonth = new SimpleObjectProperty<>(this, "displayedYearMonth");
|
private final ObjectProperty<YearMonth> displayedYearMonth
|
||||||
|
= new SimpleObjectProperty<>(this, "displayedYearMonth");
|
||||||
|
|
||||||
public ObjectProperty<YearMonth> displayedYearMonthProperty() {
|
public ObjectProperty<YearMonth> displayedYearMonthProperty() {
|
||||||
return displayedYearMonth;
|
return displayedYearMonth;
|
||||||
@ -113,27 +117,27 @@ public class CalendarSkin extends BehaviorSkinBase<Calendar, CalendarBehavior> {
|
|||||||
return firstDayOfMonth.get();
|
return firstDayOfMonth.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public CalendarSkin(Calendar datePicker) {
|
public CalendarSkin(Calendar control) {
|
||||||
super(datePicker);
|
super(control);
|
||||||
|
|
||||||
createUI();
|
createUI();
|
||||||
|
|
||||||
registerChangeListener(datePicker.valueProperty(), e -> {
|
registerChangeListener(control.valueProperty(), e -> {
|
||||||
LocalDate date = datePicker.getValue();
|
LocalDate date = control.getValue();
|
||||||
displayedYearMonthProperty().set(
|
displayedYearMonthProperty().set(
|
||||||
date != null ? YearMonth.from(date) : YearMonth.now(ZoneId.systemDefault())
|
date != null ? YearMonth.from(date) : YearMonth.now(ZoneId.systemDefault())
|
||||||
);
|
);
|
||||||
updateValues();
|
updateValues();
|
||||||
datePicker.fireEvent(new ActionEvent());
|
control.fireEvent(new ActionEvent());
|
||||||
});
|
});
|
||||||
|
|
||||||
registerChangeListener(datePicker.showWeekNumbersProperty(), e -> {
|
registerChangeListener(control.showWeekNumbersProperty(), e -> {
|
||||||
updateGrid();
|
updateGrid();
|
||||||
updateWeekNumberCells();
|
updateWeekNumberCells();
|
||||||
});
|
});
|
||||||
|
|
||||||
registerChangeListener(datePicker.topNodeProperty(), e -> {
|
registerChangeListener(control.topNodeProperty(), e -> {
|
||||||
Node node = datePicker.getTopNode();
|
Node node = control.getTopNode();
|
||||||
if (node == null) {
|
if (node == null) {
|
||||||
rootPane.getChildren().removeIf(c -> c.getStyleClass().contains("top-node"));
|
rootPane.getChildren().removeIf(c -> c.getStyleClass().contains("top-node"));
|
||||||
} else {
|
} else {
|
||||||
@ -144,8 +148,8 @@ public class CalendarSkin extends BehaviorSkinBase<Calendar, CalendarBehavior> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
registerChangeListener(datePicker.bottomNodeProperty(), e -> {
|
registerChangeListener(control.bottomNodeProperty(), e -> {
|
||||||
Node node = datePicker.getBottomNode();
|
Node node = control.getBottomNode();
|
||||||
if (node == null) {
|
if (node == null) {
|
||||||
rootPane.getChildren().removeIf(c -> c.getStyleClass().contains("bottom-node"));
|
rootPane.getChildren().removeIf(c -> c.getStyleClass().contains("bottom-node"));
|
||||||
} else {
|
} else {
|
||||||
@ -171,9 +175,7 @@ public class CalendarSkin extends BehaviorSkinBase<Calendar, CalendarBehavior> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The primary chronology for display. This may be overridden to be different from the
|
* The primary chronology for display.
|
||||||
* DatePicker chronology. For example DatePickerHijrahContent uses ISO as primary and Hijrah
|
|
||||||
* as a secondary chronology.
|
|
||||||
*/
|
*/
|
||||||
public Chronology getPrimaryChronology() {
|
public Chronology getPrimaryChronology() {
|
||||||
return getControl().getChronology();
|
return getControl().getChronology();
|
||||||
|
@ -2,20 +2,31 @@
|
|||||||
|
|
||||||
package atlantafx.base.controls;
|
package atlantafx.base.controls;
|
||||||
|
|
||||||
|
import javafx.beans.NamedArg;
|
||||||
import javafx.beans.property.StringProperty;
|
import javafx.beans.property.StringProperty;
|
||||||
import javafx.scene.control.CustomMenuItem;
|
import javafx.scene.control.CustomMenuItem;
|
||||||
import javafx.scene.control.Label;
|
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 {
|
public class CaptionMenuItem extends CustomMenuItem {
|
||||||
|
|
||||||
protected final Label title = new Label();
|
protected final Label title = new Label();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an empty menu item.
|
||||||
|
*/
|
||||||
public CaptionMenuItem() {
|
public CaptionMenuItem() {
|
||||||
this(null);
|
this(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CaptionMenuItem(String text) {
|
/**
|
||||||
|
* Creates a CaptionMenuItem with the specified text as the title.
|
||||||
|
*/
|
||||||
|
public CaptionMenuItem(@Nullable @NamedArg("text") String text) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
setTitle(text);
|
setTitle(text);
|
||||||
@ -24,6 +35,13 @@ public class CaptionMenuItem extends CustomMenuItem {
|
|||||||
getStyleClass().addAll("caption-menu-item");
|
getStyleClass().addAll("caption-menu-item");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains the title of the menu item.
|
||||||
|
*/
|
||||||
|
public StringProperty titleProperty() {
|
||||||
|
return title.textProperty();
|
||||||
|
}
|
||||||
|
|
||||||
public String getTitle() {
|
public String getTitle() {
|
||||||
return title.getText();
|
return title.getText();
|
||||||
}
|
}
|
||||||
@ -31,8 +49,4 @@ public class CaptionMenuItem extends CustomMenuItem {
|
|||||||
public void setTitle(String text) {
|
public void setTitle(String text) {
|
||||||
title.setText(text);
|
title.setText(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
public StringProperty titleProperty() {
|
|
||||||
return title.textProperty();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ import javafx.scene.control.Control;
|
|||||||
import javafx.scene.control.Skin;
|
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
|
* 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
|
* or context of the information. The sub-header and body sections provide
|
||||||
* more detailed content, while the footer may include additional actions or
|
* 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 {
|
public class Card extends Control {
|
||||||
|
|
||||||
// Default constructor
|
/**
|
||||||
|
* Creates an empty Card.
|
||||||
|
*/
|
||||||
public Card() {
|
public Card() {
|
||||||
super();
|
super();
|
||||||
getStyleClass().add("card");
|
getStyleClass().add("card");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Skin<?> createDefaultSkin() {
|
protected Skin<?> createDefaultSkin() {
|
||||||
return new CardSkin(this);
|
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<Node> headerProperty() {
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
private final ObjectProperty<Node> header = new SimpleObjectProperty<>(this, "header");
|
private final ObjectProperty<Node> header = new SimpleObjectProperty<>(this, "header");
|
||||||
|
|
||||||
public Node getHeader() {
|
public Node getHeader() {
|
||||||
return header.get();
|
return header.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObjectProperty<Node> headerProperty() {
|
|
||||||
return header;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHeader(Node header) {
|
public void setHeader(Node header) {
|
||||||
this.header.set(header);
|
this.header.set(header);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The property representing the card’s sub-header node.
|
* Represents the card’s sub-header node.
|
||||||
*/
|
*/
|
||||||
|
public final ObjectProperty<Node> subHeaderProperty() {
|
||||||
|
return subHeader;
|
||||||
|
}
|
||||||
|
|
||||||
private final ObjectProperty<Node> subHeader = new SimpleObjectProperty<>(this, "subHeader");
|
private final ObjectProperty<Node> subHeader = new SimpleObjectProperty<>(this, "subHeader");
|
||||||
|
|
||||||
public Node getSubHeader() {
|
public Node getSubHeader() {
|
||||||
return subHeader.get();
|
return subHeader.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public final ObjectProperty<Node> subHeaderProperty() {
|
|
||||||
return subHeader;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSubHeader(Node subHeader) {
|
public void setSubHeader(Node subHeader) {
|
||||||
this.subHeader.set(subHeader);
|
this.subHeader.set(subHeader);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The property representing the card’s body node.
|
* Represents the card’s body node.
|
||||||
*/
|
*/
|
||||||
|
public ObjectProperty<Node> bodyProperty() {
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
private final ObjectProperty<Node> body = new SimpleObjectProperty<>(this, "body");
|
private final ObjectProperty<Node> body = new SimpleObjectProperty<>(this, "body");
|
||||||
|
|
||||||
public Node getBody() {
|
public Node getBody() {
|
||||||
return body.get();
|
return body.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObjectProperty<Node> bodyProperty() {
|
|
||||||
return body;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBody(Node body) {
|
public void setBody(Node body) {
|
||||||
this.body.set(body);
|
this.body.set(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The property representing the card’s footer node.
|
* Represents the card’s footer node.
|
||||||
*/
|
*/
|
||||||
|
public ObjectProperty<Node> footerProperty() {
|
||||||
|
return footer;
|
||||||
|
}
|
||||||
|
|
||||||
private final ObjectProperty<Node> footer = new SimpleObjectProperty<>(this, "footer");
|
private final ObjectProperty<Node> footer = new SimpleObjectProperty<>(this, "footer");
|
||||||
|
|
||||||
public Node getFooter() {
|
public Node getFooter() {
|
||||||
return footer.get();
|
return footer.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObjectProperty<Node> footerProperty() {
|
|
||||||
return footer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFooter(Node footer) {
|
public void setFooter(Node footer) {
|
||||||
this.footer.set(footer);
|
this.footer.set(footer);
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,9 @@ import javafx.scene.layout.Priority;
|
|||||||
import javafx.scene.layout.StackPane;
|
import javafx.scene.layout.StackPane;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default skin for the {@link Card} control.
|
||||||
|
*/
|
||||||
public class CardSkin implements Skin<Card> {
|
public class CardSkin implements Skin<Card> {
|
||||||
|
|
||||||
protected static final PseudoClass HAS_HEADER = PseudoClass.getPseudoClass("has-header");
|
protected static final PseudoClass HAS_HEADER = PseudoClass.getPseudoClass("has-header");
|
||||||
|
@ -36,79 +36,29 @@ import javafx.scene.control.Skin;
|
|||||||
import javafx.scene.control.TextField;
|
import javafx.scene.control.TextField;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A base class for people wanting to customize a {@link TextField} to contain nodes
|
* A base class for people wanting to customize a {@link TextField}
|
||||||
* inside the text field itself, without being on top of the users typed-in text.
|
* 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 {
|
public class CustomTextField extends TextField {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a default CustomTextField.
|
* Creates an empty CustomTextField.
|
||||||
*/
|
*/
|
||||||
public CustomTextField() {
|
public CustomTextField() {
|
||||||
getStyleClass().add("custom-text-field");
|
getStyleClass().add("custom-text-field");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a CustomTextField with initial text content.
|
||||||
|
*
|
||||||
|
* @param text A string for text content.
|
||||||
|
*/
|
||||||
public CustomTextField(String text) {
|
public CustomTextField(String text) {
|
||||||
this();
|
this();
|
||||||
setText(text);
|
setText(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
// Properties //
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
private final ObjectProperty<Node> 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<Node> 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<Node> right = new SimpleObjectProperty<>(this, "right");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Property representing the {@link Node} that is placed on the right of the text field.
|
|
||||||
*/
|
|
||||||
public final ObjectProperty<Node> 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}
|
* {@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<Node> leftProperty() {
|
||||||
|
return left;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final ObjectProperty<Node> 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<Node> rightProperty() {
|
||||||
|
return right;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final ObjectProperty<Node> 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,9 @@ import javafx.scene.control.skin.TextFieldSkin;
|
|||||||
import javafx.scene.layout.StackPane;
|
import javafx.scene.layout.StackPane;
|
||||||
import javafx.scene.text.HitInfo;
|
import javafx.scene.text.HitInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default skin for the {@link CustomTextField} control.
|
||||||
|
*/
|
||||||
public abstract class CustomTextFieldSkin extends TextFieldSkin {
|
public abstract class CustomTextFieldSkin extends TextFieldSkin {
|
||||||
|
|
||||||
private static final PseudoClass HAS_NO_SIDE_NODE = PseudoClass.getPseudoClass("no-side-nodes");
|
private static final PseudoClass HAS_NO_SIDE_NODE = PseudoClass.getPseudoClass("no-side-nodes");
|
||||||
|
@ -29,6 +29,7 @@ package atlantafx.base.controls;
|
|||||||
|
|
||||||
import atlantafx.base.util.MaskChar;
|
import atlantafx.base.util.MaskChar;
|
||||||
import atlantafx.base.util.MaskTextFormatter;
|
import atlantafx.base.util.MaskTextFormatter;
|
||||||
|
import atlantafx.base.util.SimpleMaskChar;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import javafx.beans.NamedArg;
|
import javafx.beans.NamedArg;
|
||||||
@ -38,9 +39,9 @@ import javafx.beans.property.StringProperty;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a convenience wrapper for instantiating a {@link CustomTextField} with a
|
* A convenience wrapper for instantiating a {@link CustomTextField} with a
|
||||||
* {@code MaskTextFormatter}. For additional info refer to the {@link MaskTextFormatter}
|
* {@code MaskTextFormatter}. For additional info refer to the
|
||||||
* docs.
|
* {@link MaskTextFormatter} documentation.
|
||||||
*/
|
*/
|
||||||
public class MaskTextField extends CustomTextField {
|
public class MaskTextField extends CustomTextField {
|
||||||
|
|
||||||
@ -56,15 +57,35 @@ public class MaskTextField extends CustomTextField {
|
|||||||
protected final ReadOnlyObjectWrapper<MaskTextFormatter> formatter =
|
protected final ReadOnlyObjectWrapper<MaskTextFormatter> formatter =
|
||||||
new ReadOnlyObjectWrapper<>(this, "formatter");
|
new ReadOnlyObjectWrapper<>(this, "formatter");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an empty MaskTextField.
|
||||||
|
*/
|
||||||
public MaskTextField() {
|
public MaskTextField() {
|
||||||
super("");
|
super("");
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an empty MaskTextField with the specified input mask.
|
||||||
|
*
|
||||||
|
* <p>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) {
|
public MaskTextField(@NamedArg("mask") String mask) {
|
||||||
this("", mask);
|
this("", mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a MaskTextField with initial text content and the specified input mask.
|
||||||
|
*
|
||||||
|
* <p>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,
|
private MaskTextField(@NamedArg("text") String text,
|
||||||
@NamedArg("mask") String mask) {
|
@NamedArg("mask") String mask) {
|
||||||
super(Objects.requireNonNullElse(text, ""));
|
super(Objects.requireNonNullElse(text, ""));
|
||||||
@ -74,6 +95,15 @@ public class MaskTextField extends CustomTextField {
|
|||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a MaskTextField with initial text content and the specified input mask.
|
||||||
|
*
|
||||||
|
* <p>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<MaskChar> mask) {
|
public MaskTextField(String text, List<MaskChar> mask) {
|
||||||
super(Objects.requireNonNullElse(text, ""));
|
super(Objects.requireNonNullElse(text, ""));
|
||||||
|
|
||||||
@ -90,6 +120,18 @@ public class MaskTextField extends CustomTextField {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Properties //
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the input mask.
|
||||||
|
*
|
||||||
|
* <p>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() {
|
public StringProperty maskProperty() {
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
@ -12,21 +12,24 @@ import javafx.scene.control.Skin;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Message is a component for displaying notifications or alerts
|
* A control for displaying banners or alerts that is specifically
|
||||||
* and is specifically designed to grab the user’s attention.
|
* designed to grab the user’s attention. It is based on the {@link Tile}
|
||||||
* It is based on the Tile layout and shares its structure.
|
* layout and shares its structure.
|
||||||
*/
|
*/
|
||||||
public class Message extends TileBase {
|
public class Message extends TileBase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See {@link Tile#Tile()}.
|
* Creates an empty Message.
|
||||||
*/
|
*/
|
||||||
public Message() {
|
public Message() {
|
||||||
this(null, null, null);
|
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,
|
public Message(@Nullable @NamedArg("title") String title,
|
||||||
@Nullable @NamedArg("description") String description) {
|
@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,
|
public Message(@Nullable String title,
|
||||||
@Nullable String description,
|
@Nullable String description,
|
||||||
@ -43,6 +50,9 @@ public class Message extends TileBase {
|
|||||||
getStyleClass().add("message");
|
getStyleClass().add("message");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Skin<?> createDefaultSkin() {
|
protected Skin<?> createDefaultSkin() {
|
||||||
return new MessageSkin(this);
|
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
|
* Represents the message’s action handler. Setting an action handler makes the
|
||||||
* makes the message interactive or clickable. When a user clicks on the interactive
|
* message interactive (or clickable). When a user clicks on the interactive
|
||||||
* message, the specified action handler will be called.
|
* message, the specified action handler will be called.
|
||||||
*/
|
*/
|
||||||
|
public ObjectProperty<Runnable> actionHandlerProperty() {
|
||||||
|
return actionHandler;
|
||||||
|
}
|
||||||
|
|
||||||
private final ObjectProperty<Runnable> actionHandler = new SimpleObjectProperty<>(this, "actionHandler");
|
private final ObjectProperty<Runnable> actionHandler = new SimpleObjectProperty<>(this, "actionHandler");
|
||||||
|
|
||||||
public Runnable getActionHandler() {
|
public Runnable getActionHandler() {
|
||||||
return actionHandler.get();
|
return actionHandler.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObjectProperty<Runnable> actionHandlerProperty() {
|
|
||||||
return actionHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setActionHandler(Runnable actionHandler) {
|
public void setActionHandler(Runnable actionHandler) {
|
||||||
this.actionHandler.set(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<EventHandler<? super Event>> onCloseProperty() {
|
||||||
|
return onClose;
|
||||||
|
}
|
||||||
|
|
||||||
protected final ObjectProperty<EventHandler<? super Event>> onClose =
|
protected final ObjectProperty<EventHandler<? super Event>> onClose =
|
||||||
new SimpleObjectProperty<>(this, "onClose");
|
new SimpleObjectProperty<>(this, "onClose");
|
||||||
|
|
||||||
@ -81,10 +97,6 @@ public class Message extends TileBase {
|
|||||||
return onClose.get();
|
return onClose.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObjectProperty<EventHandler<? super Event>> onCloseProperty() {
|
|
||||||
return onClose;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOnClose(EventHandler<? super Event> onClose) {
|
public void setOnClose(EventHandler<? super Event> onClose) {
|
||||||
this.onClose.set(onClose);
|
this.onClose.set(onClose);
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,9 @@ import javafx.geometry.HPos;
|
|||||||
import javafx.geometry.VPos;
|
import javafx.geometry.VPos;
|
||||||
import javafx.scene.layout.StackPane;
|
import javafx.scene.layout.StackPane;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default skin for the {@link Message} control.
|
||||||
|
*/
|
||||||
public class MessageSkin extends TileSkinBase<Message> {
|
public class MessageSkin extends TileSkinBase<Message> {
|
||||||
|
|
||||||
protected static final PseudoClass CLOSEABLE = PseudoClass.getPseudoClass("closeable");
|
protected static final PseudoClass CLOSEABLE = PseudoClass.getPseudoClass("closeable");
|
||||||
|
@ -16,53 +16,93 @@ import javafx.geometry.Side;
|
|||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import javafx.scene.control.Control;
|
import javafx.scene.control.Control;
|
||||||
import javafx.scene.control.Skin;
|
import javafx.scene.control.Skin;
|
||||||
|
import javafx.stage.Stage;
|
||||||
import javafx.util.Duration;
|
import javafx.util.Duration;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A container for displaying application dialogs ot top of the current scene
|
* 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
|
* without opening a modal {@link Stage}. It's a translucent (glass) pane
|
||||||
* that can hold arbitrary content as well as animate its appearance.<br/><br/>
|
* that can hold arbitrary content as well as animate its appearance.
|
||||||
*
|
*
|
||||||
* <p>When {@link #displayProperty()} value is changed the modal pane modifies own
|
* <p>When {@link #displayProperty()} value is changed the modal pane modifies own
|
||||||
* {@link #viewOrderProperty()} value accordingly, thus moving itself on top of the
|
* {@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
|
* 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()}
|
* constructor param. This also means that one <b>must not</b> change the modal pane
|
||||||
* property manually.
|
* {@link #viewOrderProperty()} property manually.
|
||||||
|
*
|
||||||
|
* <p>Example:
|
||||||
|
*
|
||||||
|
* <pre>{@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));
|
||||||
|
* }</pre>
|
||||||
*/
|
*/
|
||||||
public class ModalPane extends Control {
|
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);
|
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);
|
public static final Duration DEFAULT_DURATION_OUT = Duration.millis(100);
|
||||||
|
|
||||||
private final int topViewOrder;
|
private final int topViewOrder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See {@link #ModalPane(int)}.
|
* Creates a new modal pane with the default {@code topViewOrder}
|
||||||
|
* property value.
|
||||||
*/
|
*/
|
||||||
public ModalPane() {
|
public ModalPane() {
|
||||||
this(Z_FRONT);
|
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
|
* @param topViewOrder The {@link #viewOrderProperty()} value to be set in order
|
||||||
* to display the modal pane on top of the parent container.
|
* to display the ModalPane on top of the parent container.
|
||||||
*/
|
*/
|
||||||
public ModalPane(@NamedArg("topViewOrder") int topViewOrder) {
|
public ModalPane(@NamedArg("topViewOrder") int topViewOrder) {
|
||||||
super();
|
super();
|
||||||
this.topViewOrder = topViewOrder;
|
this.topViewOrder = topViewOrder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Skin<?> createDefaultSkin() {
|
protected Skin<?> createDefaultSkin() {
|
||||||
return new ModalPaneSkin(this);
|
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() {
|
public int getTopViewOrder() {
|
||||||
return topViewOrder;
|
return topViewOrder;
|
||||||
}
|
}
|
||||||
@ -71,6 +111,13 @@ public class ModalPane extends Control {
|
|||||||
// Properties //
|
// Properties //
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the content node to display inside the modal pane.
|
||||||
|
*/
|
||||||
|
public ObjectProperty<Node> contentProperty() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
protected final ObjectProperty<Node> content = new SimpleObjectProperty<>(this, "content", null);
|
protected final ObjectProperty<Node> content = new SimpleObjectProperty<>(this, "content", null);
|
||||||
|
|
||||||
public Node getContent() {
|
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<Node> contentProperty() {
|
public BooleanProperty displayProperty() {
|
||||||
return content;
|
return display;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ~
|
|
||||||
|
|
||||||
protected final BooleanProperty display = new SimpleBooleanProperty(this, "display", false);
|
protected final BooleanProperty display = new SimpleBooleanProperty(this, "display", false);
|
||||||
|
|
||||||
public boolean isDisplay() {
|
public boolean isDisplay() {
|
||||||
@ -101,15 +148,12 @@ public class ModalPane extends Control {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the modal pane is set to top or not.
|
* Specifies the alignment of the content node.
|
||||||
* When changed the pane {@link #viewOrderProperty()} value will be modified accordingly.
|
|
||||||
*/
|
*/
|
||||||
public BooleanProperty displayProperty() {
|
public ObjectProperty<Pos> alignmentProperty() {
|
||||||
return display;
|
return alignment;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ~
|
|
||||||
|
|
||||||
protected final ObjectProperty<Pos> alignment = new SimpleObjectProperty<>(this, "alignment", Pos.CENTER);
|
protected final ObjectProperty<Pos> alignment = new SimpleObjectProperty<>(this, "alignment", Pos.CENTER);
|
||||||
|
|
||||||
public Pos getAlignment() {
|
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<Pos> alignmentProperty() {
|
public ObjectProperty<Function<Node, Animation>> inTransitionFactoryProperty() {
|
||||||
return alignment;
|
return inTransitionFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ~
|
|
||||||
|
|
||||||
protected final ObjectProperty<Function<Node, Animation>> inTransitionFactory = new SimpleObjectProperty<>(
|
protected final ObjectProperty<Function<Node, Animation>> inTransitionFactory = new SimpleObjectProperty<>(
|
||||||
this, "inTransitionFactory", node -> Animations.zoomIn(node, DEFAULT_DURATION_IN)
|
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,
|
* The factory that provides a transition to be played on content disappearance,
|
||||||
* i.e. when {@link #displayProperty()} is set to 'true'.
|
* i.e. when {@link #displayProperty()} is set to 'false'.
|
||||||
*/
|
*/
|
||||||
public ObjectProperty<Function<Node, Animation>> inTransitionFactoryProperty() {
|
public ObjectProperty<Function<Node, Animation>> outTransitionFactoryProperty() {
|
||||||
return inTransitionFactory;
|
return outTransitionFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ~
|
|
||||||
|
|
||||||
protected final ObjectProperty<Function<Node, Animation>> outTransitionFactory = new SimpleObjectProperty<>(
|
protected final ObjectProperty<Function<Node, Animation>> outTransitionFactory = new SimpleObjectProperty<>(
|
||||||
this, "outTransitionFactory", node -> Animations.zoomOut(node, DEFAULT_DURATION_OUT)
|
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,
|
* Specifies whether the content should be treated as persistent or not.
|
||||||
* i.e. when {@link #displayProperty()} is set to 'false'.
|
*
|
||||||
|
* <p>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<Function<Node, Animation>> outTransitionFactoryProperty() {
|
public BooleanProperty persistentProperty() {
|
||||||
return outTransitionFactory;
|
return persistent;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ~
|
|
||||||
|
|
||||||
protected final BooleanProperty persistent = new SimpleBooleanProperty(this, "persistent", false);
|
protected final BooleanProperty persistent = new SimpleBooleanProperty(this, "persistent", false);
|
||||||
|
|
||||||
public boolean getPersistent() {
|
public boolean getPersistent() {
|
||||||
@ -183,23 +225,13 @@ public class ModalPane extends Control {
|
|||||||
this.persistent.set(persistent);
|
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 //
|
// Public API //
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A convenience method for setting the content of the modal pane content
|
* 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) {
|
public void show(Node node) {
|
||||||
// calling show method with no content specified doesn't make any sense
|
// calling show method with no content specified doesn't make any sense
|
||||||
@ -208,6 +240,17 @@ public class ModalPane extends Control {
|
|||||||
setDisplay(true);
|
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)}.
|
* 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
|
* See {@link #usePredefinedTransitionFactories(Side, Duration, Duration)}.
|
||||||
* and triggering display state at the same time.
|
|
||||||
*/
|
*/
|
||||||
public void hide(boolean clear) {
|
public void usePredefinedTransitionFactories(@Nullable Side side) {
|
||||||
setDisplay(false);
|
usePredefinedTransitionFactories(side, DEFAULT_DURATION_IN, DEFAULT_DURATION_OUT);
|
||||||
if (clear) {
|
|
||||||
setContent(null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the predefined factory for both {@link #inTransitionFactoryProperty()} and
|
* Sets the predefined factory for both {@link #inTransitionFactoryProperty()} and
|
||||||
* {@link #outTransitionFactoryProperty()} based on content position.
|
* {@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,
|
public void usePredefinedTransitionFactories(@Nullable Side side,
|
||||||
@Nullable Duration inDuration,
|
@Nullable Duration inDuration,
|
||||||
@Nullable Duration outDuration) {
|
@Nullable Duration outDuration) {
|
||||||
|
@ -22,6 +22,9 @@ import javafx.scene.layout.StackPane;
|
|||||||
import javafx.util.Duration;
|
import javafx.util.Duration;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default skin for the {@link ModalPane} control.
|
||||||
|
*/
|
||||||
public class ModalPaneSkin extends SkinBase<ModalPane> {
|
public class ModalPaneSkin extends SkinBase<ModalPane> {
|
||||||
|
|
||||||
protected ModalPane control;
|
protected ModalPane control;
|
||||||
|
@ -15,6 +15,7 @@ import javafx.event.Event;
|
|||||||
import javafx.event.EventHandler;
|
import javafx.event.EventHandler;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
|
import javafx.scene.control.ButtonBar;
|
||||||
import javafx.scene.control.Control;
|
import javafx.scene.control.Control;
|
||||||
import javafx.scene.control.MenuItem;
|
import javafx.scene.control.MenuItem;
|
||||||
import javafx.scene.control.Skin;
|
import javafx.scene.control.Skin;
|
||||||
@ -22,23 +23,34 @@ import javafx.scene.layout.Region;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Notification control is intended for displaying alerts and messages
|
* A control that is intended for displaying notifications to users as pop-ups.
|
||||||
* to users as pop-ups. It's customizable with different colors and icons,
|
* It is customizable with different colors and icons, can contain a graphic or image,
|
||||||
* can contain a graphic or image, along with the message and additional actions
|
* along with the message and additional actions for users to take.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
public class Notification extends Control {
|
public class Notification extends Control {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an empty Notification.
|
||||||
|
*/
|
||||||
public Notification() {
|
public Notification() {
|
||||||
this(null, null);
|
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) {
|
public Notification(@Nullable @NamedArg("message") String message) {
|
||||||
this(message, null);
|
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,
|
public Notification(@Nullable @NamedArg("message") String message,
|
||||||
@Nullable @NamedArg("graphic") Node graphic) {
|
@Nullable @NamedArg("graphic") Node graphic) {
|
||||||
super();
|
super();
|
||||||
@ -66,16 +78,16 @@ public class Notification extends Control {
|
|||||||
* Represents an optional graphical component that can be displayed alongside
|
* Represents an optional graphical component that can be displayed alongside
|
||||||
* the notification message.
|
* the notification message.
|
||||||
*/
|
*/
|
||||||
|
public ObjectProperty<Node> graphicProperty() {
|
||||||
|
return graphic;
|
||||||
|
}
|
||||||
|
|
||||||
private final ObjectProperty<Node> graphic = new SimpleObjectProperty<>(this, "graphic");
|
private final ObjectProperty<Node> graphic = new SimpleObjectProperty<>(this, "graphic");
|
||||||
|
|
||||||
public Node getGraphic() {
|
public Node getGraphic() {
|
||||||
return graphic.get();
|
return graphic.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObjectProperty<Node> graphicProperty() {
|
|
||||||
return graphic;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setGraphic(Node graphic) {
|
public void setGraphic(Node graphic) {
|
||||||
this.graphic.set(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
|
* Stores a short text message that will be displayed to users when the
|
||||||
* notification appears. This property doesn't support the formatted text.
|
* notification appears. This property doesn't support the formatted text.
|
||||||
*/
|
*/
|
||||||
|
public StringProperty messageProperty() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
private final StringProperty message = new SimpleStringProperty(this, "message");
|
private final StringProperty message = new SimpleStringProperty(this, "message");
|
||||||
|
|
||||||
public String getMessage() {
|
public String getMessage() {
|
||||||
return message.get();
|
return message.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public StringProperty messageProperty() {
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMessage(String message) {
|
public void setMessage(String message) {
|
||||||
this.message.set(message);
|
this.message.set(message);
|
||||||
}
|
}
|
||||||
@ -102,8 +114,14 @@ public class Notification extends Control {
|
|||||||
* Specifies the primary actions associated with this notification.
|
* Specifies the primary actions associated with this notification.
|
||||||
*
|
*
|
||||||
* <p>This property is used to store one or more action buttons that will
|
* <p>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<ObservableList<Button>> primaryActionsProperty() {
|
||||||
|
return primaryActions.getReadOnlyProperty();
|
||||||
|
}
|
||||||
|
|
||||||
private final ReadOnlyObjectWrapper<ObservableList<Button>> primaryActions =
|
private final ReadOnlyObjectWrapper<ObservableList<Button>> primaryActions =
|
||||||
new ReadOnlyObjectWrapper<>(this, "primaryActions", FXCollections.observableArrayList());
|
new ReadOnlyObjectWrapper<>(this, "primaryActions", FXCollections.observableArrayList());
|
||||||
|
|
||||||
@ -111,10 +129,6 @@ public class Notification extends Control {
|
|||||||
return primaryActions.get();
|
return primaryActions.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReadOnlyObjectProperty<ObservableList<Button>> primaryActionsProperty() {
|
|
||||||
return primaryActions.getReadOnlyProperty();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPrimaryActions(ObservableList<Button> buttons) {
|
public void setPrimaryActions(ObservableList<Button> buttons) {
|
||||||
this.primaryActions.set(buttons);
|
this.primaryActions.set(buttons);
|
||||||
}
|
}
|
||||||
@ -128,7 +142,13 @@ public class Notification extends Control {
|
|||||||
*
|
*
|
||||||
* <p>This property is used to store one or more menu items that will be displayed
|
* <p>This property is used to store one or more menu items that will be displayed
|
||||||
* as a dropdown menu at the top corner of the notification when it appears.
|
* as a dropdown menu at the top corner of the notification when it appears.
|
||||||
|
*
|
||||||
|
* <p>The dropdown menu button will not appear if the list is empty.
|
||||||
*/
|
*/
|
||||||
|
public ReadOnlyObjectProperty<ObservableList<MenuItem>> secondaryActionsProperty() {
|
||||||
|
return secondaryActions.getReadOnlyProperty();
|
||||||
|
}
|
||||||
|
|
||||||
private final ReadOnlyObjectWrapper<ObservableList<MenuItem>> secondaryActions =
|
private final ReadOnlyObjectWrapper<ObservableList<MenuItem>> secondaryActions =
|
||||||
new ReadOnlyObjectWrapper<>(this, "secondaryActions", FXCollections.observableArrayList());
|
new ReadOnlyObjectWrapper<>(this, "secondaryActions", FXCollections.observableArrayList());
|
||||||
|
|
||||||
@ -136,10 +156,6 @@ public class Notification extends Control {
|
|||||||
return secondaryActions.get();
|
return secondaryActions.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReadOnlyObjectProperty<ObservableList<MenuItem>> secondaryActionsProperty() {
|
|
||||||
return secondaryActions.getReadOnlyProperty();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSecondaryActions(ObservableList<MenuItem> items) {
|
public void setSecondaryActions(ObservableList<MenuItem> items) {
|
||||||
this.secondaryActions.set(items);
|
this.secondaryActions.set(items);
|
||||||
}
|
}
|
||||||
@ -150,7 +166,13 @@ public class Notification extends Control {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies the close handler used to dismiss this notification.
|
* Specifies the close handler used to dismiss this notification.
|
||||||
|
*
|
||||||
|
* <p>The close button will not appear if the handler is not set for it.
|
||||||
*/
|
*/
|
||||||
|
public ObjectProperty<EventHandler<? super Event>> onCloseProperty() {
|
||||||
|
return onClose;
|
||||||
|
}
|
||||||
|
|
||||||
protected final ObjectProperty<EventHandler<? super Event>> onClose =
|
protected final ObjectProperty<EventHandler<? super Event>> onClose =
|
||||||
new SimpleObjectProperty<>(this, "onClose");
|
new SimpleObjectProperty<>(this, "onClose");
|
||||||
|
|
||||||
@ -158,10 +180,6 @@ public class Notification extends Control {
|
|||||||
return onClose.get();
|
return onClose.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObjectProperty<EventHandler<? super Event>> onCloseProperty() {
|
|
||||||
return onClose;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOnClose(EventHandler<? super Event> onClose) {
|
public void setOnClose(EventHandler<? super Event> onClose) {
|
||||||
this.onClose.set(onClose);
|
this.onClose.set(onClose);
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,9 @@ import javafx.scene.layout.VBox;
|
|||||||
import javafx.scene.text.Text;
|
import javafx.scene.text.Text;
|
||||||
import javafx.scene.text.TextFlow;
|
import javafx.scene.text.TextFlow;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default skin for the {@link Notification} control.
|
||||||
|
*/
|
||||||
public class NotificationSkin extends SkinBase<Notification> {
|
public class NotificationSkin extends SkinBase<Notification> {
|
||||||
|
|
||||||
protected final VBox container = new VBox();
|
protected final VBox container = new VBox();
|
||||||
|
@ -34,29 +34,47 @@ import javafx.beans.property.ReadOnlyObjectWrapper;
|
|||||||
import javafx.beans.property.ReadOnlyStringProperty;
|
import javafx.beans.property.ReadOnlyStringProperty;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a convenience wrapper for instantiating a {@link CustomTextField}
|
* A convenience wrapper for instantiating a {@link CustomTextField}
|
||||||
* with {@code PasswordTextFormatter}. For additional info refer to the
|
* with a {@code PasswordTextFormatter}. For additional info refer to the
|
||||||
* {@link PasswordTextFormatter} docs.
|
* {@link PasswordTextFormatter} documentation.
|
||||||
*/
|
*/
|
||||||
public class PasswordTextField extends CustomTextField {
|
public class PasswordTextField extends CustomTextField {
|
||||||
|
|
||||||
protected final ReadOnlyObjectWrapper<PasswordTextFormatter> formatter
|
protected final ReadOnlyObjectWrapper<PasswordTextFormatter> formatter
|
||||||
= new ReadOnlyObjectWrapper<>(this, "formatter");
|
= new ReadOnlyObjectWrapper<>(this, "formatter");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an empty PasswordTextField.
|
||||||
|
*/
|
||||||
public PasswordTextField() {
|
public PasswordTextField() {
|
||||||
this("", PasswordTextFormatter.BULLET);
|
this("", PasswordTextFormatter.BULLET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a PasswordTextField with initial text content.
|
||||||
|
*
|
||||||
|
* @param text A string for text content.
|
||||||
|
*/
|
||||||
public PasswordTextField(@NamedArg("text") String text) {
|
public PasswordTextField(@NamedArg("text") String text) {
|
||||||
this(text, PasswordTextFormatter.BULLET);
|
this(text, PasswordTextFormatter.BULLET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a PasswordTextField with initial text content and bullet character.
|
||||||
|
*
|
||||||
|
* @param text A string for text content.
|
||||||
|
* @param bullet A bullet character to mask the password string.
|
||||||
|
*/
|
||||||
protected PasswordTextField(@NamedArg("text") String text,
|
protected PasswordTextField(@NamedArg("text") String text,
|
||||||
@NamedArg("bullet") char bullet) {
|
@NamedArg("bullet") char bullet) {
|
||||||
super(text);
|
super(text);
|
||||||
formatter.set(PasswordTextFormatter.create(this, bullet));
|
formatter.set(PasswordTextFormatter.create(this, bullet));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Properties //
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See {@link PasswordTextFormatter#passwordProperty()}.
|
* See {@link PasswordTextFormatter#passwordProperty()}.
|
||||||
*/
|
*/
|
||||||
|
@ -62,29 +62,38 @@ import javafx.stage.WindowEvent;
|
|||||||
import javafx.util.Duration;
|
import javafx.util.Duration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Popover control provides detailed information about an owning node in a
|
* A control that is intended to provide detailed information about
|
||||||
* popup window. The popup window has a very lightweight appearance (no default
|
* an owning node in a popup window. The popup window has a lightweight
|
||||||
* window decorations) and an arrow pointing at the owner. Due to the nature of
|
* appearance (no default window decorations) and an arrow pointing at the owner.
|
||||||
* popup windows the Popover will move around with the parent window when the
|
* Due to the nature of popup windows the Popover will move around with the parent
|
||||||
* user drags it.
|
* window when the user drags it.
|
||||||
*
|
*
|
||||||
* <p>The Popover can be detached from the owning node by dragging it away from the
|
* <p>The Popover can be detached from the owning node by dragging it away from the
|
||||||
* owner. It stops displaying an arrow and starts displaying a title and a close
|
* owner. It stops displaying an arrow and starts displaying a title and a close
|
||||||
* icon.
|
* icon.
|
||||||
|
*
|
||||||
|
* <p>Example
|
||||||
|
*
|
||||||
|
* <pre>{@code
|
||||||
|
* var textFlow = new TextFlow(new Text("Some content"));
|
||||||
|
* textFlow.setPrefWidth(300);
|
||||||
|
*
|
||||||
|
* var popover = new Popover(textFlow);
|
||||||
|
* popover.setTitle("Title");
|
||||||
|
*
|
||||||
|
* var ownerLink = new Hyperlink("Show popover");
|
||||||
|
* ownerLink.setOnAction(e -> popover.show(ownerLink));
|
||||||
|
* }</pre>
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public class Popover extends PopupControl {
|
public class Popover extends PopupControl {
|
||||||
|
|
||||||
private static final String DEFAULT_STYLE_CLASS = "popover";
|
private static final String DEFAULT_STYLE_CLASS = "popover";
|
||||||
private static final Duration DEFAULT_FADE_DURATION = Duration.seconds(.2);
|
private static final Duration DEFAULT_FADE_DURATION = Duration.seconds(.2);
|
||||||
|
|
||||||
|
private final StackPane root = new StackPane();
|
||||||
private double targetX;
|
private double targetX;
|
||||||
private double targetY;
|
private double targetY;
|
||||||
|
|
||||||
private final SimpleBooleanProperty animated = new SimpleBooleanProperty(true);
|
|
||||||
private final ObjectProperty<Duration> fadeInDuration = new SimpleObjectProperty<>(DEFAULT_FADE_DURATION);
|
|
||||||
private final ObjectProperty<Duration> fadeOutDuration = new SimpleObjectProperty<>(DEFAULT_FADE_DURATION);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a popover with a label as the content node.
|
* Creates a popover with a label as the content node.
|
||||||
*/
|
*/
|
||||||
@ -96,7 +105,7 @@ public class Popover extends PopupControl {
|
|||||||
setAnchorLocation(AnchorLocation.WINDOW_TOP_LEFT);
|
setAnchorLocation(AnchorLocation.WINDOW_TOP_LEFT);
|
||||||
setOnHiding(evt -> setDetached(false));
|
setOnHiding(evt -> setDetached(false));
|
||||||
|
|
||||||
/* Create some initial content */
|
// create some initial content
|
||||||
Label label = new Label("No Content");
|
Label label = new Label("No Content");
|
||||||
label.setPrefSize(200, 200);
|
label.setPrefSize(200, 200);
|
||||||
label.setPadding(new Insets(4));
|
label.setPadding(new Insets(4));
|
||||||
@ -124,31 +133,31 @@ public class Popover extends PopupControl {
|
|||||||
/**
|
/**
|
||||||
* Creates a popover with the given node as the content node.
|
* Creates a popover with the given node as the content node.
|
||||||
*
|
*
|
||||||
* @param content The content shown by the popover
|
* @param content The content shown by the popover.
|
||||||
*/
|
*/
|
||||||
public Popover(Node content) {
|
public Popover(Node content) {
|
||||||
this();
|
this();
|
||||||
|
|
||||||
setContentNode(content);
|
setContentNode(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Skin<?> createDefaultSkin() {
|
protected Skin<?> createDefaultSkin() {
|
||||||
return new PopoverSkin(this);
|
return new PopoverSkin(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final StackPane root = new StackPane();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The root pane stores the content node of the popover. It is accessible
|
* The root pane stores the content node of the popover. It is accessible
|
||||||
* via this method in order to support proper styling.
|
* via this method in order to support proper styling.
|
||||||
*
|
*
|
||||||
* <p>Example:
|
* <p>Example:
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>{@code
|
||||||
* Popover popOver = new Popover();
|
* Popover popOver = new Popover();
|
||||||
* popOver.getRoot().getStylesheets().add(...);
|
* popOver.getRoot().getStylesheets().add(...);
|
||||||
* </pre>
|
* }</pre>
|
||||||
*
|
*
|
||||||
* @return the root pane
|
* @return the root pane
|
||||||
*/
|
*/
|
||||||
@ -156,44 +165,9 @@ public class Popover extends PopupControl {
|
|||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ObjectProperty<Node> contentNode = new SimpleObjectProperty<>(this, "contentNode") {
|
///////////////////////////////////////////////////////////////////////////
|
||||||
@Override
|
// Listeners //
|
||||||
public void setValue(Node node) {
|
///////////////////////////////////////////////////////////////////////////
|
||||||
if (node == null) {
|
|
||||||
throw new NullPointerException("Node cannot be null!");
|
|
||||||
}
|
|
||||||
this.set(node);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the content shown by the popover.
|
|
||||||
*
|
|
||||||
* @return the content node property
|
|
||||||
*/
|
|
||||||
public final ObjectProperty<Node> contentNodeProperty() {
|
|
||||||
return contentNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the value of the content property.
|
|
||||||
*
|
|
||||||
* @return the content node
|
|
||||||
* @see #contentNodeProperty()
|
|
||||||
*/
|
|
||||||
public final Node getContentNode() {
|
|
||||||
return contentNodeProperty().get();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the value of the content property.
|
|
||||||
*
|
|
||||||
* @param content the new content node value
|
|
||||||
* @see #contentNodeProperty()
|
|
||||||
*/
|
|
||||||
public final void setContentNode(Node content) {
|
|
||||||
contentNodeProperty().set(content);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final InvalidationListener hideListener = observable -> {
|
private final InvalidationListener hideListener = observable -> {
|
||||||
if (!isDetached()) {
|
if (!isDetached()) {
|
||||||
@ -220,10 +194,17 @@ public class Popover extends PopupControl {
|
|||||||
private final WeakChangeListener<Number> weakYListener = new WeakChangeListener<>(yListener);
|
private final WeakChangeListener<Number> weakYListener = new WeakChangeListener<>(yListener);
|
||||||
|
|
||||||
private Window ownerWindow;
|
private Window ownerWindow;
|
||||||
private final EventHandler<WindowEvent> closePopoverOnOwnerWindowCloseLambda = event -> ownerWindowHiding();
|
|
||||||
|
private final EventHandler<WindowEvent> closePopoverOnOwnerWindowCloseLambda
|
||||||
|
= event -> ownerWindowHiding();
|
||||||
|
|
||||||
private final WeakEventHandler<WindowEvent> closePopoverOnOwnerWindowClose =
|
private final WeakEventHandler<WindowEvent> closePopoverOnOwnerWindowClose =
|
||||||
new WeakEventHandler<>(closePopoverOnOwnerWindowCloseLambda);
|
new WeakEventHandler<>(closePopoverOnOwnerWindowCloseLambda);
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// API //
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows the popover in a position relative to the edges of the given owner
|
* Shows the popover in a position relative to the edges of the given owner
|
||||||
* node. The position is dependent on the arrow location. If the arrow is
|
* node. The position is dependent on the arrow location. If the arrow is
|
||||||
@ -232,7 +213,7 @@ public class Popover extends PopupControl {
|
|||||||
* below the given owner node. The arrow will slightly overlap with the
|
* below the given owner node. The arrow will slightly overlap with the
|
||||||
* owner node.
|
* owner node.
|
||||||
*
|
*
|
||||||
* @param owner the owner of the popover
|
* @param owner The owner of the popover.
|
||||||
*/
|
*/
|
||||||
public final void show(Node owner) {
|
public final void show(Node owner) {
|
||||||
show(owner, 4);
|
show(owner, 4);
|
||||||
@ -245,10 +226,10 @@ public class Popover extends PopupControl {
|
|||||||
* given owner. If the arrow points up then the popover will be placed
|
* given owner. If the arrow points up then the popover will be placed
|
||||||
* below the given owner node.
|
* below the given owner node.
|
||||||
*
|
*
|
||||||
* @param owner the owner of the popover
|
* @param owner The owner of the popover.
|
||||||
* @param offset if negative specifies the distance to the owner node or when
|
* @param offset If negative specifies the distance to the owner node or when
|
||||||
* positive specifies the number of pixels that the arrow will
|
* positive specifies the number of pixels that the arrow will
|
||||||
* overlap with the owner node (positive values are recommended)
|
* overlap with the owner node (positive values are recommended).
|
||||||
*/
|
*/
|
||||||
public final void show(Node owner, double offset) {
|
public final void show(Node owner, double offset) {
|
||||||
Objects.requireNonNull(owner, "Owner node cannot be null!");
|
Objects.requireNonNull(owner, "Owner node cannot be null!");
|
||||||
@ -311,9 +292,9 @@ public class Popover extends PopupControl {
|
|||||||
* the given owner node. The x and y coordinate will be the target location
|
* the given owner node. The x and y coordinate will be the target location
|
||||||
* of the arrow of the popover and not the location of the window.
|
* of the arrow of the popover and not the location of the window.
|
||||||
*
|
*
|
||||||
* @param owner the owning node
|
* @param owner The owning node.
|
||||||
* @param x the x coordinate for the popover arrow tip
|
* @param x The x coordinate for the popover arrow tip.
|
||||||
* @param y the y coordinate for the popover arrow tip
|
* @param y The y coordinate for the popover arrow tip.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public final void show(Node owner, double x, double y) {
|
public final void show(Node owner, double x, double y) {
|
||||||
@ -325,17 +306,16 @@ public class Popover extends PopupControl {
|
|||||||
* the given owner node. The x and y coordinate will be the target location
|
* the given owner node. The x and y coordinate will be the target location
|
||||||
* of the arrow of the popover and not the location of the window.
|
* of the arrow of the popover and not the location of the window.
|
||||||
*
|
*
|
||||||
* @param owner the owning node
|
* @param owner The owning node.
|
||||||
* @param x the x coordinate for the popover arrow tip
|
* @param x The x coordinate for the popover arrow tip.
|
||||||
* @param y the y coordinate for the popover arrow tip
|
* @param y The y coordinate for the popover arrow tip.
|
||||||
* @param fadeInDuration the time it takes for the popover to be fully visible.
|
* @param fadeInDuration The time it takes for the popover to be fully visible.
|
||||||
* This duration takes precedence over the fade-in property without setting.
|
* This duration takes precedence over the fade-in property without setting.
|
||||||
*/
|
*/
|
||||||
public final void show(Node owner, double x, double y, Duration fadeInDuration) {
|
public final void show(Node owner, double x, double y, Duration fadeInDuration) {
|
||||||
/*
|
|
||||||
* Calling show() a second time without first closing the popover
|
// Calling show() a second time without first closing the popover
|
||||||
* causes it to be placed at the wrong location.
|
// causes it to be placed at the wrong location.
|
||||||
*/
|
|
||||||
if (ownerWindow != null && isShowing()) {
|
if (ownerWindow != null && isShowing()) {
|
||||||
super.hide();
|
super.hide();
|
||||||
}
|
}
|
||||||
@ -433,8 +413,8 @@ public class Popover extends PopupControl {
|
|||||||
/**
|
/**
|
||||||
* Hides the popover by quickly changing its opacity to 0.
|
* Hides the popover by quickly changing its opacity to 0.
|
||||||
*
|
*
|
||||||
* @param fadeOutDuration the duration of the fade transition that is being used to
|
* @param fadeOutDuration The duration of the fade transition that is being used to
|
||||||
* change the opacity of the popover
|
* change the opacity of the popover.
|
||||||
*/
|
*/
|
||||||
public final void hide(Duration fadeOutDuration) {
|
public final void hide(Duration fadeOutDuration) {
|
||||||
if (fadeOutDuration == null) {
|
if (fadeOutDuration == null) {
|
||||||
@ -521,7 +501,46 @@ public class Popover extends PopupControl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final BooleanProperty headerAlwaysVisible = new SimpleBooleanProperty(this, "headerAlwaysVisible");
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Properties //
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the content shown by the popover.
|
||||||
|
*/
|
||||||
|
public final ObjectProperty<Node> contentNodeProperty() {
|
||||||
|
return contentNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final ObjectProperty<Node> contentNode = new SimpleObjectProperty<>(this, "contentNode") {
|
||||||
|
@Override
|
||||||
|
public void setValue(Node node) {
|
||||||
|
if (node == null) {
|
||||||
|
throw new NullPointerException("Node cannot be null!");
|
||||||
|
}
|
||||||
|
this.set(node);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value of the content property.
|
||||||
|
*
|
||||||
|
* @return the content node.
|
||||||
|
* @see #contentNodeProperty()
|
||||||
|
*/
|
||||||
|
public final Node getContentNode() {
|
||||||
|
return contentNodeProperty().get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the value of the content property.
|
||||||
|
*
|
||||||
|
* @param content The new content node value.
|
||||||
|
* @see #contentNodeProperty()
|
||||||
|
*/
|
||||||
|
public final void setContentNode(Node content) {
|
||||||
|
contentNodeProperty().set(content);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines whether the {@link Popover} header should remain visible or not,
|
* Determines whether the {@link Popover} header should remain visible or not,
|
||||||
@ -531,10 +550,12 @@ public class Popover extends PopupControl {
|
|||||||
return headerAlwaysVisible;
|
return headerAlwaysVisible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final BooleanProperty headerAlwaysVisible = new SimpleBooleanProperty(this, "headerAlwaysVisible");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the value of the headerAlwaysVisible property.
|
* Sets the value of the headerAlwaysVisible property.
|
||||||
*
|
*
|
||||||
* @param visible if true, then the header is visible even while attached
|
* @param visible If "true", then the header is visible even while attached.
|
||||||
* @see #headerAlwaysVisibleProperty()
|
* @see #headerAlwaysVisibleProperty()
|
||||||
*/
|
*/
|
||||||
public final void setHeaderAlwaysVisible(boolean visible) {
|
public final void setHeaderAlwaysVisible(boolean visible) {
|
||||||
@ -544,15 +565,13 @@ public class Popover extends PopupControl {
|
|||||||
/**
|
/**
|
||||||
* Returns the value of the detachable property.
|
* Returns the value of the detachable property.
|
||||||
*
|
*
|
||||||
* @return true if the header is visible even while attached
|
* @return "true" if the header is visible even while attached
|
||||||
* @see #headerAlwaysVisibleProperty()
|
* @see #headerAlwaysVisibleProperty()
|
||||||
*/
|
*/
|
||||||
public final boolean isHeaderAlwaysVisible() {
|
public final boolean isHeaderAlwaysVisible() {
|
||||||
return headerAlwaysVisible.getValue();
|
return headerAlwaysVisible.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
private final BooleanProperty closeButtonEnabled = new SimpleBooleanProperty(this, "closeButtonEnabled", true);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines whether the header's close button should be available or not.
|
* Determines whether the header's close button should be available or not.
|
||||||
*/
|
*/
|
||||||
@ -560,10 +579,12 @@ public class Popover extends PopupControl {
|
|||||||
return closeButtonEnabled;
|
return closeButtonEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final BooleanProperty closeButtonEnabled = new SimpleBooleanProperty(this, "closeButtonEnabled", true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the value of the closeButtonEnabled property.
|
* Sets the value of the closeButtonEnabled property.
|
||||||
*
|
*
|
||||||
* @param enabled if false, the popover will not be closeable by the header's close button
|
* @param enabled If "false", the popover will not be closeable by the header's close button.
|
||||||
* @see #closeButtonEnabledProperty()
|
* @see #closeButtonEnabledProperty()
|
||||||
*/
|
*/
|
||||||
public final void setCloseButtonEnabled(boolean enabled) {
|
public final void setCloseButtonEnabled(boolean enabled) {
|
||||||
@ -573,15 +594,13 @@ public class Popover extends PopupControl {
|
|||||||
/**
|
/**
|
||||||
* Returns the value of the closeButtonEnabled property.
|
* Returns the value of the closeButtonEnabled property.
|
||||||
*
|
*
|
||||||
* @return true if the header's close button is enabled
|
* @return "true" if the header's close button is enabled
|
||||||
* @see #closeButtonEnabledProperty()
|
* @see #closeButtonEnabledProperty()
|
||||||
*/
|
*/
|
||||||
public final boolean isCloseButtonEnabled() {
|
public final boolean isCloseButtonEnabled() {
|
||||||
return closeButtonEnabled.getValue();
|
return closeButtonEnabled.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
private final BooleanProperty detachable = new SimpleBooleanProperty(this, "detachable", true);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if the popover is detachable at all.
|
* Determines if the popover is detachable at all.
|
||||||
*/
|
*/
|
||||||
@ -589,10 +608,12 @@ public class Popover extends PopupControl {
|
|||||||
return detachable;
|
return detachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final BooleanProperty detachable = new SimpleBooleanProperty(this, "detachable", true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the value of the detachable property.
|
* Sets the value of the detachable property.
|
||||||
*
|
*
|
||||||
* @param detachable if true then the user can detach / tear off the popover
|
* @param detachable If "true" then the user can detach / tear off the popover.
|
||||||
* @see #detachableProperty()
|
* @see #detachableProperty()
|
||||||
*/
|
*/
|
||||||
public final void setDetachable(boolean detachable) {
|
public final void setDetachable(boolean detachable) {
|
||||||
@ -602,31 +623,28 @@ public class Popover extends PopupControl {
|
|||||||
/**
|
/**
|
||||||
* Returns the value of the detachable property.
|
* Returns the value of the detachable property.
|
||||||
*
|
*
|
||||||
* @return true if the user is allowed to detach / tear off the popover
|
* @return "true" if the user is allowed to detach / tear off the popover
|
||||||
* @see #detachableProperty()
|
* @see #detachableProperty()
|
||||||
*/
|
*/
|
||||||
public final boolean isDetachable() {
|
public final boolean isDetachable() {
|
||||||
return detachableProperty().get();
|
return detachableProperty().get();
|
||||||
}
|
}
|
||||||
|
|
||||||
private final BooleanProperty detached = new SimpleBooleanProperty(this, "detached", false);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines whether the popover is detached from the owning node or not.
|
* Determines whether the popover is detached from the owning node or not.
|
||||||
* A detached popover no longer shows an arrow pointing at the owner and
|
* A detached popover no longer shows an arrow pointing at the owner and
|
||||||
* features its own title bar.
|
* features its own title bar.
|
||||||
*
|
|
||||||
* @return the detached property
|
|
||||||
*/
|
*/
|
||||||
public final BooleanProperty detachedProperty() {
|
public final BooleanProperty detachedProperty() {
|
||||||
return detached;
|
return detached;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final BooleanProperty detached = new SimpleBooleanProperty(this, "detached", false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the value of the detached property.
|
* Sets the value of the detached property.
|
||||||
*
|
*
|
||||||
* @param detached if true the popover will change its appearance to "detached"
|
* @param detached If "true" the popover will change its appearance to "detached" mode.
|
||||||
* mode
|
|
||||||
* @see #detachedProperty()
|
* @see #detachedProperty()
|
||||||
*/
|
*/
|
||||||
public final void setDetached(boolean detached) {
|
public final void setDetached(boolean detached) {
|
||||||
@ -636,24 +654,23 @@ public class Popover extends PopupControl {
|
|||||||
/**
|
/**
|
||||||
* Returns the value of the detached property.
|
* Returns the value of the detached property.
|
||||||
*
|
*
|
||||||
* @return true if the popover is currently detached.
|
* @return "true" if the popover is currently detached
|
||||||
* @see #detachedProperty()
|
* @see #detachedProperty()
|
||||||
*/
|
*/
|
||||||
public final boolean isDetached() {
|
public final boolean isDetached() {
|
||||||
return detachedProperty().get();
|
return detachedProperty().get();
|
||||||
}
|
}
|
||||||
|
|
||||||
private final DoubleProperty arrowSize = new SimpleDoubleProperty(this, "arrowSize", 12);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controls the size of the arrow. Default value is 12.
|
* Controls the size of the arrow.
|
||||||
*
|
* Default value is "12".
|
||||||
* @return the arrow size property
|
|
||||||
*/
|
*/
|
||||||
public final DoubleProperty arrowSizeProperty() {
|
public final DoubleProperty arrowSizeProperty() {
|
||||||
return arrowSize;
|
return arrowSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final DoubleProperty arrowSize = new SimpleDoubleProperty(this, "arrowSize", 12);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the value of the arrow size property.
|
* Returns the value of the arrow size property.
|
||||||
*
|
*
|
||||||
@ -667,25 +684,23 @@ public class Popover extends PopupControl {
|
|||||||
/**
|
/**
|
||||||
* Sets the value of the arrow size property.
|
* Sets the value of the arrow size property.
|
||||||
*
|
*
|
||||||
* @param size the new value of the arrow size property
|
* @param size The new value of the arrow size property.
|
||||||
* @see #arrowSizeProperty()
|
* @see #arrowSizeProperty()
|
||||||
*/
|
*/
|
||||||
public final void setArrowSize(double size) {
|
public final void setArrowSize(double size) {
|
||||||
arrowSizeProperty().set(size);
|
arrowSizeProperty().set(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final DoubleProperty arrowIndent = new SimpleDoubleProperty(this, "arrowIndent", 12);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controls the distance between the arrow and the corners of the popover.
|
* Controls the distance between the arrow and the corners of the popover.
|
||||||
* The default value is 12.
|
* Default value is "12".
|
||||||
*
|
|
||||||
* @return the arrow indent property
|
|
||||||
*/
|
*/
|
||||||
public final DoubleProperty arrowIndentProperty() {
|
public final DoubleProperty arrowIndentProperty() {
|
||||||
return arrowIndent;
|
return arrowIndent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final DoubleProperty arrowIndent = new SimpleDoubleProperty(this, "arrowIndent", 12);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the value of the arrow indent property.
|
* Returns the value of the arrow indent property.
|
||||||
*
|
*
|
||||||
@ -699,24 +714,23 @@ public class Popover extends PopupControl {
|
|||||||
/**
|
/**
|
||||||
* Sets the value of the arrow indent property.
|
* Sets the value of the arrow indent property.
|
||||||
*
|
*
|
||||||
* @param size the arrow indent value
|
* @param size The arrow indent value.
|
||||||
* @see #arrowIndentProperty()
|
* @see #arrowIndentProperty()
|
||||||
*/
|
*/
|
||||||
public final void setArrowIndent(double size) {
|
public final void setArrowIndent(double size) {
|
||||||
arrowIndentProperty().set(size);
|
arrowIndentProperty().set(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final DoubleProperty cornerRadius = new SimpleDoubleProperty(this, "cornerRadius", 6);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the corner radius property for the popover.
|
* Returns the corner radius property for the popover.
|
||||||
*
|
* Default value is "6".
|
||||||
* @return the corner radius property (default is 6)
|
|
||||||
*/
|
*/
|
||||||
public final DoubleProperty cornerRadiusProperty() {
|
public final DoubleProperty cornerRadiusProperty() {
|
||||||
return cornerRadius;
|
return cornerRadius;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final DoubleProperty cornerRadius = new SimpleDoubleProperty(this, "cornerRadius", 6);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the value of the corner radius property.
|
* Returns the value of the corner radius property.
|
||||||
*
|
*
|
||||||
@ -730,24 +744,22 @@ public class Popover extends PopupControl {
|
|||||||
/**
|
/**
|
||||||
* Sets the value of the corner radius property.
|
* Sets the value of the corner radius property.
|
||||||
*
|
*
|
||||||
* @param radius the corner radius
|
* @param radius The corner radius.
|
||||||
* @see #cornerRadiusProperty()
|
* @see #cornerRadiusProperty()
|
||||||
*/
|
*/
|
||||||
public final void setCornerRadius(double radius) {
|
public final void setCornerRadius(double radius) {
|
||||||
cornerRadiusProperty().set(radius);
|
cornerRadiusProperty().set(radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final StringProperty title = new SimpleStringProperty(this, "title", "Info");
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores the title to display in the Popover's header.
|
* Stores the title to display in the Popover's header.
|
||||||
*
|
|
||||||
* @return the title property
|
|
||||||
*/
|
*/
|
||||||
public final StringProperty titleProperty() {
|
public final StringProperty titleProperty() {
|
||||||
return title;
|
return title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final StringProperty title = new SimpleStringProperty(this, "title", "Info");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the value of the title property.
|
* Returns the value of the title property.
|
||||||
*
|
*
|
||||||
@ -761,7 +773,7 @@ public class Popover extends PopupControl {
|
|||||||
/**
|
/**
|
||||||
* Sets the value of the title property.
|
* Sets the value of the title property.
|
||||||
*
|
*
|
||||||
* @param title the title to use when detached
|
* @param title The title to use when detached.
|
||||||
* @see #titleProperty()
|
* @see #titleProperty()
|
||||||
*/
|
*/
|
||||||
public final void setTitle(String title) {
|
public final void setTitle(String title) {
|
||||||
@ -771,24 +783,23 @@ public class Popover extends PopupControl {
|
|||||||
titleProperty().set(title);
|
titleProperty().set(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ObjectProperty<ArrowLocation> arrowLocation =
|
|
||||||
new SimpleObjectProperty<>(this, "arrowLocation", ArrowLocation.LEFT_TOP);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores the preferred arrow location. This might not be the actual
|
* Stores the preferred arrow location. This might not be the actual
|
||||||
* location of the arrow if auto fix is enabled.
|
* location of the arrow if auto fix is enabled.
|
||||||
*
|
*
|
||||||
* @return the arrow location property
|
|
||||||
* @see #setAutoFix(boolean)
|
* @see #setAutoFix(boolean)
|
||||||
*/
|
*/
|
||||||
public final ObjectProperty<ArrowLocation> arrowLocationProperty() {
|
public final ObjectProperty<ArrowLocation> arrowLocationProperty() {
|
||||||
return arrowLocation;
|
return arrowLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final ObjectProperty<ArrowLocation> arrowLocation =
|
||||||
|
new SimpleObjectProperty<>(this, "arrowLocation", ArrowLocation.LEFT_TOP);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the value of the arrow location property.
|
* Sets the value of the arrow location property.
|
||||||
*
|
*
|
||||||
* @param location the requested location
|
* @param location The requested location.
|
||||||
* @see #arrowLocationProperty()
|
* @see #arrowLocationProperty()
|
||||||
*/
|
*/
|
||||||
public final void setArrowLocation(ArrowLocation location) {
|
public final void setArrowLocation(ArrowLocation location) {
|
||||||
@ -824,22 +835,13 @@ public class Popover extends PopupControl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores the fade-in duration. This should be set before calling Popover.show(..).
|
* Stores the fade-in duration. This should be set before calling <code>Popover.show(..)</code>.
|
||||||
*
|
|
||||||
* @return the fade-in duration property
|
|
||||||
*/
|
*/
|
||||||
public final ObjectProperty<Duration> fadeInDurationProperty() {
|
public final ObjectProperty<Duration> fadeInDurationProperty() {
|
||||||
return fadeInDuration;
|
return fadeInDuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private final ObjectProperty<Duration> fadeInDuration = new SimpleObjectProperty<>(DEFAULT_FADE_DURATION);
|
||||||
* Stores the fade-out duration.
|
|
||||||
*
|
|
||||||
* @return the fade-out duration property
|
|
||||||
*/
|
|
||||||
public final ObjectProperty<Duration> fadeOutDurationProperty() {
|
|
||||||
return fadeOutDuration;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the value of the fade-in duration property.
|
* Returns the value of the fade-in duration property.
|
||||||
@ -855,13 +857,22 @@ public class Popover extends PopupControl {
|
|||||||
* Sets the value of the fade-in duration property. This should be set before calling
|
* Sets the value of the fade-in duration property. This should be set before calling
|
||||||
* Popover.show(..).
|
* Popover.show(..).
|
||||||
*
|
*
|
||||||
* @param duration the requested fade-in duration
|
* @param duration The requested fade-in duration.
|
||||||
* @see #fadeInDurationProperty()
|
* @see #fadeInDurationProperty()
|
||||||
*/
|
*/
|
||||||
public final void setFadeInDuration(Duration duration) {
|
public final void setFadeInDuration(Duration duration) {
|
||||||
fadeInDurationProperty().setValue(duration);
|
fadeInDurationProperty().setValue(duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores the fade-out duration.
|
||||||
|
*/
|
||||||
|
public final ObjectProperty<Duration> fadeOutDurationProperty() {
|
||||||
|
return fadeOutDuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final ObjectProperty<Duration> fadeOutDuration = new SimpleObjectProperty<>(DEFAULT_FADE_DURATION);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the value of the fade-out duration property.
|
* Returns the value of the fade-out duration property.
|
||||||
*
|
*
|
||||||
@ -875,7 +886,7 @@ public class Popover extends PopupControl {
|
|||||||
/**
|
/**
|
||||||
* Sets the value of the fade-out duration property.
|
* Sets the value of the fade-out duration property.
|
||||||
*
|
*
|
||||||
* @param duration the requested fade-out duration
|
* @param duration The requested fade-out duration.
|
||||||
* @see #fadeOutDurationProperty()
|
* @see #fadeOutDurationProperty()
|
||||||
*/
|
*/
|
||||||
public final void setFadeOutDuration(Duration duration) {
|
public final void setFadeOutDuration(Duration duration) {
|
||||||
@ -885,17 +896,17 @@ public class Popover extends PopupControl {
|
|||||||
/**
|
/**
|
||||||
* Stores the "animated" flag. If true then the Popover will be shown / hidden with a short
|
* Stores the "animated" flag. If true then the Popover will be shown / hidden with a short
|
||||||
* fade in / out animation.
|
* fade in / out animation.
|
||||||
*
|
|
||||||
* @return the "animated" property
|
|
||||||
*/
|
*/
|
||||||
public final BooleanProperty animatedProperty() {
|
public final BooleanProperty animatedProperty() {
|
||||||
return animated;
|
return animated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final SimpleBooleanProperty animated = new SimpleBooleanProperty(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the value of the "animated" property.
|
* Returns the value of the "animated" property.
|
||||||
*
|
*
|
||||||
* @return true if the Popover will be shown and hidden with a short fade animation
|
* @return "true" if the Popover will be shown and hidden with a short fade animation
|
||||||
* @see #animatedProperty()
|
* @see #animatedProperty()
|
||||||
*/
|
*/
|
||||||
public final boolean isAnimated() {
|
public final boolean isAnimated() {
|
||||||
@ -905,7 +916,7 @@ public class Popover extends PopupControl {
|
|||||||
/**
|
/**
|
||||||
* Sets the value of the "animated" property.
|
* Sets the value of the "animated" property.
|
||||||
*
|
*
|
||||||
* @param animated if true the Popover will be shown and hidden with a short fade animation
|
* @param animated If "true" the Popover will be shown and hidden with a short fade animation.
|
||||||
* @see #animatedProperty()
|
* @see #animatedProperty()
|
||||||
*/
|
*/
|
||||||
public final void setAnimated(boolean animated) {
|
public final void setAnimated(boolean animated) {
|
||||||
|
@ -62,6 +62,9 @@ import javafx.scene.shape.QuadCurveTo;
|
|||||||
import javafx.scene.shape.VLineTo;
|
import javafx.scene.shape.VLineTo;
|
||||||
import javafx.stage.Window;
|
import javafx.stage.Window;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default skin for the {@link Popover} control.
|
||||||
|
*/
|
||||||
public class PopoverSkin implements Skin<Popover> {
|
public class PopoverSkin implements Skin<Popover> {
|
||||||
|
|
||||||
private static final String DETACHED_STYLE_CLASS = "detached";
|
private static final String DETACHED_STYLE_CLASS = "detached";
|
||||||
|
@ -8,7 +8,7 @@ import javafx.scene.control.skin.SliderSkin;
|
|||||||
import javafx.scene.layout.StackPane;
|
import javafx.scene.layout.StackPane;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link Slider} skin that supports progress color.
|
* A {@link Slider} skin that supports progress color indication.
|
||||||
*/
|
*/
|
||||||
public class ProgressSliderSkin extends SliderSkin {
|
public class ProgressSliderSkin extends SliderSkin {
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
package atlantafx.base.controls;
|
package atlantafx.base.controls;
|
||||||
|
|
||||||
|
import javafx.beans.NamedArg;
|
||||||
import javafx.beans.property.ObjectProperty;
|
import javafx.beans.property.ObjectProperty;
|
||||||
import javafx.beans.property.ReadOnlyBooleanProperty;
|
import javafx.beans.property.ReadOnlyBooleanProperty;
|
||||||
import javafx.beans.property.ReadOnlyBooleanWrapper;
|
import javafx.beans.property.ReadOnlyBooleanWrapper;
|
||||||
@ -11,21 +12,43 @@ import javafx.scene.control.ProgressIndicator;
|
|||||||
import javafx.scene.control.Skin;
|
import javafx.scene.control.Skin;
|
||||||
import javafx.util.StringConverter;
|
import javafx.util.StringConverter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A ProgressIndicator that displays progress value as a ring that gradually
|
||||||
|
* empties out as a task is completed.
|
||||||
|
*/
|
||||||
public class RingProgressIndicator extends ProgressIndicator {
|
public class RingProgressIndicator extends ProgressIndicator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new indeterminate ProgressIndicator.
|
||||||
|
*/
|
||||||
public RingProgressIndicator() {
|
public RingProgressIndicator() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public RingProgressIndicator(double progress) {
|
/**
|
||||||
|
* Creates a new ProgressIndicator with the given progress value.
|
||||||
|
*
|
||||||
|
* @param progress The progress, represented as a value between 0 and 1.
|
||||||
|
*/
|
||||||
|
public RingProgressIndicator(@NamedArg("progress") double progress) {
|
||||||
this(progress, false);
|
this(progress, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RingProgressIndicator(double progress, boolean reverse) {
|
/**
|
||||||
|
* Creates a new ProgressIndicator with the given progress value and type.
|
||||||
|
*
|
||||||
|
* @param progress The progress, represented as a value between 0 and 1.
|
||||||
|
* @param reverse A flag to indicate whether the indicator is reversed or not.
|
||||||
|
*/
|
||||||
|
public RingProgressIndicator(@NamedArg("progress") double progress,
|
||||||
|
@NamedArg("reverse") boolean reverse) {
|
||||||
super(progress);
|
super(progress);
|
||||||
this.reverse.set(reverse);
|
this.reverse.set(reverse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Skin<?> createDefaultSkin() {
|
protected Skin<?> createDefaultSkin() {
|
||||||
return new RingProgressIndicatorSkin(this);
|
return new RingProgressIndicatorSkin(this);
|
||||||
@ -35,6 +58,14 @@ public class RingProgressIndicator extends ProgressIndicator {
|
|||||||
// Properties //
|
// Properties //
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the node to be displayed within the progress indicator. If null,
|
||||||
|
* it will fall back to the Label with an integer progress value from 1 to 100.
|
||||||
|
*/
|
||||||
|
public ObjectProperty<Node> graphicProperty() {
|
||||||
|
return graphic;
|
||||||
|
}
|
||||||
|
|
||||||
protected final ObjectProperty<Node> graphic = new SimpleObjectProperty<>(this, "graphic", null);
|
protected final ObjectProperty<Node> graphic = new SimpleObjectProperty<>(this, "graphic", null);
|
||||||
|
|
||||||
public Node getGraphic() {
|
public Node getGraphic() {
|
||||||
@ -46,15 +77,15 @@ public class RingProgressIndicator extends ProgressIndicator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Any node to be displayed within the progress indicator. If null,
|
* Represents an optional converter to transform the progress value to a string.
|
||||||
* it will fall back to the Label with integer progress value from 1 to 100.
|
* It is only used if a custom graphic node is not set.
|
||||||
|
*
|
||||||
|
* @see #graphicProperty()
|
||||||
*/
|
*/
|
||||||
public ObjectProperty<Node> graphicProperty() {
|
public ObjectProperty<StringConverter<Double>> stringConverterProperty() {
|
||||||
return graphic;
|
return stringConverter;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ~
|
|
||||||
|
|
||||||
protected final ObjectProperty<StringConverter<Double>> stringConverter =
|
protected final ObjectProperty<StringConverter<Double>> stringConverter =
|
||||||
new SimpleObjectProperty<>(this, "converter", null);
|
new SimpleObjectProperty<>(this, "converter", null);
|
||||||
|
|
||||||
@ -67,25 +98,16 @@ public class RingProgressIndicator extends ProgressIndicator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optional converter to transform progress value to string.
|
* Reverses the progress indicator scale. For the indeterminate variant,
|
||||||
*/
|
|
||||||
public ObjectProperty<StringConverter<Double>> stringConverterProperty() {
|
|
||||||
return stringConverter;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ~
|
|
||||||
|
|
||||||
private final ReadOnlyBooleanWrapper reverse = new ReadOnlyBooleanWrapper(this, "reverse", false);
|
|
||||||
|
|
||||||
public boolean isReverse() {
|
|
||||||
return reverse.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse progress indicator scale. For indeterminate variant
|
|
||||||
* this means it will be rotated counterclockwise.
|
* this means it will be rotated counterclockwise.
|
||||||
*/
|
*/
|
||||||
public ReadOnlyBooleanProperty reverseProperty() {
|
public ReadOnlyBooleanProperty reverseProperty() {
|
||||||
return reverse.getReadOnlyProperty();
|
return reverse.getReadOnlyProperty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected final ReadOnlyBooleanWrapper reverse = new ReadOnlyBooleanWrapper(this, "reverse", false);
|
||||||
|
|
||||||
|
public boolean isReverse() {
|
||||||
|
return reverse.get();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,9 @@ import javafx.scene.shape.Arc;
|
|||||||
import javafx.scene.shape.Circle;
|
import javafx.scene.shape.Circle;
|
||||||
import javafx.util.Duration;
|
import javafx.util.Duration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default skin for the {@link RingProgressIndicator} control.
|
||||||
|
*/
|
||||||
public class RingProgressIndicatorSkin extends SkinBase<RingProgressIndicator> {
|
public class RingProgressIndicatorSkin extends SkinBase<RingProgressIndicator> {
|
||||||
|
|
||||||
protected static final double DEFAULT_ANIMATION_TIME = 3;
|
protected static final double DEFAULT_ANIMATION_TIME = 3;
|
||||||
|
@ -11,6 +11,15 @@ import javafx.scene.Node;
|
|||||||
import javafx.scene.layout.Pane;
|
import javafx.scene.layout.Pane;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An internal convenience class for implementing slot-based approach.
|
||||||
|
*
|
||||||
|
* <p>It is intended to be used for controls that allow custom user nodes
|
||||||
|
* to be placed inside their skins. his class automatically adds or removes
|
||||||
|
* an updated <code>ObservableValue<? extends Node></code> value to/from the
|
||||||
|
* given container and also maintains the <code>:filled</code> pseudo-class
|
||||||
|
* state to indicate whether the corresponding slot is empty or not.
|
||||||
|
*/
|
||||||
final class SlotListener implements ChangeListener<Node> {
|
final class SlotListener implements ChangeListener<Node> {
|
||||||
|
|
||||||
private static final PseudoClass FILLED = PseudoClass.getPseudoClass("filled");
|
private static final PseudoClass FILLED = PseudoClass.getPseudoClass("filled");
|
||||||
@ -18,10 +27,24 @@ final class SlotListener implements ChangeListener<Node> {
|
|||||||
private final Pane slot;
|
private final Pane slot;
|
||||||
private final @Nullable BiConsumer<Node, Boolean> onContentUpdate;
|
private final @Nullable BiConsumer<Node, Boolean> onContentUpdate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new listener and binds it to the specified container.
|
||||||
|
*
|
||||||
|
* @param slot The container for user-specified node.
|
||||||
|
*/
|
||||||
public SlotListener(Pane slot) {
|
public SlotListener(Pane slot) {
|
||||||
this(slot, null);
|
this(slot, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new listener and binds it to the specified container.
|
||||||
|
* Also, it registers the custom callback handler that will be notified
|
||||||
|
* upon the container content changed.
|
||||||
|
*
|
||||||
|
* @param slot The container for user-specified node.
|
||||||
|
* @param onContentUpdate The callback handler to be notified upon
|
||||||
|
* the container content changing.
|
||||||
|
*/
|
||||||
public SlotListener(Node slot, @Nullable BiConsumer<Node, Boolean> onContentUpdate) {
|
public SlotListener(Node slot, @Nullable BiConsumer<Node, Boolean> onContentUpdate) {
|
||||||
Objects.requireNonNull(slot, "Slot cannot be null.");
|
Objects.requireNonNull(slot, "Slot cannot be null.");
|
||||||
|
|
||||||
|
@ -8,12 +8,38 @@ import javafx.scene.layout.Priority;
|
|||||||
import javafx.scene.layout.Region;
|
import javafx.scene.layout.Region;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A spacing component used to distribute remaining width between
|
||||||
|
* a parent's child components.
|
||||||
|
*
|
||||||
|
* <p>When placing a single Spacer before or after the child components,
|
||||||
|
* the components will be pushed to the right and left of its container
|
||||||
|
* for horizontally oriented Spacer, or to the top and bottom for vertically
|
||||||
|
* oriented Spacer.
|
||||||
|
*
|
||||||
|
* <p>You can also specify the `Spacer` size. In this case, it will not be
|
||||||
|
* extended and will work like a gap with the given size between sibling components.
|
||||||
|
*
|
||||||
|
* <p>Note that this control is not intended to be used in FXML unless SceneBuilder
|
||||||
|
* supports constructor arguments, because none of the properties mentioned above are
|
||||||
|
* observable.
|
||||||
|
*/
|
||||||
public class Spacer extends Region {
|
public class Spacer extends Region {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new horizontally oriented Spacer that expands
|
||||||
|
* to fill remaining space.
|
||||||
|
*/
|
||||||
public Spacer() {
|
public Spacer() {
|
||||||
this(Orientation.HORIZONTAL);
|
this(Orientation.HORIZONTAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new Spacer with the given orientation that expands
|
||||||
|
* to fill remaining space.
|
||||||
|
*
|
||||||
|
* @param orientation The orientation of the spacer.
|
||||||
|
*/
|
||||||
public Spacer(Orientation orientation) {
|
public Spacer(Orientation orientation) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
@ -23,10 +49,21 @@ public class Spacer extends Region {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new Spacer with the fixed size.
|
||||||
|
*
|
||||||
|
* @param size The size of the spacer.
|
||||||
|
*/
|
||||||
public Spacer(double size) {
|
public Spacer(double size) {
|
||||||
this(size, Orientation.HORIZONTAL);
|
this(size, Orientation.HORIZONTAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new Spacer with the fixed size and orientation.
|
||||||
|
*
|
||||||
|
* @param size The size of the spacer.
|
||||||
|
* @param orientation The orientation of the spacer.
|
||||||
|
*/
|
||||||
public Spacer(double size, Orientation orientation) {
|
public Spacer(double size, Orientation orientation) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
|
@ -10,21 +10,37 @@ import javafx.scene.control.Skin;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A versatile container that can used in various contexts such as dialog headers,
|
* A versatile container that can used in various contexts such as dialog
|
||||||
* list items, and cards. It can contain a graphic, a title, description, and optional
|
* headers, list items, and cards. It can contain a graphic, a title, description,
|
||||||
* actions.
|
* and optional actions.
|
||||||
*/
|
*/
|
||||||
public class Tile extends TileBase {
|
public class Tile extends TileBase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new empty Tile.
|
||||||
|
*/
|
||||||
public Tile() {
|
public Tile() {
|
||||||
this(null, null, null);
|
this(null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new Tile with an initial title and description.
|
||||||
|
*
|
||||||
|
* @param title A string for the title.
|
||||||
|
* @param description A string for the description.
|
||||||
|
*/
|
||||||
public Tile(@Nullable @NamedArg("title") String title,
|
public Tile(@Nullable @NamedArg("title") String title,
|
||||||
@Nullable @NamedArg("description") String description) {
|
@Nullable @NamedArg("description") String description) {
|
||||||
this(title, description, null);
|
this(title, description, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new Tile 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 Tile(@Nullable String title,
|
public Tile(@Nullable String title,
|
||||||
@Nullable String description,
|
@Nullable String description,
|
||||||
@Nullable Node graphic) {
|
@Nullable Node graphic) {
|
||||||
@ -32,6 +48,9 @@ public class Tile extends TileBase {
|
|||||||
getStyleClass().add("tile");
|
getStyleClass().add("tile");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Skin<?> createDefaultSkin() {
|
protected Skin<?> createDefaultSkin() {
|
||||||
return new TileSkin(this);
|
return new TileSkin(this);
|
||||||
@ -42,38 +61,40 @@ public class Tile extends TileBase {
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The property representing the tile’s action node. It is commonly used
|
* Represents the node to be placed in the tile’s action slot. It is commonly
|
||||||
* to place an action controls that are associated with the tile.
|
* used to place action controls that are associated with the tile.
|
||||||
*/
|
*/
|
||||||
|
public ObjectProperty<Node> actionProperty() {
|
||||||
|
return action;
|
||||||
|
}
|
||||||
|
|
||||||
private final ObjectProperty<Node> action = new SimpleObjectProperty<>(this, "action");
|
private final ObjectProperty<Node> action = new SimpleObjectProperty<>(this, "action");
|
||||||
|
|
||||||
public Node getAction() {
|
public Node getAction() {
|
||||||
return action.get();
|
return action.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObjectProperty<Node> actionProperty() {
|
|
||||||
return action;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAction(Node action) {
|
public void setAction(Node action) {
|
||||||
this.action.set(action);
|
this.action.set(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The property representing the tile’s action handler. Setting an action handler
|
* Represents the tile’s action handler.
|
||||||
* makes the tile interactive or clickable. When a user clicks on the interactive
|
*
|
||||||
* tile, the specified action handler will be called.
|
* <p>Setting an action handler makes the tile interactive (or clickable).
|
||||||
|
* When a user clicks on the interactive tile, the specified action handler will be called.
|
||||||
*/
|
*/
|
||||||
private final ObjectProperty<Runnable> actionHandler = new SimpleObjectProperty<>(this, "actionHandler");
|
public ObjectProperty<Runnable> actionHandlerProperty() {
|
||||||
|
return actionHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final ObjectProperty<Runnable> actionHandler
|
||||||
|
= new SimpleObjectProperty<>(this, "actionHandler");
|
||||||
|
|
||||||
public Runnable getActionHandler() {
|
public Runnable getActionHandler() {
|
||||||
return actionHandler.get();
|
return actionHandler.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObjectProperty<Runnable> actionHandlerProperty() {
|
|
||||||
return actionHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setActionHandler(Runnable actionHandler) {
|
public void setActionHandler(Runnable actionHandler) {
|
||||||
this.actionHandler.set(actionHandler);
|
this.actionHandler.set(actionHandler);
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
package atlantafx.base.controls;
|
package atlantafx.base.controls;
|
||||||
|
|
||||||
import javafx.beans.NamedArg;
|
import atlantafx.base.util.BBCodeParser;
|
||||||
import javafx.beans.property.ObjectProperty;
|
import javafx.beans.property.ObjectProperty;
|
||||||
import javafx.beans.property.SimpleObjectProperty;
|
import javafx.beans.property.SimpleObjectProperty;
|
||||||
import javafx.beans.property.SimpleStringProperty;
|
import javafx.beans.property.SimpleStringProperty;
|
||||||
@ -11,14 +11,18 @@ import javafx.scene.Node;
|
|||||||
import javafx.scene.control.Control;
|
import javafx.scene.control.Control;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A common class for implementing tile-based controls, specifically the
|
||||||
|
* {@link Message} and the {@link Tile}.
|
||||||
|
*/
|
||||||
public abstract class TileBase extends Control {
|
public abstract class TileBase extends Control {
|
||||||
|
|
||||||
public TileBase() {
|
public TileBase() {
|
||||||
this(null, null, null);
|
this(null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TileBase(@Nullable @NamedArg("title") String title,
|
public TileBase(@Nullable String title,
|
||||||
@Nullable @NamedArg("description") String description) {
|
@Nullable String description) {
|
||||||
this(title, description, null);
|
this(title, description, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,54 +42,56 @@ public abstract class TileBase extends Control {
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The property representing the tile’s graphic node. It is commonly used
|
* Represents the tile’s graphic node. It is commonly used to add images or icons
|
||||||
* to add images or icons that are associated with the tile.
|
* that are associated with the tile.
|
||||||
*/
|
*/
|
||||||
|
public ObjectProperty<Node> graphicProperty() {
|
||||||
|
return graphic;
|
||||||
|
}
|
||||||
|
|
||||||
private final ObjectProperty<Node> graphic = new SimpleObjectProperty<>(this, "graphic");
|
private final ObjectProperty<Node> graphic = new SimpleObjectProperty<>(this, "graphic");
|
||||||
|
|
||||||
public Node getGraphic() {
|
public Node getGraphic() {
|
||||||
return graphic.get();
|
return graphic.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObjectProperty<Node> graphicProperty() {
|
|
||||||
return graphic;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setGraphic(Node graphic) {
|
public void setGraphic(Node graphic) {
|
||||||
this.graphic.set(graphic);
|
this.graphic.set(graphic);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The property representing the tile’s title. Although it is not mandatory,
|
* Represents the tile’s title (or header).
|
||||||
* you typically would not want to have a tile without a title.
|
|
||||||
*/
|
*/
|
||||||
|
public StringProperty titleProperty() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
private final StringProperty title = new SimpleStringProperty(this, "title");
|
private final StringProperty title = new SimpleStringProperty(this, "title");
|
||||||
|
|
||||||
public String getTitle() {
|
public String getTitle() {
|
||||||
return title.get();
|
return title.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public StringProperty titleProperty() {
|
|
||||||
return title;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTitle(String title) {
|
public void setTitle(String title) {
|
||||||
this.title.set(title);
|
this.title.set(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The property representing the tile’s description.
|
* Represents the tile’s description (or optional text).
|
||||||
|
*
|
||||||
|
* <p>This property supports BBCode formatted text. Refer to the {@link BBCodeParser}
|
||||||
|
* for more information.
|
||||||
*/
|
*/
|
||||||
|
public StringProperty descriptionProperty() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
private final StringProperty description = new SimpleStringProperty(this, "description");
|
private final StringProperty description = new SimpleStringProperty(this, "description");
|
||||||
|
|
||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
return description.get();
|
return description.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public StringProperty descriptionProperty() {
|
|
||||||
return description;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDescription(String description) {
|
public void setDescription(String description) {
|
||||||
this.description.set(description);
|
this.description.set(description);
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,9 @@ package atlantafx.base.controls;
|
|||||||
|
|
||||||
import atlantafx.base.theme.Styles;
|
import atlantafx.base.theme.Styles;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default skin for the {@link Tile} control.
|
||||||
|
*/
|
||||||
public class TileSkin extends TileSkinBase<Tile> {
|
public class TileSkin extends TileSkinBase<Tile> {
|
||||||
|
|
||||||
public TileSkin(Tile control) {
|
public TileSkin(Tile control) {
|
||||||
|
@ -15,6 +15,10 @@ import javafx.scene.layout.StackPane;
|
|||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
import javafx.scene.text.TextFlow;
|
import javafx.scene.text.TextFlow;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A common skin for implementing tile-based controls, specifically the
|
||||||
|
* {@link MessageSkin} and the {@link TileSkin}.
|
||||||
|
*/
|
||||||
public abstract class TileSkinBase<T extends TileBase> extends SkinBase<T> {
|
public abstract class TileSkinBase<T extends TileBase> extends SkinBase<T> {
|
||||||
|
|
||||||
protected static final PseudoClass HAS_GRAPHIC = PseudoClass.getPseudoClass("has-graphic");
|
protected static final PseudoClass HAS_GRAPHIC = PseudoClass.getPseudoClass("has-graphic");
|
||||||
|
@ -51,7 +51,11 @@ import javafx.scene.control.Skin;
|
|||||||
import javafx.scene.control.Toggle;
|
import javafx.scene.control.Toggle;
|
||||||
import javafx.scene.control.ToggleGroup;
|
import javafx.scene.control.ToggleGroup;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
/**
|
||||||
|
* A control that provides users with the ability to choose between two distinct values.
|
||||||
|
* It is functionally similar, though aesthetically different, from the RadioButton
|
||||||
|
* and Checkbox.
|
||||||
|
*/
|
||||||
public class ToggleSwitch extends Labeled implements Toggle {
|
public class ToggleSwitch extends Labeled implements Toggle {
|
||||||
|
|
||||||
protected static final String DEFAULT_STYLE_CLASS = "toggle-switch";
|
protected static final String DEFAULT_STYLE_CLASS = "toggle-switch";
|
||||||
@ -68,13 +72,21 @@ public class ToggleSwitch extends Labeled implements Toggle {
|
|||||||
/**
|
/**
|
||||||
* Creates a toggle switch with the specified label.
|
* Creates a toggle switch with the specified label.
|
||||||
*
|
*
|
||||||
* @param text The label string of the control
|
* @param text The label string of the control.
|
||||||
*/
|
*/
|
||||||
public ToggleSwitch(String text) {
|
public ToggleSwitch(String text) {
|
||||||
super(text);
|
super(text);
|
||||||
initialize();
|
initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected Skin<?> createDefaultSkin() {
|
||||||
|
return new ToggleSwitchSkin(this);
|
||||||
|
}
|
||||||
|
|
||||||
private void initialize() {
|
private void initialize() {
|
||||||
getStyleClass().setAll(DEFAULT_STYLE_CLASS);
|
getStyleClass().setAll(DEFAULT_STYLE_CLASS);
|
||||||
}
|
}
|
||||||
@ -83,18 +95,6 @@ public class ToggleSwitch extends Labeled implements Toggle {
|
|||||||
// Properties //
|
// Properties //
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
private BooleanProperty selected;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final void setSelected(boolean value) {
|
|
||||||
selectedProperty().set(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final boolean isSelected() {
|
|
||||||
return selected != null && selected.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether this Toggle Switch is selected.
|
* Returns whether this Toggle Switch is selected.
|
||||||
*/
|
*/
|
||||||
@ -151,24 +151,23 @@ public class ToggleSwitch extends Labeled implements Toggle {
|
|||||||
return selected;
|
return selected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private BooleanProperty selected;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void setSelected(boolean value) {
|
||||||
|
selectedProperty().set(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean isSelected() {
|
||||||
|
return selected != null && selected.get();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link ToggleGroup} to which this {@code ToggleSwitch} belongs.
|
* The {@link ToggleGroup} to which this ToggleSwitch belongs. A toggle can only
|
||||||
* A {@code ToggleSwitch} can only be in one group at any one time. If the
|
* be in one group at any one time. If the group is changed, then the toggle is
|
||||||
* group is changed, then the button is removed from the old group prior to
|
* removed from the old group prior to being added to the new group.
|
||||||
* being added to the new group.
|
|
||||||
*/
|
*/
|
||||||
private ObjectProperty<ToggleGroup> toggleGroup;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final void setToggleGroup(ToggleGroup value) {
|
|
||||||
toggleGroupProperty().set(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final ToggleGroup getToggleGroup() {
|
|
||||||
return toggleGroup == null ? null : toggleGroup.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final ObjectProperty<ToggleGroup> toggleGroupProperty() {
|
public final ObjectProperty<ToggleGroup> toggleGroupProperty() {
|
||||||
if (toggleGroup == null) {
|
if (toggleGroup == null) {
|
||||||
@ -204,23 +203,20 @@ public class ToggleSwitch extends Labeled implements Toggle {
|
|||||||
return toggleGroup;
|
return toggleGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ~
|
private ObjectProperty<ToggleGroup> toggleGroup;
|
||||||
|
|
||||||
private ObjectProperty<HorizontalDirection> labelPosition;
|
@Override
|
||||||
|
public final void setToggleGroup(ToggleGroup value) {
|
||||||
|
toggleGroupProperty().set(value);
|
||||||
|
}
|
||||||
|
|
||||||
public final void setLabelPosition(HorizontalDirection pos) {
|
@Override
|
||||||
labelPositionProperty().setValue(pos);
|
public final ToggleGroup getToggleGroup() {
|
||||||
|
return toggleGroup == null ? null : toggleGroup.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether this Toggle Switch is selected.
|
* Specifies the side where {@link #textProperty()} value should be placed.
|
||||||
*/
|
|
||||||
public final HorizontalDirection getLabelPosition() {
|
|
||||||
return labelPosition == null ? HorizontalDirection.LEFT : labelPosition.getValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specifies the side where {@link #textProperty()} values should be placed.
|
|
||||||
* Default is {@link HorizontalDirection#LEFT}.
|
* Default is {@link HorizontalDirection#LEFT}.
|
||||||
*/
|
*/
|
||||||
public final ObjectProperty<HorizontalDirection> labelPositionProperty() {
|
public final ObjectProperty<HorizontalDirection> labelPositionProperty() {
|
||||||
@ -253,13 +249,22 @@ public class ToggleSwitch extends Labeled implements Toggle {
|
|||||||
return labelPosition;
|
return labelPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ObjectProperty<HorizontalDirection> labelPosition;
|
||||||
|
|
||||||
|
public final void setLabelPosition(HorizontalDirection pos) {
|
||||||
|
labelPositionProperty().setValue(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final HorizontalDirection getLabelPosition() {
|
||||||
|
return labelPosition == null ? HorizontalDirection.LEFT : labelPosition.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Methods //
|
// Methods //
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggles the state of the {@code Switch}. The {@code Switch} will cycle
|
* Toggles the state of the switch, cycling through the selected and unselected states.
|
||||||
* through the selected and unselected states.
|
|
||||||
*/
|
*/
|
||||||
public void fire() {
|
public void fire() {
|
||||||
if (!isDisabled()) {
|
if (!isDisabled()) {
|
||||||
@ -268,13 +273,9 @@ public class ToggleSwitch extends Labeled implements Toggle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
///////////////////////////////////////////////////////////////////////////
|
||||||
* {@inheritDoc}
|
// Styleable Properties //
|
||||||
*/
|
///////////////////////////////////////////////////////////////////////////
|
||||||
@Override
|
|
||||||
protected Skin<?> createDefaultSkin() {
|
|
||||||
return new ToggleSwitchSkin(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
@ -284,10 +285,6 @@ public class ToggleSwitch extends Labeled implements Toggle {
|
|||||||
return StyleableProperties.STYLEABLES;
|
return StyleableProperties.STYLEABLES;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
// Styleable Properties //
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
private static class StyleableProperties {
|
private static class StyleableProperties {
|
||||||
|
|
||||||
private static final CssMetaData<ToggleSwitch, HorizontalDirection> LABEL_POSITION = new CssMetaData<>(
|
private static final CssMetaData<ToggleSwitch, HorizontalDirection> LABEL_POSITION = new CssMetaData<>(
|
||||||
|
@ -48,6 +48,9 @@ import javafx.scene.control.SkinBase;
|
|||||||
import javafx.scene.layout.StackPane;
|
import javafx.scene.layout.StackPane;
|
||||||
import javafx.util.Duration;
|
import javafx.util.Duration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default skin for the {@link ToggleSwitch} control.
|
||||||
|
*/
|
||||||
public class ToggleSwitchSkin extends SkinBase<ToggleSwitch> {
|
public class ToggleSwitchSkin extends SkinBase<ToggleSwitch> {
|
||||||
|
|
||||||
protected static final Duration DEFAULT_ANIMATION_TIME = Duration.millis(200);
|
protected static final Duration DEFAULT_ANIMATION_TIME = Duration.millis(200);
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
/**
|
||||||
|
* Defines the UI controls and their corresponding skins.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package atlantafx.base.controls;
|
@ -22,15 +22,15 @@ import javafx.util.Duration;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DeckPane represents a pane that displays all of its child nodes in a deck,
|
* Represents a pane that displays all of its child nodes in a deck,
|
||||||
* where only one node can be visible at a time. It does not maintain any sequence
|
* where only one node can be visible at a time. It <b>does not maintain any
|
||||||
* (model), but only cares about the top node, which can be changed by various
|
* sequence</b> (model), but only cares about the top node, which can be changed
|
||||||
* transition effects.<p/>
|
* by various transition effects.<p/>
|
||||||
*
|
*
|
||||||
* <h3>View Order</h3>
|
* <h3>View Order</h3>
|
||||||
*
|
*
|
||||||
* <p>DeckPane manages {@link Node#viewOrderProperty()} of its children. Topmost
|
* <p>DeckPane manages {@link Node#viewOrderProperty()} of its children. Topmost
|
||||||
* visible node always has a higher view order value, while the rest of the nodes
|
* visible node always has the highest view order value, while the rest of the nodes
|
||||||
* have the default value, which is zero. Following that logic, one must not set
|
* have the default value, which is zero. Following that logic, one must not set
|
||||||
* child nodes view order manually, because it will break the contract.
|
* child nodes view order manually, because it will break the contract.
|
||||||
*
|
*
|
||||||
@ -53,6 +53,9 @@ public class DeckPane extends AnchorPane {
|
|||||||
// the rest of the nodes
|
// the rest of the nodes
|
||||||
protected static final int Z_DEFAULT = 0;
|
protected static final int Z_DEFAULT = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new empty DeckPane.
|
||||||
|
*/
|
||||||
public DeckPane() {
|
public DeckPane() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
@ -66,14 +69,19 @@ public class DeckPane extends AnchorPane {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an DeckPane with the given children.
|
||||||
|
*
|
||||||
|
* @param children The initial set of children for this pane.
|
||||||
|
*/
|
||||||
public DeckPane(Node... children) {
|
public DeckPane(Node... children) {
|
||||||
this();
|
this();
|
||||||
getChildren().addAll(children);
|
getChildren().addAll(children);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the node with the higher view order value or the last node
|
* Returns the node with the highest view order value, or the
|
||||||
* if all child nodes have the same view order value.
|
* last node if all child nodes have the same view order value.
|
||||||
*/
|
*/
|
||||||
public @Nullable Node getTopNode() {
|
public @Nullable Node getTopNode() {
|
||||||
var size = getChildren().size();
|
var size = getChildren().size();
|
||||||
@ -93,6 +101,8 @@ public class DeckPane extends AnchorPane {
|
|||||||
/**
|
/**
|
||||||
* Sets given node on top without playing any transition.
|
* Sets given node on top without playing any transition.
|
||||||
* Does nothing if that node isn't added to the pane.
|
* Does nothing if that node isn't added to the pane.
|
||||||
|
*
|
||||||
|
* @param target The node to be set on top.
|
||||||
*/
|
*/
|
||||||
public void setTopNode(Node target) {
|
public void setTopNode(Node target) {
|
||||||
if (!getChildren().contains(target)) {
|
if (!getChildren().contains(target)) {
|
||||||
@ -120,16 +130,19 @@ public class DeckPane extends AnchorPane {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds given nodes to the pane and binds them to the pane edges
|
* Adds the given nodes to the pane and binds them to the pane edges
|
||||||
* using the provided offsets. See {@link AnchorPane#setTopAnchor(Node, Double)}
|
* using the provided offset. See {@link AnchorPane#setTopAnchor(Node, Double)}
|
||||||
* for the reference.
|
* for the reference.
|
||||||
|
*
|
||||||
|
* @param offset The offset values for each othe the specified nodes.
|
||||||
|
* @param nodes The array of the nodes to be added.
|
||||||
*/
|
*/
|
||||||
public void addChildren(Insets offsets, Node... nodes) {
|
public void addChildren(Insets offset, Node... nodes) {
|
||||||
for (var node : nodes) {
|
for (var node : nodes) {
|
||||||
AnchorPane.setTopAnchor(node, offsets.getTop());
|
AnchorPane.setTopAnchor(node, offset.getTop());
|
||||||
AnchorPane.setRightAnchor(node, offsets.getRight());
|
AnchorPane.setRightAnchor(node, offset.getRight());
|
||||||
AnchorPane.setBottomAnchor(node, offsets.getBottom());
|
AnchorPane.setBottomAnchor(node, offset.getBottom());
|
||||||
AnchorPane.setLeftAnchor(node, offsets.getLeft());
|
AnchorPane.setLeftAnchor(node, offset.getLeft());
|
||||||
}
|
}
|
||||||
getChildren().addAll(nodes);
|
getChildren().addAll(nodes);
|
||||||
}
|
}
|
||||||
@ -138,6 +151,8 @@ public class DeckPane extends AnchorPane {
|
|||||||
* Places target node on the top of the pane while playing the
|
* Places target node on the top of the pane while playing the
|
||||||
* swipe transition from bottom to top. If the pane doesn't contain
|
* swipe transition from bottom to top. If the pane doesn't contain
|
||||||
* that node, it will be added to the end before playing transition.
|
* that node, it will be added to the end before playing transition.
|
||||||
|
*
|
||||||
|
* @param target The node to be set on top.
|
||||||
*/
|
*/
|
||||||
public void swipeUp(Node target) {
|
public void swipeUp(Node target) {
|
||||||
var topNode = getTopNode();
|
var topNode = getTopNode();
|
||||||
@ -164,6 +179,8 @@ public class DeckPane extends AnchorPane {
|
|||||||
* Places target node on the top of the pane while playing the
|
* Places target node on the top of the pane while playing the
|
||||||
* swipe transition from top to bottom. If the pane doesn't contain
|
* swipe transition from top to bottom. If the pane doesn't contain
|
||||||
* that node, it will be added to the end before playing transition.
|
* that node, it will be added to the end before playing transition.
|
||||||
|
*
|
||||||
|
* @param target The node to be set on top.
|
||||||
*/
|
*/
|
||||||
public void swipeDown(Node target) {
|
public void swipeDown(Node target) {
|
||||||
var topNode = getTopNode();
|
var topNode = getTopNode();
|
||||||
@ -190,6 +207,8 @@ public class DeckPane extends AnchorPane {
|
|||||||
* Places target node on the top of the pane while playing the
|
* Places target node on the top of the pane while playing the
|
||||||
* swipe transition from right to left. If the pane doesn't contain
|
* swipe transition from right to left. If the pane doesn't contain
|
||||||
* that node, it will be added to the end before playing transition.
|
* that node, it will be added to the end before playing transition.
|
||||||
|
*
|
||||||
|
* @param target The node to be set on top.
|
||||||
*/
|
*/
|
||||||
public void swipeLeft(Node target) {
|
public void swipeLeft(Node target) {
|
||||||
var topNode = getTopNode();
|
var topNode = getTopNode();
|
||||||
@ -216,6 +235,8 @@ public class DeckPane extends AnchorPane {
|
|||||||
* Places target node on the top of the pane while playing the
|
* Places target node on the top of the pane while playing the
|
||||||
* swipe transition from left to right. If the pane doesn't contain
|
* swipe transition from left to right. If the pane doesn't contain
|
||||||
* that node, it will be added to the end before playing transition.
|
* that node, it will be added to the end before playing transition.
|
||||||
|
*
|
||||||
|
* @param target The node to be set on top.
|
||||||
*/
|
*/
|
||||||
public void swipeRight(Node target) {
|
public void swipeRight(Node target) {
|
||||||
var topNode = getTopNode();
|
var topNode = getTopNode();
|
||||||
@ -242,6 +263,8 @@ public class DeckPane extends AnchorPane {
|
|||||||
* Places target node on the top of the pane while playing the
|
* Places target node on the top of the pane while playing the
|
||||||
* slide transition from bottom to top. If the pane doesn't contain
|
* slide transition from bottom to top. If the pane doesn't contain
|
||||||
* that node, it will be added to the end before playing transition.
|
* that node, it will be added to the end before playing transition.
|
||||||
|
*
|
||||||
|
* @param target The node to be set on top.
|
||||||
*/
|
*/
|
||||||
public void slideUp(Node target) {
|
public void slideUp(Node target) {
|
||||||
var topNode = getTopNode();
|
var topNode = getTopNode();
|
||||||
@ -265,6 +288,8 @@ public class DeckPane extends AnchorPane {
|
|||||||
* Places target node on the top of the pane while playing the
|
* Places target node on the top of the pane while playing the
|
||||||
* slide transition from top to bottom. If the pane doesn't contain
|
* slide transition from top to bottom. If the pane doesn't contain
|
||||||
* that node, it will be added to the end before playing transition.
|
* that node, it will be added to the end before playing transition.
|
||||||
|
*
|
||||||
|
* @param target The node to be set on top.
|
||||||
*/
|
*/
|
||||||
public void slideDown(Node target) {
|
public void slideDown(Node target) {
|
||||||
var topNode = getTopNode();
|
var topNode = getTopNode();
|
||||||
@ -288,6 +313,8 @@ public class DeckPane extends AnchorPane {
|
|||||||
* Places target node on the top of the pane while playing the
|
* Places target node on the top of the pane while playing the
|
||||||
* slide transition from right to left. If the pane doesn't contain
|
* slide transition from right to left. If the pane doesn't contain
|
||||||
* that node, it will be added to the end before playing transition.
|
* that node, it will be added to the end before playing transition.
|
||||||
|
*
|
||||||
|
* @param target The node to be set on top.
|
||||||
*/
|
*/
|
||||||
public void slideLeft(Node target) {
|
public void slideLeft(Node target) {
|
||||||
var topNode = getTopNode();
|
var topNode = getTopNode();
|
||||||
@ -311,6 +338,8 @@ public class DeckPane extends AnchorPane {
|
|||||||
* Places target node on the top of the pane while playing the
|
* Places target node on the top of the pane while playing the
|
||||||
* slide transition from left to right. If the pane doesn't contain
|
* slide transition from left to right. If the pane doesn't contain
|
||||||
* that node, it will be added to the end before playing transition.
|
* that node, it will be added to the end before playing transition.
|
||||||
|
*
|
||||||
|
* @param target The node to be set on top.
|
||||||
*/
|
*/
|
||||||
public void slideRight(Node target) {
|
public void slideRight(Node target) {
|
||||||
var topNode = getTopNode();
|
var topNode = getTopNode();
|
||||||
@ -334,6 +363,13 @@ public class DeckPane extends AnchorPane {
|
|||||||
// Properties //
|
// Properties //
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the duration of the transition effect that is played when changing the top node.
|
||||||
|
*/
|
||||||
|
public ObjectProperty<Duration> animationDurationProperty() {
|
||||||
|
return animationDuration;
|
||||||
|
}
|
||||||
|
|
||||||
protected final ObjectProperty<Duration> animationDuration =
|
protected final ObjectProperty<Duration> animationDuration =
|
||||||
new SimpleObjectProperty<>(this, "animationDuration", Duration.seconds(1));
|
new SimpleObjectProperty<>(this, "animationDuration", Duration.seconds(1));
|
||||||
|
|
||||||
@ -341,18 +377,17 @@ public class DeckPane extends AnchorPane {
|
|||||||
return animationDuration.get();
|
return animationDuration.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Duration of the transition effect which is played when changing the top node.
|
|
||||||
*/
|
|
||||||
public ObjectProperty<Duration> animationDurationProperty() {
|
|
||||||
return animationDuration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAnimationDuration(@Nullable Duration animationDuration) {
|
public void setAnimationDuration(@Nullable Duration animationDuration) {
|
||||||
this.animationDuration.set(Objects.requireNonNullElse(animationDuration, Duration.ZERO));
|
this.animationDuration.set(Objects.requireNonNullElse(animationDuration, Duration.ZERO));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ~
|
/**
|
||||||
|
* Indicates whether the transition is in progress. Subscribe to this property
|
||||||
|
* to be notified when the animation starts or finishes.
|
||||||
|
*/
|
||||||
|
public ReadOnlyBooleanProperty animationActiveProperty() {
|
||||||
|
return animationActive.getReadOnlyProperty();
|
||||||
|
}
|
||||||
|
|
||||||
protected final ReadOnlyBooleanWrapper animationActive =
|
protected final ReadOnlyBooleanWrapper animationActive =
|
||||||
new ReadOnlyBooleanWrapper(this, "animationActive");
|
new ReadOnlyBooleanWrapper(this, "animationActive");
|
||||||
@ -361,19 +396,16 @@ public class DeckPane extends AnchorPane {
|
|||||||
return animationActive.get();
|
return animationActive.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether transition is in progress. Subscribe to be notified
|
|
||||||
* when animation started or finished.
|
|
||||||
*/
|
|
||||||
public ReadOnlyBooleanProperty animationActiveProperty() {
|
|
||||||
return animationActive.getReadOnlyProperty();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setAnimationActive(boolean animationActive) {
|
protected void setAnimationActive(boolean animationActive) {
|
||||||
this.animationActive.set(animationActive);
|
this.animationActive.set(animationActive);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ~
|
/**
|
||||||
|
* Sets the callback action to be called before setting a node at the top of the DeckPane.
|
||||||
|
*/
|
||||||
|
public ObjectProperty<Consumer<Node>> beforeShowCallbackProperty() {
|
||||||
|
return beforeShowCallback;
|
||||||
|
}
|
||||||
|
|
||||||
protected final ObjectProperty<Consumer<Node>> beforeShowCallback =
|
protected final ObjectProperty<Consumer<Node>> beforeShowCallback =
|
||||||
new SimpleObjectProperty<>(this, "beforeShowCallback");
|
new SimpleObjectProperty<>(this, "beforeShowCallback");
|
||||||
@ -382,13 +414,6 @@ public class DeckPane extends AnchorPane {
|
|||||||
return beforeShowCallback.get();
|
return beforeShowCallback.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback action to be called before setting a node at the top of the deck.
|
|
||||||
*/
|
|
||||||
public ObjectProperty<Consumer<Node>> beforeShowCallbackProperty() {
|
|
||||||
return beforeShowCallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBeforeShowCallback(@Nullable Consumer<Node> callback) {
|
public void setBeforeShowCallback(@Nullable Consumer<Node> callback) {
|
||||||
this.beforeShowCallback.set(callback);
|
this.beforeShowCallback.set(callback);
|
||||||
}
|
}
|
||||||
@ -399,7 +424,12 @@ public class DeckPane extends AnchorPane {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ~
|
/**
|
||||||
|
* Sets the callback action to be called after removing the top node from the top of the DeckPane.
|
||||||
|
*/
|
||||||
|
public ObjectProperty<Consumer<Node>> afterHideCallbackProperty() {
|
||||||
|
return afterHideCallback;
|
||||||
|
}
|
||||||
|
|
||||||
protected final ObjectProperty<Consumer<Node>> afterHideCallback =
|
protected final ObjectProperty<Consumer<Node>> afterHideCallback =
|
||||||
new SimpleObjectProperty<>(this, "afterHideCallback");
|
new SimpleObjectProperty<>(this, "afterHideCallback");
|
||||||
@ -408,13 +438,6 @@ public class DeckPane extends AnchorPane {
|
|||||||
return afterHideCallback.get();
|
return afterHideCallback.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback action to be called after removing the top node from the top of the deck.
|
|
||||||
*/
|
|
||||||
public ObjectProperty<Consumer<Node>> afterHideCallbackProperty() {
|
|
||||||
return afterHideCallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAfterHideCallback(@Nullable Consumer<Node> callback) {
|
public void setAfterHideCallback(@Nullable Consumer<Node> callback) {
|
||||||
this.afterHideCallback.set(callback);
|
this.afterHideCallback.set(callback);
|
||||||
}
|
}
|
||||||
|
@ -9,16 +9,18 @@ import javafx.scene.Node;
|
|||||||
import javafx.scene.layout.HBox;
|
import javafx.scene.layout.HBox;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* InputGroup is a layout that helps combine multiple controls into a group
|
* A layout that helps combine multiple controls into a group that looks
|
||||||
* that looks like a single control. Without it, you would have to manually
|
* like a single control.
|
||||||
* add the "left-pill", "center-pill," and "right-pill" styles classes to
|
*
|
||||||
* each control in such combination. The InputGroup removes this ceremony.
|
* <p>Without it, you would have to manually add the ".left-pill", ".center-pill"
|
||||||
* Since it inherits from HBox, you can use the same API.
|
* and ".right-pill" styles classes to each control in such combination.
|
||||||
|
* The InputGroup removes this ceremony. Since it inherits from HBox, you can use
|
||||||
|
* the same API.
|
||||||
*/
|
*/
|
||||||
public class InputGroup extends HBox {
|
public class InputGroup extends HBox {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See {@link HBox#HBox()}.
|
* Creates a new empty InputGroup.
|
||||||
*/
|
*/
|
||||||
public InputGroup() {
|
public InputGroup() {
|
||||||
super();
|
super();
|
||||||
@ -26,7 +28,9 @@ public class InputGroup extends HBox {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See {@link HBox#HBox(Node...)}.
|
* Creates an InputGroup with the given children.
|
||||||
|
*
|
||||||
|
* @param children The initial set of children for this pane.
|
||||||
*/
|
*/
|
||||||
public InputGroup(Node... children) {
|
public InputGroup(Node... children) {
|
||||||
super(children);
|
super(children);
|
||||||
|
@ -17,11 +17,12 @@ import javafx.scene.layout.StackPane;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The ModalBox is a specialized control or layout designed to hold the
|
* A specialized control (or layout) designed to hold the {@link ModalPane}
|
||||||
* {@link ModalPane} dialog content. It includes the close button out-of-the-box
|
* dialog content. It includes the close button out-of-the-box and allows for the
|
||||||
* and allows for the addition of arbitrary children. The ModalBox is derived
|
* addition of arbitrary children.
|
||||||
* from the {@link AnchorPane}, so it inherits the same API. Just be sure that
|
*
|
||||||
* you haven't removed the close button while using it.
|
* <p>The ModalBox is derived from the {@link AnchorPane}, so it inherits the same API.
|
||||||
|
* Just be sure that you haven't removed the close button while using it.
|
||||||
*/
|
*/
|
||||||
public class ModalBox extends AnchorPane {
|
public class ModalBox extends AnchorPane {
|
||||||
|
|
||||||
@ -40,7 +41,7 @@ public class ModalBox extends AnchorPane {
|
|||||||
/**
|
/**
|
||||||
* Creates a ModalBox layout with the given children.
|
* Creates a ModalBox layout with the given children.
|
||||||
*
|
*
|
||||||
* @param children the initial set of children for this pane
|
* @param children The initial set of children for this pane.
|
||||||
*/
|
*/
|
||||||
public ModalBox(Node... children) {
|
public ModalBox(Node... children) {
|
||||||
this((String) null, children);
|
this((String) null, children);
|
||||||
@ -52,8 +53,8 @@ public class ModalBox extends AnchorPane {
|
|||||||
* on the close button, it performs a ModalPane lookup via the specified
|
* on the close button, it performs a ModalPane lookup via the specified
|
||||||
* selector and calls the {@link ModalPane#hide()} method automatically.
|
* selector and calls the {@link ModalPane#hide()} method automatically.
|
||||||
*
|
*
|
||||||
* @param selector the ModalPane pane CSS selector
|
* @param selector The ModalPane pane CSS selector.
|
||||||
* @param children the initial set of children for this pane
|
* @param children The initial set of children for this pane.
|
||||||
*/
|
*/
|
||||||
public ModalBox(@Nullable @NamedArg("selector") String selector, Node... children) {
|
public ModalBox(@Nullable @NamedArg("selector") String selector, Node... children) {
|
||||||
super(children);
|
super(children);
|
||||||
@ -69,8 +70,8 @@ public class ModalBox extends AnchorPane {
|
|||||||
* the close handler to a ModalPane. When user clicks on the close button,
|
* the close handler to a ModalPane. When user clicks on the close button,
|
||||||
* it calls the {@link ModalPane#hide()} method automatically.
|
* it calls the {@link ModalPane#hide()} method automatically.
|
||||||
*
|
*
|
||||||
* @param modalPane the ModalPane pane CSS selector
|
* @param modalPane The ModalPane pane CSS selector.
|
||||||
* @param children the initial set of children for this pane
|
* @param children The initial set of children for this pane.
|
||||||
*/
|
*/
|
||||||
public ModalBox(@Nullable ModalPane modalPane, Node... children) {
|
public ModalBox(@Nullable ModalPane modalPane, Node... children) {
|
||||||
super(children);
|
super(children);
|
||||||
@ -88,7 +89,7 @@ public class ModalBox extends AnchorPane {
|
|||||||
* and {@link Node#isMouseTransparent()} is false, then the close button
|
* and {@link Node#isMouseTransparent()} is false, then the close button
|
||||||
* will not receive mouse events and therefore will not be clickable.
|
* will not receive mouse events and therefore will not be clickable.
|
||||||
*
|
*
|
||||||
* @param node the node to be added
|
* @param node The node to be added.
|
||||||
*/
|
*/
|
||||||
public void addContent(Node node) {
|
public void addContent(Node node) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null.");
|
Objects.requireNonNull(node, "Node cannot be null.");
|
||||||
@ -142,11 +143,16 @@ public class ModalBox extends AnchorPane {
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The property representing the user specified close handler. Note that
|
* The property representing the user specified close handler.
|
||||||
* if you have also specified the ModalPane instance or CSS selector, this
|
*
|
||||||
* handler will be executed after the default close handler. Therefore, you
|
* <p>Note that if you have also specified the ModalPane instance or CSS selector,
|
||||||
|
* this handler will be executed after the default close handler. Therefore, you
|
||||||
* can use it to perform arbitrary actions on dialog close.
|
* can use it to perform arbitrary actions on dialog close.
|
||||||
*/
|
*/
|
||||||
|
public ObjectProperty<EventHandler<? super Event>> onCloseProperty() {
|
||||||
|
return onClose;
|
||||||
|
}
|
||||||
|
|
||||||
protected final ObjectProperty<EventHandler<? super Event>> onClose =
|
protected final ObjectProperty<EventHandler<? super Event>> onClose =
|
||||||
new SimpleObjectProperty<>(this, "onClose");
|
new SimpleObjectProperty<>(this, "onClose");
|
||||||
|
|
||||||
@ -154,27 +160,25 @@ public class ModalBox extends AnchorPane {
|
|||||||
return onClose.get();
|
return onClose.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObjectProperty<EventHandler<? super Event>> onCloseProperty() {
|
|
||||||
return onClose;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOnClose(EventHandler<? super Event> onClose) {
|
public void setOnClose(EventHandler<? super Event> onClose) {
|
||||||
this.onClose.set(onClose);
|
this.onClose.set(onClose);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See {@link ModalPane#hide(boolean)}.
|
* Specifies whether to remove (clear) the ModalPane content after it's closed.
|
||||||
|
*
|
||||||
|
* @see ModalPane#hide(boolean).
|
||||||
*/
|
*/
|
||||||
|
public BooleanProperty clearOnCloseProperty() {
|
||||||
|
return clearOnClose;
|
||||||
|
}
|
||||||
|
|
||||||
protected final BooleanProperty clearOnClose = new SimpleBooleanProperty(this, "clearOnClose");
|
protected final BooleanProperty clearOnClose = new SimpleBooleanProperty(this, "clearOnClose");
|
||||||
|
|
||||||
public boolean isClearOnClose() {
|
public boolean isClearOnClose() {
|
||||||
return clearOnClose.get();
|
return clearOnClose.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public BooleanProperty clearOnCloseProperty() {
|
|
||||||
return clearOnClose;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setClearOnClose(boolean clearOnClose) {
|
public void setClearOnClose(boolean clearOnClose) {
|
||||||
this.clearOnClose.set(clearOnClose);
|
this.clearOnClose.set(clearOnClose);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
/**
|
||||||
|
* Defines additional layouts and layout helpers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package atlantafx.base.layout;
|
@ -11,8 +11,8 @@ import javafx.scene.Node;
|
|||||||
import javafx.scene.control.TabPane;
|
import javafx.scene.control.TabPane;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A set of constants and utility methods that simplifies adding
|
* A set of constants and utility methods that simplifies adding CSS
|
||||||
* CSS classes programmatically.
|
* classes programmatically.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public final class Styles {
|
public final class Styles {
|
||||||
@ -132,11 +132,11 @@ public final class Styles {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds given style class to the node if it's not present, otherwise
|
* Adds the given style class to the node if it's not present,
|
||||||
* removes it.
|
* otherwise removes it.
|
||||||
*
|
*
|
||||||
* @param node the target node
|
* @param node The target node.
|
||||||
* @param styleClass the style class to be toggled
|
* @param styleClass The style class to be toggled.
|
||||||
* @throws NullPointerException if node or style class is null
|
* @throws NullPointerException if node or style class is null
|
||||||
*/
|
*/
|
||||||
public static void toggleStyleClass(Node node, String styleClass) {
|
public static void toggleStyleClass(Node node, String styleClass) {
|
||||||
@ -156,13 +156,13 @@ public final class Styles {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds given style class to the node and removes the excluded classes.
|
* Adds the given style class to the node and removes the excluded classes.
|
||||||
* This method is supposed to be used when only one from a set of classes
|
* This method is supposed to be used when only one from a set of classes
|
||||||
* have to be present at once.
|
* have to be present at once.
|
||||||
*
|
*
|
||||||
* @param node the target node
|
* @param node The target node.
|
||||||
* @param styleClass the style class to be toggled
|
* @param styleClass The style class to be toggled.
|
||||||
* @param excludes the style classes to be excluded
|
* @param excludes The style classes to be excluded.
|
||||||
* @throws NullPointerException if node or styleClass is null
|
* @throws NullPointerException if node or styleClass is null
|
||||||
*/
|
*/
|
||||||
public static void addStyleClass(Node node, String styleClass, String... excludes) {
|
public static void addStyleClass(Node node, String styleClass, String... excludes) {
|
||||||
@ -187,9 +187,9 @@ public final class Styles {
|
|||||||
* This method is supposed to be used when only one from a set of pseudo-classes
|
* This method is supposed to be used when only one from a set of pseudo-classes
|
||||||
* have to be present at once.
|
* have to be present at once.
|
||||||
*
|
*
|
||||||
* @param node the node to activate the pseudo-class on
|
* @param node The node to activate the pseudo-class on.
|
||||||
* @param pseudoClass the pseudo-class to be activated
|
* @param pseudoClass The pseudo-class to be activated.
|
||||||
* @param excludes the pseudo-classes to be deactivated
|
* @param excludes The pseudo-classes to be deactivated.
|
||||||
* @throws NullPointerException if node or pseudo-class is null
|
* @throws NullPointerException if node or pseudo-class is null
|
||||||
*/
|
*/
|
||||||
public static void activatePseudoClass(Node node, PseudoClass pseudoClass, PseudoClass... excludes) {
|
public static void activatePseudoClass(Node node, PseudoClass pseudoClass, PseudoClass... excludes) {
|
||||||
@ -213,9 +213,9 @@ public final class Styles {
|
|||||||
* There's no check for duplicates, so the CSS declarations with the same property
|
* There's no check for duplicates, so the CSS declarations with the same property
|
||||||
* name can be appended multiple times.
|
* name can be appended multiple times.
|
||||||
*
|
*
|
||||||
* @param node the node to append the new style declaration
|
* @param node The node to append the new style declaration.
|
||||||
* @param prop CSS property name
|
* @param prop The CSS property name.
|
||||||
* @param value CSS property value
|
* @param value The CSS property value.
|
||||||
* @throws NullPointerException if node is null
|
* @throws NullPointerException if node is null
|
||||||
*/
|
*/
|
||||||
public static void appendStyle(Node node, String prop, String value) {
|
public static void appendStyle(Node node, String prop, String value) {
|
||||||
@ -239,8 +239,8 @@ public final class Styles {
|
|||||||
/**
|
/**
|
||||||
* Removes the specified CSS style declaration from the specified node.
|
* Removes the specified CSS style declaration from the specified node.
|
||||||
*
|
*
|
||||||
* @param node the node to remove the style from
|
* @param node The node to remove the style from.
|
||||||
* @param prop the name of the style property to remove
|
* @param prop The name of the style property to remove.
|
||||||
* @throws NullPointerException if node is null
|
* @throws NullPointerException if node is null
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("StringSplitter")
|
@SuppressWarnings("StringSplitter")
|
||||||
@ -284,8 +284,8 @@ public final class Styles {
|
|||||||
* node.getStylesheets().remove(dataUri);
|
* node.getStylesheets().remove(dataUri);
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @param css the CSS string to encode
|
* @param css The CSS string to encode.
|
||||||
* @return the resulting data URI string
|
* @return The resulting data URI string.
|
||||||
*/
|
*/
|
||||||
public static String toDataURI(String css) {
|
public static String toDataURI(String css) {
|
||||||
if (css == null) {
|
if (css == null) {
|
||||||
|
@ -9,7 +9,7 @@ import javafx.application.Application;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic theme interface.
|
* The basic theme interface.
|
||||||
*/
|
*/
|
||||||
public interface Theme {
|
public interface Theme {
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ public interface Theme {
|
|||||||
boolean isDarkMode();
|
boolean isDarkMode();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple factory method for instantiating a new theme.
|
* A simple factory method for instantiating a new theme.
|
||||||
*/
|
*/
|
||||||
static Theme of(final String name, final String userAgentStylesheet, final boolean darkMode) {
|
static Theme of(final String name, final String userAgentStylesheet, final boolean darkMode) {
|
||||||
if (name == null) {
|
if (name == null) {
|
||||||
|
@ -11,10 +11,21 @@ import java.util.stream.Stream;
|
|||||||
import javafx.css.Stylesheet;
|
import javafx.css.Stylesheet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lazy man CSS to BSS compiler wrapper.
|
* A lazy man CSS to BSS compiler wrapper.
|
||||||
*/
|
*/
|
||||||
public class ThemeCompiler {
|
public class ThemeCompiler {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The main class that accepts exactly one parameter, which is the path to
|
||||||
|
* the source directory to be scanned for CSS files.
|
||||||
|
*
|
||||||
|
* <p>Usage:
|
||||||
|
* <pre>{@code
|
||||||
|
* java ThemeCompiler <path>
|
||||||
|
* }</pre>
|
||||||
|
*
|
||||||
|
* @see #convertToBinary(Path)
|
||||||
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
try {
|
try {
|
||||||
if (args.length < 1) {
|
if (args.length < 1) {
|
||||||
@ -38,7 +49,7 @@ public class ThemeCompiler {
|
|||||||
/**
|
/**
|
||||||
* Converts all CSS files in the specified directory to BSS.
|
* Converts all CSS files in the specified directory to BSS.
|
||||||
*
|
*
|
||||||
* @param dir the source directory to scan for CSS files
|
* @param dir The source directory to scan for CSS files.
|
||||||
* @throws IOException to punish you for using Java
|
* @throws IOException to punish you for using Java
|
||||||
*/
|
*/
|
||||||
public void convertToBinary(Path dir) throws IOException {
|
public void convertToBinary(Path dir) throws IOException {
|
||||||
@ -62,8 +73,8 @@ public class ThemeCompiler {
|
|||||||
* Converts the specified CSS file to BSS. If no output file is given,
|
* Converts the specified CSS file to BSS. If no output file is given,
|
||||||
* then the input file name is used with an extension of 'bss'.
|
* then the input file name is used with an extension of 'bss'.
|
||||||
*
|
*
|
||||||
* @param in input file path
|
* @param in The input file path.
|
||||||
* @param out output file path
|
* @param out The output file path.
|
||||||
* @throws IOException to punish you for using Java
|
* @throws IOException to punish you for using Java
|
||||||
*/
|
*/
|
||||||
public void convertToBinary(Path in, Path out) throws IOException {
|
public void convertToBinary(Path in, Path out) throws IOException {
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
package atlantafx.base.theme;
|
package atlantafx.base.theme;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains extra style class names introduced to tweak some controls view if and where it makes sense.
|
* Contains extra style class names introduced to tweak some controls view
|
||||||
* The reason of supporting tweaks is to allow users to write less CSS code. Search for #tweak/classname
|
* if and where it makes sense. The reason of supporting tweaks is to allow
|
||||||
* to find the controls supporting tweaks or check the control page in the Sampler app.
|
* users to write less CSS code.
|
||||||
*/
|
*/
|
||||||
public final class Tweaks {
|
public final class Tweaks {
|
||||||
|
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
/**
|
||||||
|
* Contains provided themes and style constants.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package atlantafx.base.theme;
|
@ -38,7 +38,7 @@ public final class Animations {
|
|||||||
* Changes the node opacity to full transparency and then back to its
|
* Changes the node opacity to full transparency and then back to its
|
||||||
* original opacity in quick succession, creating a flashing effect.
|
* original opacity in quick succession, creating a flashing effect.
|
||||||
*
|
*
|
||||||
* @param node the node to be animated
|
* @param node The node to be animated.
|
||||||
*/
|
*/
|
||||||
public static Timeline flash(Node node) {
|
public static Timeline flash(Node node) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null!");
|
Objects.requireNonNull(node, "Node cannot be null!");
|
||||||
@ -81,8 +81,8 @@ public final class Animations {
|
|||||||
* Repeatedly increases and decreases the scale of the node,
|
* Repeatedly increases and decreases the scale of the node,
|
||||||
* giving it a pulsating effect that draws attention to it.
|
* giving it a pulsating effect that draws attention to it.
|
||||||
*
|
*
|
||||||
* @param node the node to be animated
|
* @param node The node to be animated.
|
||||||
* @param scale the scale factor
|
* @param scale The scale factor.
|
||||||
*/
|
*/
|
||||||
public static Timeline pulse(Node node, double scale) {
|
public static Timeline pulse(Node node, double scale) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null!");
|
Objects.requireNonNull(node, "Node cannot be null!");
|
||||||
@ -127,8 +127,8 @@ public final class Animations {
|
|||||||
* Rapidly moves the node from side-to-side horizontally,
|
* Rapidly moves the node from side-to-side horizontally,
|
||||||
* creating a shaking or vibrating effect.
|
* creating a shaking or vibrating effect.
|
||||||
*
|
*
|
||||||
* @param node the node to be animated
|
* @param node The node to be animated.
|
||||||
* @param offset the shake offset
|
* @param offset The shake offset.
|
||||||
*/
|
*/
|
||||||
public static Timeline shakeX(Node node, double offset) {
|
public static Timeline shakeX(Node node, double offset) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null!");
|
Objects.requireNonNull(node, "Node cannot be null!");
|
||||||
@ -186,8 +186,8 @@ public final class Animations {
|
|||||||
* Rapidly moves the node up and down vertically, creating
|
* Rapidly moves the node up and down vertically, creating
|
||||||
* a shaking or bouncing effect.
|
* a shaking or bouncing effect.
|
||||||
*
|
*
|
||||||
* @param node the node to be animated
|
* @param node The node to be animated.
|
||||||
* @param offset the shake offset
|
* @param offset The shake offset.
|
||||||
*/
|
*/
|
||||||
public static Timeline shakeY(Node node, double offset) {
|
public static Timeline shakeY(Node node, double offset) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null!");
|
Objects.requireNonNull(node, "Node cannot be null!");
|
||||||
@ -241,7 +241,7 @@ public final class Animations {
|
|||||||
* Causes the node to rapidly wobble back and forth,
|
* Causes the node to rapidly wobble back and forth,
|
||||||
* creating a visually engaging effect.
|
* creating a visually engaging effect.
|
||||||
*
|
*
|
||||||
* @param node the node to be animated
|
* @param node The node to be animated.
|
||||||
*/
|
*/
|
||||||
public static Timeline wobble(Node node) {
|
public static Timeline wobble(Node node) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null!");
|
Objects.requireNonNull(node, "Node cannot be null!");
|
||||||
@ -295,8 +295,8 @@ public final class Animations {
|
|||||||
* Gradually increases the opacity of the node from 0 to 1,
|
* Gradually increases the opacity of the node from 0 to 1,
|
||||||
* making it appear on the scene with a fading-in effect.
|
* making it appear on the scene with a fading-in effect.
|
||||||
*
|
*
|
||||||
* @param node the node to be animated
|
* @param node The node to be animated.
|
||||||
* @param duration the animation duration
|
* @param duration The animation duration.
|
||||||
*/
|
*/
|
||||||
public static Timeline fadeIn(Node node, Duration duration) {
|
public static Timeline fadeIn(Node node, Duration duration) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null!");
|
Objects.requireNonNull(node, "Node cannot be null!");
|
||||||
@ -324,8 +324,8 @@ public final class Animations {
|
|||||||
* Gradually decreases the opacity of the node from 1 to 0,
|
* Gradually decreases the opacity of the node from 1 to 0,
|
||||||
* making it disappear from the scene with a fading-out effect.
|
* making it disappear from the scene with a fading-out effect.
|
||||||
*
|
*
|
||||||
* @param node the node to be animated
|
* @param node The node to be animated.
|
||||||
* @param duration the animation duration
|
* @param duration The animation duration.
|
||||||
*/
|
*/
|
||||||
public static Timeline fadeOut(Node node, Duration duration) {
|
public static Timeline fadeOut(Node node, Duration duration) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null!");
|
Objects.requireNonNull(node, "Node cannot be null!");
|
||||||
@ -353,8 +353,8 @@ public final class Animations {
|
|||||||
* Combines the {@link #fadeIn(Node, Duration)} effect with the node’s downward
|
* Combines the {@link #fadeIn(Node, Duration)} effect with the node’s downward
|
||||||
* movement, creating an animated entrance of the node from the top.
|
* movement, creating an animated entrance of the node from the top.
|
||||||
*
|
*
|
||||||
* @param node the node to be animated
|
* @param node The node to be animated.
|
||||||
* @param duration the animation duration
|
* @param duration The animation duration.
|
||||||
*/
|
*/
|
||||||
public static Timeline fadeInDown(Node node, Duration duration) {
|
public static Timeline fadeInDown(Node node, Duration duration) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null!");
|
Objects.requireNonNull(node, "Node cannot be null!");
|
||||||
@ -386,8 +386,8 @@ public final class Animations {
|
|||||||
* Combines the {@link #fadeOut(Node, Duration)} effect with the node’s downward
|
* Combines the {@link #fadeOut(Node, Duration)} effect with the node’s downward
|
||||||
* movement, creating an animated exit of the node to the bottom.
|
* movement, creating an animated exit of the node to the bottom.
|
||||||
*
|
*
|
||||||
* @param node the node to be animated
|
* @param node The node to be animated.
|
||||||
* @param duration the animation duration
|
* @param duration The animation duration.
|
||||||
*/
|
*/
|
||||||
public static Timeline fadeOutDown(Node node, Duration duration) {
|
public static Timeline fadeOutDown(Node node, Duration duration) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null!");
|
Objects.requireNonNull(node, "Node cannot be null!");
|
||||||
@ -418,8 +418,8 @@ public final class Animations {
|
|||||||
* Combines the {@link #fadeIn(Node, Duration)} effect with the node’s leftward
|
* Combines the {@link #fadeIn(Node, Duration)} effect with the node’s leftward
|
||||||
* movement, creating an animated entrance of the node from the left.
|
* movement, creating an animated entrance of the node from the left.
|
||||||
*
|
*
|
||||||
* @param node the node to be animated
|
* @param node The node to be animated.
|
||||||
* @param duration the animation duration
|
* @param duration The animation duration.
|
||||||
*/
|
*/
|
||||||
public static Timeline fadeInLeft(Node node, Duration duration) {
|
public static Timeline fadeInLeft(Node node, Duration duration) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null!");
|
Objects.requireNonNull(node, "Node cannot be null!");
|
||||||
@ -450,8 +450,8 @@ public final class Animations {
|
|||||||
* Combines the {@link #fadeOut(Node, Duration)} effect with the node’s leftward
|
* Combines the {@link #fadeOut(Node, Duration)} effect with the node’s leftward
|
||||||
* movement, creating an animated exit of the node to the left.
|
* movement, creating an animated exit of the node to the left.
|
||||||
*
|
*
|
||||||
* @param node the node to be animated
|
* @param node The node to be animated.
|
||||||
* @param duration the animation duration
|
* @param duration The animation duration.
|
||||||
*/
|
*/
|
||||||
public static Timeline fadeOutLeft(Node node, Duration duration) {
|
public static Timeline fadeOutLeft(Node node, Duration duration) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null!");
|
Objects.requireNonNull(node, "Node cannot be null!");
|
||||||
@ -482,8 +482,8 @@ public final class Animations {
|
|||||||
* Combines the {@link #fadeIn(Node, Duration)} effect with the node’s rightward
|
* Combines the {@link #fadeIn(Node, Duration)} effect with the node’s rightward
|
||||||
* movement, creating an animated entrance of the node from the right.
|
* movement, creating an animated entrance of the node from the right.
|
||||||
*
|
*
|
||||||
* @param node the node to be animated
|
* @param node The node to be animated.
|
||||||
* @param duration the animation duration
|
* @param duration The animation duration.
|
||||||
*/
|
*/
|
||||||
public static Timeline fadeInRight(Node node, Duration duration) {
|
public static Timeline fadeInRight(Node node, Duration duration) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null!");
|
Objects.requireNonNull(node, "Node cannot be null!");
|
||||||
@ -514,8 +514,8 @@ public final class Animations {
|
|||||||
* Combines the {@link #fadeOut(Node, Duration)} effect with the node’s rightward
|
* Combines the {@link #fadeOut(Node, Duration)} effect with the node’s rightward
|
||||||
* movement, creating an animated exit of the node to the right.
|
* movement, creating an animated exit of the node to the right.
|
||||||
*
|
*
|
||||||
* @param node the node to be animated
|
* @param node The node to be animated.
|
||||||
* @param duration the animation duration
|
* @param duration The animation duration.
|
||||||
*/
|
*/
|
||||||
public static Timeline fadeOutRight(Node node, Duration duration) {
|
public static Timeline fadeOutRight(Node node, Duration duration) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null!");
|
Objects.requireNonNull(node, "Node cannot be null!");
|
||||||
@ -546,8 +546,8 @@ public final class Animations {
|
|||||||
* Combines the {@link #fadeIn(Node, Duration)} effect with the node’s upward
|
* Combines the {@link #fadeIn(Node, Duration)} effect with the node’s upward
|
||||||
* movement, creating an animated entrance of the node from the bottom.
|
* movement, creating an animated entrance of the node from the bottom.
|
||||||
*
|
*
|
||||||
* @param node the node to be animated
|
* @param node The node to be animated.
|
||||||
* @param duration the animation duration
|
* @param duration The animation duration.
|
||||||
*/
|
*/
|
||||||
public static Timeline fadeInUp(Node node, Duration duration) {
|
public static Timeline fadeInUp(Node node, Duration duration) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null!");
|
Objects.requireNonNull(node, "Node cannot be null!");
|
||||||
@ -578,8 +578,8 @@ public final class Animations {
|
|||||||
* Combines the {@link #fadeOut(Node, Duration)} effect with the node’s upward
|
* Combines the {@link #fadeOut(Node, Duration)} effect with the node’s upward
|
||||||
* movement, creating an animated exit of the node to the top.
|
* movement, creating an animated exit of the node to the top.
|
||||||
*
|
*
|
||||||
* @param node the node to be animated
|
* @param node The node to be animated.
|
||||||
* @param duration the animation duration
|
* @param duration The animation duration.
|
||||||
*/
|
*/
|
||||||
public static Timeline fadeOutUp(Node node, Duration duration) {
|
public static Timeline fadeOutUp(Node node, Duration duration) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null!");
|
Objects.requireNonNull(node, "Node cannot be null!");
|
||||||
@ -614,8 +614,8 @@ public final class Animations {
|
|||||||
* Applies an animated effect to the node causing it to roll into
|
* Applies an animated effect to the node causing it to roll into
|
||||||
* the scene from the left side at an angle.
|
* the scene from the left side at an angle.
|
||||||
*
|
*
|
||||||
* @param node the node to be animated
|
* @param node The node to be animated.
|
||||||
* @param duration the animation duration
|
* @param duration The animation duration.
|
||||||
*/
|
*/
|
||||||
public static Timeline rollIn(Node node, Duration duration) {
|
public static Timeline rollIn(Node node, Duration duration) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null!");
|
Objects.requireNonNull(node, "Node cannot be null!");
|
||||||
@ -649,8 +649,8 @@ public final class Animations {
|
|||||||
* Applies an animated effect to the node causing it to roll out
|
* Applies an animated effect to the node causing it to roll out
|
||||||
* from the scene to the right side at an angle.
|
* from the scene to the right side at an angle.
|
||||||
*
|
*
|
||||||
* @param node the node to be animated
|
* @param node The node to be animated.
|
||||||
* @param duration the animation duration
|
* @param duration The animation duration.
|
||||||
*/
|
*/
|
||||||
public static Timeline rollOut(Node node, Duration duration) {
|
public static Timeline rollOut(Node node, Duration duration) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null!");
|
Objects.requireNonNull(node, "Node cannot be null!");
|
||||||
@ -688,8 +688,8 @@ public final class Animations {
|
|||||||
* Rotates the node and gradually increases its opacity,
|
* Rotates the node and gradually increases its opacity,
|
||||||
* giving it an animated entrance effect.
|
* giving it an animated entrance effect.
|
||||||
*
|
*
|
||||||
* @param node the node to be animated
|
* @param node The node to be animated.
|
||||||
* @param duration the animation duration
|
* @param duration The animation duration.
|
||||||
*/
|
*/
|
||||||
public static Timeline rotateIn(Node node, Duration duration) {
|
public static Timeline rotateIn(Node node, Duration duration) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null!");
|
Objects.requireNonNull(node, "Node cannot be null!");
|
||||||
@ -722,8 +722,8 @@ public final class Animations {
|
|||||||
* Rotates the node and gradually decreases its opacity,
|
* Rotates the node and gradually decreases its opacity,
|
||||||
* giving it an animated exit effect.
|
* giving it an animated exit effect.
|
||||||
*
|
*
|
||||||
* @param node the node to be animated
|
* @param node The node to be animated.
|
||||||
* @param duration the animation duration
|
* @param duration The animation duration.
|
||||||
*/
|
*/
|
||||||
public static Timeline rotateOut(Node node, Duration duration) {
|
public static Timeline rotateOut(Node node, Duration duration) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null!");
|
Objects.requireNonNull(node, "Node cannot be null!");
|
||||||
@ -757,8 +757,8 @@ public final class Animations {
|
|||||||
* movement from the left, creating an animated entrance of the node from the top
|
* movement from the left, creating an animated entrance of the node from the top
|
||||||
* left corner.
|
* left corner.
|
||||||
*
|
*
|
||||||
* @param node the node to be animated
|
* @param node The node to be animated.
|
||||||
* @param duration the animation duration
|
* @param duration The animation duration.
|
||||||
*/
|
*/
|
||||||
public static Timeline rotateInDownLeft(Node node, Duration duration) {
|
public static Timeline rotateInDownLeft(Node node, Duration duration) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null!");
|
Objects.requireNonNull(node, "Node cannot be null!");
|
||||||
@ -794,8 +794,8 @@ public final class Animations {
|
|||||||
* movement to the left, creating an animated exit of the node towards the bottom
|
* movement to the left, creating an animated exit of the node towards the bottom
|
||||||
* left corner.
|
* left corner.
|
||||||
*
|
*
|
||||||
* @param node the node to be animated
|
* @param node The node to be animated.
|
||||||
* @param duration the animation duration
|
* @param duration The animation duration.
|
||||||
*/
|
*/
|
||||||
public static Timeline rotateOutDownLeft(Node node, Duration duration) {
|
public static Timeline rotateOutDownLeft(Node node, Duration duration) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null!");
|
Objects.requireNonNull(node, "Node cannot be null!");
|
||||||
@ -831,8 +831,8 @@ public final class Animations {
|
|||||||
* movement from the right, creating an animated entrance of the node from the top
|
* movement from the right, creating an animated entrance of the node from the top
|
||||||
* right corner.
|
* right corner.
|
||||||
*
|
*
|
||||||
* @param node the node to be animated
|
* @param node The node to be animated.
|
||||||
* @param duration the animation duration
|
* @param duration The animation duration.
|
||||||
*/
|
*/
|
||||||
public static Timeline rotateInDownRight(Node node, Duration duration) {
|
public static Timeline rotateInDownRight(Node node, Duration duration) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null!");
|
Objects.requireNonNull(node, "Node cannot be null!");
|
||||||
@ -871,8 +871,8 @@ public final class Animations {
|
|||||||
* movement to the right, creating an animated exit of the node towards the bottom
|
* movement to the right, creating an animated exit of the node towards the bottom
|
||||||
* right corner.
|
* right corner.
|
||||||
*
|
*
|
||||||
* @param node the node to be animated
|
* @param node The node to be animated.
|
||||||
* @param duration the animation duration
|
* @param duration The animation duration.
|
||||||
*/
|
*/
|
||||||
public static Timeline rotateOutDownRight(Node node, Duration duration) {
|
public static Timeline rotateOutDownRight(Node node, Duration duration) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null!");
|
Objects.requireNonNull(node, "Node cannot be null!");
|
||||||
@ -911,8 +911,8 @@ public final class Animations {
|
|||||||
* movement from the left, creating an animated entrance of the node from the
|
* movement from the left, creating an animated entrance of the node from the
|
||||||
* bottom left corner.
|
* bottom left corner.
|
||||||
*
|
*
|
||||||
* @param node the node to be animated
|
* @param node The node to be animated.
|
||||||
* @param duration the animation duration
|
* @param duration The animation duration.
|
||||||
*/
|
*/
|
||||||
public static Timeline rotateInUpLeft(Node node, Duration duration) {
|
public static Timeline rotateInUpLeft(Node node, Duration duration) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null!");
|
Objects.requireNonNull(node, "Node cannot be null!");
|
||||||
@ -948,8 +948,8 @@ public final class Animations {
|
|||||||
* movement to the left, creating an animated exit of the node towards the top
|
* movement to the left, creating an animated exit of the node towards the top
|
||||||
* left corner.
|
* left corner.
|
||||||
*
|
*
|
||||||
* @param node the node to be animated
|
* @param node The node to be animated.
|
||||||
* @param duration the animation duration
|
* @param duration The animation duration.
|
||||||
*/
|
*/
|
||||||
public static Timeline rotateOutUpLeft(Node node, Duration duration) {
|
public static Timeline rotateOutUpLeft(Node node, Duration duration) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null!");
|
Objects.requireNonNull(node, "Node cannot be null!");
|
||||||
@ -985,8 +985,8 @@ public final class Animations {
|
|||||||
* movement from the right, creating an animated entrance of the node from the
|
* movement from the right, creating an animated entrance of the node from the
|
||||||
* bottom right corner.
|
* bottom right corner.
|
||||||
*
|
*
|
||||||
* @param node the node to be animated
|
* @param node The node to be animated.
|
||||||
* @param duration the animation duration
|
* @param duration The animation duration.
|
||||||
*/
|
*/
|
||||||
public static Timeline rotateInUpRight(Node node, Duration duration) {
|
public static Timeline rotateInUpRight(Node node, Duration duration) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null!");
|
Objects.requireNonNull(node, "Node cannot be null!");
|
||||||
@ -1025,8 +1025,8 @@ public final class Animations {
|
|||||||
* movement to the right, creating an animated exit of the node towards the top
|
* movement to the right, creating an animated exit of the node towards the top
|
||||||
* right corner.
|
* right corner.
|
||||||
*
|
*
|
||||||
* @param node the node to be animated
|
* @param node The node to be animated.
|
||||||
* @param duration the animation duration
|
* @param duration The animation duration.
|
||||||
*/
|
*/
|
||||||
public static Timeline rotateOutUpRight(Node node, Duration duration) {
|
public static Timeline rotateOutUpRight(Node node, Duration duration) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null!");
|
Objects.requireNonNull(node, "Node cannot be null!");
|
||||||
@ -1068,8 +1068,8 @@ public final class Animations {
|
|||||||
* Applies an animated effect to the node, causing it to slide into view
|
* Applies an animated effect to the node, causing it to slide into view
|
||||||
* from the top side.
|
* from the top side.
|
||||||
*
|
*
|
||||||
* @param node the node to be animated
|
* @param node The node to be animated.
|
||||||
* @param duration the animation duration
|
* @param duration The animation duration.
|
||||||
*/
|
*/
|
||||||
public static Timeline slideInDown(Node node, Duration duration) {
|
public static Timeline slideInDown(Node node, Duration duration) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null!");
|
Objects.requireNonNull(node, "Node cannot be null!");
|
||||||
@ -1097,8 +1097,8 @@ public final class Animations {
|
|||||||
* Applies an animated effect to the node, causing it to slide out of view
|
* Applies an animated effect to the node, causing it to slide out of view
|
||||||
* through the bottom side.
|
* through the bottom side.
|
||||||
*
|
*
|
||||||
* @param node the node to be animated
|
* @param node The node to be animated.
|
||||||
* @param duration the animation duration
|
* @param duration The animation duration.
|
||||||
*/
|
*/
|
||||||
public static Timeline slideOutDown(Node node, Duration duration) {
|
public static Timeline slideOutDown(Node node, Duration duration) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null!");
|
Objects.requireNonNull(node, "Node cannot be null!");
|
||||||
@ -1126,8 +1126,8 @@ public final class Animations {
|
|||||||
* Applies an animated effect to the node, causing it to slide into view
|
* Applies an animated effect to the node, causing it to slide into view
|
||||||
* from the left side.
|
* from the left side.
|
||||||
*
|
*
|
||||||
* @param node the node to be animated
|
* @param node The node to be animated.
|
||||||
* @param duration the animation duration
|
* @param duration The animation duration.
|
||||||
*/
|
*/
|
||||||
public static Timeline slideInLeft(Node node, Duration duration) {
|
public static Timeline slideInLeft(Node node, Duration duration) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null!");
|
Objects.requireNonNull(node, "Node cannot be null!");
|
||||||
@ -1155,8 +1155,8 @@ public final class Animations {
|
|||||||
* Applies an animated effect to the node, causing it to slide out of view
|
* Applies an animated effect to the node, causing it to slide out of view
|
||||||
* through the left side.
|
* through the left side.
|
||||||
*
|
*
|
||||||
* @param node the node to be animated
|
* @param node The node to be animated.
|
||||||
* @param duration the animation duration
|
* @param duration The animation duration.
|
||||||
*/
|
*/
|
||||||
public static Timeline slideOutLeft(Node node, Duration duration) {
|
public static Timeline slideOutLeft(Node node, Duration duration) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null!");
|
Objects.requireNonNull(node, "Node cannot be null!");
|
||||||
@ -1184,8 +1184,8 @@ public final class Animations {
|
|||||||
* Applies an animated effect to the node, causing it to slide into view
|
* Applies an animated effect to the node, causing it to slide into view
|
||||||
* from the right side.
|
* from the right side.
|
||||||
*
|
*
|
||||||
* @param node the node to be animated
|
* @param node The node to be animated.
|
||||||
* @param duration the animation duration
|
* @param duration The animation duration.
|
||||||
*/
|
*/
|
||||||
public static Timeline slideInRight(Node node, Duration duration) {
|
public static Timeline slideInRight(Node node, Duration duration) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null!");
|
Objects.requireNonNull(node, "Node cannot be null!");
|
||||||
@ -1213,8 +1213,8 @@ public final class Animations {
|
|||||||
* Applies an animated effect to the node, causing it to slide out of view
|
* Applies an animated effect to the node, causing it to slide out of view
|
||||||
* through the right side.
|
* through the right side.
|
||||||
*
|
*
|
||||||
* @param node the node to be animated
|
* @param node The node to be animated.
|
||||||
* @param duration the animation duration
|
* @param duration The animation duration.
|
||||||
*/
|
*/
|
||||||
public static Timeline slideOutRight(Node node, Duration duration) {
|
public static Timeline slideOutRight(Node node, Duration duration) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null!");
|
Objects.requireNonNull(node, "Node cannot be null!");
|
||||||
@ -1242,8 +1242,8 @@ public final class Animations {
|
|||||||
* Applies an animated effect to the node, causing it to slide into view
|
* Applies an animated effect to the node, causing it to slide into view
|
||||||
* from the bottom side.
|
* from the bottom side.
|
||||||
*
|
*
|
||||||
* @param node the node to be animated
|
* @param node The node to be animated.
|
||||||
* @param duration the animation duration
|
* @param duration The animation duration.
|
||||||
*/
|
*/
|
||||||
public static Timeline slideInUp(Node node, Duration duration) {
|
public static Timeline slideInUp(Node node, Duration duration) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null!");
|
Objects.requireNonNull(node, "Node cannot be null!");
|
||||||
@ -1271,8 +1271,8 @@ public final class Animations {
|
|||||||
* Applies an animated effect to the node, causing it to slide out of view
|
* Applies an animated effect to the node, causing it to slide out of view
|
||||||
* through the top side.
|
* through the top side.
|
||||||
*
|
*
|
||||||
* @param node the node to be animated
|
* @param node The node to be animated.
|
||||||
* @param duration the animation duration
|
* @param duration The animation duration.
|
||||||
*/
|
*/
|
||||||
public static Timeline slideOutUp(Node node, Duration duration) {
|
public static Timeline slideOutUp(Node node, Duration duration) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null!");
|
Objects.requireNonNull(node, "Node cannot be null!");
|
||||||
@ -1311,9 +1311,9 @@ public final class Animations {
|
|||||||
* Increases the scale of the node, starting from a smaller size and gradually
|
* Increases the scale of the node, starting from a smaller size and gradually
|
||||||
* zooming it to the regular size, emphasizing the node’s entrance.
|
* zooming it to the regular size, emphasizing the node’s entrance.
|
||||||
*
|
*
|
||||||
* @param node the node to be animated
|
* @param node The node to be animated.
|
||||||
* @param duration the animation duration
|
* @param duration The animation duration.
|
||||||
* @param startValue the initial zoom value
|
* @param startValue The initial zoom value.
|
||||||
*/
|
*/
|
||||||
public static Timeline zoomIn(Node node, Duration duration, double startValue) {
|
public static Timeline zoomIn(Node node, Duration duration, double startValue) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null!");
|
Objects.requireNonNull(node, "Node cannot be null!");
|
||||||
@ -1355,9 +1355,9 @@ public final class Animations {
|
|||||||
* its original size and gradually zooms out to a smaller size, emphasizing
|
* its original size and gradually zooms out to a smaller size, emphasizing
|
||||||
* the node’s exit.
|
* the node’s exit.
|
||||||
*
|
*
|
||||||
* @param node the node to be animated
|
* @param node The node to be animated.
|
||||||
* @param duration the animation duration
|
* @param duration The animation duration.
|
||||||
* @param endValue the target zoom value
|
* @param endValue The target zoom value.
|
||||||
*/
|
*/
|
||||||
public static Timeline zoomOut(Node node, Duration duration, double endValue) {
|
public static Timeline zoomOut(Node node, Duration duration, double endValue) {
|
||||||
Objects.requireNonNull(node, "Node cannot be null!");
|
Objects.requireNonNull(node, "Node cannot be null!");
|
||||||
|
@ -36,7 +36,7 @@ import javafx.scene.text.TextFlow;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic handler interface for the {@link BBCodeParser} that will
|
* The basic handler interface for the {@link BBCodeParser} that will
|
||||||
* receive notifications while processing user input text.
|
* receive notifications while processing user input text.
|
||||||
*/
|
*/
|
||||||
public interface BBCodeHandler {
|
public interface BBCodeHandler {
|
||||||
@ -57,10 +57,10 @@ public interface BBCodeHandler {
|
|||||||
* Notifies about the start of the tag.
|
* Notifies about the start of the tag.
|
||||||
* In case of self-closing tag this also notifies about the end of the tag.
|
* In case of self-closing tag this also notifies about the end of the tag.
|
||||||
*
|
*
|
||||||
* @param name tag name
|
* @param name The tag name.
|
||||||
* @param params tag params
|
* @param params The tag params.
|
||||||
* @param start tag start position, i.e. the position of open square bracket (not the tag name start)
|
* @param start The tag start position, i.e. the position of open square bracket (not the tag name start).
|
||||||
* @param length tag length, including closing bracket
|
* @param length The tag length, including closing bracket.
|
||||||
*/
|
*/
|
||||||
void startTag(String name, @Nullable Map<String, String> params, int start, int length);
|
void startTag(String name, @Nullable Map<String, String> params, int start, int length);
|
||||||
|
|
||||||
@ -68,9 +68,9 @@ public interface BBCodeHandler {
|
|||||||
* Notifies about the end of the tag.
|
* Notifies about the end of the tag.
|
||||||
* In case of self-closing tag only {@link #startTag(String, Map, int, int)} method is called.
|
* In case of self-closing tag only {@link #startTag(String, Map, int, int)} method is called.
|
||||||
*
|
*
|
||||||
* @param name tag name
|
* @param name The tag name.
|
||||||
* @param start tag start position, i.e. the position of open square bracket (not the tag name start)
|
* @param start The tag start position, i.e. the position of open square bracket (not the tag name start).
|
||||||
* @param length tag length, including closing bracket
|
* @param length The tag length, including closing bracket.
|
||||||
*/
|
*/
|
||||||
void endTag(String name, int start, int length);
|
void endTag(String name, int start, int length);
|
||||||
|
|
||||||
@ -78,8 +78,8 @@ public interface BBCodeHandler {
|
|||||||
* Notifies about characters data that doesn't belong to any tag, i.e.
|
* Notifies about characters data that doesn't belong to any tag, i.e.
|
||||||
* leading, intermediate or trailing text.
|
* leading, intermediate or trailing text.
|
||||||
*
|
*
|
||||||
* @param start text start position
|
* @param start The text start position.
|
||||||
* @param length text length
|
* @param length The text length.
|
||||||
*/
|
*/
|
||||||
void characters(int start, int length);
|
void characters(int start, int length);
|
||||||
|
|
||||||
@ -89,9 +89,9 @@ public interface BBCodeHandler {
|
|||||||
* A basic {@link BBCodeHandler} implementation.<br/><br/>
|
* A basic {@link BBCodeHandler} implementation.<br/><br/>
|
||||||
*
|
*
|
||||||
* <p>While parsing all created nodes will be added to the given root container.
|
* <p>While parsing all created nodes will be added to the given root container.
|
||||||
* The choice depends on the actual markup. Default constructor accepts any {@link Pane}
|
* The container choice depends on the actual markup. Default constructor accepts any
|
||||||
* or its descendant. Using {@link TextFlow} for text-only markup (no block nodes) and
|
* {@link Pane} or its descendant. Using the{@link TextFlow} for text-only markup
|
||||||
* {@link VBox} otherwise, is recommended.<br/><br/>
|
* (no block nodes) and {@link VBox} otherwise, is recommended.<br/><br/>
|
||||||
*
|
*
|
||||||
* <h3>Supported tags</h3><br/>
|
* <h3>Supported tags</h3><br/>
|
||||||
* <pre>
|
* <pre>
|
||||||
@ -149,16 +149,17 @@ public interface BBCodeHandler {
|
|||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>If tag param contains whitespaces or trailing slash is must be
|
* <li>If a tag param contains whitespaces or trailing slash is must be
|
||||||
* enclosed in double or single quotes.
|
* enclosed in double or single quotes.
|
||||||
* <li>If tag only has a single param, it can be shortened to {@code [name=value]{text}[/name]}.
|
* <li>If a tag only has a single param, it can be shortened to the
|
||||||
* In that case tag param name considered to be equal to the tag name.
|
* {@code [name=value]{text}[/name]}. In this case the tag param name
|
||||||
|
* considered to be equal to the tag name.
|
||||||
* <li>Unknown tag params will be ignored.
|
* <li>Unknown tag params will be ignored.
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* <h3>Action Events</h3><br/>
|
* <h3>Action Events</h3><br/>
|
||||||
* Some nodes, e.g. {@link Hyperlink} require action handlers. To avoid traversing
|
* Some nodes, e.g. {@link Hyperlink} require action handlers. To avoid traversing
|
||||||
* the root node graph you can add an event filter.
|
* the root container's node graph you can add an event filter.
|
||||||
*
|
*
|
||||||
* <pre>{@code
|
* <pre>{@code
|
||||||
* var input = "Visit the [url=https://example.com]website[/url].";
|
* var input = "Visit the [url=https://example.com]website[/url].";
|
||||||
@ -672,10 +673,10 @@ public interface BBCodeHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic block record.
|
* A generic block record.
|
||||||
*
|
*
|
||||||
* @param node the node that represents the block
|
* @param node The node that represents the block.
|
||||||
* @param text text content
|
* @param text The text content.
|
||||||
*/
|
*/
|
||||||
record Block(Pane node, @Nullable TextFlow text) {
|
record Block(Pane node, @Nullable TextFlow text) {
|
||||||
|
|
||||||
@ -712,10 +713,12 @@ public interface BBCodeHandler {
|
|||||||
/**
|
/**
|
||||||
* Generic tag record.
|
* Generic tag record.
|
||||||
*
|
*
|
||||||
* @param name tag name
|
* @param name The tag name.
|
||||||
* @param params tag params
|
* @param params The tag params.
|
||||||
* @param styleClasses CSS classes, each element is either a single style or space delimited string
|
* @param styleClasses The CSS classes.
|
||||||
* @param styles CSS styles, each element is either a single style or semicolon delimited string
|
* Each element is either a single style or space delimited string.
|
||||||
|
* @param styles The CSS styles.
|
||||||
|
* Each element is either a single style or semicolon delimited string.
|
||||||
*/
|
*/
|
||||||
record Tag(String name,
|
record Tag(String name,
|
||||||
Type type,
|
Type type,
|
||||||
|
@ -22,10 +22,11 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
*
|
*
|
||||||
* <p>The parser doesn't impose restrictions on tag names or tag params.
|
* <p>The parser doesn't impose restrictions on tag names or tag params.
|
||||||
* It's a handler implementation responsibility to differentiate supported
|
* It's a handler implementation responsibility to differentiate supported
|
||||||
* tags from unsupported and so to for tag params. This allows user to utilize
|
* tags from unsupported and so to for the tag params. This allows user to utilize
|
||||||
* arbitrary tags or params without changing the parser behaviour. The parser,
|
* arbitrary tags or params without changing the parser behaviour. The parser,
|
||||||
* however, verifies that each opening tag has the matching closing tag.
|
* however, verifies that each opening tag has the matching closing tag.
|
||||||
* If parsing is failed due to invalid input an {@link IllegalStateException}
|
*
|
||||||
|
* <p>If parsing is failed due to invalid input an {@link IllegalStateException}
|
||||||
* will be thrown.
|
* will be thrown.
|
||||||
*/
|
*/
|
||||||
public class BBCodeParser {
|
public class BBCodeParser {
|
||||||
@ -53,7 +54,9 @@ public class BBCodeParser {
|
|||||||
private int lastClosingPos = 0;
|
private int lastClosingPos = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See {@link #BBCodeParser(String, BBCodeHandler, Set)}.
|
* Creates a new parser.
|
||||||
|
*
|
||||||
|
* @see #BBCodeParser(String, BBCodeHandler, Set).
|
||||||
*/
|
*/
|
||||||
public BBCodeParser(String input, BBCodeHandler handler) {
|
public BBCodeParser(String input, BBCodeHandler handler) {
|
||||||
this(input, handler, RESERVED_TAGS);
|
this(input, handler, RESERVED_TAGS);
|
||||||
@ -62,9 +65,9 @@ public class BBCodeParser {
|
|||||||
/**
|
/**
|
||||||
* Creates a new parser.
|
* Creates a new parser.
|
||||||
*
|
*
|
||||||
* @param input an input non-null string
|
* @param input An input non-null string.
|
||||||
* @param handler a {@link BBCodeHandler} implementation
|
* @param handler A {@link BBCodeHandler} implementation.
|
||||||
* @param tags the list of processed tags, i.e. the tags that parser won't ignore
|
* @param tags The list of processed tags, i.e. the tags that parser won't ignore.
|
||||||
*/
|
*/
|
||||||
public BBCodeParser(String input, BBCodeHandler handler, @Nullable Set<String> tags) {
|
public BBCodeParser(String input, BBCodeHandler handler, @Nullable Set<String> tags) {
|
||||||
this.input = Objects.requireNonNull(input, "Input can't be null.");
|
this.input = Objects.requireNonNull(input, "Input can't be null.");
|
||||||
@ -73,8 +76,8 @@ public class BBCodeParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts input parsing. There's no way to stop the process until
|
* Starts input parsing.
|
||||||
* parsing is finished.
|
* There's no way to stop the process until parsing is finished.
|
||||||
*/
|
*/
|
||||||
public void parse() {
|
public void parse() {
|
||||||
handler.startDocument(input.toCharArray());
|
handler.startDocument(input.toCharArray());
|
||||||
@ -175,8 +178,9 @@ public class BBCodeParser {
|
|||||||
* Parses the given string using BBCode markup and returns corresponding layout.
|
* Parses the given string using BBCode markup and returns corresponding layout.
|
||||||
* This is a shorthand method for using the feature.
|
* This is a shorthand method for using the feature.
|
||||||
*
|
*
|
||||||
* @param input BBCode markup string
|
* @param input The BBCode markup string.
|
||||||
* @param container root container
|
* @param container The root container.
|
||||||
|
* @see BBCodeHandler
|
||||||
*/
|
*/
|
||||||
public static <T extends Pane> T createLayout(String input, T container) {
|
public static <T extends Pane> T createLayout(String input, T container) {
|
||||||
var handler = new BBCodeHandler.Default<>(container);
|
var handler = new BBCodeHandler.Default<>(container);
|
||||||
|
@ -13,16 +13,16 @@ import javafx.scene.control.Tooltip;
|
|||||||
import javafx.util.StringConverter;
|
import javafx.util.StringConverter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts between user-edited strings and {@link Double} values.
|
* Converts between user-edited strings and Double values.
|
||||||
* Accepts an optional {@link Runnable} that resets the editor on {@link NumberFormatException},
|
*
|
||||||
* or a {@link TextField} or {@link Spinner} that is preemptively monitored for invalid
|
* <p>Accepts an optional Runnable that resets the editor on {@code NumberFormatException},
|
||||||
* input during typing, and restricts valid input to a specified range when committed.
|
* or a TextField or Spinner that is preemptively monitored for invalid input
|
||||||
* <p>
|
* during typing, and restricts valid input to a specified range when committed.
|
||||||
* This implementation shows up to two decimal digits, but only if a fractional part exists.
|
*
|
||||||
* The default implementation always shows one decimal digit which hinders typing.</p>
|
* <p>This implementation shows up to two decimal digits, but only if a fractional part
|
||||||
|
* exists. The default implementation always shows one decimal digit which hinders typing.
|
||||||
*
|
*
|
||||||
* @author Christoph Nahr
|
* @author Christoph Nahr
|
||||||
* @version 1.0.2
|
|
||||||
*/
|
*/
|
||||||
public class DoubleStringConverter extends StringConverter<Double> {
|
public class DoubleStringConverter extends StringConverter<Double> {
|
||||||
|
|
||||||
@ -30,8 +30,9 @@ public class DoubleStringConverter extends StringConverter<Double> {
|
|||||||
private Runnable reset;
|
private Runnable reset;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a {@link DoubleStringConverter}.
|
* Creates a DoubleStringConverter.
|
||||||
* Swallows {@link NumberFormatException} but does nothing
|
*
|
||||||
|
* <p>Swallows {@code NumberFormatException} but does nothing
|
||||||
* in response until {@link #setReset} is defined.
|
* in response until {@link #setReset} is defined.
|
||||||
*/
|
*/
|
||||||
public DoubleStringConverter() {
|
public DoubleStringConverter() {
|
||||||
@ -39,26 +40,27 @@ public class DoubleStringConverter extends StringConverter<Double> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a {@link DoubleStringConverter} with an editor reset callback.
|
* Creates a DoubleStringConverter with an editor reset callback.
|
||||||
* Specifying {@code null} has the same effect as the default constructor.
|
* Specifying null has the same effect as the default constructor.
|
||||||
*
|
*
|
||||||
* @param reset the {@link Runnable} to call upon {@link NumberFormatException}
|
* @param reset the Runnable to call upon {@code NumberFormatException}
|
||||||
*/
|
*/
|
||||||
public DoubleStringConverter(Runnable reset) {
|
public DoubleStringConverter(Runnable reset) {
|
||||||
this.reset = reset;
|
this.reset = reset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a {@link DoubleStringConverter} with the specified input range.
|
* Creates a DoubleStringConverter with the specified input range.
|
||||||
* Preemptively monitors {@code input} to reject any invalid characters during
|
*
|
||||||
* typing, restricts {@code input} to [{@code min}, {@code max}] (inclusive) when
|
* <p>Preemptively monitors input to reject any invalid characters during
|
||||||
* valid text is committed, and resets {@code input} to the closest value to zero
|
* typing. Restricts input to [{@code min}, {@code max}] (inclusive) when
|
||||||
|
* valid text is committed, and resets input to the closest value to zero
|
||||||
* within [{@code min}, {@code max}] when invalid text is committed.
|
* within [{@code min}, {@code max}] when invalid text is committed.
|
||||||
*
|
*
|
||||||
* @param input the {@link TextField} providing user-edited strings
|
* @param input The TextField providing user-edited strings.
|
||||||
* @param min the smallest valid {@link Double} value
|
* @param min The smallest valid value.
|
||||||
* @param max the greatest valid {@link Double} value
|
* @param max The greatest valid value.
|
||||||
* @throws NullPointerException if {@code input} is {@code null}
|
* @throws NullPointerException if input is {@code null}.
|
||||||
*/
|
*/
|
||||||
public DoubleStringConverter(TextField input, double min, double max) {
|
public DoubleStringConverter(TextField input, double min, double max) {
|
||||||
if (input == null) {
|
if (input == null) {
|
||||||
@ -68,11 +70,6 @@ public class DoubleStringConverter extends StringConverter<Double> {
|
|||||||
final double resetValue = Math.min(Math.max(0, min), max);
|
final double resetValue = Math.min(Math.max(0, min), max);
|
||||||
reset = () -> input.setText(decimalFormat.format(resetValue));
|
reset = () -> input.setText(decimalFormat.format(resetValue));
|
||||||
|
|
||||||
// bound JavaFX properties cannot be explicitly set
|
|
||||||
// if (!input.tooltipProperty().isBound()) {
|
|
||||||
// input.setTooltip(new Tooltip(String.format("Enter a value between %.2f and %.2f", min, max)));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// restrict direct input to valid numerical characters
|
// restrict direct input to valid numerical characters
|
||||||
input.textProperty().addListener((ov, oldValue, newValue) -> {
|
input.textProperty().addListener((ov, oldValue, newValue) -> {
|
||||||
if (newValue == null || newValue.isEmpty()) {
|
if (newValue == null || newValue.isEmpty()) {
|
||||||
@ -115,14 +112,15 @@ public class DoubleStringConverter extends StringConverter<Double> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a {@link DoubleStringConverter} for the specified {@link Spinner}.
|
* Creates a DoubleStringConverter for the specified Spinner.
|
||||||
* Uses the {@link TextField} and minimum and maximum values of the specified
|
*
|
||||||
* {@link Spinner} for construction, and also sets the new {@link DoubleStringConverter}
|
* <p>Uses the TextField and minimum and maximum values of the specified
|
||||||
|
* Spinner for construction, and also sets the new DoubleStringConverter
|
||||||
* on its {@link SpinnerValueFactory.DoubleSpinnerValueFactory}.
|
* on its {@link SpinnerValueFactory.DoubleSpinnerValueFactory}.
|
||||||
*
|
*
|
||||||
* @param spinner the {@link Spinner} to create a {@link DoubleStringConverter} for
|
* @param spinner The Spinner to create a DoubleStringConverter for.
|
||||||
* @return the new {@link DoubleStringConverter}
|
* @return the new DoubleStringConverter
|
||||||
* @throws NullPointerException if {@code spinner} is {@code null}
|
* @throws NullPointerException if the Spinner is {@code null}
|
||||||
*/
|
*/
|
||||||
public static DoubleStringConverter createFor(Spinner<Double> spinner) {
|
public static DoubleStringConverter createFor(Spinner<Double> spinner) {
|
||||||
final SpinnerValueFactory.DoubleSpinnerValueFactory factory =
|
final SpinnerValueFactory.DoubleSpinnerValueFactory factory =
|
||||||
@ -141,13 +139,14 @@ public class DoubleStringConverter extends StringConverter<Double> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the editor reset callback.
|
* Sets the editor reset callback.
|
||||||
* Specify {@code null} to clear a previously set {@link Runnable}. When creating
|
|
||||||
* a {@link DoubleStringConverter} for a {@link TextField} or {@link Spinner},
|
|
||||||
* this callback is automatically defined to reset committed invalid input to the
|
|
||||||
* closest value to zero within the legal range. Setting a different callback
|
|
||||||
* will overwrite this functionality.
|
|
||||||
*
|
*
|
||||||
* @param reset the {@link Runnable} to call upon {@link NumberFormatException}
|
* <p>Specify {@code null} to clear a previously set Runnable. When creating
|
||||||
|
* a DoubleStringConverter for a TextField or Spinner, this callback is
|
||||||
|
* automatically defined to reset committed invalid input to the closest value
|
||||||
|
* to zero within the legal range. Setting a different callback will overwrite this
|
||||||
|
* functionality.
|
||||||
|
*
|
||||||
|
* @param reset The Runnable to call upon NumberFormatException.
|
||||||
* @see #fromString
|
* @see #fromString
|
||||||
*/
|
*/
|
||||||
public void setReset(Runnable reset) {
|
public void setReset(Runnable reset) {
|
||||||
@ -155,12 +154,12 @@ public class DoubleStringConverter extends StringConverter<Double> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts the specified {@link String} into its {@link Double} value.
|
* Converts the specified string into its double value.
|
||||||
* A {@code null}, empty, or otherwise invalid argument returns zero
|
* A {@code null}, empty, or otherwise invalid argument returns zero
|
||||||
* and also executes the editor reset callback, if any.
|
* and also executes the editor reset callback, if any.
|
||||||
*
|
*
|
||||||
* @param s the {@link String} to convert
|
* @param s The string to convert.
|
||||||
* @return the {@link Double} value of {@code s}
|
* @return the double value of {@code s}
|
||||||
* @see #setReset
|
* @see #setReset
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@ -183,11 +182,11 @@ public class DoubleStringConverter extends StringConverter<Double> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts the specified {@link Double} into its {@link String} form.
|
* Converts the specified double into its string form.
|
||||||
* A {@code null} argument is converted into the literal string "0".
|
* A {@code null} argument is converted into the literal string "0".
|
||||||
*
|
*
|
||||||
* @param value the {@link Double} to convert
|
* @param value The Double to convert.
|
||||||
* @return the {@link String} form of {@code value}
|
* @return the string form of {@code value}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String toString(Double value) {
|
public String toString(Double value) {
|
||||||
|
@ -12,47 +12,48 @@ import javafx.scene.control.Tooltip;
|
|||||||
import javafx.util.StringConverter;
|
import javafx.util.StringConverter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts between user-edited strings and {@link Integer} values.
|
* Converts between user-edited strings and integer values.
|
||||||
* Accepts an optional {@link Runnable} that resets the editor on {@link NumberFormatException},
|
*
|
||||||
* or a {@link TextField} or {@link Spinner} that is preemptively monitored for invalid
|
* <p>Accepts an optional Runnable that resets the editor on NumberFormatException,
|
||||||
|
* or a TextField or Spinner that is preemptively monitored for invalid
|
||||||
* input during typing, and restricts valid input to a specified range when committed.
|
* input during typing, and restricts valid input to a specified range when committed.
|
||||||
*
|
*
|
||||||
* @author Christoph Nahr
|
* @author Christoph Nahr
|
||||||
* @version 1.0.2
|
|
||||||
*/
|
*/
|
||||||
public class IntegerStringConverter extends StringConverter<Integer> {
|
public class IntegerStringConverter extends StringConverter<Integer> {
|
||||||
|
|
||||||
private Runnable reset;
|
private Runnable reset;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an {@link IntegerStringConverter}.
|
* Creates an IntegerStringConverter.
|
||||||
* Swallows {@link NumberFormatException} but does nothing
|
* Swallows NumberFormatException but does nothing
|
||||||
* in response until {@link #setReset} is defined.
|
* in response until {@link #setReset} is defined.
|
||||||
*/
|
*/
|
||||||
public IntegerStringConverter() {
|
public IntegerStringConverter() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an {@link IntegerStringConverter} with an editor reset callback.
|
* Creates an IntegerStringConverter with an editor reset callback.
|
||||||
* Specifying {@code null} has the same effect as the default constructor.
|
* Specifying {@code null} has the same effect as the default constructor.
|
||||||
*
|
*
|
||||||
* @param reset the {@link Runnable} to call upon {@link NumberFormatException}
|
* @param reset The Runnable to call upon NumberFormatException.
|
||||||
*/
|
*/
|
||||||
public IntegerStringConverter(Runnable reset) {
|
public IntegerStringConverter(Runnable reset) {
|
||||||
this.reset = reset;
|
this.reset = reset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an {@link IntegerStringConverter} with the specified input range.
|
* Creates an IntegerStringConverter with the specified input range.
|
||||||
* Preemptively monitors {@code input} to reject any invalid characters during
|
*
|
||||||
* typing, restricts {@code input} to [{@code min}, {@code max}] (inclusive) when
|
* <p>Preemptively monitors input to reject any invalid characters during
|
||||||
* valid text is committed, and resets {@code input} to the closest value to zero
|
* typing, restricts input to [{@code min}, {@code max}] (inclusive) when
|
||||||
|
* valid text is committed, and resets input to the closest value to zero
|
||||||
* within [{@code min}, {@code max}] when invalid text is committed.
|
* within [{@code min}, {@code max}] when invalid text is committed.
|
||||||
*
|
*
|
||||||
* @param input the {@link TextField} providing user-edited strings
|
* @param input The TextField providing user-edited strings.
|
||||||
* @param min the smallest valid {@link Integer} value
|
* @param min The smallest valid integer value.
|
||||||
* @param max the greatest valid {@link Integer} value
|
* @param max The greatest valid integer value.
|
||||||
* @throws NullPointerException if {@code input} is {@code null}
|
* @throws NullPointerException if input is {@code null}
|
||||||
*/
|
*/
|
||||||
public IntegerStringConverter(TextField input, int min, int max) {
|
public IntegerStringConverter(TextField input, int min, int max) {
|
||||||
if (input == null) {
|
if (input == null) {
|
||||||
@ -62,11 +63,6 @@ public class IntegerStringConverter extends StringConverter<Integer> {
|
|||||||
final int resetValue = Math.min(Math.max(0, min), max);
|
final int resetValue = Math.min(Math.max(0, min), max);
|
||||||
reset = () -> input.setText(Integer.toString(resetValue));
|
reset = () -> input.setText(Integer.toString(resetValue));
|
||||||
|
|
||||||
// bound JavaFX properties cannot be explicitly set
|
|
||||||
// if (!input.tooltipProperty().isBound()) {
|
|
||||||
// input.setTooltip(new Tooltip(String.format("Enter a value between %d and %d", min, max)));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// restrict direct input to valid numerical characters
|
// restrict direct input to valid numerical characters
|
||||||
input.textProperty().addListener((ov, oldValue, newValue) -> {
|
input.textProperty().addListener((ov, oldValue, newValue) -> {
|
||||||
if (newValue == null || newValue.isEmpty()) {
|
if (newValue == null || newValue.isEmpty()) {
|
||||||
@ -109,13 +105,13 @@ public class IntegerStringConverter extends StringConverter<Integer> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an {@link IntegerStringConverter} for the specified {@link Spinner}.
|
* Creates an IntegerStringConverter for the specified Spinner.
|
||||||
* Uses the {@link TextField} and minimum and maximum values of the specified
|
* Uses the TextField and minimum and maximum values of the specified
|
||||||
* {@link Spinner} for construction, and also sets the new {@link IntegerStringConverter}
|
* Spinner for construction, and also sets the new IntegerStringConverter
|
||||||
* on its {@link SpinnerValueFactory.IntegerSpinnerValueFactory}.
|
* on its {@link SpinnerValueFactory.IntegerSpinnerValueFactory}.
|
||||||
*
|
*
|
||||||
* @param spinner the {@link Spinner} to create an {@link IntegerStringConverter} for
|
* @param spinner The Spinner to create an IntegerStringConverter for.
|
||||||
* @return the new {@link IntegerStringConverter}
|
* @return the new IntegerStringConverter
|
||||||
* @throws NullPointerException if {@code spinner} is {@code null}
|
* @throws NullPointerException if {@code spinner} is {@code null}
|
||||||
*/
|
*/
|
||||||
public static IntegerStringConverter createFor(Spinner<Integer> spinner) {
|
public static IntegerStringConverter createFor(Spinner<Integer> spinner) {
|
||||||
@ -135,13 +131,14 @@ public class IntegerStringConverter extends StringConverter<Integer> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the editor reset callback.
|
* Sets the editor reset callback.
|
||||||
* Specify {@code null} to clear a previously set {@link Runnable}. When creating
|
|
||||||
* an {@link IntegerStringConverter} for a {@link TextField} or {@link Spinner},
|
|
||||||
* this callback is automatically defined to reset committed invalid input to the
|
|
||||||
* closest value to zero within the legal range. Setting a different callback
|
|
||||||
* will overwrite this functionality.
|
|
||||||
*
|
*
|
||||||
* @param reset the {@link Runnable} to call upon {@link NumberFormatException}
|
* <p>Specify {@code null} to clear a previously set Runnable. When creating
|
||||||
|
* an IntegerStringConverter for a TextField or Spinner, this callback is
|
||||||
|
* automatically defined to reset committed invalid input to the closest value
|
||||||
|
* to zero within the legal range. Setting a different callback will overwrite
|
||||||
|
* this functionality.
|
||||||
|
*
|
||||||
|
* @param reset The Runnable to call upon NumberFormatException.
|
||||||
* @see #fromString
|
* @see #fromString
|
||||||
*/
|
*/
|
||||||
public void setReset(Runnable reset) {
|
public void setReset(Runnable reset) {
|
||||||
@ -149,12 +146,12 @@ public class IntegerStringConverter extends StringConverter<Integer> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts the specified {@link String} into its {@link Integer} value.
|
* Converts the specified string into its integer value.
|
||||||
* A {@code null}, empty, or otherwise invalid argument returns zero
|
* A {@code null}, empty, or otherwise invalid argument returns zero
|
||||||
* and also executes the editor reset callback, if any.
|
* and also executes the editor reset callback, if any.
|
||||||
*
|
*
|
||||||
* @param s the {@link String} to convert
|
* @param s The {@link String} to convert.
|
||||||
* @return the {@link Integer} value of {@code s}
|
* @return the integer value of {@code s}
|
||||||
* @see #setReset
|
* @see #setReset
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@ -177,10 +174,10 @@ public class IntegerStringConverter extends StringConverter<Integer> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts the specified {@link Integer} into its {@link String} form.
|
* Converts the specified integer into its string form.
|
||||||
* A {@code null} argument is converted into the literal string "0".
|
* A {@code null} argument is converted into the literal string "0".
|
||||||
*
|
*
|
||||||
* @param value the {@link Integer} to convert
|
* @param value The integer to convert.
|
||||||
* @return the {@link String} form of {@code value}
|
* @return the {@link String} form of {@code value}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@ -26,7 +26,7 @@ public interface MaskChar {
|
|||||||
char INPUT_MASK_DIGIT_ZERO = '0';
|
char INPUT_MASK_DIGIT_ZERO = '0';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the character is allowed, false otherwise.
|
* Returns "true" if the character is allowed, "false" otherwise.
|
||||||
*/
|
*/
|
||||||
boolean isAllowed(char ch);
|
boolean isAllowed(char ch);
|
||||||
|
|
||||||
|
@ -36,14 +36,19 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* <p><h3>Behavior</h3>
|
* <p><h3>Behavior</h3>
|
||||||
* Any {@code TextField} with {@code MaskTextFormatter} applied shows a placeholder mask by default.
|
* Any {@code TextField} with {@code MaskTextFormatter} applied shows a placeholder
|
||||||
* This is basically the input mask with all mask characters replaced with {@link MaskChar#getPlaceholder()}.
|
* mask by default. This is basically the input mask with all mask characters replaced
|
||||||
* The behavior changes if you set {@link TextField#promptTextProperty()}. In that case placeholder
|
* with the {@link MaskChar#getPlaceholder()} character.
|
||||||
* mask is only displayed when {@code TextField} gets focus and will be hidden after focus lost.
|
*
|
||||||
* So, the placeholder mask is always displayed when focus is set to the {@code TextField}.
|
* <p>The behavior changes if you set the {@link TextField#promptTextProperty()}.
|
||||||
* You can replace the placeholder mask with any sensible default simply by changing initial
|
* In that case placeholder mask is only displayed when {@code TextField} gets focus and
|
||||||
* {@code TextField} text to any string that is valid against the input mask.
|
* will be hidden after focus lost. So, the placeholder mask is always displayed when focus
|
||||||
* <br/><br/>The caret will be positioned before the first not fixed character (see {@link MaskChar#isFixed()})
|
* is set to the {@code TextField}.
|
||||||
|
*
|
||||||
|
* <p>You can replace the placeholder mask with any sensible default simply by changing initial
|
||||||
|
* {@code TextField} text to any string that is valid against the input mask.<br/><br/>
|
||||||
|
*
|
||||||
|
* <p>The caret will be positioned before the first not fixed character (see {@link MaskChar#isFixed()})
|
||||||
* starting from the beginning of the input mask.<br/><br/>
|
* starting from the beginning of the input mask.<br/><br/>
|
||||||
*
|
*
|
||||||
* <p><h3>Validation</h3>
|
* <p><h3>Validation</h3>
|
||||||
@ -68,8 +73,6 @@ public class MaskTextFormatter extends TextFormatter<String> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new text field with the provided string input mask.
|
* Creates a new text field with the provided string input mask.
|
||||||
* Use this if you create your controls from Java code and don't need to
|
|
||||||
* modify the default {@link MaskChar} implementation.
|
|
||||||
*/
|
*/
|
||||||
public static TextField createTextField(String mask) {
|
public static TextField createTextField(String mask) {
|
||||||
return createTextField(fromString(mask));
|
return createTextField(fromString(mask));
|
||||||
@ -77,8 +80,6 @@ public class MaskTextFormatter extends TextFormatter<String> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new text field with the provided input mask.
|
* Creates a new text field with the provided input mask.
|
||||||
* Use this if you create your controls from Java code and want to
|
|
||||||
* modify the default {@link MaskChar} implementation.
|
|
||||||
*/
|
*/
|
||||||
public static TextField createTextField(List<MaskChar> mask) {
|
public static TextField createTextField(List<MaskChar> mask) {
|
||||||
final var field = new TextField();
|
final var field = new TextField();
|
||||||
@ -88,9 +89,7 @@ public class MaskTextFormatter extends TextFormatter<String> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new mask text formatter with the provided string input mask and
|
* Creates a new mask text formatter with the provided string input mask and
|
||||||
* applies itself to the specified text field. Use this if you create your
|
* applies itself to the specified text field.
|
||||||
* controls from FXML and don't need to modify the default {@link MaskChar}
|
|
||||||
* implementation.
|
|
||||||
*/
|
*/
|
||||||
public static MaskTextFormatter create(TextField field, String mask) {
|
public static MaskTextFormatter create(TextField field, String mask) {
|
||||||
return create(field, fromString(mask));
|
return create(field, fromString(mask));
|
||||||
@ -98,8 +97,7 @@ public class MaskTextFormatter extends TextFormatter<String> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new mask text formatter with the provided input mask and
|
* Creates a new mask text formatter with the provided input mask and
|
||||||
* applies itself to the specified text field. Use this if you create your
|
* applies itself to the specified text field.
|
||||||
* controls from FXML and want to modify the default {@link MaskChar} implementation.
|
|
||||||
*/
|
*/
|
||||||
public static MaskTextFormatter create(TextField field, List<MaskChar> mask) {
|
public static MaskTextFormatter create(TextField field, List<MaskChar> mask) {
|
||||||
Objects.requireNonNull(field, "Text field can't be null");
|
Objects.requireNonNull(field, "Text field can't be null");
|
||||||
|
@ -8,13 +8,14 @@ import javafx.beans.property.BooleanProperty;
|
|||||||
import javafx.beans.property.ReadOnlyStringProperty;
|
import javafx.beans.property.ReadOnlyStringProperty;
|
||||||
import javafx.beans.property.ReadOnlyStringWrapper;
|
import javafx.beans.property.ReadOnlyStringWrapper;
|
||||||
import javafx.beans.property.SimpleBooleanProperty;
|
import javafx.beans.property.SimpleBooleanProperty;
|
||||||
|
import javafx.scene.control.PasswordField;
|
||||||
import javafx.scene.control.TextField;
|
import javafx.scene.control.TextField;
|
||||||
import javafx.scene.control.TextFormatter;
|
import javafx.scene.control.TextFormatter;
|
||||||
import javafx.util.StringConverter;
|
import javafx.util.StringConverter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An alternative for the {@link javafx.scene.control.PasswordField}.
|
* An alternative to the {@link PasswordField} class. This formatter masks
|
||||||
* The formatter (un)masks text field content based on boolean property.
|
* or unmasks text field content based on a boolean property.
|
||||||
*/
|
*/
|
||||||
public class PasswordTextFormatter extends TextFormatter<String> {
|
public class PasswordTextFormatter extends TextFormatter<String> {
|
||||||
|
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
package atlantafx.base.util;
|
package atlantafx.base.util;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class that provides just some basic methods that's commonly necessary
|
* A utility class that provides just some platform methods that's commonly
|
||||||
* for control/skin development.
|
* necessary for control/skin development.
|
||||||
*/
|
*/
|
||||||
public final class PlatformUtils {
|
public final class PlatformUtils {
|
||||||
|
|
||||||
@ -20,18 +20,30 @@ public final class PlatformUtils {
|
|||||||
private static final boolean OPEN_BSD = OS.startsWith("openbsd");
|
private static final boolean OPEN_BSD = OS.startsWith("openbsd");
|
||||||
private static final boolean NET_BSD = OS.startsWith("netbsd");
|
private static final boolean NET_BSD = OS.startsWith("netbsd");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns "true" if this is Windows.
|
||||||
|
*/
|
||||||
public static boolean isWindows() {
|
public static boolean isWindows() {
|
||||||
return WINDOWS;
|
return WINDOWS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns "true" if this is Mac.
|
||||||
|
*/
|
||||||
public static boolean isMac() {
|
public static boolean isMac() {
|
||||||
return MAC;
|
return MAC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns "true" if this is Linux.
|
||||||
|
*/
|
||||||
public static boolean isLinux() {
|
public static boolean isLinux() {
|
||||||
return LINUX;
|
return LINUX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns "true" if this is a UNIX like system.
|
||||||
|
*/
|
||||||
public static boolean isUnix() {
|
public static boolean isUnix() {
|
||||||
return LINUX || FREE_BSD || OPEN_BSD || NET_BSD;
|
return LINUX || FREE_BSD || OPEN_BSD || NET_BSD;
|
||||||
}
|
}
|
||||||
|
@ -17,21 +17,53 @@ public final class SimpleMaskChar implements MaskChar {
|
|||||||
private final char placeholder;
|
private final char placeholder;
|
||||||
private final boolean fixed;
|
private final boolean fixed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a SimpleMaskChar.
|
||||||
|
*
|
||||||
|
* @param matchExpr The matching predicate that determines which characters are masked.
|
||||||
|
* @see #SimpleMaskChar(Predicate, UnaryOperator, char, boolean)
|
||||||
|
*/
|
||||||
public SimpleMaskChar(Predicate<Character> matchExpr) {
|
public SimpleMaskChar(Predicate<Character> matchExpr) {
|
||||||
this(matchExpr, UnaryOperator.identity(), UNDERSCORE, false);
|
this(matchExpr, UnaryOperator.identity(), UNDERSCORE, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a SimpleMaskChar.
|
||||||
|
*
|
||||||
|
* @param matchExpr The matching predicate that determines which characters are masked.
|
||||||
|
* @param transform The transformation function that is applied to input characters.
|
||||||
|
* @see #SimpleMaskChar(Predicate, UnaryOperator, char, boolean)
|
||||||
|
*/
|
||||||
public SimpleMaskChar(Predicate<Character> matchExpr,
|
public SimpleMaskChar(Predicate<Character> matchExpr,
|
||||||
UnaryOperator<Character> transform) {
|
UnaryOperator<Character> transform) {
|
||||||
this(matchExpr, transform, UNDERSCORE, false);
|
this(matchExpr, transform, UNDERSCORE, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a SimpleMaskChar.
|
||||||
|
*
|
||||||
|
* @param matchExpr The matching predicate that determines which characters are masked.
|
||||||
|
* @param transform The transformation function that is applied to input characters.
|
||||||
|
* @param placeholder The placeholder character to use for masking.
|
||||||
|
* @see #SimpleMaskChar(Predicate, UnaryOperator, char, boolean)
|
||||||
|
*/
|
||||||
public SimpleMaskChar(Predicate<Character> matchExpr,
|
public SimpleMaskChar(Predicate<Character> matchExpr,
|
||||||
UnaryOperator<Character> transform,
|
UnaryOperator<Character> transform,
|
||||||
char placeholder) {
|
char placeholder) {
|
||||||
this(matchExpr, transform, placeholder, false);
|
this(matchExpr, transform, placeholder, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a SimpleMaskChar.
|
||||||
|
*
|
||||||
|
* @param matchExpr The matching predicate that determines which characters are masked.
|
||||||
|
* @param transform The transformation function that is applied to input characters.
|
||||||
|
* No transformation is applied by default.
|
||||||
|
* @param placeholder The placeholder character to use for masking.
|
||||||
|
* The default replacement is underscore character.
|
||||||
|
* @param fixed Boolean value indicating if the character is fixed or not.
|
||||||
|
* Default is false.
|
||||||
|
*/
|
||||||
public SimpleMaskChar(Predicate<Character> matchExpr,
|
public SimpleMaskChar(Predicate<Character> matchExpr,
|
||||||
UnaryOperator<Character> transform,
|
UnaryOperator<Character> transform,
|
||||||
char placeholder,
|
char placeholder,
|
||||||
@ -42,26 +74,42 @@ public final class SimpleMaskChar implements MaskChar {
|
|||||||
this.fixed = fixed;
|
this.fixed = fixed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isAllowed(final char ch) {
|
public boolean isAllowed(final char ch) {
|
||||||
return matchExpr.test(ch);
|
return matchExpr.test(ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public char transform(final char ch) {
|
public char transform(final char ch) {
|
||||||
return transform.apply(ch);
|
return transform.apply(ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public char getPlaceholder() {
|
public char getPlaceholder() {
|
||||||
return placeholder;
|
return placeholder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isFixed() {
|
public boolean isFixed() {
|
||||||
return fixed;
|
return fixed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A utility method for creating a fixed character - that is, the character used to represent
|
||||||
|
* the fixed part (a prefix or a suffix) of the input mask.
|
||||||
|
*/
|
||||||
public static SimpleMaskChar fixed(char ch) {
|
public static SimpleMaskChar fixed(char ch) {
|
||||||
return new SimpleMaskChar(c -> c == ch, UnaryOperator.identity(), ch, true);
|
return new SimpleMaskChar(c -> c == ch, UnaryOperator.identity(), ch, true);
|
||||||
}
|
}
|
||||||
|
5
base/src/main/java/atlantafx/base/util/package-info.java
Normal file
5
base/src/main/java/atlantafx/base/util/package-info.java
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
/**
|
||||||
|
* Provides various utility classes, formatters and converters.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package atlantafx.base.util;
|
@ -1,4 +1,7 @@
|
|||||||
/* SPDX-License-Identifier: MIT */
|
/**
|
||||||
|
* Provides additional controls, layout and Java API for
|
||||||
|
* custom themes support.
|
||||||
|
*/
|
||||||
|
|
||||||
module atlantafx.base {
|
module atlantafx.base {
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user