Está en la página 1de 21

Programación de Interfaces Gráficas con JavaFX

Parte 3:
Animaciones, Audio y Video, Menús

ELO329 – 2020

Este material ha sido preparado desde varias fuentes, entre ellas el


material del Dr. Paul Fodor, Stony Brook University
Animaciones

ELO-329: Diseño y Programación Orientados a Objetos JavaFX Part_2 - 2


Animaciones
Una animación básicamente es cambiar las propiedades (tamaño,
posición, color, etc) de un objeto a intervalos pequeños para dar la
impresión de movimiento.
Animaciones en JavaFX son divididas en animaciones de linea de tiempo y
transiciones: clases Timeline y Transition. Ambas subclases de Animation.
Hay varias subclases de Transition, cada una de ellas define la animación
de un valor o propiedad particular.
Así tenemos, por ejemplo:
Clase FadeTransition la cual cambia la opacidad (cualidad de opaco) a intervalos
regulares.
Clase PathTransition la cual traslada las coordenada x e y del nodo a intervalos
regulares.
Con Timeline podemos definir animaciones de manera libre.
ELO-329: Diseño y Programación Orientados a Objetos JavaFX Part_2 - 3
Ejemplo: PathTransitionDemo
public class PathTransitionDemo extends Application {
public void start(Stage primaryStage) {
Pane pane = new Pane();
Rectangle rectangle = new Rectangle(0, 0, 25, 50);
rectangle.setFill(Color.ORANGE);
Circle circle = new Circle(125, 100, 50);
circle.setFill(Color.WHITE);
circle.setStroke(Color.BLACK);
pane.getChildren().addAll(circle, rectangle);
// Create a path transition
PathTransition pt = new PathTransition();
pt.setDuration(Duration.millis(4000));
pt.setPath(circle);
pt.setNode(rectangle);
pt.setOrientation(PathTransition.OrientationType.ORTHOGONAL_TO_TANGENT);
pt.setCycleCount(Timeline.INDEFINITE);
pt.setAutoReverse(true); // commnet and try
//pt.setInterpolator(Interpolator.LINEAR); // uncommnet and try
pt.play(); // Start animation
circle.setOnMousePressed(e -> pt.pause());
circle.setOnMouseReleased(e -> pt.play());
Scene scene = new Scene(pane, 250, 200);
primaryStage.setTitle("PathTransitionDemo");
primaryStage.setScene(scene);
primaryStage.show();
}
/* main has been omitted */
}
ELO-329: Diseño y Programación Orientados a Objetos JavaFX Part_2 - 4
Ejemplo: TimelineDemo
public class TimelineDemo extends Application {
public void start(Stage primaryStage) {
StackPane pane = new StackPane();
Text text = new Text(20, 50, "Programming if fun");
text.setFill(Color.RED);
pane.getChildren().add(text);
// Create a handler for changing text Define tiempos específicos
EventHandler<ActionEvent> eH = e -> { de la animación. Aquí
if (text.getText().length() != 0)
text.setText(""); vemos un uso básico.
else
text.setText("Programming is fun");
};
Timeline animation = new Timeline(new KeyFrame(Duration.millis(500), eH));
animation.setCycleCount(Timeline.INDEFINITE);
animation.play(); // Start animation
text.setOnMouseClicked(e -> { // Pause and resume animation
if (animation.getStatus()== Animation.Status.PAUSED)
animation.play(); Handler invocado al
else término del tiempo
animation.pause();
});
Scene scene = new Scene(pane, 250, 50);
primaryStage.setTitle("TimelineDemo");
primaryStage.setScene(scene);
primaryStage.show();
}
//… main
}
ELO-329: Diseño y Programación Orientados a Objetos JavaFX Part_2 - 5
Reproducción de Audio y Video

ELO-329: Diseño y Programación Orientados a Objetos JavaFX Part_2 - 6


Incorporando medios a la aplicación
El paquete javafx.scene.media permite incorporar
reproducción de audio y video en las aplicaciones.
Actualmente hay soporte para una variedad de formatos de
audio y video.
Tres clases básicas son:
Media: Contiene información sobre el medio (su
fuente, resolución, etc)
MediaPlayer: Provee métodos para reproducir un
medio
MediaView: Subclase de Node, es requerida para
video, sus instancias soportan animación y efectos.

ELO-329: Diseño y Programación Orientados a Objetos JavaFX Part_2 - 7


Ejemplo: AudioMediaDemo
public class AudioMediaDemo extends Application {
private static final String MEDIA_URL =
"http://profesores.elo.utfsm.cl/~agv/elo329/JavaProg/JavaFX/AudioMediaDemo/droneSound.mp3";
public void start(Stage primaryStage) {
Media media = new Media(MEDIA_URL); Otras opciones para especificar la fuente:
MediaPlayer mediaPlayer = new MediaPlayer(media); private static final String MEDIA_URL = "file:/path/to/file/droneSound.mp3";
mediaPlayer.setCycleCount(MediaPlayer.INDEFINITE); // or
Button playButton = new Button(">"); private static final String MEDIA_URL =
AudioMediaDemo.class.getResource("droneSound.mp3").toExternalForm();
playButton.setOnAction(e -> {
if (playButton.getText().equals(">")) {
mediaPlayer.play(); playButton.setText("||");
} else {
mediaPlayer.pause(); playButton.setText(">");
}
});
Slider slVolume = new Slider();
slVolume.setPrefWidth(150); Cambio en slider,
slVolume.setMaxWidth(Region.USE_PREF_SIZE); cambia volumen
slVolume.setMinWidth(30);
slVolume.setValue(50);
mediaPlayer.volumeProperty().bind(slVolume.valueProperty().divide(100));
HBox hBox = new HBox(10);
hBox.setAlignment(Pos.CENTER);
hBox.getChildren().addAll(playButton, new Label("Volume"), slVolume);
Scene scene = new Scene(hBox, 350, 100);
primaryStage.setTitle("AudioMediaDemo");
primaryStage.setScene(scene);
primaryStage.show();
}
// … main
}
ELO-329: Diseño y Programación Orientados a Objetos JavaFX Part_2 - 8
Ejemplo VideoMediaDemo
public class VideoMediaDemo extends Application {
private static final String MEDIA_URL = VideoMediaDemo.class.getResource("video.mp4").toExternalForm();
public void start(Stage primaryStage) {
Media media = new Media(MEDIA_URL);
MediaPlayer mediaPlayer = new MediaPlayer(media);
MediaView mediaView = new MediaView(mediaPlayer);
Button playButton = new Button(">");
playButton.setOnAction(e -> {
if (playButton.getText().equals(">")) {
mediaPlayer.play(); playButton.setText("||");
} else {
mediaPlayer.pause(); playButton.setText(">");
}
});
Button rewindButton = new Button("<<");
rewindButton.setOnAction(e -> mediaPlayer.seek(Duration.ZERO));
Slider slVolume = new Slider();
slVolume.setPrefWidth(150);
slVolume.setMinWidth(30); slVolume.setValue(50);
mediaPlayer.volumeProperty().bind(slVolume.valueProperty().divide(100));
HBox hBox = new HBox(10);
hBox.setAlignment(Pos.CENTER);
hBox.getChildren().addAll(playButton, rewindButton,
new Label("Volume"), slVolume);
BorderPane pane = new BorderPane();
pane.setCenter(mediaView); pane.setBottom(hBox);
Scene scene = new Scene(pane, 600, 350);
primaryStage.setTitle("VideoMediaDemo");
primaryStage.setScene(scene);
primaryStage.show();
}
// ... main
}
ELO-329: Diseño y Programación Orientados a Objetos JavaFX Part_2 - 9
Menús

ELO-329: Diseño y Programación Orientados a Objetos JavaFX Part_2 - 10


Menús
JavaFx provee 5 clases para implementar menús: MenuBar, Menu,
MenuItem, CheckMenuItem, y RadioButtonMenuItem.
Ítems de un menú son instancias de MenuItem, CheckMenuItem, o
RadioButtonMenuItem.
Veamos un ejemplo...

ELO-329: Diseño y Programación Orientados a Objetos JavaFX Part_2 - 11


Ejemplo: MenuBarDemo
public class MenuBarDemo extends Application { VBox vBox = new VBox(10);
private TextField tfNumber1 = new TextField(); vBox.getChildren().addAll(menuBar, hBox1);
private TextField tfNumber2 = new TextField(); Scene scene = new Scene(vBox, 450, 100);
private TextField tfResult = new TextField(); primaryStage.setTitle("MenuBarDemo");
public void start(Stage primaryStage) { primaryStage.setScene(scene);
MenuBar menuBar = new MenuBar(); primaryStage.show();
Menu menuOperation = new Menu("Operation"); // Handle menu actions
Menu menuExit = new Menu("Exit"); menuItemAdd.setOnAction(e -> perform('+'));
menuBar.getMenus().addAll(menuOperation, menuExit); menuItemSubtract.setOnAction(e -> perform('-'));
MenuItem menuItemAdd = new MenuItem("Add"); menuItemClose.setOnAction(e -> System.exit(0));
MenuItem menuItemSubtract = new MenuItem("Subtract"); }
menuOperation.getItems().addAll(menuItemAdd, menuItemSubtract);
MenuItem menuItemClose = new MenuItem("Close"); private void perform(char operator) {
menuExit.getItems().add(menuItemClose); double number1 = Double.parseDouble(tfNumber1.getText());
menuItemAdd.setAccelerator(KeyCombination. double number2 = Double.parseDouble(tfNumber2.getText());
keyCombination("Ctrl+A")); double result = 0;
menuItemSubtract.setAccelerator(KeyCombination. switch (operator) {
keyCombination("Ctrl+S")); case '+': result = number1 + number2; break;
HBox hBox1 = new HBox(5); case '-': result = number1 - number2; break;
hBox1.getChildren().addAll(new Label("Number 1:"), tfNumber1, }
new Label("Number 2:"), tfNumber2, new Label("Result:"), tfResult.setText(result + "");
tfResult); }
hBox1.setAlignment(Pos.CENTER);
tfNumber1.setPrefColumnCount(2); public static void main(String[] args) {
tfNumber2.setPrefColumnCount(2); launch(args);
tfResult.setPrefColumnCount(2); }
}

ELO-329: Diseño y Programación Orientados a Objetos JavaFX Part_2 - 12


Menú de contexto (ContextMenu)
Un menú de contexto (conocidos como menú popup) es
como un menú regular, pero no tiene barra de menú y puede
flotar en cualquier parte de la escena.
La creación de un menú popup es similar al menú regular, la
diferencia está en que un menú de contexto se puede
asociar a cualquier instancia de Nodo.
Una vez construido el menú de contexto
ésta parece al invocar:
void show(Node anchor, double screenX, double screenY)

ELO-329: Diseño y Programación Orientados a Objetos JavaFX Part_2 - 13


Ejemplo: ContextMenuDemo
public class ContextMenuDemo extends Application {
public void start(Stage primaryStage) {
ContextMenu contextMenu = new ContextMenu();
MenuItem menuItemNew = new MenuItem("New", new ImageView("image/new.gif"));
MenuItem menuItemOpen = new MenuItem("Open", new ImageView("image/open.gif"));
MenuItem menuItemPrint = new MenuItem("Print",new ImageView("image/print.gif"));
MenuItem menuItemExit = new MenuItem("Exit");
contextMenu.getItems().addAll(menuItemNew, menuItemOpen,
menuItemPrint, menuItemExit);
Pane pane = new Pane();
Scene scene = new Scene(pane, 300, 250);
primaryStage.setTitle("ContextMenuDemo");
primaryStage.setScene(scene);
primaryStage.show();
pane.setOnMousePressed(
e -> contextMenu.show(pane, e.getScreenX(), e.getScreenY()));
menuItemNew.setOnAction(e -> System.out.println("New"));
menuItemOpen.setOnAction(e -> System.out.println("Open"));
menuItemPrint.setOnAction(e -> System.out.println("Print"));
menuItemExit.setOnAction(e -> System.exit(0));
}
// .... main ...
}

ELO-329: Diseño y Programación Orientados a Objetos JavaFX Part_2 - 14


Se podrían ver más temas como
transformaciones 2D y 3D, efectos visuales, etc.,
pero quedaremos hasta aquí.
Los interesados ver:
https://docs.oracle.com/javase/8/javase-clienttechnologies.htm

ELO-329: Diseño y Programación Orientados a Objetos JavaFX Part_2 - 15


Desarrollo de Interfaces Gráficas con
Scene Builder

ELO-329: Diseño y Programación Orientados a Objetos JavaFX Part_2 - 16


Instalación y uso de Scene Builder en IntelliJ
Bajar Scene Builder desde:
https://gluonhq.com/products/scene-builder/
En linux haga doble click en archivo bajado y se instalará. El
ejecutable queda instalado en /opt/SceneBuilder/. Allí, el
ejecutable es SceneBuilder.
Scene Builder puede ser integrado a algunas IDEs como
IntelliJ. Ver aquí cómo.

ELO-329: Diseño y Programación Orientados a Objetos JavaFX Part_2 - 17


Uso de SceneBuilder con Jgrasp (1/2)
Primero cree la interfaz con SceneBuilder.
Cosas importantes: en la sección Code de la derecha dar un
id para sus objetos gráficos y nombres a los métodos de los
eventos que desee manejar. Ese id será el nombre del
objeto gráfico en su programa.
Para definir la clase controladora que manejará los eventos,
en la sección izquierda inferior, usted debe indicar el
nombre de la clase controladora.
Luego acceda a View -> “Show Sample Controller Skeleton”
y verá el esqueleto del código del controlador.

ELO-329: Diseño y Programación Orientados a Objetos JavaFX Part_2 - 18


Uso de SceneBuilder con Jgrasp (2/2)
Luego acceda a View -> “Show Sample Controller Skeleton”
y usted ver´a el esqueleto de la clase controladora.
Puede usar botón copy y luego en Jgrasp cree un archivo
java nuevo y haga paste el esqueleto del controlador.
Complete los import necesarios, dé código a los
manejadores de eventos y compile el controlador.
Es importante que en el mismo directorio del código java,
usted ponga el archivo .fxml generado por Scene Builder.
A continuación un ejemplo de aplicación JavaFX que usa la
interfaz creada por Scene Builder.
ELO-329: Diseño y Programación Orientados a Objetos JavaFX Part_2 - 19
Ejemplo: MyFirstSceneBuilderApp
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.application.Application; import javafx.event.ActionEvent;
import javafx.fxml.FXMLLoader; import javafx.scene.input.MouseEvent;
import javafx.scene.*;
import javafx.stage.Stage; public class ButtonController {
@FXML
public class MyFirstSceneBuilderApp extends Application { private Button MyButtonID;
public void start(Stage primaryStage) throws Exception { @FXML
Parent root = FXMLLoader.load(getClass(). void buttonHandler(ActionEvent event) {
getResource("myFirstButton.fxml")); System.out.println("Button has been pressed");
primaryStage.setTitle("My First Button Scene Builder App"); }
primaryStage.setScene(new Scene(root,300,200)); @FXML
primaryStage.show(); void mouseEntered(MouseEvent event) {
} System.out.println("Mouse has entered");
} }
@FXML
void mouseExited(MouseEvent event) {
System.out.println("Mouse has exited");
}
}

ELO-329: Diseño y Programación Orientados a Objetos JavaFX Part_2 - 20


MyFirstSceneBuilderApp
Archivo .fxml
En este caso el archivo myFirstButton.fxml generado por
Scene Builder fue:
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.StackPane?>

<StackPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity"


prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1"
xmlns:fx="http://javafx.com/fxml/1" fx:controller="ButtonController">
<children>
<Button fx:id="MyButtonID" mnemonicParsing="false" onAction="#buttonHandler"
onMouseEntered="#mouseEntered" onMouseExited="#mouseExited" text="MyFirstButton"
textAlignment="CENTER" />
</children>
</StackPane>

ELO-329: Diseño y Programación Orientados a Objetos JavaFX Part_2 - 21

También podría gustarte