【问题标题】:How do I initialize the DatePicker in a Java FXML app?如何在 Java FXML 应用程序中初始化 DatePicker?
【发布时间】:2019-07-02 00:00:07
【问题描述】:

单击添加约会按钮时,新表单会弹出,但 DatePicker 为空白(应填充 LocalDate.now()),并且周六/周日日期均未禁用。尝试在 Initialize 和启动新场景的方法中调用 setup 方法。无论我把它放在一个或另一个或两者中它都不起作用。请告知我做错了什么。谢谢。

显示 DatePicker 值空白且日历中没有禁用日期的图像。

package gci.controllers.dialogs;

import gci.App;
import gci.models.Appointment;
import gci.utilities.CustomerDAO;
import java.io.IOException;
import java.net.URL;
import java.sql.SQLException;
import java.time.*;
import java.util.*;
import java.util.logging.*;
import java.util.stream.*;
import javafx.collections.*;
import javafx.event.ActionEvent;
import javafx.fxml.*;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.*;
import javafx.util.*;

public class AddAppointmentController implements Initializable {

    @FXML private ChoiceBox<String> nameChoiceBox;
    @FXML private ChoiceBox<String> typeChoiceBox;
    @FXML private ChoiceBox<String> timeChoiceBox;
    @FXML private Label titleLabel;
    @FXML private Label copyrightLabel;
    @FXML private Button saveButton;
    @FXML private Button cancelButton;
    @FXML private DatePicker datePicker;

    private final CustomerDAO dao = new CustomerDAO();
    private Stage stage;
    private static final Region modal = new Region();

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        initApptChoiceBoxes();
        setDatePicker();
        setCopyright();
        modal.setStyle("-fx-background-color: #00000099;");
    }

    private void initApptChoiceBoxes() {
        try {
            nameChoiceBox.setItems(dao.retrieveAll().stream().map(m -> m.getName())
                .collect(Collectors.toCollection(FXCollections::observableArrayList)));
        } catch (SQLException ex) {
            Logger.getLogger(AddAppointmentController.class.getName()).log(Level.SEVERE, null, ex);
        }

        typeChoiceBox.setItems(FXCollections.observableArrayList("In-Person", "Phone", "WebMeeting"));
    }

    public void loadAddModifyAppointmentScene(Stage stage, Appointment appt) throws IOException {
        Stage addAppointmentForm = new Stage();
        FXMLLoader loader = new FXMLLoader();
        loader.setLocation(App.class.getResource("views/dialogs/add_appointment.fxml"));
        Parent root = loader.load();
        Parent parent = stage.getScene().getRoot();
        StackPane stack = new StackPane(parent, modal);
        modal.setVisible(true);
        stage.setScene(new Scene(stack));
        addAppointmentForm.setScene(new Scene(root));
        addAppointmentForm.initModality(Modality.WINDOW_MODAL);
        addAppointmentForm.initOwner(stage);
        addAppointmentForm.initStyle(StageStyle.UNDECORATED);
        AddAppointmentController controller = loader.getController();
        controller.setStage(addAppointmentForm);
        controller.setAppointment(appt);
        controller.setDatePicker();
        addAppointmentForm.show();
        addAppointmentForm.centerOnScreen();
    }

    private void setStage(Stage stage) {
        this.stage = stage;
    }

    private void setAppointment(Appointment appt) {
    }

    @FXML
    private void handleCancelButton(ActionEvent event) {
        this.stage.close();
        modalOff();
    }

    @FXML
    private void handleSaveButton(ActionEvent event) {

    }

    private void setCopyright() {
        int year = LocalDate.now().getYear();
        copyrightLabel.setText("Copyright © " + year + " Global Consulting Institution");
    }

    public void modalOff() {
        modal.setVisible(false);
    }

    private void setDatePicker() {
        datePicker = new DatePicker(LocalDate.now());
        StringConverter<LocalDate> converter = datePicker.getConverter();
        datePicker.setConverter(new StringConverter<LocalDate>() {
            @Override
            public String toString(LocalDate object) {
                return converter.toString(object);
            }

            @Override
            public LocalDate fromString(String string) {
                LocalDate date = converter.fromString(string);
                if (date.getDayOfWeek() == DayOfWeek.SATURDAY
                    || date.getDayOfWeek() == DayOfWeek.SUNDAY) {
                    return datePicker.getValue();
                } else {
                    return date;
                }
            }
        });

        datePicker.setDayCellFactory(d -> new DateCell() {
            @Override
            public void updateItem(LocalDate date, boolean empty) {
                super.updateItem(date, empty);
                setDisable(empty || date.getDayOfWeek() == DayOfWeek.SATURDAY
                    || date.getDayOfWeek() == DayOfWeek.SUNDAY);
            }
        });

        datePicker.valueProperty().addListener((obs, ov, nv) -> {
            if (nv.getDayOfWeek() == DayOfWeek.SATURDAY || nv.getDayOfWeek() == DayOfWeek.SUNDAY) {
                Alert alert = new Alert(Alert.AlertType.WARNING);
                alert.setTitle("Select Appointment");
                alert.setHeaderText(null);
                alert.setContentText("Business Hours are Mon - Fri, 8am - 5pm");
                alert.showAndWait();
            }
        });
    }

}

【问题讨论】:

  • @Zephyr 我在构造函数中设置了它。根据 JavaDoc “可以通过构造函数或调用 setValue() 来设置初始日期。”不过,我也尝试过使用 setValue,但还是不行。
  • 啊,是的,我确实错过了。

标签: java javafx datepicker fxml


【解决方案1】:

您在setDatePicker() 中创建的DatePicker 实例永远不会添加到场景中。它会在加载 fxml 时覆盖由FXMLLoader 注入的DatePicker 对象(除非您没有正确添加fx:id)。在此方法中完成的所有其他修改也在此实例上完成。

你需要换行

datePicker = new DatePicker(LocalDate.now());

datePicker.setValue(LocalDate.now());

一般情况下,您不应将值分配给 @FXML 带注释的字段。如果需要“修复”NullPointerException 或类似的东西,您只需修复症状而不是修复实际问题。此规则可能有例外,但您需要注意,您需要确保自己将节点添加到场景中。

【讨论】:

  • 使用 setValue 而不是新的构造函数有效!现在我的 DatePicker 禁用周六和周日,它还提供默认日期。虽然,我不确定我是否理解你最后的评论,所以如果你能澄清一下你是否说我应该以另一种方式禁用周末?感谢您的帮助。
猜你喜欢
  • 2015-12-19
  • 2013-07-02
  • 1970-01-01
  • 1970-01-01
  • 2015-06-10
  • 2015-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多