![JAR search and dependency download from the Maven repository](/logo.png)
javafx.scene.StyleTrigger Maven / Gradle / Ivy
package javafx.scene;
import com.sun.javafx.collections.TrackableObservableList;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
/**
* Style triggers dynamically add or remove style classes from a {@link Node} depending on a user-specified condition.
*
* If the condition is true, the specified style classes are added to the {@link Node#getStyleClass()} list;
* if it is false, the style classes are removed.
*
*
Once a style trigger is added to {@link Node#getStyleTriggers()}, it is attached to the node and can not
* be re-used for another node unless it is removed from the original node.
*/
public class StyleTrigger {
private final BooleanProperty condition = new SimpleBooleanProperty(this, "condition") {
@Override
protected void invalidated() {
boolean value = get();
if (node == null) {
return;
}
if (value) {
addStyleClasses(styleClass);
} else {
removeStyleClasses(styleClass);
}
}
};
private final ObservableList styleClass = new TrackableObservableList<>(new ArrayList<>(2)) {
@Override
protected void onChanged(ListChangeListener.Change c) {
if (node == null) {
return;
}
while (c.next()) {
if (c.getAddedSize() > 0 && isCondition()) {
addStyleClasses(c.getAddedSubList());
}
if (c.getRemovedSize() > 0) {
removeStyleClasses(c.getRemoved());
}
}
}
};
private Node node;
public StyleTrigger() {}
public StyleTrigger(String... styleClass) {
this.styleClass.addAll(styleClass);
}
/**
* Gets the list of style classes that will be dynamically added to the {@link Node}'s style class list.
*
* @return an {@link ObservableList} of style classes
*/
public ObservableList getStyleClass() {
return styleClass;
}
/**
* The condition that determines whether the style classes contained in {@link StyleTrigger#getStyleClass()}
* are added to the {@link Node}'s style class list.
*/
public BooleanProperty conditionProperty() {
return condition;
}
public boolean isCondition() {
return condition.get();
}
public void setCondition(boolean value) {
condition.set(value);
}
void setNode(Node node) {
if (this.node != null && node != null) {
throw new RuntimeException("Cannot re-use a StyleTrigger that is attached to a Node.");
}
if (node == null && this.node != null) {
removeStyleClasses(styleClass);
}
this.node = node;
if (node != null && isCondition()) {
addStyleClasses(styleClass);
}
}
private void addStyleClasses(List added) {
List nodeStyleClass = node.getStyleClass();
for (String style : added) {
if (!nodeStyleClass.contains(style)) {
nodeStyleClass.add(style);
}
}
}
private void removeStyleClasses(List removed) {
List nodeStyleClass = node.getStyleClass();
outer:
for (String style : removed) {
ListIterator it = nodeStyleClass.listIterator(nodeStyleClass.size());
while (it.hasPrevious()) {
String value = it.previous();
if (value != null && value.equals(style)) {
it.remove();
continue outer;
}
}
}
}
}