Por 9.99€ al mes tendrás acceso completo a todos los cursos. Sin matrícula ni permanencia.
- JavaFX es una librería open source nativa de Java.
- Reemplaza a Swing en el desarrollo de interfaces visuales.
- Aunque en su concepción estaba enfocado en la creación de interfaces para móviles, web y escritorio, actualmente se usa sólo en el escritorio.
- Las aplicaciones creadas se pueden ejecutar en los escritorios Linux, Windows y Mac.
Añadir soporte de JavaFX a Eclipse
- Vamos a instalar un plugin en eclipse para tener este soporte: Menu help → Eclipse Marketplace → javafx → e(fx)clipse
- Project explorer → botón derecho del ratón → new → JavaFX Project
Crear una escena básica con JavaFX
public class MainEscenaBasica extends Application {
@Override
public void start(Stage primaryStage) {
try {
//Especificamos el layout que definirá la distribución de los componentes en escena
StackPane root = new StackPane();
// Definimos la escena (la vista o ventana con la que el usuario va a interactuar)
// Dicha escena recibe como parámetro la distrubución de sus componentes y sus medidas
Scene scene = new Scene(root,400,400);
// Para que una escena sea visible, debe ser añadida al escenario
primaryStage.setScene(scene);
// Hacemos visible el escenario
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
Detectar y procesar el click sobre un botón
Button btn = new Button("Púlsame");
btn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println("hola");
}
});
root.getChildren().add(btn);
Usando lambdas (funciones anónimas):
En las lambdas no es necesario declarar el tipo de dato de los argumentos aunque sí que se puede hacer.
btn.setOnAction(event -> System.out.println("hola"));
Acceder al elemento con el que acabamos de interactuar
public static void btnPulsado(Event e) {
Button b = (Button) e.getTarget();
...
}
Layouts de JavaFX
StackPane
Superpone los objetos.
StackPane root = new StackPane();
GridPane
GridPane root = new GridPane();
// El primer parámetro es el objeto que estamos añadiendo a la rejilla
// El segundo parámetro es la columna que ocupará dicho objeto
// El tercer parámetro es la fila que ocupará dicho objeto
root.add(btn1, 1, 0);
Hacer que las celdas del gridpane ocupen el 100% del espacio disponible:
GridPane.setVgrow(btn2, Priority.ALWAYS);
GridPane.setHgrow(btn1, Priority.ALWAYS);
btn.setMaxWidth(Double.MAX_VALUE); btn.setMaxHeight(Double.MAX_VALUE);
VBox
Coloca los elementos en vertical.
Para que el componente ocupe el 100% del layout que lo envuelve:
VBox.setVgrow(btn1, Priority.ALWAYS);
btn1.setMaxHeight(Double.MAX_VALUE);
HBox
Coloca los elementos en horizontal.
HBox root = new HBox();
Para que el componente ocupe el 100% del layout que lo envuelve:
HBox.setHgrow(btn1, Priority.ALWAYS);
btn1.setMaxWidth(Double.MAX_VALUE);
Priority.Always hace que el layout se extienda siempre que sea posible al máximo tamaño.
Añadir elementos a un layout
HBox root = new HBox(btn, btn2);
root.getChildren().add(btn);
Ejercicio layout
Hacer un layout con dos botones que ocupen el 100% del ancho.
Aplicar estilos en línea
root.setStyle("-fx-background-color:#333;");
Algunos componentes de JavaFX
Botón
Button btn = new Button("Calcular");
Cuadro de texto
TextField n2 = new TextField ();
ComboBox
ComboBox op = new ComboBox(options);
Para alimentar la ComboBox:
Con código Java:
ObservableList<String> options = FXCollections.observableArrayList("+","-","*");
final ComboBox op = new ComboBox(options);
Desde el fxml:
<?import javafx.collections.FXCollections ?>
<ComboBox fx:id="op" prefWidth="150.0">
<items>
<FXCollections fx:factory="observableArrayList">
<String fx:value="+" />
<String fx:value="-" />
<String fx:value="*" />
<String fx:value="/" />
</FXCollections>
</items>
<value>
<String fx:value="+" />
</value>
</ComboBox>
Texto
Text txt = new Text("Ha ganado el jugador " + color);
Mensaje de alerta
Stage stage = (Stage)((Button)e.getSource()).getScene().getWindow();
final Stage dialog = new Stage();
dialog.initModality(Modality.APPLICATION_MODAL);
dialog.initOwner(stage);
VBox dialogVbox = new VBox();
Text txt = new Text("Ha ganado el jugador " + color);
dialogVbox.setAlignment(Pos.CENTER);
VBox.setVgrow(txt, Priority.ALWAYS);
dialogVbox.getChildren().add(txt);
Scene dialogScene = new Scene(dialogVbox, 300, 200);
dialog.setScene(dialogScene);
dialog.show();
Documentos FXML programando JavaFX
- Es posible crear las interfaces visuales con código Java o con FXML (similar a HTML).
- FXML soporta el estandar de CSS 2.1 y tiene algunas características de CSS3.
- Los estilos que alteran el posicionamiento de las capas, como position, o display, no funcionan con JavaFX.
- Cuenta con un Scene Builder para poder crear interfaces de manera más amigable.
Botón derecho sobre un paquete → new → New FXML Document
Configurar el Scene Builder en Eclipse
1. Para editar visualmente estos ficheros, podemos instalar el Scene Builder: https://www.oracle.com/java/technologies/javafxscenebuilder-1x-archive-downloads.html
2. Configurar el uso del Scene Builder en Eclipse: Window → Preferences → JavaFX → Scene Builder Executable → C:\Program Files (x86)\Oracle\JavaFX Scene Builder 2.0
3. Botón derecho sobre el fichero FXML que queremos editar → Open With Scene Builder
Cargar una escena definida con el scene Builder
Parent root = FXMLLoader.load(getClass().getResource("/view/tresenraya.fxml"));
Llamar a un método definido en nuestro .java desde nuestro fichero FXML
1. Tendremos que vincular nuestro fichero fxml a su correspondiente controlador:
2. Debemos vincular el nombre del método que queremos ejecutar a su correspondiente botón.
Y en el controlador, definir el método que será llamado con su correspondiente anotación.
@FXML
public void calcular() {
System.out.println("Llega al método");
}
Acceder a un elemento de nuestro fichero .fxml
Hay varias formas, aunque la más sencilla, sería ponerle un identificador en el fxml:
Y luego hacer referencia a ese identificador desde el controlador:
@FXML
private TextField n1;
Hacer que un elemento ocupe el 100% de la capa que lo envuelve:
Con CSS:
.btn {
-fx-max-width: Infinity;
max-width: Infinity;
-fx-max-height: Infinity;
max-height: Infinity;
}
Con atributos:
<Node maxWidth="Infinity"/>
Con el Scene Builder:
- Layout → maxWidth
- Layout → VGrow, HGrou
Los códigos anteriores son equivalentes a este:
node.setMaxWidth(Double.MAX_VALUE);
Hacer una calculadora
Tres en raya – con FXML
- Para detectar la pulsación de una casilla utilizaremos el evento onAction en lugar del evento onMouseClicked. De lo contrario si pulsasemos sobre el texto que hay en el botón, el target sería el label en lugar del propio botón.
- Cada vez que pulsemos sobre una casilla, obtendremos la id de la casilla. Habremos asignado esa id a cada una de las casillas utilizando el Scene Editor. Utilizaremos esa id para ir rellenando con el color del jugador que ha pulsado sobre la casilla el array del tablero. Para recuperar la id de la casilla, utilizaremos el siguiente código:
@FXML
public void btnPulsado(Event e) {
Button b = (Button) e.getTarget();
int id = Integer.parseInt(b.getId());
...
}
- Después de cada tirada, se comprobará si alguien ha ganado llamando al método evaluateWin(String [] tablero);
- El método evaluateWin(String [] tablero) mediante sucesivos if evaluará todas las posibilidades de que un jugador gane.
Tres en raya – sin FXML
Hacer el juego del tres en raya para dos jugadores.
- Utilizando HBox y VBox, montaremos un tablero de 9 posiciones.
- Iremos almacenando en un array de 9 posiciones las casillas a las que se vaya moviendo cada jugador.
- Cada vez que un jugador pulse sobre una casilla, su color quedará modificado en función del jugador al que le tocaba mover.
- Además, ada vez que un jugador pulse sobre una posición quedará modificado un array con el identificador del jugador almacenado en la posición correspondiente. Para ello, podemos vincular a cada botón un atributo que recuperaremos en el momento en que el botón sea pulsado:
// Para añadir un atributo al botón
btn.getProperties().put("index", i);
// Para recuperar un atributo del botón:
int id = (int)b.getProperties().get("index");
- Después de cada tirada, se comprobará si alguien ha ganado, llamando al método evaluateWin(String [] tablero);
- El método evaluateWin(String [] tablero) mediante sucesivos if todas las posibilidades de que un jugador gane.
Insertar imagen
Image img = new Image("/images/perro.jpg");
ImageView imgView = new ImageView(img);
Habremos creado la carpeta images dentro de la carpeta src de nuestro proyecto.
Insertar sonido
String musicFile = "sound/HakunaMatataItMeansNoWorries.mp3";
Media sound = new Media(new File(musicFile).toURI().toString());
MediaPlayer mediaPlayer = new MediaPlayer(sound);
mediaPlayer.play();
sound será una carpeta creada en la raíz de nuestro proyecto.
Para cargar un sonido de internet, usaremos:
Media sound = new Media("http://pablomonteserin.com/res/html5/ex/HakunaMatataItMeansNoWorries.mp3");
Insertar formas
Círculo
Circle circle = new Circle(40);
circle.setFill(Color.RED); // Color de relleno
circle.setStroke(Color.BLACK); // Color del borde
circle.setStrokeWidth(2.0); // Ancho del borde
Rectángulo
Rectangle rect = new Rectangle(0,0, 120, 75);
rect.setFill(Color.RED);
Parámetros:
- x, y de la esquina superior izquierda del rectángulo (si es 0,0 se puede omitir).
- ancho y alto del rectángulo
Línea
Line line = new Line(0, 0, 150, 50);
Parámetros:
- x,y del punto de origin
- x,y, del punto de destino
Arco
Arc arc = new Arc(0, 0, 50, 100, 0, 90);
arc.setType(ArcType.CHORD);
Parámetros:
- centerX
- centerY
- radiusX → El ancho de la elipse de la que forma parte el arco.
- radiusY → El alto de la elipse de la que forma parte el arco.
- startAngle → El ángulo inicial del arco.
- length → La extensión del arco en grados.
Polígono
Polygon poligono = new Polygon();
poligono.getPoints().addAll(30.0, 0.0,
130.0, 0.0,
120.00, 50.0,
0.0, 50.0);
poligono.setStroke(Color.BLACK);
Parámetros:
- Los pares de coordenadas x,y de cada uno de los puntos que componen el polígono.
Polilínea
Polyline polilinea = new Polyline(100.0, 0.0,
120.0, 20.0,
110.0, 140.0,
100.0, 60.0,
80.0, 40.0,
80.0, 120.0);
Parámetros:
- Los pares de coordenadas x,y de cada uno de los puntos que componen el polígono.
Exportar proyecto
Exportar a un jar
Este fichero será ejecutable en linux, windows y mac siempre que el sitema operativo tenga instalada la máquina virtual de Java.
Botón derecho sobre el proyecto → Export … → Runnable JAR file
Exportar a un exe
1. Descargaremos la aplicación Launch4J.
2. En la aplicación debemos rellenar tres casillas:
- Pestaña basic → Output file (debe terminar en .exe)
- Pestaña basic → Jar (le pasamos la ubicación del jar que queremos convertir en ejecutable)
- Pestaña JRE → Min JRE Versión → Yo puse la 1.5