Ejemplo de calendario en JavaFX
No tenia mucho que hacer y vi que Java 7 trae un calendario (Swing), muy bonito, a mi gusto. En la noche tuve un poco de tiempo y quise crear el mio con JavaFX, pues aquí se los dejo y si lo pueden mejorar, pues agradecería enormemente lo compartieran.
Si tienes consejos, sugerencias, dudas, etc. me dices ok... :P
FechaItem: Esta clase es la unidad de una fecha en un mes de un año (jajajaja). Como atributo publico obtiene un objeto tipo Date. Deje un evento de tipo onMouseClicked para ejemplificar donde pones código para meterlo en una base de datos o lo que se le antoje, en este caso solo cambia de color y te dice por consola que día pinchaste y si esta libre o con cita.
import javafx.scene.CustomNode;
import javafx.scene.Group;
import javafx.scene.Node;
import java.util.Date;
import javafx.scene.paint.Color;
import java.util.Calendar;
import javafx.scene.control.Label;
import javafx.scene.shape.Rectangle;
import java.util.GregorianCalendar;
import javafx.scene.layout.Panel;
import javafx.scene.input.MouseEvent;
/**
* @author Rodrigo Salado Anaya
*/
public class FechaItem extends CustomNode {
/*atributos publicos*/
public var fecha: Date;
/*posibles colores de la fecha*/
def libre: Color = Color.WHITE;
def cita: Color = Color.LIGHTBLUE;
/*estado de la fecha*/
var estado: Boolean = true;
/*colores de la celda*/
var colorFill: Color = libre;
def colorStroke: Color = Color.BLACK;
/**/
var calendario: Calendar;
var fechaLabel: Label = Label {text: fechaToString() };
/*marco de la celda*/
public var marco: Rectangle = Rectangle {
width: 15
height: 15
fill: bind colorFill
stroke: colorStroke
strokeWidth: 0.2
}
function fechaToString(): String {
if (fecha == null) {
calendario = new GregorianCalendar();
return "";
} else {
calendario = new GregorianCalendar();
calendario.setTime(fecha);
return calendario.get(Calendar.DATE).toString();
}
}
var panel: Panel = Panel {
content: [marco, fechaLabel]
onLayout: function (): Void {
panel.positionNode(marco, 0, 0);
var w = fechaLabel.getPrefWidth(0);
var h = fechaLabel.getPrefHeight(0);
panel.layoutNode(fechaLabel, (marco.width - w) / 2, (marco.height - h) / 2, w, h);
}
}
public override function create(): Node {
return Group {
content: [panel]
onMouseClicked: function (e: MouseEvent): Void {
estado = not estado;
colorFill = if (estado) libre
else cita;
println("{fecha}:{if (estado) " Libre!!!" else " Cita"}");
}
};
}
}
MesItem: Representa el mes [0:Enero, 1:Febrero... 11:Diciembre] del año deseado. Recibe de manera publica un año como anio y un mes, tail y panel son los encargado de darle forma de cuadricula, aun así la función generaMes() es la encargada de generar los FechaItem con los datos deseados.
import javafx.scene.CustomNode;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.geometry.HPos;
import javafx.scene.layout.Panel;
import javafx.scene.layout.Tile;
import javafx.scene.shape.Rectangle;
import java.util.Calendar;
import java.util.GregorianCalendar;
/**
* @author Rodrigo Salado Anaya
*/
public class MesItem extends CustomNode {
/*atributos publicos*/
public var anio: Integer;
public var mes: Integer;
/*conjunto de fechas*/
var mesCalendario: FechaItem[];
var mesArr = [
"ENERO", "FEBRERO", "MARZO", "ABRIL",
"MAYO", "JUNIO", "JULIO", "AGOSTO",
"SEPTIEMBRE", "OCTUBRE", "NOVIEMBRE", "DICIEMBRE"
];
var mesLabel = Label {text: mesArr[mes] textFill: Color.BLACK font: Font {size: 14 } };
var dias = [
Label {text: "L" textFill: Color.DODGERBLUE },
Label {text: "M" textFill: Color.DODGERBLUE },
Label {text: "M" textFill: Color.DODGERBLUE },
Label {text: "J" textFill: Color.DODGERBLUE },
Label {text: "V" textFill: Color.DODGERBLUE },
Label {text: "S" textFill: Color.DODGERBLUE },
Label {text: "D" textFill: Color.DODGERBLUE }
];
function generaMes(): FechaItem[] {
/*asignamos la fecha deseada*/
var c: Calendar = new GregorianCalendar();
c.set(anio, mes, 1);
/*generamos las fechas vacias del inicio*/
var fechasVacias = c.get(Calendar.DAY_OF_WEEK) - Calendar.MONDAY;
if (fechasVacias < 0) {
fechasVacias = fechasVacias + 7;
}
mesCalendario = for (n in [1..fechasVacias]) {
FechaItem {};
}
/*generamos las fechas del mes*/
while (Integer.valueOf(c.get(Calendar.MONTH)) == mes) {
insert FechaItem {fecha: c.getTime() } into mesCalendario;
c.add(Calendar.DATE, 1);
}
/*generamos las fechas vacias del final del mes*/
for (n in [mesCalendario.size()..41]) {
insert FechaItem {} into mesCalendario;
}
/*return; regresamos todos los items de las fechas*/
mesCalendario;
};
var marco: Rectangle = Rectangle {
width: 170, height: 162
fill: Color.WHITE;
stroke: Color.BLACK;
}
/*acomoda los items de las fechas, y las etiquetas de los días*/
var tail: Tile = Tile {
columns: 8
hgap: 5
vgap: 5
hpos: HPos.CENTER
content: [dias, generaMes()]
}
/*mmmmm... a mi me gusta mucho usar 'panel' pero aqui lo use para acomodar todo*/
var panel: Panel = Panel {
content: [marco, mesLabel, tail]
onLayout: function (): Void {
panel.positionNode(marco, 0, 0);
var w = mesLabel.getPrefWidth(0);
var h = mesLabel.getPrefHeight(0);
var x = (marco.width - w) / 2;
var y = 2;
panel.layoutNode(mesLabel, x, y, w, h);
w = 150;
h = 500;
x = (marco.width - w) / 2;
y = 20;
panel.layoutNode(tail, x, y, w, h);
}
}
public override function create(): Node {
return Group {
content: [panel]
};
}
}
Por ejemplo para generar el mes de junio del año 2010 basta con crear un nodo así:
Y si quisiéramos generar todos los meses del 2010, podríamos usar algo así, donde tail se encarga de formar la cuadrilla:
function generaMeses(): MesItem[] {
mesesCalendario = for (n in [0..11]) {
MesItem {anio: 2010 mes: n }
}
}
var tail: Tile = Tile {
columns: 4
hgap: 5
vgap: 5
hpos: HPos.CENTER
content: [generaMeses()]
}
O crear un CustomNode como este:
public var anio: Integer;
var mesesCalendario: MesItem[];
function generaMeses(): MesItem[] {
mesesCalendario = for (n in [0..11]) {
MesItem {anio: anio mes: n }
}
}
var tail: Tile = Tile {
columns: 4
hgap: 5
vgap: 5
hpos: HPos.CENTER
content: [generaMeses()]
}
public override function create(): Node {
return Group {
content: [tail]
};
}
}
Entonces solo necesitaríamos crear un nodo así:
AnioItem{anio:2010}
Nota: http://www.javahispano.org/forum/j2se/es/como_crear_un_calendario_en_java/ , http://learnjavafx.typepad.com/weblog/2008/03/a-javafx-script.html y http://kenai.com/projects/jfxcalendarpicker/pages/Home , la verdad no le eche una leída intensa a la clase Calendar y todas las demás, como dije es solo un ejemplo, ya que se ve mucho código, y es muy posible que se pueda hacer mas sencillo y eficiente.
Nos leemos pronto y buen mes para todos :P
Adjunto | Tamaño |
---|---|
fullCal.png | 68.09 KB |
oneCal.png | 18.89 KB |
- rodrigo salado anaya's blog
- Inicie sesión o regístrese para enviar comentarios
Comentarios
Muy bien
Me agrada mucho que te interesaras en probar y hacer el calendario en JFX, yo nunca he usado JFX pero al ver el código entiendo la lógica sin saber exactamente la sintaxis, muy buen aporte. Sobre todo me agrada la vista que le da JFX a la interfaz es muy buena.
exelente trabajo, ojalá
exelente trabajo, ojalá pudieras mostrar algunos otros proyectos con javaFx para que los que nos iciamos en él, puédamos aprender. gran aporte
Fantastico aporte!!
Fantastico aporte!! Enhorabuena y muchas gracias!!