DatePicker Control JavaFX para manejar fechas

El control DatePicker de JavaFX es un ComboxBox con la apariencia rediseñada, la fecha se puede cambiar escribiendo en el cuadro de texto directamente o seleccionando la fecha adecuada mediante el calendario que se muestra al desplegar el pop-up, en la primera fila ubicaremos el mes y año, en la segunda se establece el día.

Usando el constructor de la clase podemos indicar la fecha que se muestra inicialmente, si no lo indicamos el control se mostrará vacío, veamos este ejemplo:

DatePicker fecha1 = new DatePicker();

DatePicker fecha2 = new DatePicker(LocalDate.now());
fecha2.setEditable(false);

DatePicker control para fechas

Al segundo DatePicker le aplicamos setEditable(false) esto impide que se edite la fecha usando el control de texto, la misma solo se puede cambiar usando el calendario.

Podemos establecer la fecha programáticamente usando el método setValue(LocalDate) del mismo modo obtenemos la fecha actual a través de getValue() que devuelve un objeto LocalDate que puede ser nulo.

fecha1.setValue(LocalDate.of(2000, Month.JANUARY, 1));    
LocalDate date = fecha1.getValue();

Cambiar el formato de fecha

Si deseamos cambiar el formato en que se muestra la fecha seleccionada usaremos un objeto LocalDateStringConverter para indicar como se convierte el objeto LocalDate a una cadena de texto y viceversa.

fecha2.setConverter(new LocalDateStringConverter(FormatStyle.FULL));

Usando la enumeración FormatStyle seleccionamos el formato que deseamos utilizar, las opciones son: [FULL, LONG, MEDIUM, SHORT].

LocalDateTimeConverter de JavaFX

Podemos ser más específicos y establecer un patrón personalizado, en nuestro caso: "dd/MM/yy".

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yy");

DatePicker fecha2 = new DatePicker(LocalDate.now());
fecha2.setConverter(new LocalDateStringConverter(formatter, null));

Formato de fecha en un DatePicker

Si deseamos recibir una notificación cuando se cambia la fecha podemos usar el método setOnAction() para agregar un manejador de eventos, el evento se dispara cuando el usuario cambia la fecha.

DatePicker fecha1 = new DatePicker();
fecha1.setOnAction(e -> System.out.println("fecha: " +  fecha1.getValue()));

Personalizar las celdas del DatePicker

Para personalizar las celdas del calendario, aquellas que representan los días del mes, necesitaremos especificar el objeto DateCell encargado de crear dichas celdas, sobre escribiremos el método updateItem() para programar la funcionalidad.

Callback<DatePicker, DateCell> dayCellFactory = dp -> new DateCell() {
    @Override
    public void updateItem(LocalDate item, boolean empty) {

        super.updateItem(item, empty);
        
        this.setDisable(false);
        this.setBackground(null);
        this.setTextFill(Color.BLACK);

        // deshabilitar las fechas futuras
        if (item.isAfter(LocalDate.now())) {
            this.setDisable(true);
        }

        // marcar los dias de quincena
        int day = item.getDayOfMonth();
        if(day == 15 || day == 30) {

            Paint color = Color.RED;
            BackgroundFill fill = new BackgroundFill(color, null, null);
            
            this.setBackground(new Background(fill));
            this.setTextFill(Color.WHITESMOKE);
        }
        
        // fines de semana en color verde
        DayOfWeek dayweek = item.getDayOfWeek();
        if (dayweek == DayOfWeek.SATURDAY || dayweek == DayOfWeek.SUNDAY) {
            this.setTextFill(Color.GREEN);
        }
    }
};

Este código realiza las siguiente configuraciones:

1. Deshabilita todas los días superiores al actual, es decir nos podremos seleccionar fechas más haya de la actual.

if (item.isAfter(LocalDate.now())) {
    this.setDisable(true);
}

2. Resaltamos con un fondo de color rojo, los días importantes, los 15 y los 30 ya que nos pagarán nuestra quincena.

int day = item.getDayOfMonth();
if(day == 15 || day == 30) {

    Paint color = Color.RED;
    BackgroundFill fill = new BackgroundFill(color, null, null);
    
    this.setBackground(new Background(fill));
    this.setTextFill(Color.WHITESMOKE);
}

3. Los sábados y domingos por ser fines de semana los marcaremos en color verde.

DayOfWeek dayweek = item.getDayOfWeek();
if (dayweek == DayOfWeek.SATURDAY || dayweek == DayOfWeek.SUNDAY) {
    this.setTextFill(Color.GREEN);
}

Para indicarle al control DatePicker que debe usar esta configuración de celdas usamos el método setDayCellFactory(), ejemplo:

DatePicker fecha = new DatePicker();
fecha.setDayCellFactory(dayCellFactory);

DatePicker control JavaFX

Finalizamos mencionando que el método setShowWeekNumbers(true) le indica al calendario que debe mostrar el numero de semana, este se mostrará en el lateral izquierdo, por defecto esta funcionalidad está inactiva.

Descargar ejemplo: datepicker-javafx.zip

Comentarios

  1. Buenas que tal, me gustaria saber cual es el interfax que utilizas para que tus formularios sean asi estilo web. Desde ya gracias y saludos.

    ResponderEliminar
    Respuestas
    1. Esta tecnología se llama JavaFX y es parte de Java, puedes crear GUIs modernas y estilizadas con CSS, puedes ver más tutoriales en: http://acodigo.blogspot.com/p/java.html

      Eliminar
  2. Buenas tardes, una pregunta. Tengo una lista de Pedidos que traigo de la base de datos... Y los muestro en mi TableView... pero en una de las columnas del TableView necesito mostrar un valor count(rp.recibidos) que no hace parte del modelo(Person) de datos del TableView.. Como puedo mostrar el valor que necesito? El valor lo tengo en el ResultSet .. pero no se en donde añadirlo. Pues el metodo add() de los items de la tabla necesita un objecto de tipo Person.. pero el modelo Person no tiene el atributo count(rp.recibidos).. Pues count(rp.recibidos) solo es una sumatoria de cuantas veces aparece en otra tabla...

    ResponderEliminar

Publicar un comentario

Temas relacionados

Entradas populares de este blog

tkinter Grid

tkinter Canvas

Histogramas OpenCV Python

Python Binance API