All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
jidefx.scene.control.popup.ShapedPopup Maven / Gradle / Ivy
/*
* @(#)ShapedPopup.java 6/4/2013
*
* Copyright 2002 - 2013 JIDE Software Inc. All rights reserved.
*/
package jidefx.scene.control.popup;
import javafx.application.Platform;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Bounds;
import javafx.geometry.Insets;
import javafx.geometry.Point2D;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import javafx.scene.control.PopupControl;
import javafx.scene.effect.DropShadow;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Path;
import javafx.stage.Window;
import jidefx.utils.PredefinedShapes;
/**
* A {@link PopupControl} that can set an outline of any shape.
*/
public class ShapedPopup extends PopupControl {
private ObjectProperty _popupContentProperty;
private ObjectProperty _insetsProperty;
private ObjectProperty _popupOutlineProperty;
private BooleanProperty _closeButtonVisibleProperty;
public ShapedPopup() {
initializePopup();
initializeStyle();
}
protected void initializePopup() {
setAutoFix(false);
setAutoHide(true);
setHideOnEscape(true);
}
protected void initializeStyle() {
}
private void initializePath() {
Node content = getPopupContent();
content.getStyleClass().add("shaped-popup-content");
PopupOutline path = getPopupOutline();
path.getStyleClass().add("shaped-popup-outline");
customizePath(path);
Button closeButton = new Button();
closeButton.setVisible(isCloseButtonVisible());
closeButton.getStyleClass().add("shaped-popup-close-button");
closeButton.setOnAction(new EventHandler() {
@Override
public void handle(ActionEvent event) {
hide();
}
});
closeButton.setStyle("-fx-background-color: #ffffff00;");
Node clearIcon = PredefinedShapes.getInstance().createCloseIcon(20);
clearIcon.setEffect(new DropShadow(2, Color.DARKGRAY));
closeButton.setGraphic(clearIcon);
AnchorPane anchorPane = new AnchorPane(path, content, closeButton);
anchorPane.getStyleClass().add("shaped-popup");
anchorPane.setEffect(new DropShadow(8, Color.DARKGRAY));
path.widthProperty().bind(anchorPane.widthProperty());
path.heightProperty().bind(anchorPane.heightProperty());
Insets insets = getInsets();
Insets padding = path.getContentPadding();
AnchorPane.setTopAnchor(content, insets.getTop() + padding.getTop());
AnchorPane.setBottomAnchor(content, insets.getBottom() + padding.getBottom());
AnchorPane.setLeftAnchor(content, insets.getLeft() + padding.getLeft());
AnchorPane.setRightAnchor(content, insets.getRight() + padding.getRight());
adjustCloseButton(closeButton, padding);
closeButton.setVisible(isCloseButtonVisible());
Parent root = getScene().getRoot();
if(root instanceof Group) {
((Group) root).getChildren().setAll(anchorPane);
}
else if(root instanceof Pane) {
((Pane) root).getChildren().setAll(anchorPane);
}
InvalidationListener invalidationListener = new InvalidationListener() {
@Override
public void invalidated(Observable observable) {
anchorPane.requestLayout();
}
};
getScene().widthProperty().addListener(invalidationListener);
getScene().heightProperty().addListener(invalidationListener);
}
protected void adjustCloseButton(Button closeButton, Insets padding) {
AnchorPane.setTopAnchor(closeButton, padding.getTop() - 14.0);
AnchorPane.setRightAnchor(closeButton, padding.getRight() - 14.0);
}
/**
* Customizes the path.
*
* @param path the path to be customized
*/
protected void customizePath(Path path) {
path.setStroke(Color.LIGHTGRAY);
path.setFill(Color.WHITE);
path.setStrokeWidth(1);
path.setSmooth(true);
}
@Override
public void show(Window owner) {
throw new IllegalStateException("Please call one of the showPopup methods");
}
@Override
public void show(Node ownerNode, double screenX, double screenY) {
throw new IllegalStateException("Please call one of the showPopup methods");
}
@Override
public void show(Window ownerWindow, double screenX, double screenY) {
throw new IllegalStateException("Please call one of the showPopup methods");
}
public void showPopup(Node node, Pos pos) {
showPopup(node, pos, 0, 0);
}
public void showPopup(final Node node, final Pos pos, final double xOffset, final double yOffset) {
initializePath();
// bind with window
Window w = node.getScene().getWindow();
ChangeListener adjustListener = new ChangeListener() {
@Override
public void changed(ObservableValue extends Number> observable, Number oldValue, Number newValue) {
if (isShowing()) {
Runnable runnable = new Runnable() {
public void run() {
adjustPopup(node, pos, xOffset, yOffset, false);
}
};
Platform.runLater(runnable);
}
}
};
w.xProperty().addListener(adjustListener);
w.yProperty().addListener(adjustListener);
w.widthProperty().addListener(adjustListener);
w.heightProperty().addListener(adjustListener);
getScene().widthProperty().addListener(adjustListener);
getScene().heightProperty().addListener(adjustListener);
adjustPopup(node, pos, xOffset, yOffset, true);
}
public void adjustPopup(Node node, Pos pos, double xOffset, double yOffset) {
adjustPopup(node, pos, xOffset, yOffset, false);
}
private void adjustPopup(Node node, Pos pos, double xOffset, double yOffset, boolean show) {
Bounds bounds = node.getBoundsInLocal();
// use the center of the node as the starting point
double w = bounds.getWidth();
double h = bounds.getHeight();
Point2D p = node.localToScreen(bounds.getMinX() + w / 2 + xOffset, bounds.getMinY() + h / 2 + yOffset);
double x = p.getX();
double y = p.getY();
switch (pos) {
case CENTER:
case BASELINE_CENTER:
break;
case CENTER_RIGHT:
case BASELINE_RIGHT:
x += w / 2;
break;
case CENTER_LEFT:
case BASELINE_LEFT:
x -= w / 2;
break;
case BOTTOM_RIGHT:
x += w / 2;
y += h / 2;
break;
case BOTTOM_LEFT:
x -= w / 2;
y += h / 2;
break;
case BOTTOM_CENTER:
y += h / 2;
break;
case TOP_RIGHT:
x += w / 2;
y -= h / 2;
break;
case TOP_LEFT:
x -= w / 2;
y -= h / 2;
break;
case TOP_CENTER:
y -= h / 2;
break;
}
if (show) {
super.show(node, x, y);
}
// adjust the anchor point.
PopupOutline path = getPopupOutline();
Point2D anchorPoint = path.getOriginPoint();
setX(x - anchorPoint.getX());
setY(y - anchorPoint.getY());
}
public ObjectProperty insetsProperty() {
if (_insetsProperty == null) {
_insetsProperty = new SimpleObjectProperty<>(this, "insets", new Insets(10)); //NON-NLS
}
return _insetsProperty;
}
/**
* Gets the insets for the popup.
*
* @return the insets for the popup.
*/
public Insets getInsets() {
return insetsProperty().get();
}
/**
* Sets the insets for the popup.
*
* @param insets the insets for the popup.
*/
public void setInsets(Insets insets) {
insetsProperty().set(insets);
}
public ObjectProperty popupContentProperty() {
if (_popupContentProperty == null) {
_popupContentProperty = new SimpleObjectProperty<>(this, "popupContent"); //NON-NLS
}
return _popupContentProperty;
}
/**
* Gets the popup content.
*
* @return the popup content.
*/
public Node getPopupContent() {
return popupContentProperty().get();
}
/**
* Sets the content for the popup.
*
* @param content the content for the popup.
*/
public void setPopupContent(Node content) {
popupContentProperty().set(content);
}
public ObjectProperty popupOutlineProperty() {
if (_popupOutlineProperty == null) {
_popupOutlineProperty = new SimpleObjectProperty(this, "popupOutline", new RectanglePopupOutline()); //NON-NLS
}
return _popupOutlineProperty;
}
/**
* Gets the popup outline.
*
* @return the popup outline.
*/
public PopupOutline getPopupOutline() {
return popupOutlineProperty().get();
}
/**
* Sets the outline for the popup.
*
* @param popupOutline the outline for the popup.
*/
public void setPopupOutline(PopupOutline popupOutline) {
popupOutlineProperty().set(popupOutline);
}
public BooleanProperty closeButtonVisibleProperty() {
if (_closeButtonVisibleProperty == null) {
_closeButtonVisibleProperty = new SimpleBooleanProperty(this, "closeButtonVisible", false);
}
return _closeButtonVisibleProperty;
}
/**
* Checks if the close button is visible.
*
* @return true if visible. Otherwise false.
*/
public boolean isCloseButtonVisible() {
return closeButtonVisibleProperty().get();
}
/**
* Sets the close button visible or invisible.
*
* @param closeButtonVisible true or false.
*/
public void setCloseButtonVisible(boolean closeButtonVisible) {
closeButtonVisibleProperty().set(closeButtonVisible);
}
}