Reputation: 1939
When clicking the Add Appointment button the new form pops up, but the DatePicker is blank (should have LocalDate.now() populated), and none of the Saturday/Sunday dates are disabled. Tried calling the setup method in both Initialize and the method launching the new scene. Whether I put it in one or the other or both it never works. Please advise what I am doing wrong. Thank you.
Image showing DatePicker value blank and no disabled dates in Calendar.
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();
}
});
}
}
Upvotes: 1
Views: 1663
Reputation: 82461
The DatePicker
instance you create in setDatePicker()
is never added to the scene. It overwrites the DatePicker
object injected by FXMLLoader
when loading the fxml (unless you didn't properly add the fx:id
). All other modifications done in this method are done on this instance too.
You need to replace the line
datePicker = new DatePicker(LocalDate.now());
with
datePicker.setValue(LocalDate.now());
In general you shouldn't assing values to @FXML
annotated fields. If this is needed to "fix" a NullPointerException
or something similar, you just fix the symptoms instead of fixing the actual issue. There may be exceptions to this rule, but you need to be aware of the fact that you need to make sure that the node is added to the scene yourself.
Upvotes: 2