【问题标题】:Own minimize button with effect自带最小化按钮效果
【发布时间】:2018-11-23 00:30:06
【问题描述】:
@FXML
void minimize(MouseEvent event) {
    Stage stage=(Stage) iconMinimize.getScene().getWindow();
    stage.setIconified(true);
}

我有一个图标,可以通过鼠标单击来最小化我的程序。例如,当我为某个程序最小化 Windows 时,您可以看到该程序如何使用效果。程序慢慢移回任务栏。我也想有这样的效果。如果我使用顶部的代码执行此操作,则该程序就在系统托盘中。怎样才能得到这样的效果?

【问题讨论】:

    标签: java javafx icons minimize


    【解决方案1】:

    当你想要图标化应用程序时动画窗口大小并在Stage恢复时听iconified属性做反向动画:

    @Override
    public void start(Stage primaryStage) {
        StageHideAnimator.create(primaryStage);
    
        Button minimize = new Button("minimize");
        minimize.setOnAction(evt -> {
            StageHideAnimator animator = StageHideAnimator.getStageHideAnimator((Node) evt.getSource());
            animator.iconify();
        });
    
        Button close = new Button("close");
        close.setOnAction(evt -> primaryStage.close());
    
        VBox content = new VBox(minimize, close, new Rectangle(200, 200, Color.BLUE));
        content.setPadding(new Insets(10));
        content.setStyle("-fx-background-color: green;");
    
        primaryStage.initStyle(StageStyle.TRANSPARENT);
    
        Scene scene = new Scene(content);
    
        primaryStage.setScene(scene);
        primaryStage.setOnShown(evt -> {
            WindowUtils.placeAtPrimaryScreenBottom(primaryStage);
        });
        primaryStage.show();
    }
    
    public final class WindowUtils {
    
        private WindowUtils() { }
    
        public static void placeAtPrimaryScreenBottom(Stage stage) {
            stage.setY(Screen.getPrimary().getVisualBounds().getMaxY() - stage.getHeight());
        }
    
    }
    
    public class StageHideAnimator {
    
        // key used for storing animators in the properties map of a Stage
        private static final Object PROPERTY_KEY = new Object();
    
        private double sceneHeight;
        private double decorationHeight;
        private final Stage stage;
        private Timeline animation;
    
        // fraction of height relative to full height
        private final DoubleProperty height = new SimpleDoubleProperty();
    
        // getter for the animator
        public static StageHideAnimator getStageHideAnimator(Stage stage) {
            return (StageHideAnimator) stage.getProperties().get(PROPERTY_KEY);
        }
    
        // get animator of window containing the node
        public static StageHideAnimator getStageHideAnimator(Node node) {
            return getStageHideAnimator((Stage) node.getScene().getWindow());
        }
    
        private StageHideAnimator(Stage stage) {
            this.stage = stage;
            stage.iconifiedProperty().addListener((o, oldValue, newValue) -> {
                // do reverse hide animation when stage is shown
                if (!newValue) {
                    animation.setRate(-1);
    
                    if (animation.getStatus() == Animation.Status.STOPPED) {
                        animation.playFrom("end");
                    } else {
                        animation.play();
                    }
                }
            });
            height.addListener((o, oldValue, newValue) -> {
                // resize stage and put it at the bottom of the primary screen
                stage.setHeight(sceneHeight * newValue.doubleValue() + decorationHeight);
                WindowUtils.placeAtPrimaryScreenBottom(stage);
            });
        }
    
        public static StageHideAnimator create(Stage stage) {
            if (stage.getProperties().containsKey(PROPERTY_KEY)) {
                // don't allow 2 animators
                throw new IllegalArgumentException("animator already exists");
            }
    
            StageHideAnimator animator = new StageHideAnimator(stage);
            stage.getProperties().put(PROPERTY_KEY, animator);
            return animator;
        }
    
        private void initHeight() {
            sceneHeight = stage.getScene().getHeight();
            decorationHeight = stage.getHeight() - sceneHeight;
        }
    
        public void iconify() {
            if (stage.isIconified()) {
                return;
            }
    
            if (animation == null) {
                initHeight(); // save initial height of stage
    
                animation = new Timeline(
                        new KeyFrame(Duration.ZERO, new KeyValue(height, 1d, Interpolator.EASE_BOTH)),
                        new KeyFrame(Duration.seconds(1), new KeyValue(height, 0d, Interpolator.EASE_BOTH)));
    
                animation.setOnFinished(evt -> {
                    if (animation.getRate() == 1) {
                        // iconify at end of hiding animation
                        animation.setRate(-1);
                        stage.setIconified(true);
                    }
                });
    
                animation.play();
            } else {
                animation.setRate(1);
                if (animation.getStatus() == Animation.Status.STOPPED) {
                    initHeight(); // save initial height of stage
                    animation.playFromStart();
                } else {
                    animation.play();
                }
            }
        }
    
    }
    

    【讨论】:

    • 首先,非常感谢。我已经将我的程序外包了 3 个部分。 Main.java、Controller.java 和 sample.fxml。如何将最小化按钮移动到 Controller.java 类,以便 animator.iconify (); 工作。
    猜你喜欢
    • 1970-01-01
    • 2013-04-17
    • 1970-01-01
    • 2015-05-02
    • 2020-07-31
    • 2012-10-17
    • 1970-01-01
    • 2019-06-18
    • 1970-01-01
    相关资源
    最近更新 更多