Java 处理PopupWindow中的事件

Java 处理PopupWindow中的事件,java,datepicker,javafx,javafx-8,timepicker,Java,Datepicker,Javafx,Javafx 8,Timepicker,我自己做了一个计时器,它的工作原理应该和DatePicker非常相似。我想知道处理事件的最佳方式,例如选择时间并从弹出窗口确认时间 我可以: 使我的时间选择器的弹出节点(一个单独的FXML和控制器)定义一个接口,并强制时间选择器父节点实现处理所选日期的方法。(我非常希望避免以这种方式使用接口。这似乎是一种非常糟糕的方式。) 在弹出窗口中注册某种自定义EventHandler和侦听器?然后,如果在从弹出窗口中选择日期后单击OK,则可以一直激发事件直到时间选择器 实现某种类似回调的函数。例如,在安

我自己做了一个计时器,它的工作原理应该和DatePicker非常相似。我想知道处理事件的最佳方式,例如选择时间并从弹出窗口确认时间

我可以:

  • 使我的时间选择器的弹出节点(一个单独的FXML和控制器)定义一个接口,并强制时间选择器父节点实现处理所选日期的方法。(我非常希望避免以这种方式使用接口。这似乎是一种非常糟糕的方式。)
  • 在弹出窗口中注册某种自定义EventHandler和侦听器?然后,如果在从弹出窗口中选择日期后单击OK,则可以一直激发事件直到时间选择器
  • 实现某种类似回调的函数。例如,在安卓系统中,可以选择转到另一个屏幕来检索结果。我不确定JavaFX是否有这种功能。这些屏幕彼此非常分开

只需公开表示该值的
ReadOnlyProperty
。弹出窗口的用户可以观察属性

下面是使用日期选择器的概念证明:

import java.time.LocalDate;

import javafx.application.Application;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.geometry.Bounds;
import javafx.geometry.Insets;
import javafx.geometry.Point2D;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.DatePicker;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Popup;
import javafx.stage.PopupWindow;
import javafx.stage.Stage;


public class DatePickerPopupExample extends Application {

    @Override
    public void start(Stage primaryStage) {
        Label dateLabel = new Label(LocalDate.now().toString());
        Button changeButton = new Button("Change");

        HBox root = new HBox(5, dateLabel, changeButton);
        root.setAlignment(Pos.CENTER);

        changeButton.setOnAction(event -> {
            DatePickerPopup popup = new DatePickerPopup();
            popup.valueProperty().addListener((obs, oldDate, newDate) -> {
                dateLabel.setText(newDate.toString());
            });
            Bounds buttonBds = changeButton.getBoundsInLocal();
            Point2D loc = changeButton.localToScreen(buttonBds.getMaxX(), buttonBds.getMinY());
            popup.showPopup(primaryStage, loc.getX(), loc.getY());
        });

        Scene scene = new Scene(root, 250, 150);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public class DatePickerPopup  {
        private final ReadOnlyObjectWrapper<LocalDate> value = new ReadOnlyObjectWrapper<>();

        private final Popup popup ;

        public ReadOnlyObjectProperty<LocalDate> valueProperty() {
            return value.getReadOnlyProperty();
        }

        public final LocalDate getValue() {
            return valueProperty().get();
        }
        public DatePickerPopup(LocalDate date) {

            value.set(date);

            DatePicker picker = new DatePicker(date);
            Button okButton = new Button("OK");
            okButton.setOnAction(event -> {
                popup.hide();
                value.set(picker.getValue());
            });
            Button cancelButton = new Button("Cancel");
            cancelButton.setOnAction(event -> {
                popup.hide();
            });

            BorderPane root = new BorderPane();
            root.setCenter(picker);
            HBox buttons = new HBox(5, okButton, cancelButton);
            buttons.setPadding(new Insets(5));
            buttons.setAlignment(Pos.CENTER);
            root.setBottom(buttons);

            popup = new Popup();
            popup.getContent().add(root);
        }

        public DatePickerPopup() {
            this(LocalDate.now());
        }

        public void showPopup(Stage owner, double x, double y) {
            popup.show(owner, x, y);
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}
import java.time.LocalDate;
导入javafx.application.application;
导入javafx.beans.property.ReadOnlyObject属性;
导入javafx.beans.property.ReadOnlyObjectWrapper;
导入javafx.geometry.Bounds;
导入javafx.geometry.Insets;
导入javafx.geometry.Point2D;
导入javafx.geometry.Pos;
导入javafx.scene.scene;
导入javafx.scene.control.Button;
导入javafx.scene.control.DatePicker;
导入javafx.scene.control.Label;
导入javafx.scene.layout.BorderPane;
导入javafx.scene.layout.HBox;
导入javafx.stage.Popup;
导入javafx.stage.PopupWindow;
导入javafx.stage.stage;
公共类DatePickerPopupExample扩展应用程序{
@凌驾
公共无效开始(阶段primaryStage){
Label dateLabel=新标签(LocalDate.now().toString());
按钮更改按钮=新按钮(“更改”);
HBox root=新HBox(5,日期标签,更改按钮);
根部设置对齐(位置中心);
changeButton.setOnAction(事件->{
DatePickerPopup=新建DatePickerPopup();
popup.valueProperty().addListener((obs、oldDate、newDate)->{
dateLabel.setText(newDate.toString());
});
Bounds buttonBds=changeButton.getBoundsInLocal();
Point2D loc=changeButton.localToScreen(buttonBds.getMaxX(),buttonBds.getMinY());
showPopup(primaryStage,loc.getX(),loc.getY());
});
场景=新场景(根,250,150);
初级阶段。场景(场景);
primaryStage.show();
}
公共类DatePickerPopup{
私有最终ReadOnlyObjectWrapper值=新的ReadOnlyObjectWrapper();
私有最终弹出窗口;
public ReadOnlyObjectProperty valueProperty(){
返回值。getReadOnlyProperty();
}
公共最终LocalDate getValue(){
返回valueProperty().get();
}
public datepickerpoup(LocalDate-date){
值。设置(日期);
日期选择器选择器=新的日期选择器(日期);
按钮OK按钮=新按钮(“OK”);
OK按钮。设置操作(事件->{
popup.hide();
set(picker.getValue());
});
按钮取消按钮=新按钮(“取消”);
取消按钮。设置操作(事件->{
popup.hide();
});
BorderPane根=新的BorderPane();
根设置中心(选择器);
HBox按钮=新HBox(5,OK按钮,Cancel按钮);
按钮。设置填充(新插图(5));
按钮。设置对齐(位置中心);
root.setBottom(按钮);
popup=新的popup();
popup.getContent().add(根目录);
}
公共日期选择器opup(){
这是(LocalDate.now());
}
公共无效显示弹出窗口(舞台所有者,双x,双y){
弹出显示(所有者、x、y);
}
}
公共静态void main(字符串[]args){
发射(args);
}
}

只需公开一个表示该值的
ReadOnlyProperty
。弹出窗口的用户可以观察属性

下面是使用日期选择器的概念证明:

import java.time.LocalDate;

import javafx.application.Application;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.geometry.Bounds;
import javafx.geometry.Insets;
import javafx.geometry.Point2D;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.DatePicker;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Popup;
import javafx.stage.PopupWindow;
import javafx.stage.Stage;


public class DatePickerPopupExample extends Application {

    @Override
    public void start(Stage primaryStage) {
        Label dateLabel = new Label(LocalDate.now().toString());
        Button changeButton = new Button("Change");

        HBox root = new HBox(5, dateLabel, changeButton);
        root.setAlignment(Pos.CENTER);

        changeButton.setOnAction(event -> {
            DatePickerPopup popup = new DatePickerPopup();
            popup.valueProperty().addListener((obs, oldDate, newDate) -> {
                dateLabel.setText(newDate.toString());
            });
            Bounds buttonBds = changeButton.getBoundsInLocal();
            Point2D loc = changeButton.localToScreen(buttonBds.getMaxX(), buttonBds.getMinY());
            popup.showPopup(primaryStage, loc.getX(), loc.getY());
        });

        Scene scene = new Scene(root, 250, 150);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public class DatePickerPopup  {
        private final ReadOnlyObjectWrapper<LocalDate> value = new ReadOnlyObjectWrapper<>();

        private final Popup popup ;

        public ReadOnlyObjectProperty<LocalDate> valueProperty() {
            return value.getReadOnlyProperty();
        }

        public final LocalDate getValue() {
            return valueProperty().get();
        }
        public DatePickerPopup(LocalDate date) {

            value.set(date);

            DatePicker picker = new DatePicker(date);
            Button okButton = new Button("OK");
            okButton.setOnAction(event -> {
                popup.hide();
                value.set(picker.getValue());
            });
            Button cancelButton = new Button("Cancel");
            cancelButton.setOnAction(event -> {
                popup.hide();
            });

            BorderPane root = new BorderPane();
            root.setCenter(picker);
            HBox buttons = new HBox(5, okButton, cancelButton);
            buttons.setPadding(new Insets(5));
            buttons.setAlignment(Pos.CENTER);
            root.setBottom(buttons);

            popup = new Popup();
            popup.getContent().add(root);
        }

        public DatePickerPopup() {
            this(LocalDate.now());
        }

        public void showPopup(Stage owner, double x, double y) {
            popup.show(owner, x, y);
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}
import java.time.LocalDate;
导入javafx.application.application;
导入javafx.beans.property.ReadOnlyObject属性;
导入javafx.beans.property.ReadOnlyObjectWrapper;
导入javafx.geometry.Bounds;
导入javafx.geometry.Insets;
导入javafx.geometry.Point2D;
导入javafx.geometry.Pos;
导入javafx.scene.scene;
导入javafx.scene.control.Button;
导入javafx.scene.control.DatePicker;
导入javafx.scene.control.Label;
导入javafx.scene.layout.BorderPane;
导入javafx.scene.layout.HBox;
导入javafx.stage.Popup;
导入javafx.stage.PopupWindow;
导入javafx.stage.stage;
公共类DatePickerPopupExample扩展应用程序{
@凌驾
公共无效开始(阶段primaryStage){
Label dateLabel=新标签(LocalDate.now().toString());
按钮更改按钮=新按钮(“更改”);
HBox root=新HBox(5,日期标签,更改按钮);
根部设置对齐(位置中心);
changeButton.setOnAction(事件->{
DatePickerPopup=新建DatePickerPopup();
popup.valueProperty().addListener((obs、oldDate、newDate)->{
dateLabel.setText(newDate.toString());
});
Bounds buttonBds=changeButton.getBoundsInLocal();
Point2D loc=changeButton.localToScreen(buttonBds.getMaxX(),buttonBds.getMinY());
showPopup(primaryStage,loc.getX(),loc.getY());
});
场景=新场景(根,250,150);
初级阶段。场景(场景);
primaryStage.show();
}
公共类DatePickerPopup{