Tutorial del JCalendar con ejemplos, Java Swing.
Que mejor manera de controlar la fecha que un usuario ingresa que con un calendario en donde con un simple clic ya obtengamos Año, Mes y Día, en Java Swing no trae por defecto un componente que facilite este comportamiento, así que por eso hay que descargar una librería externa llamada JCalendar, dicha librería tiene varias funcionalidades, podemos elegir desde un calendario la fecha completa, la fecha de hoy, elegir una fecha maxima o minima para seleccionar, elegir solo un día, año o mes... En fin en este Tutorial de JCalendar vamos hacer varios ejemplos con las funcionalidades que ofrece utilizando el IDE JBoss Developer Studio o eclipse.
Tabla De Contenidos
1. Descargar JCalendar.
2. Crear proyecto Java.
3. Ejemplo de JCalendar.
4. Ejemplo de JDateChooser.
5. Ejemplo de JTextFieldDateEditor.
6. Ejemplo de JDayChooser.
7. Ejemplo de JMonthChooser.
8. Ejemplo de JYearChooser.
1. Descargar JCalendar.
Para realizar los ejemplos tenemos que descargar jcalendar-1.4.jar, y luego importarlo a nuestro classpath, puedes descargarlo desde aquí.
2. Crear proyecto Java.
Vamos a crear desde nuestro IDE un simple "Java Project" con el nombre de
JCalendarDatoJava
. Para eso recordamos que vamos a la opción de File> New> Java Project.
src
, creamos un paquete llamado datojava.jcalendar
, y dentro del mismo vamos a crear la clase DJJCalendar
en la cual vamos a desarrollar los ejemplos, aparte de eso vamos a crear otra clase llamada DJFechasEspInv
que extiende de la interface IDateEvaluator
en la cual vamos a desarrollar un ejemplo agregando fechas especiales/invalidas a nuestro JCalendar
. Por ultimo importamos la librería jcalendar-1.4.jar al classpath de nuestro proyecto y esta es la estructura que debería tener hasta ahora nuestro proyecto:
3. Ejemplo de JCalendar.
Hay varios componentes que ofrece esta librería, entre ellos esta el mas común
JCalendar
, que no es mas que un calendario en el cual podremos elegir una fecha:
JCalendar
:
private JCalendar calendar; // Instanciar Componente calendar = new JCalendar(); // Ubicar y agregar al panel calendar.setBounds... panel.add(calendar);A este
JCalendar
podemos agregarle/quitarle varias cosas, por ejemplo para agregar un boton que nos permita elegir la fecha de hoy:
calendar.setTodayButtonVisible(true);A ese boton podemos cambiarle el label (por defecto es "Hoy") de esta manera:
calendar.setTodayButtonText("Hoy Día");También podemos agregarle un boton para no seleccionar ninguna fecha:
calendar.setNullDateButtonVisible(true);Y de igual manera podemos cambiar el label por defecto ("Sin fecha"), así se ve el
JCalendar
con los botones:
Para quitar el numero de semanas:
calendar.setWeekOfYearVisible(false);
calendar.setMaxDayCharacters(1);
// Cambiar color de letra del numero de día calendar.setForeground(Color.GREEN); // Cambiar color de letra del dia domingo calendar.setSundayForeground(Color.BLUE); // Cambiar color de letra de semana calendar.setWeekdayForeground(Color.RED);Establecer una fecha en el
JCalendar
:
Calendar calendario = new GregorianCalendar(2014,5,10); calendar.setDate(calendario.getTime());
// Fecha minima seleccionable calendar.setMinSelectableDate(new Date()); // Fecha maxima seleccionable calendar.setMaxSelectableDate(new Date());Para establecer algunas fechas especiales o invalidas en el
JCalendar
, implementamos la clase DJFechasEspInv
que creamos anteriormente, si por ejemplo queremos establecer como fecha especial el día 24 de diciembre y como fecha invalida el dia 01 de Enero:
package datojava.jcalendar; import java.awt.Color; import java.util.Calendar; import java.util.Date; import com.toedter.calendar.IDateEvaluator; public class DJFechasEspInv implements IDateEvaluator { Calendar calendar = Calendar.getInstance(); public DJFechasEspInv() { } @Override public boolean isSpecial(Date date) { calendar.setTime(date); return calendar.get(Calendar.MONTH) == Calendar.DECEMBER && calendar.get(Calendar.DAY_OF_MONTH) == 24; } @Override public Color getSpecialForegroundColor() { return Color.GREEN; } @Override public Color getSpecialBackroundColor() { return Color.WHITE; } @Override public String getSpecialTooltip() { return "Es Navidad"; } @Override public boolean isInvalid(Date date) { calendar.setTime(date); return calendar.get(Calendar.MONTH) == Calendar.JANUARY && calendar.get(Calendar.DAY_OF_MONTH) == 01; } @Override public Color getInvalidForegroundColor() { return Color.WHITE; } @Override public Color getInvalidBackroundColor() { return Color.BLACK; } @Override public String getInvalidTooltip() { return "No es día Laborable"; } }Explicando un poco el codigo, en la implementación del metodo
boolean isSpecial(Date date)
(18), obtenemos la fecha y verificamos si coincide con el día "24 de Diciembre", en caso de ser cierto, ese día tendrá la letra de color verde (Color getSpecialForegroundColor()
(25)) y el fondo de color blanco (Color getSpecialBackroundColor()
(30)), adicionalmente vamos agregarle el ToolTip
con la descripción del día especial (String getSpecialTooltip()
(35)), lo propio hacemos con el día invalido que en este caso es el día "01 de Enero" (boolean isInvalid(Date date)
(40)), con la letra de color blanco (Color getInvalidForegroundColor()
(47)), el fondo de color negro (Color getInvalidBackroundColor()
(52)) y la descripción correspondiente (String getInvalidTooltip()
(57)). Ahora tenemos que agregarle esta clase el calendar:
calendar.getDayChooser().addDateEvaluator(new DJFechasEspInv());Ya con eso funciona, pero en el caso de que necesitemos hacer algo como esto no creo que sea solo con una fecha, así que para agregar varias fechas se complica un poco, pero para todo hay solución. En la clase
DJJCalendar
tenemos que hacer dos metodos, uno en el cual crearemos una lista con todas las fechas especiales y otro con una lista de ToolTip
por cada fecha especial, en el caso de que queramos agregar fechas invalidas creamos otro metodo adicional.Metodo que retorna la lista de fechas especiales:
public static ListMetodo que retorna la lista defechasEspeciales() { List fechas = new ArrayList (); Calendar calendar = new GregorianCalendar(2015, Calendar.SEPTEMBER, 10); fechas.add(calendar); calendar = new GregorianCalendar(2015, Calendar.NOVEMBER, 10); fechas.add(calendar); calendar = new GregorianCalendar(2015, Calendar.NOVEMBER, 18); fechas.add(calendar); return fechas; }
ToolTip
por cada fecha:
public static ListAhora en la implementación del metodotipFechas() { List tips = new ArrayList (); tips.add("Septiembre 10"); tips.add("Noviembre 10"); tips.add("Noviembre 18"); return tips; }
boolean isSpecial(Date date)
recorremos la lista de fechas especiales y vamos pintando en el calendario las mismas:
private int i = 0; @Override public boolean isSpecial(Date date) { calendar.setTime(date); for (i = 0; i < DJJCalendar.fechasEspeciales().size(); i++) { if (calendar.get(Calendar.MONTH) == DJJCalendar.fechasEspeciales() .get(i).get(Calendar.MONTH) && calendar.get(Calendar.DAY_OF_MONTH) == DJJCalendar .fechasEspeciales().get(i) .get(Calendar.DAY_OF_MONTH)) { return true; } } return false; }Hacemos lo propio en el metodo
String getSpecialTooltip()
, obtenemos la descripción en la posición correspondiente y la pintamos en el calendario
@Override public String getSpecialTooltip() { return DJJCalendar.tipFechas().get(i); }Hay mas propiedades con las que podemos jugar, todo depende de lo que necesitemos para nuestra aplicación.
4. Ejemplo de JDateChooser.
El
JDateChooser
es mucho mas util, ya que este componente nos presenta un campo de texto con un boton al lado, que al presionarlo nos muestra el JCalendar
descrito anteriormente, y al momento de seleccionar la fecha, la misma se muestra en el campo de texto:
JDateChooser
:
private JDateChooser dateChooser; // Instanciar Componente dateChooser = new JDateChooser(); // Ubicar y agregar al panel dateChooser.setBounds... panel.add(calendar);Obviamente a este componente también podemos modificarle sus propiedades, y como en si es otro
JCalendar
pero con un campo de texto, son practicamente las mismas propiedades, por ejemplo para obtener el JCalendar
y aplicar las modificaciones anteriores necesitamos este codigo:
dateChooser.getJCalendar();En el campo de texto que ofrece
JDateChooser
el usuario puede ingresar la fecha manualmente, en el caso de que ingrese cualquier tontería se mostrará en rojo y al obtener la fecha la misma sera null, para controlar este comportamiento podemos agregar un patron, una mascara, que le indique al usuario como debe ingresar la fecha si lo quiere hacer de forma manual. Con este codigo:
JDateChooser dateChooser = new JDateChooser("yyyy/MM/dd", "####/##/##", '_');Indicamos que solo puede ingresar numeros, año/mes/día y en el campo de texto se mostrará este patron "____/__/__" mientras no ingrese o seleccione una fecha.
JSpinnerDateEditor
, para que cuando el usuario ingrese una fecha pueda desplazarse sobre la misma.
JDateChooser dateChooser = new JDateChooser(null, null, null, new JSpinnerDateEditor());
JDateChooser
.
dateChooser.getDate();Como hemos visto el
JDateChooser
no es mas que un campo de texto con un JCalendar
que hace de popup al momento de presionar un boton.5. Ejemplo de JTextFieldDateEditor.
También podemos utilizar solamente el campo de texto
JTextFieldDateEditor
de esta manera.
private JTextFieldDateEditor textFieldDateEditor; // Instanciar Componente textFieldDateEditor = new JTextFieldDateEditor("yyyy/MM/dd", "####/##/##", '_'); // Ubicar y agregar al panel textFieldDateEditor.setBounds... panel.add(textFieldDateEditor);
Pasando a otros componentes utiles, podemos ver el
JDayChooser
, JMonthChooser
y el JYearChooser
.6. Ejemplo de JDayChooser.
JDayChooser
:
private JDayChooser dayChooser; // Instanciar Componente dayChooser = new JDayChooser(); // Ubicar y agregar al panel dayChooser.setBounds... panel.add(dayChooser);
7. Ejemplo de JMonthChooser.
JMonthChooser
private JMonthChooser monthChooser; // Instanciar Componente monthChooser = new JMonthChooser(); // Ubicar y agregar al panel monthChooser.setBounds... panel.add(monthChooser);
8. Ejemplo de JYearChooser.
JYearChooser
private JYearChooser yearChooser; // Instanciar Componente yearChooser = new JYearChooser(); // Ubicar y agregar al panel yearChooser.setBounds... panel.add(yearChooser);
Como puedo mostrar lo seleccionado en un JMonthChooser?
ResponderEliminarHola Hector, en el caso de que selecciones la fecha desde un JDateChooser y dependiendo de esa fecha quieras mostrar el mes seleccionado en un JMonthChooser podrías hacer algo como esto:
EliminarJMonthChooser monthChooser = new JMonthChooser();
// Le asignas el mes seleccionado en el JDateChooser
monthChooser.setMonth(dateChooser.getDate().getMonth());
Algo parecido puedes hacer con los otros componentes de JCalendar, todos tienen métodos parecidos.
Suerte!!
y si necesito buscar una fecha?? como le haria?
ResponderEliminarHola Ulises Lopez, necesito que te expliques mejor para poder ayudarte! No entiendo a que te refieres exactamente.
EliminarSuerte!!
...Excelente explicación, hay otras funciones interesantes que pueden ser manejadas como eventos en un JDateChooser, pero hay un error que aun tiene esta librería:
ResponderEliminarhttps://postimg.org/image/gw6xdhic9/
Detalle:
1. Click en jspinner del MonthChooser
2. Click en jcombobox del Montchooser
3. Click en cualquier parte fuera del Jcalendar...y salta el error
Estimado(a),
EliminarAcabo de descargar el proyecto, hice la prueba desde eclipse y no fui capaz de reproducir esa salida en la consola, siguiendo los pasos de tu imagen te puedo asegurar que no hay ningún error.
Suerte!!
Hola como podria saber si el usuario me deja vacia la fecha en un JDateChooser Gracias
ResponderEliminarEstimado, podrías hacer la pregunta de esta manera:
Eliminarif(jDateChooser.getDate() != null){
// no esta vacío
}
Saludos!
tengo dos jdatechooser, como puedo hacer para que seleccoinando un año en el primero, en el segundo jdatechooser tome el mismo año y no se pueda modificar ? me podrias ayudar con eso porfavor te dejo mi codigo
ResponderEliminar//desde aqui empieza lo del jdatechooser
String dia = Integer.toString(jdt.getCalendar().get(Calendar.DAY_OF_MONTH));
String mes = Integer.toString(jdt.getCalendar().get(Calendar.MONTH)+1);
String año = Integer.toString(jdt.getCalendar().get(Calendar.YEAR));
String fecha1 = año + "-" + mes +"-"+dia;
String dia2 = Integer.toString(jdt2.getCalendar().get(Calendar.DAY_OF_MONTH));
String mes2 = Integer.toString(jdt2.getCalendar().get(Calendar.MONTH)+1);
String año2 = Integer.toString(jdt2.getCalendar().get(Calendar.YEAR));
String fecha2 = año2 + "-" + mes2 +"-"+dia2;
Hola Arez Odesska, necesitas agregarle el PropertyChangeListener al JDateChooser y dentro de ese evento hacer tu codigo, un ejemplo de esto (Adaptado a tu codigo) sería algo así:
Eliminarjdt.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
public void propertyChange(java.beans.PropertyChangeEvent evt) {
// If the 'date' property was changed...
if ("date".equals(evt.getPropertyName())) {
try {
String año = Integer.toString(jdt.getCalendar().get(Calendar.YEAR));
Calendar cal = Calendar.getInstance();
cal.set(Integer.parseInt(año), 0, 01);
// Segundo JDateChooser
jdt2.setDate(cal.getTime());
jdt2.setEnabled(false);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
});
Esto tiene que funcionarte, Suerte!!
No sirve la implementacion de la lista, marca error
ResponderEliminarHola, manda el log del error para ayudarte a ver cual es el problema exacto!
EliminarBuenas Noches datojava he estado interesado en aplicar algunos tips que has puesto con el jCalendar pero en mi caso quisiera deshabilitar dias que ya pasaron y futuros dias (en mi caso que estoy haciendo una agenda).
ResponderEliminartengo un problema al querer aplicarlo
public static List fechasEspeciales() {
List fechas = new ArrayList();
Calendar calendar = new GregorianCalendar(2015, Calendar.SEPTEMBER, 10);
fechas.add(calendar);
calendar = new GregorianCalendar(2015, Calendar.NOVEMBER, 10);
fechas.add(calendar);
calendar = new GregorianCalendar(2015, Calendar.NOVEMBER, 18);
fechas.add(calendar);
return fechas;
}
me pide que cree la case calendar lo estoy implementando en un jFrame
agradeceria tu consejo o ayuda Saludis
por mas que intento no puedo. no soy de pedir ayuda pero esta vez no pude solucionar hasta hoy el problema.
ResponderEliminarTengo un JDateChooser. Quiero que cuando se cambie al año o el mes se actualice automaticamente la fecha que muestra. Solo se actualiza cuando se hace click en el dia y no en el año o mes. Gracias
Hola, la función de JDateChooser es esa, solo actualizara el TextField cuando se seleccione un día, recuerda que también puedes utilizar el JMonthChooser o JYearChooser.
EliminarSuerte!
Ayuda. Con el JDateChooser no puedo hacer que se actualice su fecha a menos que se haga click en el dia. Quiero que se actualice cuando hago click en el mes o en el año automaticamente por ejemplo selecciono diciembre y hago click en cualquier otra parte menos el boton del dia por ejemplo 10. no se actualiza la fecha del combobox. ¿porque?
ResponderEliminarHola buenas, como podria extraer la fecha seleccionada en un formato valido para introducirla en un base de datos sql?
ResponderEliminarGracias.
Hola David Ben, el problema aquí no es ese, con solo obtener la fecha jCal.getDate() obtienes la fecha, ahora la cuestión es, si esa fecha vas a formatearla con un DateFormat y en qué campo quieres agregar dicha fecha, depende del tipo de campo de sql. Si explicas un poco más puedo ayudarte con eso.
EliminarSuerte!!
Yo lo trabaje en Java de la siguiente manera:
EliminarDate date = jdcDate.getDate();
java.sql.Date sDate = new java.sql.Date(date.getTime());
return sDate;
Y el resultado me da "yyyy-MM-dd" siendo "2017-10-26".
Excelente Bryan, es una manera, depende de lo que se adapte a nuestra app.
EliminarSuerte!
Hola Buenas
ResponderEliminarTengo un problema con la implementación de un JCalendar en el que creo que podrías darme alguna orientación.
Tengo un formulario para mostrar un estadillo de jornadas en el cada trabajador dispone de un JCalendar en el que se muestra si trabaja de mañana, tarde,.... en función de un cambio en el color de fondo del día en cuestión.
El caso es que si pulsas en cualquiera de los días se muestran en un formulario anejo datos complementarios (hora de entrada, hora de salida, compañeros en la jornada,....) el problema es que al pulsar en ese día el color de fondo de la celda (que como te he dicho define que tipo de jornada es) cambia al que el JCalendar establece por defecto.
Sería posible evitar este comportamiento?
Muchas gracias por tu respuesta y un saludo
Hola Eu, claro que hay alguna manera de hacerlo, mándame una parte del código, por ejemplo en donde pintas el background. Me parece muy interesante lo que estás haciendo, si quieres compartir parte del proyecto me avisas y podría agregarlo a esta entrada!
EliminarSaludos!
Nivel un excelente aporte muhcas gracias por el tutorial me ayudo bastante...
ResponderEliminarHola Edgar, gracias por comentar! Suerte y Saludos!
Eliminarhola que tal, yo tengo otra consulta, ¿Cómo haría si el usuario quiere dejar un campo de fecha vacio?, es decir tengo varios campos de fecha, pero quizá hay uno que en esa ocasión no debe ir, como haría para que inserte vacio
ResponderEliminarAmig@, con dejar el campo vacío tienes, ahora si hablas de deshabilitar es otra cosa. Para deshabilitar el campo puedes hacer esto:
EliminardateChooser.setEnabled(false);
Suerte y saludos!
Como puedo poner el dateChooser otra vez en vacío es decir ya tiene información pero un método que lo vuelva otra vez vacío
EliminarAmigo Jesus, fácil, para poner el dateChooser de nuevo vacío puedes crear un método haciendo esto, dateChooser.setDate(null), es todo, espero te sirva,
EliminarSuerte!
hola, una pregunta el jdatechosser toma el idioma del computador o hay que hacer algo para que se pase de español a ingles los meses (december>diciembre) ?
ResponderEliminarDebe ser que esta tomando el idioma de tu computador, es lo mas seguro..
EliminarSuerte!
Muy buenas tardes como hago para que la fecha de datachooser me la muestre en una tabla, muchas gracias
ResponderEliminarHola. Como podria hacer para seleccionar una fecha en jdatechooser con el teclado sin el uso del mause. Es decir una vez q despliego el jdatechooser poder llegar al panel de dias con el tab o con enter y una vez sobre los dias utilizar las flechas para elejir el dia q quiera y luego con enter confirmarlo cerrando el jdatechooser
ResponderEliminar