Sunday 21 April 2019

dialog in StackPane



package sam.fx.dialog;

import java.util.List;

import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.effect.DropShadow;
import javafx.scene.effect.Effect;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.Border;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.BorderStroke;
import javafx.scene.layout.BorderStrokeStyle;
import javafx.scene.layout.BorderWidths;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import sam.reference.WeakPool;

public class StackPaneDialogViewer implements DialogViewer {
    private final Effect effect = new DropShadow();
    private final List<Node> list;
    
    public StackPaneDialogViewer(StackPane root) {
        this.list = root.getChildren();
    }

    private Temp primary;
    private boolean primary_in_use;
    private final WeakPool<Temp> dialogs = new WeakPool<>(Temp::new); 

    @Override
    public Runnable viewDialog(String title, Node node, Runnable onClose) {
       // Node prev = list.isEmpty() ? null : list.get(list.size() - 1);
        Temp temp;

        if(primary_in_use) {
            temp = dialogs.poll();
        } else {
            if(primary == null)
                primary = new Temp();
            temp = primary;
            primary_in_use = true;
        }

        temp.pane.setCenter(node);
        temp.title.setText(title);
        list.add(temp);

        Runnable r = new Runnable() {
            boolean closed = false;

            @Override
            public void run() {
                if(closed)
                    return;

                closed = true;
                temp.close = null;
                temp.pane.setCenter(null);
                list.remove(temp);

                if(temp == primary)
                    primary_in_use = false;
                else
                    dialogs.add(temp);

                if(onClose != null)
                    onClose.run();
            }
        };
        
        temp.close = r;
        return r;
    }
    
    private class Temp extends Group implements EventHandler<ActionEvent> { 
        private Runnable close;
        private final BorderPane pane = new BorderPane();
        private Button button = new Button("X");
        private final Label title = new Label(); 
        
        public Temp() {
            
            BorderPane.setAlignment(title, Pos.CENTER_LEFT);
            title.setMaxWidth(Double.MAX_VALUE);
            title.setPadding(new Insets(0, 0, 0, 10));
            BorderPane top = new BorderPane(title, null, button, null, null);
            top.setBorder(new Border(new BorderStroke(Color.BLACK, BorderStrokeStyle.SOLID, CornerRadii.EMPTY, new BorderWidths(0, 0, 2, 0))));
            top.setPadding(new Insets(2));
            BorderPane.setMargin(top, new Insets(0,0,5,0));
                    
            pane.setTop(top);
            getChildren().add(pane);
            pane.setBackground(new Background(new BackgroundFill(Color.WHITE, new CornerRadii(2), Insets.EMPTY)));
            
            button.getStyleClass().clear();
            button.setPadding(new Insets(3, 7,3, 7));
            button.setBackground(new Background(new BackgroundFill(Color.RED, new CornerRadii(50, true), Insets.EMPTY)));
            button.setTextFill(Color.WHITE);
            button.setFont(Font.font("Consolas", FontWeight.BOLD, -1));
            
            button.setTranslateX(10);
            button.setTranslateY(-10);
            
            button.setOnAction(this);
            
            BorderPane.setAlignment(button, Pos.TOP_RIGHT);
            StackPane.setAlignment(this, Pos.CENTER);
            pane.setEffect(effect);
        }

        @Override
        public void handle(ActionEvent event) {
            close.run();
        }
    }
}


code highlighted using: hilite.me

StackPaneDialogViewer.java