исчезновение JavaFX Popup, позволяющее получить дополнительный контент - PullRequest
1 голос
/ 23 февраля 2012

Вот класс, который нужно добавить как всплывающее окно, похожее на модальное диалоговое окно JQuery ... И с привязками вы можете добавлять контент, и он будет увеличиваться в размерах, я не смогу изменить его размер, так как размер контента остается То же самое, пока всплывающее окно не будет закрыто. Не стесняйтесь комментировать, улучшать, адаптировать и использовать

enter image description here

Он зафиксирован в центре экрана, но с небольшим количеством кода, который может быть подвижным .. (я просто еще не потрудился)

С уважением, D07114915

  package Utilities;

import javafx.animation.FadeTransition;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Bounds;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonBuilder;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.RectangleBuilder;
import javafx.util.Duration;

public class PopupMenu {

    private Group group;
    private Scene scene;
    private Node content;
    private Pane pane;
    private StackPane stackpane;
    private TilePane tile;
    private Rectangle outRectangle, inRectangle, borderRectangle;
    private Button closeBtn;
    private final Double MIN_HEIGHT = 60.0, MIN_WIDTH = 80.0;
    private Double height, width;
    private final SimpleDoubleProperty sdpHeightInRect = new SimpleDoubleProperty(0);
    private final SimpleDoubleProperty sdpWidthInRect = new SimpleDoubleProperty(0);
    private final SimpleDoubleProperty sdpHeightBorderRect = new SimpleDoubleProperty(0);
    private final SimpleDoubleProperty sdpWidthBorderRect = new SimpleDoubleProperty(0);
    private final SimpleDoubleProperty tileX = new SimpleDoubleProperty(0);
    private final SimpleDoubleProperty tileY = new SimpleDoubleProperty(0);
    private final SimpleDoubleProperty closeBtnX = new SimpleDoubleProperty(0);
    private final SimpleDoubleProperty closeBtnY = new SimpleDoubleProperty(0);
    private final int BORDER_SIZE = 3;
    private final int CONTENT_PADDING = 20;

    public PopupMenu(final Scene scene, final Node content) {
        this.content = content;
        this.content.setVisible(true);
        this.content.layoutBoundsProperty().addListener(new InvalidationListener() {

            @Override
            public void invalidated(Observable observable) {
                calculateWidthAndHeight();
            }
        });

        this.group = (Group) scene.getRoot();
        this.scene = scene;

        outRectangle = RectangleBuilder.create().width(scene.getWidth() - 2).height(scene.getHeight() - 2).opacity(0.2).fill(Color.BLACK).onMouseReleased(new EventHandler<MouseEvent>() {

            @Override
            public void handle(MouseEvent event) {
                event.consume();
                closeMenu();
            }
        }).build();

        inRectangle = RectangleBuilder.create().width(sdpHeightInRect.get()).height(sdpWidthInRect.get()).fill(Color.WHITESMOKE).arcHeight(10).arcWidth(10).opacity(0.9).build();
        inRectangle.heightProperty().bindBidirectional(sdpHeightInRect);
        inRectangle.widthProperty().bindBidirectional(sdpWidthInRect);

        borderRectangle = RectangleBuilder.create().width(sdpWidthBorderRect.get()).height(sdpHeightBorderRect.get()).arcHeight(10).arcWidth(10).opacity(0.9).build();
        borderRectangle.heightProperty().bindBidirectional(sdpHeightBorderRect);
        borderRectangle.widthProperty().bindBidirectional(sdpWidthBorderRect);

        tile = TilePaneBuilder.create().orientation(Orientation.HORIZONTAL).tileAlignment(Pos.CENTER).managed(false).children(this.content).build();
        tile.layoutXProperty().bindBidirectional(tileX);
        tile.layoutYProperty().bindBidirectional(tileY);

        stackpane = StackPaneBuilder.create().alignment(Pos.CENTER).children(outRectangle, borderRectangle, inRectangle, tile).build();

        closeBtn = ButtonBuilder.create().text("[X]").cancelButton(true).visible(true).onAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent event) {
                closeMenu();
            }
        }).build();

        closeBtn.layoutXProperty().bindBidirectional(closeBtnX);
        closeBtn.layoutYProperty().bindBidirectional(closeBtnY);

        pane = PaneBuilder.create().children(stackpane, closeBtn).build();

        //This is needed to fire to set everything first time around. Otherwise the display is not centered
        // when the popup is shown on subsequent ocasions without the content being altered
                calculateWidthAndHeight();
    }

    public void openMenu() {
        group.getChildren().addAll(pane);

        FadeTransition fadein = new FadeTransition(Duration.millis(800), pane);
        fadein.setFromValue(0.0);
        fadein.setToValue(1.0);
        fadein.play();
    }

    public void closeMenu() {
        FadeTransition fadeout = new FadeTransition(Duration.millis(700), pane);
        fadeout.setFromValue(1.0);
        fadeout.setToValue(0.0);
        fadeout.play();
        fadeout.setOnFinished(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent event) {
                group.getChildren().removeAll(pane);
            }
        });
    }

    private void calculateWidthAndHeight() {
        Bounds boundsInLocal = this.content.getBoundsInLocal();
        height = (boundsInLocal.getHeight() < MIN_HEIGHT) ? MIN_HEIGHT : boundsInLocal.getHeight();
        width = (boundsInLocal.getWidth() < MIN_WIDTH) ? MIN_WIDTH : boundsInLocal.getWidth();

        sdpHeightInRect.set(height + CONTENT_PADDING);
        sdpWidthInRect.set(width + CONTENT_PADDING);

        sdpHeightBorderRect.set(sdpHeightInRect.get() + BORDER_SIZE);
        sdpWidthBorderRect.set(sdpWidthInRect.get() + BORDER_SIZE);

        tileX.set(scene.getWidth() / 2 - width / 2);
        tileY.set(scene.getHeight() / 2 - height / 2);

        closeBtnX.set((scene.getWidth() / 2) - 18);
        closeBtnY.set((scene.getHeight() - (scene.getHeight() - borderRectangle.getHeight()) / 2) - (((borderRectangle.getHeight() - inRectangle.getHeight()) * 2)) - 5);
        System.err.println("H:" + height + ", W:" + width);
    }
}// end of class

Чтобы запустить это в вашем основном классе, вы должны сделать что-то вроде этого

Scene scene;

VBox popupBOX = VBoxBuilder.create().children(new Label("MY CONTENT").visible(false).build();

        final Button firePopup = ButtonBuilder.create().text("FIRE POPUP").build()).onAction(new EventHandler() {

        @Override
        public void handle(Event event) {
            new PopupMenu(scene, popupBOX).openMenu();
        }
    }).build()

И обратите внимание, что узел popupBOX должен быть добавлен уже к текущей рабочей сцене (это позволяет вычислять макет, ширину и т. Д.), Он просто скрыт, но установлен видимым в классе PopupMenu ....

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...