0% encontró este documento útil (0 votos)
418 vistas

Javafx 2 Tutorial

Este documento presenta la primera parte de un tutorial de JavaFX para crear una aplicación de direcciones. Explica cómo crear un nuevo proyecto JavaFX, dividir el código en paquetes según el patrón MVC, diseñar la interfaz gráfica con Scene Builder, y agregar la vista principal y de detalles al escenario principal mediante FXML y controladores.

Cargado por

Getreng Wae
Derechos de autor
© © All Rights Reserved
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
418 vistas

Javafx 2 Tutorial

Este documento presenta la primera parte de un tutorial de JavaFX para crear una aplicación de direcciones. Explica cómo crear un nuevo proyecto JavaFX, dividir el código en paquetes según el patrón MVC, diseñar la interfaz gráfica con Scene Builder, y agregar la vista principal y de detalles al escenario principal mediante FXML y controladores.

Cargado por

Getreng Wae
Derechos de autor
© © All Rights Reserved
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 63

http://edu.makery.

ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

JavaFX 2 Tutorial Parte I -


Generador de Escena
16 DE NOVIEMBRE TH , 2012

Objetivo
El objetivo de este tutorial es aprender cómo crear interfaces gráficas de usuario
con JavaFX 2 yConstructor de escena . Vamos a cubrir muchas características
de JavaFX 2 mediante la creación de una aplicación de direcciones y
mejorándola de forma paso a paso.
Temas en la Parte I
 Conocer JavaFX 2
 Creación e inicio de un proyecto JavaFX
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

 Mediante el Generador de escenas a diseñar la interfaz de usuario


 Estructura de la aplicación básica utilizando el patrón Modelo Vista Controlador 
(MVC)
Otras piezas Tutorial
 Parte I - Generador de Escena
 Parte II - Modelo y TableView
 Parte III - Interactuar con el usuario
 Parte IV - CSS Styling
 Parte V - Almacenamiento de datos como XML
 Parte VI - Estadísticas Gráfico
 Parte VII - Despliegue con e (fx)
( fx) clipse
Requisitos previos
 Últimas Java JDK 7 que incluye JavaFX 2.2 o superior.
 Eclipse 4.2 o más con e (fx) clipse plugin. La forma más fácil es descargar la
distro preconfigurada de la página
la página web
web clipse e (fx) .
 Escena Generador de 1,1 o mayor 
Preparación y enlaces útiles
Juega un poco con los widgets de JavaFX en el JavaFX Conjunto :
 JavaFX Ensemble es una galería de más de 100 aplicaci
aplicaciones
ones de ejemplo que
utilizan una amplia gama de funciones de JavaFX.
 Contiene código fuente para cada muestra.
 Contiene enlaces a documentación de la API (JavaDoc).
Otros enlaces útiles:

 JavaFX Tutoriales - Tutoriales oficiales de Oracle


 JavaFX 2 API - JavaDoc para las clases de JavaFX
 API Java 7 - JavaDoc para las clases Java estándar 
Ahora, vamos a empezar!
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

Crear un nuevo proyecto JavaFX


En Eclipse (con e (fx) clipse instalado) ir a File | New | Other ... y
seleccione Proyecto de JavaFX .Especifique el nombre del proyecto (es decir 
AddressApp).
Cree los paquetes
Desde el primer momento vamos a seguir los buenos principios de diseño de
software. Un principio muy importante es el de la Modelo-Vista-Controlador
(MVC) . De acuerdo con esto, dividimos nuestro código en tres unidades y crear 
un paquete para cada uno (Haga clic derecho en la carpeta src, New ... |
 Package ):
 Para las clases de controlador: ch.makery.address
 Para las clases de vista: ch.makery.address.view
 Para las clases del modelo: ch.makery.address.model
Creación del archivo de diseño FXML
Hay dos maneras de crear la interfaz de usuario. Cualquier uso de un archivo
XML o programación todo en Java. Mirando alrededor de la internet se
encontrará con ambos. Vamos a utilizar XML (que terminan en. Fxml) para la
mayoría de las partes. Me parece una forma más limpia de mantener el
controlador y el modelo separados unos de otros. Además, podemos utilizar el
Generador de escena gráfica para editar el XML. Eso significa que casi nunca
tienen que trabajar directamente con XML.

Haga clic en el paquete de vista y crear un nuevo documento


 FXML llamada PersonOverview .
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

Diseño con el Generador de Escena


Nota: Si te quedas atascado en algún lugar, ver
la Guía de introducción a JavaFX
Escena Constructor YouTube Film. Esto ayuda mucho!
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

Haga clic en PersonOverview.fxml y seleccione Abrir con el Generador de


 Escena . Ahora debería ver el Constructor Escena con sólo
un AncherPane (visible bajo la Jerarquía de la izquierda).
1. Seleccione el panel de anclaje en la Jerarquía y ajustar el tamaño en Diseño (lado
derecho):
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

2. Agregar un panel de Split (flujo horizontal) arrastrándolo desde la biblioteca a la


zona principal. Haga clic derecho y seleccione Ajustar a los padres .

3. Añadir un TableView en el lado izquierdo. Seleccione la TableView (no una


columna) y establezca las siguientes restricciones de diseño. Dentro de
un AnchorPane siempre se puede establecer puntos de anclaje para los cuatro
 bordes ( más información sobre los diseños ).

4. Ir al menú Ver | Vista previa en la ventana para ver, si se comporta bien. Trate de


cambiar el tamaño de la ventana. El TableView siempre debe mantener la
distancia 10px a la frontera circundante.
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

5. Cambiar el texto de la columna (bajo Propiedades) en "Nombre" y "Apellido" y


ajustar el tamaño.

6. Agregar una etiqueta a la derecha con el texto "Detalles Persona". Ajuste su


diseño mediante anclajes.
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

7. Añadir un GridPane en la parte derecha, seleccione y ajuste su diseño.


http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

8. Agregue un poco de filas (bajo Layout | GridPane Filas ). Añadir etiquetas a las


células.

9. Añadir los tres botones en la parte inferior. Tipp: Seleccione todos ellos, haga
clic derecho y llameWrap sesión | HBox . Esto, junto los agrupa. Es posible que
tenga que especificar un espaciado dentro de la caja horizontal.
10.Ahora usted debería ver algo como lo siguiente. Por favor, pruébelo usando el
menú Vista previa.
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

Creación de la aplicación Principal


 Necesitamos otro FXML para nuestro diseño raíz que contendrá una barra de
menú y ajusta el recién creado PersonOverview.fxml? .
1. Cree otro documento FXML dentro del embalaje del
llamado RootLayout.fxml . Esta vez, elija BorderPane como elemento raíz.

2. Abrirlo en el Generador de escena.

3. Cambiar el tamaño del BorderPane con Pref Ancho establece en 600 y Pref 


 Altura establece en 400.
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

4. Añadir un MenuBar en el TOP Slot. No vamos a implementar la funcionalidad


del menú en el momento.

5. Ahora, tenemos que crear el Java principal que inicia nuestra aplicación con
el RootLayout.fxml y agrega el PersonOverview.fxml en el centro.
6. Haga clic en el paquete del controlador,  New | Other ... y seleccione JavaFX 
clase principal . Lo llamaremos MainApp .

Básicos de la clase principal JavaFX


El generado MainApp.java clase se extiende desde la aplicación y contiene
dos métodos. Esta es la estructura básica que necesitamos para iniciar una
aplicación JavaFX. La parte más importante para nosotros es el comienzo
(primaryStage Stage) método. Se llama automáticamente cuando se ejecute la
aplicación.
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

Como puede ver, el comienzo (...) método recibe un escenario como


 parámetro. Es bueno entender el concepto básico de una aplicación gráfica con
JavaFX: Fuente de la imagen: http://www.oracle.com/ 

Es como una obra de teatro: El Stage es el contenedor principal, que suele ser una
ventana con un borde y el típico minimizar, maximizar y cerrar botones. Dentro
de la etapa de agregar una escena que puede, por supuesto, se cambió por otra
escena. Dentro de la escena se añaden los nodos reales JavaFX como
AnchorPane, TextBox, etc.

Abrir MainApp.java y reemplace el código con lo siguiente:


package ch.makery.address;

import java.io.IOException;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class MainApp extends Application {

private Stage primaryStage;


private BorderPane rootLayout;
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

@Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;
this.primaryStage.setTitle("AddressApp");

try {
// Load the root layout from the fxml file
FXMLLoader loader = new
FXMLLoader(MainApp.class.getResource("view/RootLayout.fxml"));
rootLayout = (BorderPane) loader.load();
Scene scene = new Scene(rootLayout);
primaryStage.setScene(scene);
primaryStage.show();
} catch (IOException e) {
// Exception gets thrown if the fxml file could not be loaded
e.printStackTrace();
}

showPersonOverview();
}

/**
* Returns the main stage.
* @return
*/
public Stage getPrimaryStage() {
return primaryStage;
}

/**
* Shows the person overview scene.
*/
public void showPersonOverview() {
try {
// Load the fxml file and set into the center of the main
layout
FXMLLoader loader = new
FXMLLoader(MainApp.class.getResource("view/PersonOverview.fxml"));
AnchorPane overviewPage = (AnchorPane) loader.load();
rootLayout.setCenter(overviewPage);

} catch (IOException e) {
// Exception gets thrown if the fxml file could not be loaded
e.printStackTrace();
}
}

public static void main(String[] args) {


launch(args);
}
}

Trate de entender el código. Los diversos comentarios deben darle algunas pistas
sobre lo que está pasando.
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

Si ejecuta la aplicación ahora, debería ver algo como la captura de pantalla al


inicio de este post.

JavaFX 2 Tutorial Parte II -


Modelo y TableView 
17 DE NOVIEMBRE TH , 2012

Los temas de la parte II


 La creación de un modelo de clase
 Utilización de la clase modelo en un ObservableList
 Mostrar datos de la TableView utilizando Controladores
Otras piezas Tutorial
 Parte I - Generador de Escena
 Parte II - Modelo y TableView
 Parte III - Interactuar con el usuario
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

 Parte IV - CSS Styling


 Parte V - Almacenamiento de datos como XML
 Parte VI - Estadísticas Gráfico
 Parte VII - Despliegue con e (fx) clipse
Crear la Clase Modelo
 Necesitamos un modelo de clase para guardar información sobre las personas en
nuestra libreta de direcciones. Añadir una nueva clase en el paquete modelo
( ch.makery.address.model ) denominado Person . Esto tiene sentido, ya que
queremos manejar a la gente y sus direcciones. La persona de clase tendrá
algunas variables de instancia para el nombre, dirección y fecha de
nacimiento. Agregue el código siguiente a la clase:
package ch.makery.address.model;

import java.util.Calendar;

/**
* Model class for a Person.
*
* @author Marco Jakob
*/
public class Person {

private String firstName;


private String lastName;
private String street;
private int postalCode;
private String city;
private Calendar birthday;

/**
* Default constructor.
*/
public Person() {
}

/**
* Constructor with some initial data.
*
* @param firstName
* @param lastName
*/
public Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;

// some initial dummy data


this.street = "some street";
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

this.postalCode = 1234;
this.city = "some city";
this.birthday = Calendar.getInstance();
}

public String getFirstName() {


return firstName;
}

public void setFirstName(String firstName) {


this.firstName = firstName;
}

public String getLastName() {


return lastName;
}

public void setLastName(String lastName) {


this.lastName = lastName;
}

public String getStreet() {


return street;
}

public void setStreet(String street) {


this.street = street;
}

public int getPostalCode() {


return postalCode;
}

public void setPostalCode(int postalCode) {


this.postalCode = postalCode;
}

public String getCity() {


return city;
}

public void setCity(String city) {


this.city = city;
}

public Calendar getBirthday() {


return birthday;
}

public void setBirthday(Calendar birthday) {


this.birthday = birthday;
}
}

Una lista de personas


http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

Los principales datos que nuestra aplicación gestiona es un grupo de


personas. Vamos a crear una lista de persona objetos dentro
del MainApp clase. Todas las demás clases de controlador después tener
acceso a la lista dentro de la MainApp .
ObservableList

Estamos trabajando con clases de vista JavaFX que siempre necesitan ser
informados de los cambios realizados en la lista de personas. Esto es
importante, ya que de lo contrario la vista no estaría en sintonía con los
datos. Para este propósito, JavaFX introduce algunas nuevas clases de
colección .
 A partir de esas colecciones, necesitamos la ObservableList . Para crear
un nuevo ObservableList , agregue el código siguiente al principio
del MainApp clase. También vamos a añadir un constructor que crea
algunos datos de ejemplo y un método getter público:
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;

// ...

/**
* The data as an observable list of Persons.
*/
private ObservableList<Person> personData =
FXCollections.observableArrayList();

/**
* Constructor
*/
public MainApp() {
// Add some sample data
personData.add(new Person("Hans", "Muster"));
personData.add(new Person("Ruth", "Mueller"));
personData.add(new Person("Heinz", "Kurz"));
personData.add(new Person("Cornelia", "Meier"));
personData.add(new Person("Werner", "Meyer"));
personData.add(new Person("Lydia", "Kunz"));
personData.add(new Person("Anna", "Best"));
personData.add(new Person("Stefan", "Meier"));
personData.add(new Person("Martin", "Mueller"));
}

/**
* Returns the data as an observable list of Persons.
* @return
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

*/
public ObservableList<Person> getPersonData() {
return personData;
}

El PersonOverviewController
 Ahora vamos a ver finalmente algunos datos en nuestra mesa.

1. Crear una clase normal, dentro del paquete controlador 


llamado PersonOverviewController.java.
2. Vamos a añadir algunas variables de instancia que nos dan acceso a la tabla y las
etiquetas dentro de la vista. Los campos y algunos métodos tienen una
especial FXML @ anotación. Esto es necesario para el archivo de fxml tener acceso
a esas variables. Después de que tengamos todo listo en el archivo fxml, la
aplicación rellenará automáticamente las variables cuando se carga el archivo
fxml.Así que vamos a agregar el siguiente código:
Nota: Recuerde que debe utilizar siempre las importaciones javafx (no
 AWT o swing)!

PersonOverviewController.java
1 public class PersonOverviewController {
2 @FXML
3 private TableView<Person> personTable;
4 @FXML
5 private TableColumn<Person, String> firstNameColumn;
6 @FXML
7 private TableColumn<Person, String> lastNameColumn;
8
9 @FXML
10 private Label firstNameLabel;
11 @FXML
12 private Label lastNameLabel;
13 @FXML
14 private Label streetLabel;
15 @FXML
16 private Label postalCodeLabel;
17 @FXML
18 private Label cityLabel;
19 @FXML
20 private Label birthdayLabel;
21
22 // Reference to the main application
23 private MainApp mainApp;
24
25 /**
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

26 * The constructor.
27 * The constructor is called before the initialize() method.
28 */
29 public PersonOverviewController() {
30 }
31
32 /**
33 * Initializes the controller class. This method is automatically
34 called
35 * after the fxml file has been loaded.
36 */
37 @FXML
38 private void initialize() {
39 // Initialize the person table
40 firstNameColumn.setCellValueFactory(new
41 PropertyValueFactory<Person, String>("firstName"));
42 lastNameColumn.setCellValueFactory(new
43 PropertyValueFactory<Person, String>("lastName"));
44 }
45
46 /**
47 * Is called by the main application to give a reference back to
48 itself.
49 *
50 * @param mainApp
51 */
52 public void setMainApp(MainApp mainApp) {
53 this.mainApp = mainApp;
54
// Add observable list data to the table
personTable.setItems(mainApp.getPersonData());
}
}

 Ahora bien, este código tendrá alguna explicación:

 Todos los campos y métodos donde el archivo fxml necesidades de acceso deben
ser anotados con @ FXML . En realidad, sólo si son privados, pero es mejor 
tenerlos privado y marcarlos con la anotación!.
 El initialize () método se llama de forma automática después de que se haya
cargado el archivo fxml. En este momento, todos los campos FXML deberían
haberse inicializado ya.
 El PropertyValueFactory que establecimos en las columnas de mesa se utilizan
 para determinar qué campo dentro de la persona objeto se debe utilizar para la
columna en particular.
 El setMainApp (...) método debe ser llamado por el MainApp clase. Esto nos
da una manera de acceder a la MainApp objeto y obtener la lista de datos y otras
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

cosas. De hecho, vamos a hacer esa llamada ahora. Vuelva a colocar 


la showPersonOverview () método con la siguiente. Contiene dos líneas
adicionales:
 MainApp.java
/**
1
* Shows the person overview scene.
2
*/
3
public void showPersonOverview() {
4
try {
5
// Load the fxml file and set into the center of the main layout
6
FXMLLoader loader = new
7
FXMLLoader(MainApp.class.getResource("view/PersonOverview.fxml"));
8
AnchorPane overviewPage = (AnchorPane) loader.load();
9
rootLayout.setCenter(overviewPage);
10
11
// Give the controller access to the main app
12
PersonOverviewController controller = loader.getController();
13
controller.setMainApp(this);
14
15
} catch (IOException e) {
16
// Exception gets thrown if the fxml file could not be loaded
17
e.printStackTrace();
18
}
19
}

Enganche la vista al controlador


 Ya casi llegamos! Pero una cosa que falta: Nosotros no hemos dicho
nuestra PersonOverview.fxmlarchivo, sin embargo, que el controlador de
usar y de qué elemento debe coincidir con el campo que en el interior del
controlador.
1. Abra PersonOverview.fxml con el Constructor de escena.
2. Seleccione la más alta AnchorPane en la Jerarquía.
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

3. Abierto Código en el lado derecho y seleccione


la PersonOverviewController como clase controlador .

4. Seleccione la TableView y elija en Propiedades del personTable campo fx: id .

5. Haga lo mismo para las columnas y


seleccione firstNameColumn y lastNameColumnrespectivamente.
6. Para cada etiqueta en la segunda columna, elija el correspondiente fx: id .
7. Importante: Volver a Eclipse y refrescar todo el proyecto AddressApp (F5). Esto
es necesario porque Eclipse veces no sabe acerca de los cambios que se hicieron
en el interior del generador de escena.
Inicio de la aplicación
 Al iniciar la aplicación ahora, usted debería ver algo como la captura de
pantalla al comienzo de esta entrada del blog.

¡Enhorabuena!
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

JavaFX 2 Tutorial Parte III


- Interacción con el
Usuario
20 DE NOVIEMBRE TH , 2012

Los temas de la Parte III


 Reaccionar a los cambios de selección en la tabla.
 Agregar funcionalidad al añadir , editar y eliminar botones.
 ¡Crea una alfombrilla de diálogo emergente para editar una persona.
 Validar la entrada del usuario .
Otras piezas Tutorial
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

 Parte I - Generador de Escena


 Parte II - Modelo y TableView
 Parte III - Interactuar con el usuario
 Parte IV - CSS Styling
 Parte V - Almacenamiento de datos como XML
 Parte VI - Estadísticas Gráfico
 Parte VII - Despliegue con e (fx) clipse
Reaccionar a la tabla Selección
Obviousely, no hemos utilizado el lado derecho de nuestra aplicación,
todavía. La idea es que cuando el usuario selecciona una persona en la mesa, los
detalles acerca de esa persona se debe mostrar en el lado derecho.

En primer lugar, vamos a añadir un nuevo método dentro


de PersonOverviewController que nos ayuda a rellenar las etiquetas con los
datos de una sola persona .
Cree un método llamado showPersonDetails (persona Person) . Tras pasar 
 por todas las etiquetas y establecer el texto usando setText (...) con los
detalles de la persona. Si nulo se pasa como parámetro, todas las etiquetas deben
ser borrados.
PersonOverviewController.java
1 /**
2 * Fills all text fields to show details about the person.
3 * If the specified person is null, all text fields are cleared.
4 *
5 * @param person the person or null
6 */
7 private void showPersonDetails(Person person) {
8
9 // use setText(...) on all labels with info from the person object
10 // use setText("") on all labels if the person is null
11 }

Convertir la Fecha de cumpleaños a una cadena

Si ha implementado el método anterior, se habrá dado cuenta de que


necesitamos una manera de convertir el Calendario del campo de
cumpleaños a un String. En una etiqueta sólo podemos mostrar Strings.
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

 Vamos a utilizar la conversión de calendario y secuencia (y viceversa) en


 varios lugares. Es una buena práctica para crear una clase de ayuda
con estáticas métodos para ello. Lo llamaremos CalendarUtil y 
colóquela en un paquete separado llamado ch.makery.address.util :
(CalendarUtil.java) download
1 package ch.makery.address.util;
2
3 import java.text.ParseException;
4 import java.text.SimpleDateFormat;
5 import java.util.Calendar;
6
7 /**
8 * Helper functions for handling dates.
9 */
10 public class CalendarUtil {
11
12 /**
13 * Default date format in the form 2013-03-18.
14 */
15 private static final SimpleDateFormat DATE_FORMAT = new
16 SimpleDateFormat("yyyy-MM-dd");
17
18 /**
19 * Returns the given date as a well formatted string. The above
20 defined date
21 * format is used.
22 *
23 * @param calendar date to be returned as a string
24 * @return formatted string
25 */
26 public static String format(Calendar calendar) {
27 if (calendar == null) {
28 return null;
29 }
30 return DATE_FORMAT.format(calendar.getTime());
31 }
32
33 /**
34 * Converts a String in the format "yyyy-MM-dd" to a Calendar object.
35 *
36 * Returns null if the String could not be converted.
37 *
38 * @param dateString the date as String
39 * @return the calendar object or null if it could not be converted
40 */
41 public static Calendar parse(String dateString) {
42 Calendar result = Calendar.getInstance();
43 try {
44 result.setTime(DATE_FORMAT.parse(dateString));
45 return result;
46 } catch (ParseException e) {
47 return null;
48 }
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

49 }
50
51 /**
52 * Checks the String whether it is a valid date.
53 *
54 * @param dateString
55 * @return true if the String is a valid date
56 */
57 public static boolean validString(String dateString) {
58 try {
59 DATE_FORMAT.parse(dateString);
60 return true;
61 } catch (ParseException e) {
62 return false;
63 }
}
}

Tenga en cuenta que puede cambiar el formato de la fecha cambiando la


constante DATE_FORMAT .Para todos los formatos posibles
 ver SimpleDateFormat en la API de Java.
Preste atención a los cambios Tabla de selección

Para estar informado cuando el usuario selecciona una persona en la tabla


persona, tenemos queescuchar los cambios .
Si usted no está familiarizado con el concepto de clases anónimas es posible
que desee echar un vistazo a una explicación en alemán o Inglés .
Existe una interfaz de JavaFX llamada ChangeListener con un método
llamado cambiado (...) .Necesitamos una clase anónima que implementa
esta interfaz y la añadiremos a nuestra mesa persona. Eso suena muy 
complicado. Te lo explicaré, pero primero vamos a echar un vistazo a el
nuevo código, añadido a la initialize () método en
el PersonOverviewController :
PersonOverviewController.java
1 @FXML
2 private void initialize() {
3 // Initialize the person table
4 firstNameColumn.setCellValueFactory(new PropertyValueFactory<Person,
5 String>("firstName"));
6 lastNameColumn.setCellValueFactory(new PropertyValueFactory<Person,
7 String>("lastName"));
8 // Auto resize columns
9
10 personTable.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
11
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

12 // clear person
13 showPersonDetails(null);
14
15 // Listen for selection changes
16
17 personTable.getSelectionModel().selectedItemProperty().addListener(new
18 ChangeListener<Person>() {
19
20 @Override
21 public void changed(ObservableValue<? extends Person> observable,
Person oldValue, Person newValue) {
showPersonDetails(newValue);
}
});
}

En la línea 10 es restablecer los datos persona. Si ha


implementado showPersonDetails (...)correctamente esta debe
establecer una cadena vacía a todos los campos de texto.
En la línea 13 se obtiene la selectedItemProperty de la tabla persona y 
añadimos un oyente al mismo. El nuevo ChangeListener es del tipo
de persona , ya que tenemos Persona objetos en la tabla. Ahora, cada vez
que el usuario selecciona una persona en la tabla, el método cambia
(...)se llama. Nos tomamos la persona que acaba de seleccionar y 
pasarlo al showPersonDetails (...)método.
Trate de ejecutar la aplicación en este punto. Verificar que cuando se
selecciona una persona en la mesa, los detalles sobre esa persona se
muestran a la derecha.
Si algo no funciona, usted puede comparar
su PersonOverviewController clase con PersonOverviewController.java .
El botón Eliminar
Nuestra interfaz de usuario que ya contiene un botón de eliminar, pero sin
ninguna funcionalidad.Podemos seleccionar la acción de un botón en el
interior del generador de Escena . Cualquier método dentro de nuestro
controlador que está anotado con @ FXML (o es público) es accesible por
el Generador de Escena . Por lo tanto, creemos primero el método de
eliminación al final de nuestra PersonOverviewController clase:
PersonOverviewController.java
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

/**
1
* Called when the user clicks on the delete button.
2
*/
3
@FXML
4
private void handleDeletePerson() {
5
int selectedIndex =
6
personTable.getSelectionModel().getSelectedIndex();
7
personTable.getItems().remove(selectedIndex);
8
}

 Ahora, abra el PersonOverview.fxml archivo en SceneBuilder . Seleccione


el Borrar botón, abrir elcódigo de vista y elija # handleDeletePerson en el
menú desplegable de Acción .
 Escena Problema Constructor ( fijado en escena Constructor 1.1 beta 17 y por
encima! no aparecen los métodos En mi versión del Generador de escena
(1.1 beta_11):). Tuve que ir a la raíz AnchorPane (en la vista Jerarquía),
eliminar la clase del controlador, pulse intro y agregar la clase de
controlador de nuevo. Ahora, los métodos aparecen en la lista
desplegable. Espero que este error será corregido pronto.

Control de errores

Si ejecuta la aplicación en este punto, usted debe ser capaz de eliminar


personas seleccionadas de la tabla. Pero lo happenes, si hace clic en el
botón Eliminar si ninguna persona se ha seleccionado en la tabla?
Habrá un ArrayIndexOutOfBoundsException porque no podía quitar un
elemento de persona en el índice -1 . El índice de -1 fue devuelto
por getSelectedIndex () lo que significa que no había selección.
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

Hacer caso omiso de este tipo de error no es muy agradable, por


supuesto. Debemos dejar que el usuario sepa que él / ella debe seleccionar
a una persona antes de eliminarlos. Aún mejor sería si deshabilitado el
 botón para que el usuario ni siquiera tiene la oportunidad de hacer algo
mal. Te voy a mostrar cómo hacer el primer acercamiento aquí.

 Vamos a añadir un cuadro de diálogo emergente para informar al


usuario. Usted tendrá queagregar una biblioteca de los cuadros de diálogo:
1. Descarga los nuevos javafx-diálogos-xxxjar archivo de mi página GitHub .
2. Crear un lib subcarpeta en el proyecto y agregar el archivo jar en esta carpeta.
3. Agregue el archivo jar a classpath del proyecto: En Eclipse haga clic derecho en
el archivo jar | Construye Ruta | Agregar a la Vía de construcción .
Con algunos cambios realizados en el handleDeletePerson () método,
podemos mostrar un cuadro de diálogo emergente cada vez que el usuario
pulsa el botón de borrar, mientras que ninguna persona se ha
seleccionado en la tabla:
PersonOverviewController.java
/**
1
* Called when the user clicks on the delete button.
2
*/
3
@FXML
4
private void handleDeletePerson() {
5
int selectedIndex =
6
personTable.getSelectionModel().getSelectedIndex();
7
if (selectedIndex >= 0) {
8
personTable.getItems().remove(selectedIndex);
9
} else {
10
// Nothing selected
11
Dialogs.showWarningDialog(mainApp.getPrimaryStage(),
12
"Please select a person in the table.",
13
"No Person Selected", "No Selection");
14
}
15
}

Los botones de edición y creación


Las nuevas y editar botones son un poco más de trabajo: Necesitamos un
nuevo diálogo personalizado (estadio aka) con un formulario para pedir al
usuario para obtener detalles sobre la persona.
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

1. Cree un nuevo archivo llamado fxml PersonEditDialog.fxml el interior del


envase vista.
2. Utilice un GridPane , Label s, TextBoxe s y Button s para crear un cuadro de
diálogo como el siguiente: Si no lo hace para hacer el trabajo, usted puede
descargar PersonEditDialog.fxml .

3. Crear el controlador PersonEditDialogController :
4. PersonEditDialogController.java) download
1 package ch.makery.address;
2
3 import javafx.fxml.FXML;
4 import javafx.scene.control.Dialogs;
5 import javafx.scene.control.TextField;
6 import javafx.stage.Stage;
7 import ch.makery.address.model.Person;
8 import ch.makery.address.util.CalendarUtil;
9
10 /**
11 * Dialog to edit details of a person.
12 *
13 * @author Marco Jakob
14 */
15 public class PersonEditDialogController {
16
17 @FXML
18 private TextField firstNameField;
19 @FXML
20 private TextField lastNameField;
21 @FXML
22 private TextField streetField;
23 @FXML
24 private TextField postalCodeField;
25 @FXML
26 private TextField cityField;
27 @FXML
28 private TextField birthdayField;
29
30
31 private Stage dialogStage;
32 private Person person;
33 private boolean okClicked = false;
34
35 /**
36 * Initializes the controller class. This method is automatically
37 called
38 * after the fxml file has been loaded.
39 */
40 @FXML
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

41 private void initialize() {


42
43 }
44
45 /**
46 * Sets the stage of this dialog.
47 * @param dialogStage
48 */
49 public void setDialogStage(Stage dialogStage) {
50 this.dialogStage = dialogStage;
51 }
52
53 /**
54 * Sets the person to be edited in the dialog.
55 *
56 * @param person
57 */
58 public void setPerson(Person person) {
59 this.person = person;
60
61 firstNameField.setText(person.getFirstName());
62 lastNameField.setText(person.getLastName());
63 streetField.setText(person.getStreet());
64
65 postalCodeField.setText(Integer.toString(person.getPostalCode()));
66 cityField.setText(person.getCity());
67
68 birthdayField.setText(CalendarUtil.format(person.getBirthday()));
69 birthdayField.setPromptText("yyyy-mm-dd");
70 }
71
72 /**
73 * Returns true if the user clicked OK, false otherwise.
74 * @return
75 */
76 public boolean isOkClicked() {
77 return okClicked;
78 }
79
80 /**
81 * Called when the user clicks ok.
82 */
83 @FXML
84 private void handleOk() {
85 if (isInputValid()) {
86 person.setFirstName(firstNameField.getText());
87 person.setLastName(lastNameField.getText());
88 person.setStreet(streetField.getText());
89
90 person.setPostalCode(Integer.parseInt(postalCodeField.getText()));
91 person.setCity(cityField.getText());
92
93 person.setBirthday(CalendarUtil.parse(birthdayField.getText()));
94
95 okClicked = true;
96 dialogStage.close();
97 }
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

98 }
99
100 /**
101 * Called when the user clicks cancel.
102 */
103 @FXML
104 private void handleCancel() {
105 dialogStage.close();
106 }
107
108 /**
109 * Validates the user input in the text fields.
110 *
111 * @return true if the input is valid
112 */
113 private boolean isInputValid() {
114 String errorMessage = "";
115
116 if (firstNameField.getText() == null ||
117 firstNameField.getText().length() == 0) {
118 errorMessage += "No valid first name!\n";
119 }
120 if (lastNameField.getText() == null ||
121 lastNameField.getText().length() == 0) {
122 errorMessage += "No valid last name!\n";
123 }
124 if (streetField.getText() == null ||
125 streetField.getText().length() == 0) {
126 errorMessage += "No valid street!\n";
127 }
128
129 if (postalCodeField.getText() == null ||
130 postalCodeField.getText().length() == 0) {
131 errorMessage += "No valid postal code!\n";
132 } else {
133 // try to parse the postal code into an int
134 try {
135 Integer.parseInt(postalCodeField.getText());
136 } catch (NumberFormatException e) {
137 errorMessage += "No valid postal code (must be an
138 integer)!\n";
139 }
140 }
141
142 if (cityField.getText() == null || cityField.getText().length()
143 == 0) {
144 errorMessage += "No valid city!\n";
145 }
146
147 if (birthdayField.getText() == null ||
148 birthdayField.getText().length() == 0) {
149 errorMessage += "No valid birthday!\n";
150 } else {
151 if (!CalendarUtil.validString(birthdayField.getText())) {
152 errorMessage += "No valid birthday. Use the format yyyy-
153 mm-dd!\n";
}
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

if (errorMessage.length() == 0) {
return true;
} else {
// Show the error message
Dialogs.showErrorDialog(dialogStage, errorMessage,
"Please correct invalid fields", "Invalid Fields");
return false;
}
}
}

 Algunas cosas a tener en cuenta sobre este controlador:


o El setPerson (...) se puede llamar de otra clase para establecer que la

 persona que se va a editar.


o Cuando el usuario hace clic en el butten OK, el handleOk () método se

llama. En primer lugar, algunos de validación se hace llamando a


la isInputValid () método. Sólo si la validación se ha realizado
correctamente, el objeto persona se llena con los datos que el usuario
introduce.Esos cambios se pueden aplicar directamente a la persona objeto que
se pasó a setPerson (...) !
o El booleano okClicked se utiliza para que la persona que llama puede

determinar si el usuario hace clic en el botón Aceptar o Cancelar.


 Abrir el diálogo

 Agregue un método para cargar y mostrar el cuadro de diálogo de edición


persona dentro de nuestro MainApp :
MainApp.java
1 /**
2 * Opens a dialog to edit details for the specified person. If the user
3 * clicks OK, the changes are saved into the provided person object and
4 * true is returned.
5 *
6 * @param person the person object to be edited
7 * @return true if the user clicked OK, false otherwise.
8 */
9 public boolean showPersonEditDialog(Person person) {
10 try {
11 // Load the fxml file and create a new stage for the popup
12 FXMLLoader loader = new
13 FXMLLoader(MainApp.class.getResource("view/PersonEditDialog.fxml"));
14 AnchorPane page = (AnchorPane) loader.load();
15 Stage dialogStage = new Stage();
16 dialogStage.setTitle("Edit Person");
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

17 dialogStage.initModality(Modality.WINDOW_MODAL);
18 dialogStage.initOwner(primaryStage);
19 Scene scene = new Scene(page);
20 dialogStage.setScene(scene);
21
22 // Set the person into the controller
23 PersonEditDialogController controller = loader.getController();
24 controller.setDialogStage(dialogStage);
25 controller.setPerson(person);
26
27 // Show the dialog and wait until the user closes it
28 dialogStage.showAndWait();
29
30 return controller.isOkClicked();
31
32 } catch (IOException e) {
33 // Exception gets thrown if the fxml file could not be loaded
34 e.printStackTrace();
35 return false;
36 }
}
 Agregue los siguientes métodos para la PersonOverviewController :
PersonOverviewController.java
1 /**
2 * Called when the user clicks the new button.
3 * Opens a dialog to edit details for a new person.
4 */
5 @FXML
6 private void handleNewPerson() {
7 Person tempPerson = new Person();
8 boolean okClicked = mainApp.showPersonEditDialog(tempPerson);
9 if (okClicked) {
10 mainApp.getPersonData().add(tempPerson);
11 }
12 }
13
14 /**
15 * Called when the user clicks the edit button.
16 * Opens a dialog to edit details for the selected person.
17 */
18 @FXML
19 private void handleEditPerson() {
20 Person selectedPerson =
21 personTable.getSelectionModel().getSelectedItem();
22 if (selectedPerson != null) {
23 boolean okClicked = mainApp.showPersonEditDialog(selectedPerson);
24 if (okClicked) {
25 refreshPersonTable();
26 showPersonDetails(selectedPerson);
27 }
28
29 } else {
30 // Nothing selected
31 Dialogs.showWarningDialog(mainApp.getPrimaryStage(),
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

32 "Please select a person in the table.",


33 "No Person Selected", "No Selection");
34 }
35 }
36
37 /**
38 * Refreshes the table. This is only necessary if an item that is
39 already in
40 * the table is changed. New and deleted items are refreshed
41 automatically.
42 *
43 * This is a workaround because otherwise we would need to use property
44 * bindings in the model class and add a *property() method for each
45 * property. Maybe this will not be necessary in future versions of
46 JavaFX
47 * (see http://javafx-jira.kenai.com/browse/RT-22599)
48 */
49 private void refreshPersonTable() {
50 int selectedIndex =
51 personTable.getSelectionModel().getSelectedIndex();
52 personTable.setItems(null);
personTable.layout();
personTable.setItems(mainApp.getPersonData());
// Must set the selected index again (see http://javafx-
jira.kenai.com/browse/RT-26291)
personTable.getSelectionModel().select(selectedIndex);
}

 Abra la PersonOverview.fxml archivo en el Generador de escena. Elegir


los métodos correspondientes de Acción para los botones nuevos y 
edición.
¡Ya está!
Usted debe tener un trabajo de aplicación de direcciones ahora. La
aplicación es capaz de añadir, editar y eliminar personas. Incluso hay 
 validación para los campos de texto para evitar las entradas de usuario
malas.
Espero que los conceptos y la estructura de esta aplicación le ayudará a
empezar a escribir su propia aplicación JavaFX! Diviértete y permanezca
atento a posibles futuros tutoriales.

JavaFX 2 Tutorial Parte IV 


- CSS Styling
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

26 DE NOVIEMBRE TH , 2012

Los temas de la Parte IV 


 CSS Styling
 Adición de un icono de aplicación
Otras piezas Tutorial
 Parte I - Generador de Escena
 Parte II - Modelo y TableView
 Parte III - Interactuar con el usuario
 Parte IV - CSS Styling
 Parte V - Almacenamiento de datos como XML
 Parte VI - Estadísticas Gráfico
 Parte VII - Despliegue con e (fx) clipse
CSS Styling
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

En JavaFX puede estilo de la interfaz de usuario usando las Hojas de Estilo en


Cascada (CSS). Esto es genial! Nunca ha sido tan fácil de personalizar la
apariencia de una aplicación Java.

En este tutorial vamos a crear un  DarkTheme inspirado en el diseño de Metro de


Windows 8. El CSS para los botones se basa en la entrada de blog JMetro - 8
controles de Windows Metro en Java por Pedro Duque Vieira.
Familiarizarse con CSS
Si usted quiere el estilo de su aplicación JavaFX que debe tener un conocimiento
 básico de CSS en general. Un buen lugar para comenzar es este tutorial CSS .
Para obtener más información específica sobre JavaFX CSS:

 Skinning aplicaciones JavaFX con CSS - Tutorial de Oracle


 JavaFX CSS Referencia - Referencia Oficial
Defecto JavaFX CSS
La fuente predeterminada para los estilos CSS es un archivo
llamado . Este archivo css se puede encontrar en el archivo jar Java
FX jfxrt.jar encuentra en la carpeta Java bajo / jdk_x.xx / jre / lib /
jfxrt.jar .
Esta hoja de estilo por defecto se aplica siempre a una aplicación
JavaFX. Mediante la adición de una hoja de estilo personalizada podemos
reemplazar los estilos predeterminados del caspian.css .
Sugerencia: Es bueno ver el archivo CSS por defecto para ver los estilos que
 puede que tenga que reemplazar.
Colocación de las hojas de estilo CSS
Agregue el siguiente archivo CSS denominado DarkTheme.css a la vista de
 paquetes.
(DarkTheme.css) download
1 .background {
2 -fx-background-color: #1d1d1d;
3 }
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

4
5 .label {
6 -fx-font-size: 11pt;
7 -fx-font-family: "Segoe UI Semibold";
8 -fx-text-fill: white;
9 -fx-opacity: 0.6;
10 }
11
12 .label-bright {
13 -fx-font-size: 11pt;
14 -fx-font-family: "Segoe UI Semibold";
15 -fx-text-fill: white;
16 -fx-opacity: 1;
17 }
18
19 .label-header {
20 -fx-font-size: 32pt;
21 -fx-font-family: "Segoe UI Light";
22 -fx-text-fill: white;
23 -fx-opacity: 1;
24 }
25
26 .table-view {
27 -fx-base: #1d1d1d;
28 -fx-control-inner-background: #1d1d1d;
29 -fx-background-color: #1d1d1d;
30 -fx-table-cell-border-color: transparent;
31 -fx-table-header-border-color: transparent;
32 -fx-padding: 5;
33 }
34
35 .table-view .column-header-background {
36 -fx-background-color: transparent;
37 }
38
39 .table-view .column-header, .table-view .filler {
40 -fx-size: 35;
41 -fx-border-width: 0 0 1 0;
42 -fx-border-color:
43 transparent
44 transparent
45 derive(-fx-base, 80%)
46 transparent;
47 -fx-border-insets: 0 10 1 0;
48 }
49
50 .table-view .column-header .label {
51 -fx-font-size: 20pt;
52 -fx-font-family: "Segoe UI Light";
53 -fx-text-fill: white;
54 -fx-alignment: center-left;
55 -fx-opacity: 1;
56 }
57
58 .table-view:focused .table-row-cell:filled:focused:selected {
59 -fx-background-color: -fx-focus-color;
60 }
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

61
62 .split-pane:horizontal > * > .split-pane-divider {
63 -fx-border-color: transparent #1d1d1d transparent #1d1d1d;
64 -fx-background-color: transparent, derive(#1d1d1d,20%);
65 }
66
67 .split-pane {
68 -fx-padding: 1 0 0 0;
69 }
70
71 .menu-bar {
72 -fx-background-color: derive(#1d1d1d,20%);
73 -fx-selection-bar: derive(-fx-background,-7%);
74 }
75
76 .menu-bar .label {
77 -fx-font-size: 14pt;
78 -fx-font-family: "Segoe UI Light";
79 -fx-text-fill: white;
80 -fx-opacity: 0.9;
81 }
82
83 .text-field {
84 -fx-font-size: 12pt;
85 -fx-font-family: "Segoe UI Semibold";
86 }
87
88
89
90 /*
91 * Metro style Push Button
92 * Author: Pedro Duque Vieira
93 * http://pixelduke.wordpress.com/2012/10/23/jmetro-windows-8-
94 controls-on-java/
95 */
96 .button {
97 -fx-padding: 5 22 5 22;
98 -fx-border-color: #e2e2e2;
99 -fx-border-width: 2;
100 -fx-background-radius: 0;
101 -fx-background-color: #1d1d1d;
102 -fx-font-family: "Segoe UI", Helvetica, Arial, sans-serif;
103 -fx-font-size: 11pt;
104 -fx-text-fill: #d8d8d8;
105 -fx-background-insets: 0 0 0 0, 0, 1, 2;
106 }
107
108 .button:hover {
109 -fx-background-color: #3a3a3a;
110 }
111
112 .button:pressed, .button:default:hover:pressed {
113 -fx-background-color: white;
114 -fx-text-fill: #1d1d1d;
115 }
116
117 .button:focused {
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

118 -fx-border-color: white, white;


119 -fx-border-width: 1, 1;
120 -fx-border-style: solid, segments(1, 1);
121 -fx-border-radius: 0, 0;
122 -fx-border-insets: 1 1 1 1, 0;
123 }
124
125 .button:disabled, .button:default:disabled {
126 -fx-opacity: 0.4;
127 -fx-background-color: #1d1d1d;
128 -fx-text-fill: white;
129 }
130
131 .button:default {
132 -fx-background-color: -fx-focus-color;
133 -fx-text-fill: #ffffff;
134 }
135
136 .button:default:hover {
137 -fx-background-color: derive(-fx-focus-color,30%);
}

 Ahora tenemos que conectar el CSS a nuestra escena. Podemos hacer esto
mediante programación en el código Java, pero vamos a utilizar el
Generador de Escena para añadirlo a nuestros ficheros fxml:

Conecte CSS para RootLayout.fxml 

 Abra el archivo RootLayout.fxml en el Generador de escena. Seleccione la


raíz BorderPane en la vista de Jerarquía. En Propiedades añadir
el DarkTheme.css archivo como hoja de estilos.
Conecte CSS para PersonEditDialog.fxml 

 Abra el archivo PersonEditDialog.fxml en el Generador de


escena. Seleccione la raíz AnchorPane y elija DarkTheme.css en la ventana
de propiedades como de estilo.
El fondo sigue siendo blanco, por lo que añadir la clase de estilo de
fondo a la raíz AnchorPane .
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

Seleccione el botón OK y seleccione Botón predeterminado en Propiedades


de la vista. Esto va a cambiar su color y que éste sea el botón
predeterminado cuando el enter tecla es presionada por el usuario.
Conecte CSS para PersonOverview.fxml 

 Abra el archivo PersonOverview.fxml en el Generador de


escena. Seleccione la raíz AnchorPaneen la vista de Jerarquía. En
Propiedades añadir el DarkTheme.css archivo como hoja de estilos.
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

Usted ya debe ver algunos cambios ahora: La tabla y los botones son de
color negro. Si selecciona un botón y mira la parte CSS en la vista
Propiedades, verá que ya hay una clase de estilo por defecto
llamada botón .

Todos los estilos de clase . botón de caspian.css aplican a esos


 botones. Ya hemos redefinido (y por lo tanto anulado) algunos de esos
estilos en nuestra costumbre CSS, la apariencia de los botones cambian
automáticamente.
Puede que tenga que ajustar el tamaño de los botones para que se muestre
todo el texto.

Seleccionar la adecuada AnchorPane que está dentro del SplitPane . Vaya


a las propiedades de ver y usar el signo más (+) para agregar una clase de
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

estilo. Seleccione el fondo de clase de estilo.Ahora El fondo debe girar


negro.

Si hay un borde blanco alrededor de la tabla, seleccione la TableView y 


seleccione 0 para todos los anclajes en la vista Diseño. Ahora, la tabla
debe ocupar todo el espacio de la izquierda.
 Etiquetas con estilo diferente

En este momento, todas las etiquetas en la parte derecha tienen el mismo


tamaño. Ya hay algunas formas que se indican en el archivo css llamado .
etiqueta de encabezado y  . etiqueta brillante que vamos a utilizar
para el estilo aún más las etiquetas.
Seleccione la persona Detalles etiqueta y añadir etiquetas de
encabezado como una clase de estilo.
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

Para cada etiqueta en la columna de la derecha (donde se muestran los


detalles reales por persona), agregue la clase de estilo CSS etiqueta
brillante .
 Adición de un icono de aplicación
En este momento nuestra aplicación sólo tiene el icono por defecto en la
 barra de título y la barra de TAKS:

Se ve mucho mejor con un icono personalizado:

El archivo de icono

Un lugar posible para obtener los iconos libres es Icon Buscador . He


descargado un pequeño icono de la libreta de direcciones .
Crear una carpeta (normal) dentro de su proyecto denominado
 AddressApp recursos y una subcarpeta llamada imágenes en él. Coloque el
icono de su elección dentro de la carpeta de imágenes. Su estructura de
carpetas debe ser algo como esto ahora:

Conjunto del icono de la escena


http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

Para establecer el icono de nuestra escena añada la siguiente línea


al comienzo (...) método MainApp.java
this.primaryStage.getIcons().add(new
1
Image("file:resources/images/address_book_32.png"));
El conjunto inicial (...) método se verá algo como esto ahora:

MainApp.java
public void start(Stage primaryStage) {
1 this.primaryStage = primaryStage;
2 this.primaryStage.setTitle("AddressApp");
3 // Set the application icon
4 this.primaryStage.getIcons().add(new
5 Image("file:resources/images/address_book_32.png"));
6
7 try {
8 // Load the root layout from the fxml file
9 FXMLLoader loader = new
10 FXMLLoader(MainApp.class.getResource("view/RootLayout.fxml"));
11 rootLayout = (BorderPane) loader.load();
12 Scene scene = new Scene(rootLayout);
13 primaryStage.setScene(scene);
14 primaryStage.show();
15 } catch (IOException e) {
16 // Exception gets thrown if the fxml file could not be loaded
17 e.printStackTrace();
18 }
19
20 showPersonOverview();
}
También puede añadir un icono a la etapa del diálogo de edición persona,
por supuesto.

JavaFX 2 Tutorial Parte V -


 Almacenamiento de datos
como XML
27 DE NOVIEMBRE TH , 2012
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

Los temas de la Parte V 


 La persistencia de datos como XML
 Usando el JavaFX FileChooser
 Uso de la JavaFX Menú
 Ahorro de la última ruta del archivo abierto en las preferencias del usuario
Otras piezas Tutorial
 Parte I - Generador de Escena
 Parte II - Modelo y TableView
 Parte III - Interactuar con el usuario
 Parte IV - CSS Styling
 Parte V - Almacenamiento de datos como XML
 Parte VI - Estadísticas Gráfico
 Parte VII - Despliegue con e (fx) clipse
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

 Almacenamiento de las preferencias del


usuario
Java nos permite ahorrar un poco de estado de la aplicación con una clase
llamada Preferencias .Dependiendo del sistema operativo, las preferencias se
guardan en diferentes lugares (por ejemplo, el archivo de registro de Windows).
 No vamos a ser capaces de utilizar Preferencias para guardar nuestra libreta de
direcciones completa. Pero nos permite ahorrar unos sencillos estado de la
aplicación. Una de esas cosas es la ruta de acceso al último archivo abierto . Con
esta información, podemos cargar el último estado de la aplicación cada vez que
el usuario reinicie la aplicación.
Los dos métodos se encargan de guardar y recuperar Preferencias. Añadir a la
final de su MainAppclase.

MainApp.java
1 /**
2 * Returns the person file preference, i.e. the file that was last
3 opened.
4 * The preference is read from the OS specific registry. If no such
5 * preference can be found, null is returned.
6 *
7 * @return
8 */
9 public File getPersonFilePath() {
10 Preferences prefs = Preferences.userNodeForPackage(MainApp.class);
11 String filePath = prefs.get("filePath", null);
12 if (filePath != null) {
13 return new File(filePath);
14 } else {
15 return null;
16 }
17 }
18
19 /**
20 * Sets the file path of the currently loaded file.
21 * The path is persisted in the OS specific registry.
22 *
23 * @param file the file or null to remove the path
24 */
25 public void setPersonFilePath(File file) {
26 Preferences prefs = Preferences.userNodeForPackage(MainApp.class);
27 if (file != null) {
28 prefs.put("filePath", file.getPath());
29
30 // Update the stage title
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

31 primaryStage.setTitle("AddressApp - " + file.getName());


32 } else {
33 prefs.remove("filePath");
34
35 // Update the stage title
36 primaryStage.setTitle("AddressApp");
37 }
}

La persistencia de datos como XML


Por el momento los datos de nuestra aplicación única dirección reside en
la memoria. Cada vez que cerremos la aplicación, los datos se pierden. Así
que ya es hora de empezar a pensar persistentemente almacenar datos.

¿Por qué XML?

Una de las maneras más comunes para conservar los datos es el uso de
una base de datos. Las bases de datos suelen contener algún tipo de datos
relacionales (como tablas), mientras que los datos que necesitamos para
salvar son objetos. Esto se conoce como la diferencia de impedancia objeto-
relacional . Es un poco de trabajo para que coincida con los objetos a las
tablas de bases de datos relacionales. Hay algunos de los marcos que
ayudan con el juego (por ejemplo, Hibernate , el más popular), pero todavía
requiere un poco de trabajo de configurar.
En nuestro modelo de datos simple es mucho más fácil de usar
XML. Vamos a utilizar una biblioteca llamada XStream . Con sólo unas
pocas líneas de código que esto nos permitirá generar XML de salida
como esta:
sample.xml
1 <list>
2 <person>
3 <firstName>Hans</firstName>
4 <lastName>Muster</lastName>
5 <street>some street</street>
6 <postalCode>1234</postalCode>
7 <city>some city</city>
8 <birthday>
9 <time>1354035227734</time>
10 <timezone>Europe/Berlin</timezone>
11 </birthday>
12 </person>
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

13 <person>
14 <firstName>Anna</firstName>
15 <lastName>Best</lastName>
16 <street>some street</street>
17 <postalCode>1234</postalCode>
18 <city>some city</city>
19 <birthday>
20 <time>1354035227734</time>
21 <timezone>Europe/Berlin</timezone>
22 </birthday>
23 </person>
24 </list>

Lectura y escritura de archivos

Desde Java 7 hay algunas clases convenientes para hacer frente a la


lectura y escritura de archivos.Para ver un tutorial detallado de
Oracle Tutorial de E / S del archivo .
Dado que es posible que necesitemos los archivos de lectura / escritura en
diferentes lugares de nuestra aplicación crearemos un
práctico FileUtil clase de ayuda. Esta clase proporciona un método
estático para la lectura de un archivo y otra para escribir en un
archivo. Copie el archivo siguiente en el ch.makery.util paquete:
(FileUtil.java) download
1 package ch.makery.address.util;
2
3 import java.io.BufferedReader;
4 import java.io.BufferedWriter;
5 import java.io.File;
6 import java.io.IOException;
7 import java.nio.charset.Charset;
8 import java.nio.file.Files;
9
10 /**
11 * Helper class for reading and writing files.
12 */
13 public class FileUtil {
14
15 /**
16 * The character set. UTF-8 works good for windows, mac and Umlaute.
17 */
18 private static final Charset CHARSET = Charset.forName("UTF-8");
19
20 /**
21 * Reads the specified file and returns the content as a String.
22 *
23 * @param file
24 * @return
25 * @throws IOException thrown if an I/O error occurs opening the file
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

26 */
27 public static String readFile(File file) throws IOException {
28 StringBuffer stringBuffer = new StringBuffer();
29
30 BufferedReader reader = Files.newBufferedReader(file.toPath(),
31 CHARSET);
32
33 String line = null;
34 while ((line = reader.readLine()) != null) {
35 stringBuffer.append(line);
36 }
37
38 reader.close();
39
40 return stringBuffer.toString();
41 }
42
43 /**
44 * Saves the content String to the specified file.
45 *
46 * @param content
47 * @param file
48 * @throws IOException thrown if an I/O error occurs opening or
49 creating the file
50 */
51 public static void saveFile(String content, File file) throws
52 IOException {
53 BufferedWriter writer = Files.newBufferedWriter(file.toPath(),
54 CHARSET);
writer.write(content, 0, content.length());
writer.close();
}
}

Usando XStream

Para utilizar XStream necesitamos tres bibliotecas. Agregue las siguientes


 bibliotecas para
para el proyecto
proyecto lib carpeta y añadirlos a la ruta de
compilación
compilación (clic derecho sobre las bibliotecas).
 xstream-1.4.3.jar  biblioteca
 biblioteca principal
principal XStream
XStream -
 xmlpull-1.1.3.1.jar -- XmlPull para detectar analizadores disponibles
xmlpull-1.1.3.1.jar 
 xpp3_min-1.1.4c.jar -- Xpp3, un analizado
xpp3_min-1.1.4c.jar  analizadorr tirón rápido
También puede descargar las tres bibliotecas de la  página de descarga
descarga
XStream .
Haremos nuestro MainApp clase responsable de la lectura y escritura de los
datos de la persona.Añadir los dos métodos siguientes hasta el final
del MainApp.java :
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

MainApp.java
/**
1 * Loads person data from the specified file. The current person data
2 will
3 * be replaced.
4 *
5 * @param file
6 */
7 @SuppressWarnings("unchecked")
8 public void loadPersonDataFromFile(File file) {
9 XStream xstream = new XStream();
10 xstream.alias("person", Person.class);
11
12 try {
13 String xml = FileUtil.readFile(file);
14
15 ArrayList<Person> personList = (ArrayList<Person>)
16 xstream.fromXML(xml);
17
18 personData.clear();
19 personData.addAll(personList);
20
21 setPersonFilePath(file);
22 } catch (Exception e) { // catches ANY exception
23 Dialogs.showErrorDialog(primaryStage,
24 "Could not load data from file:\n" + file.getPath(),
25 "Could not load data", "Error", e);
26 }
27 }
28
29 /**
30 * Saves the current person data to the specified file.
31 *
32 * @param file
33 */
34 public void savePersonDataToFile(File file) {
35 XStream xstream = new XStream();
36 xstream.alias("person", Person.class);
37
38 // Convert ObservableList to a normal ArrayList
39 ArrayList<Person> personList = new ArrayList<>(personData);
40
41 String xml = xstream.toXML(personList);
42 try {
43 FileUtil.saveFile(xml, file);
44
45 setPersonFilePath(file);
46 } catch (Exception e) { // catches ANY exception
47 Dialogs.showErrorDialog(primaryStage,
48 "Could not save data to file:\n" + file.getPath(),
49 "Could not save data", "Error", e);
50 }
}

El método de almacenamiento utiliza xstream.toXML (...) para convertir


la lista de Personasobjetos en una representación XML. El método de
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

carga utiliza xstream.fromXML (...) para convertir los datos XML de


 vuelta a una lista de persona s.
Si algo sale mal, un diálogo de error se presenta al usuario.

Manejando acciones del menú


En nuestro RootLayout.fxml ya hay un menú, pero no hemos utilizado
todavía. Antes de añadir la acción al menú que vamos a crear por primera
 vez todos los elementos del menú.
 Abra la RootLayout.fxml archivo en el Generador de escena y arrastre los
elementos de menú necesarias desde el vista de la biblioteca de la barra de
menú en la vista de jerarquía . Crear unNuevo , Abrir
... , Guardar , Guardar como ... y Salir del menú. También puede utilizar
separadores entre algunos elementos.

Sugerencia: Con el acelerador ajuste en propiedades que se pueden


configurar teclas de acceso directo a los elementos del menú.
El RootLayoutController
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

Para el manejo de las acciones del menú que necesitaremos una nueva
clase de controlador. Crear una clase RootLayoutController dentro del
paquete controlador ch.makery.address .
 Añadir el contenido siguiente al controlador:

(RootLayoutController.java) download
1 package ch.makery.address;
2
3 import java.io.File;
4
5 import javafx.fxml.FXML;
6 import javafx.scene.control.Dialogs;
7 import javafx.stage.FileChooser;
8
9 /**
10 * The controller for the root layout. The root layout provides the
11 basic
12 * application layout containing a menu bar and space where other
13 JavaFX
14 * elements can be placed.
15 *
16 * @author Marco Jakob
17 */
18 public class RootLayoutController {
19
20 // Reference to the main application
21 private MainApp mainApp;
22
23 /**
24 * Is called by the main application to give a reference back to
25 itself.
26 *
27 * @param mainApp
28 */
29 public void setMainApp(MainApp mainApp) {
30 this.mainApp = mainApp;
31 }
32
33 /**
34 * Creates an empty address book.
35 */
36 @FXML
37 private void handleNew() {
38 mainApp.getPersonData().clear();
39 mainApp.setPersonFilePath(null);
40 }
41
42 /**
43 * Opens a FileChooser to let the user select an address book to
44 load.
45 */
46 @FXML
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

47 private void handleOpen() {


48 FileChooser fileChooser = new FileChooser();
49
50 // Set extension filter
51 FileChooser.ExtensionFilter extFilter = new
52 FileChooser.ExtensionFilter(
53 "XML files (*.xml)", "*.xml");
54 fileChooser.getExtensionFilters().add(extFilter);
55
56 // Show save file dialog
57 File file =
58 fileChooser.showOpenDialog(mainApp.getPrimaryStage());
59
60 if (file != null) {
61 mainApp.loadPersonDataFromFile(file);
62 }
63 }
64
65 /**
66 * Saves the file to the person file that is currently open. If there
67 is no
68 * open file, the "save as" dialog is shown.
69 */
70 @FXML
71 private void handleSave() {
72 File personFile = mainApp.getPersonFilePath();
73 if (personFile != null) {
74 mainApp.savePersonDataToFile(personFile);
75 } else {
76 handleSaveAs();
77 }
78 }
79
80 /**
81 * Opens a FileChooser to let the user select a file to save to.
82 */
83 @FXML
84 private void handleSaveAs() {
85 FileChooser fileChooser = new FileChooser();
86
87 // Set extension filter
88 FileChooser.ExtensionFilter extFilter = new
89 FileChooser.ExtensionFilter(
90 "XML files (*.xml)", "*.xml");
91 fileChooser.getExtensionFilters().add(extFilter);
92
93 // Show save file dialog
94 File file = fileChooser.showSaveDialog(mainApp.getPrimaryStage());
95
96 if (file != null) {
97 // Make sure it has the correct extension
98 if (!file.getPath().endsWith(".xml")) {
99 file = new File(file.getPath() + ".xml");
100 }
101 mainApp.savePersonDataToFile(file);
102 }
103 }
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

104
105 /**
106 * Opens an about dialog.
107 */
108 @FXML
109 private void handleAbout() {
110 Dialogs.showInformationDialog(mainApp.getPrimaryStage(),
111 "Author: Marco Jakob\nWebsite: http://edu.makery.ch", "AddressApp",
112 "About");
113 }

/**
* Closes the application.
*/
@FXML
private void handleExit() {
System.exit(0);
}

El controlador contiene un FXML @ método para cada elemento del menú.


 FileChooser 

Tome nota de los métodos que utilizan la FileChooser clase dentro


de RootLayoutControllerarriba. En primer lugar, un nuevo objeto de la
clase FileChooser se crea. A continuación, se añade un filtro de extensión
de manera que sólo los archivos que terminan en . xml se muestran. Por
último, el selector de archivos se muestra en la parte superior de la
primera etapa.
Si el usuario cierra el cuadro de diálogo sin seleccionar un archivo, nula se
devuelve. De lo contrario, se obtiene el archivo seleccionado y podemos
pasarlo al loadPersonDataFromFile (...)o savePersonDataToFile
(...) Método de MainApp .
Conexión de la Vista fxml al controlador

1. Abra RootLayout.fxml en el Generador de escena. Seleccione la


raíz BorderPane . En la vista Código, seleccione
el RootLayoutController como clase Controller.
2. Seleccione cada elemento del menú en la vista de Jerarquía. En la vista Código,
en virtud Accióndebería ver una selección de todos los @ FXML métodos del
controlador. Elija el método correspondiente para cada elemento del menú. Si
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

usted no ve las opciones en Acción : Debido a un bug en el Generador de escena


tiene que quitar el controlador de la raíz, pulse intro y agregarlo de nuevo. Tuve
que hacer esto después de cada reinicio del Constructor escena! ( fijado en
escena Constructor 1.1 beta 17 y más arriba! )

3. Cerrar Escena Builder y golpe Refresh (F5) en la carpeta raíz del proyecto. Esto
hará que Eclipse conscientes de los cambios que ha realizado en el Generador de
escena.
Conexión del MainApp y RootLayoutController

En varios lugares, el RootLayoutController necesita una referencia de


nuevo a la MainApp . No hemos superado la referencia
al RootLayoutController todavía.
Por lo tanto, abrir la MainApp clase y reemplazar el comienzo
(...) método con el siguiente código:
MainApp.java
1 @Override
2 public void start(Stage primaryStage) {
3 this.primaryStage = primaryStage;
4 this.primaryStage.setTitle("AddressApp");
5 this.primaryStage.getIcons().add(new
6 Image("file:resources/images/address_book_32.png"));
7
8 try {
9 // Load the root layout from the fxml file
10 FXMLLoader loader = new
11 FXMLLoader(MainApp.class.getResource("view/RootLayout.fxml"));
12 rootLayout = (BorderPane) loader.load();
13 Scene scene = new Scene(rootLayout);
14 primaryStage.setScene(scene);
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

15
16 // Give the controller access to the main app
17 RootLayoutController controller = loader.getController();
18 controller.setMainApp(this);
19
20 primaryStage.show();
21 } catch (IOException e) {
22 // Exception gets thrown if the fxml file could not be loaded
23 e.printStackTrace();
24 }
25
26 showPersonOverview();
27
28 // Try to load last opened person file
29 File file = getPersonFilePath();
30 if (file != null) {
31 loadPersonDataFromFile(file);
}
}

Observe los dos cambios: Las líneas que dan acceso al controlador de la
aplicación principal y las tres últimas líneas para cargar el último archivo
abierto persona .
¿Cómo funciona?
Hacer una prueba de manejo de su solicitud, usted debe ser capaz de
utilizar los menús para guardar los datos de la persona a un archivo y 
cargarlo de nuevo. Después de un reinicio, debe cargar automáticamente
el último archivo utilizado.

 Vamos a ver cómo funciona todo en conjunto:

1. La aplicación se inicia con el principal (...) método dentro de MainApp .


2. El constructor público MainApp () es llamado y añade algunos datos de
muestra.
3. MainApp s comienzo (...) se llama al método y se inicializa el diseño raíz
de RootLayout.fxml .El archivo fxml tiene la información acerca de qué
controlador utilizar y enlaza el objeto de su RootLayoutController .
4. El MainApp recupera el RootLayoutController desde el cargador fxml y pasa
una referencia a sí misma al controlador. Con esta referencia el controlador más
tarde puede tener acceso a los métodos (pública) de MainApp .
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

5. Al final de la partida (...) método que tratamos de conseguir el último


archivo abierto persona dePreferencias . Si las preferencias saben acerca de
un archivo como XML, vamos a cargar los datos desde el archivo XML. Esto
aparentemente sobrescribir los datos de la muestra del constructor.

JavaFX 2 Tutorial Parte VI


- Estadísticas Gráfico
04 DE DICIEMBRE TH , 2012

Los temas de la Parte VI


 Creación de un Estadísticas Gráfico para mostrar la distribución de cumpleaños.
Otras piezas Tutorial
 Parte I - Generador de Escena
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

 Parte II - Modelo y TableView


 Parte III - Interactuar con el usuario
 Parte IV - CSS Styling
 Parte V - Almacenamiento de datos como XML
 Parte VI - Estadísticas Gráfico
 Parte VII - Despliegue con e (fx) clipse
Estadísticas de cumpleaños
Todas las personas en el AddressApp celebra su cumpleaños. ¿No sería bueno
tener algunas estadísticas acerca de que nuestro pueblo celebran su cumpleaños.

Vamos a utilizar un gráfico de barras que contiene una barra para cada
mes. Cada barra muestra cuántas personas tienen su cumpleaños en ese mes
 particular.
Las estadísticas FXML View 
1. Empezamos creando un BirthdayStatistics.fxml archivo dentro de
nuestra ch.makery.address.view paquete ( Haga clic en el paquete | Nuevo |
otras ... | New FXML documento ).
2. Abra la BirthdayStatistics.fxml archivo en el Generador de escena.
3. Seleccione la raíz AnchorPane y establezca el Ancho Pref a 620 y la altura Pref a
450.
4. Añadir un BarChart al AnchorPane .
5. Haga clic en el BarChart y seleccione Ajustar a los padres .
6. Guarde el archivo fxml, vaya a Eclipse y actualizar el proyecto.
Antes de que nos volveremos a Constructor de escena, lo primero que va a crear 
el controlador y el alambre todo para arriba en nuestro MainApp.

El controlador de Estadísticas
En el paquete del controlador ch.makery.address crear una clase Java
llamada BirthdayStatisticsController.java .
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

Primero echemos un vistazo a toda la clase del controlador antes de empezar a


explicar:

JavaFX 2 Tutorial Parte VI


- Estadísticas Gráfico
04 DE DICIEMBRE TH , 2012

Los temas de la Parte VI


 Creación de un Estadísticas Gráfico para mostrar la distribución de cumpleaños.
Otras piezas Tutorial
 Parte I - Generador de Escena
 Parte II - Modelo y TableView
 Parte III - Interactuar con el usuario
 Parte IV - CSS Styling
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

 Parte V - Almacenamiento de datos como XML


 Parte VI - Estadísticas Gráfico
 Parte VII - Despliegue con e (fx) clipse
Estadísticas de cumpleaños
Todas las personas en el AddressApp celebra su cumpleaños. ¿No sería bueno
tener algunas estadísticas acerca de que nuestro pueblo celebran su cumpleaños.

Vamos a utilizar un gráfico de barras que contiene una barra para cada
mes. Cada barra muestra cuántas personas tienen su cumpleaños en ese mes
 particular.
Las estadísticas FXML View 
1. Empezamos creando un BirthdayStatistics.fxml archivo dentro de
nuestra ch.makery.address.view paquete ( Haga clic en el paquete | Nuevo |
otras ... | New FXML documento ).
2. Abra la BirthdayStatistics.fxml archivo en el Generador de escena.
3. Seleccione la raíz AnchorPane y establezca el Ancho Pref a 620 y la altura Pref a
450.
4. Añadir un BarChart al AnchorPane .
5. Haga clic en el BarChart y seleccione Ajustar a los padres .
6. Guarde el archivo fxml, vaya a Eclipse y actualizar el proyecto.
Antes de que nos volveremos a Constructor de escena, lo primero que va a crear 
el controlador y el alambre todo para arriba en nuestro MainApp.

El controlador de Estadísticas
En el paquete del controlador ch.makery.address crear una clase Java
llamada BirthdayStatisticsController.java .
Primero echemos un vistazo a toda la clase del controlador antes de empezar a
explicar:
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

Cómo funciona el controlador

1. El controlador tendrá acceso a dos elementos de nuestro archivo FXML:

 El Barchar : Tiene el tipo de cadena y de Integer . La cadena se utiliza para


el mes en el eje x y el número entero se utiliza para el número de personas en
un mes específico. Vamos a utilizar la referencia al BarChart establecer 
nuestros datos.
 El ejeX : Usaremos esto para agregar las cadenas meses.
2. La inicialización () método rellena el eje x con una lista de todos los meses.
3. El setPersonData (...) método se accede por la MainApp clase para establecer 
los datos de la persona. Se recorre todas las personas y cuenta los cumpleaños
 por mes.
4. Los createMonthDataSeries (...) método toma la matriz con un número para
cada mes y crea los datos del gráfico. Por cada mes un
nuevo XYChart.Data objeto se crea con el nombre del mes y el número de
 personas que tienen su cumpleaños en este mes. Cada XYChart.Data objeto
representará a una de las barras en el gráfico.
Conexión Vista y Controlador
1. Abra BirthdayStatistics.fxml en el Generador de escena.
2. Seleccione la raíz AncherPane y agregue
el BirthdayStatisticsController como controlador (en vista de código).
3. Seleccione la BarChart y elija barChart como fx: Identificación de la propiedad.
4. Seleccione la CategoryAxis y elija ejeX como fx: id propiedad.
5. Usted puede agregar un título al gráfico, quite la leyenda, etc para estilizar aún
más el cuadro.
Conexión de la Vista / Controlador con
MainApp
http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/

 Vamos a utilizar el mismo mecanismo para nuestras estadísticas de


cumpleaños que utilizamos para el diálogo de persona edición : Un diálogo
emergente simple que contiene.
 Agregue el método siguiente a su MainApp clase:
MainApp.java
/**
1
* Opens a dialog to show birthday statistics.
2
*/
3
public void showBirthdayStatistics() {
4
try {
5
// Load the fxml file and create a new stage for the popup
6
FXMLLoader loader = new
7
FXMLLoader(MainApp.class.getResource("view/BirthdayStatistics.fxml"));
8
AnchorPane page = (AnchorPane) loader.load();
9
Stage dialogStage = new Stage();
10
dialogStage.setTitle("Birthday Statistics");
11
dialogStage.initModality(Modality.WINDOW_MODAL);
12
dialogStage.initOwner(primaryStage);
13
Scene scene = new Scene(page);
14
dialogStage.setScene(scene);
15
16
// Set the persons into the controller
17
BirthdayStatisticsController controller = loader.getController();
18
controller.setPersonData(personData);
19
20
dialogStage.show();
21
22
} catch (IOException e) {
23
// Exception gets thrown if the fxml file could not be loaded
24
e.printStackTrace();
25
}
26
}

Todo está establecido, pero no tenemos a nadie que realmente llama la


nueva showBirthdayStatistics () método. Afortunadamente ya tenemos
un menú en RootLayout.fxml que se puede utilizar para este propósito.
Mostrar estadísticas Birthday Menu

En su RootLayoutController añadir el siguiente método que se encargará


usuario hace clic en elcumpleaños estadísticas muestran elemento del menú:
RootLayoutController.java
1 /**
2 * Opens the birthday statistics.
3 */
4 @FXML
5 private void handleShowBirthdayStatistics() {
6 mainApp.showBirthdayStatistics();
7 }

También podría gustarte