Images and media
IA tooling, not an exam topic. These are JavaFX patterns to adapt for your IA. Media is optional for most projects. Nothing here is examinable, and your IA must be your own work.
This page covers showing an image, letting the user pick one, using an image as a button icon, and playing a sound. For all of these, the media file must travel with your project so it can be found at run time.
New here? Read Start here: how every recipe fits together first; it explains the two places you edit and the fx:id link every recipe relies on.
Show an image
What this does: displays a picture in an ImageView, loaded from a file that ships with your project.
When you would use it in your IA: a logo, an icon, a product photo, or any fixed picture the app shows.
In SceneBuilder (the layout): add an ImageView and give it an fx:id of imgLogo. Set fitWidth and turn on preserveRatio so it does not stretch.
<ImageView fx:id="imgLogo" fitWidth="200" preserveRatio="true" />
In the controller (the .java file):
Imports:
import javafx.fxml.FXML;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
Controller:
@FXML private ImageView imgLogo;
@FXML
public void initialize() {
// your IA logic here: the image file your app should show
// logo.png sits next to this class in the project.
Image image = new Image(getClass().getResourceAsStream("logo.png"));
imgLogo.setImage(image);
}
Where your own logic goes: the image file you load, marked // your IA logic here. Creating the Image and putting it in the ImageView is reusable wiring.
Make it your own:
- Change
"logo.png"to your own file, and put the file in the same place as your classes sogetResourceAsStreamfinds it. fitWidthsets the display width;preserveRatio="true"stops the image from stretching.
Watch out for:
- The
fx:idimgLogomust match the@FXMLfield name exactly, or the screen will not load. - If the picture does not appear,
getResourceAsStream("logo.png")probably returnednullbecause the file is not where the code looks. Check the file name and its location in the project. - Setting both
fitWidthandfitHeightwithoutpreserveRatiosquashes the image. Set the ratio flag, or set only one dimension.
Mix with: Let the user pick an image and show it, Put an image on a button.
Let the user pick an image and show it
What this does: lets the user choose an image file from disk and displays it in an ImageView.
When you would use it in your IA: a profile picture the user uploads, or any app where the picture is the user’s own rather than one you shipped.
In SceneBuilder (the layout): add an ImageView (fx:id imgPhoto) and a button to pick the file (onAction handleChoosePhoto).
<ImageView fx:id="imgPhoto" fitWidth="200" preserveRatio="true" />
<Button text="Choose photo..." onAction="#handleChoosePhoto" />
In the controller (the .java file): this combines the file-picker recipe with an ImageView.
Imports:
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import java.io.File;
Controller:
@FXML private ImageView imgPhoto;
@FXML
private void handleChoosePhoto(ActionEvent event) {
FileChooser chooser = new FileChooser();
chooser.getExtensionFilters().add(
new FileChooser.ExtensionFilter("Images", "*.png", "*.jpg", "*.gif"));
Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
File file = chooser.showOpenDialog(stage);
if (file == null) {
return; // the user cancelled
}
// your IA logic here: what to do with the chosen image (here, show it)
imgPhoto.setImage(new Image(file.toURI().toString()));
}
Where your own logic goes: the line marked // your IA logic here, where you use the chosen file (show it, or copy and remember its path). The dialog and Cancel handling are reusable wiring.
Make it your own:
- Adjust the extension filter to the image types you accept.
file.toURI().toString()turns the chosenFileinto an addressImagecan load. Use this form for files the user picks, rather thangetResourceAsStream, which is for files inside your project.
Watch out for:
- The
fx:idimgPhotomust match the@FXMLfield name, andhandleChoosePhotomust exist in the controller, or the screen will not load. - Handle the
nullfrom a cancelled dialog, the same as the file-picker recipe. - If you want to keep the picture between runs, remember to save the file path (or copy the file into your project folder), since the user’s original file could move.
Mix with: Let the user choose a file, Show an image.
Put an image on a button
What this does: sets a small image as a button’s icon, with or without text beside it.
When you would use it in your IA: a toolbar of icon buttons (save, delete, edit), or a single button you want to stand out with a picture.
In SceneBuilder (the layout): add a Button and give it an fx:id of btnSave. The icon is set in code.
<Button fx:id="btnSave" text="Save" onAction="#handleSave" />
In the controller (the .java file):
Imports:
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
Controller:
@FXML private Button btnSave;
@FXML
public void initialize() {
// your IA logic here: the icon file for this button
Image icon = new Image(getClass().getResourceAsStream("save.png"));
ImageView iconView = new ImageView(icon);
iconView.setFitWidth(16);
iconView.setFitHeight(16);
btnSave.setGraphic(iconView); // the image becomes the button's icon
}
Where your own logic goes: the icon file, marked // your IA logic here. Sizing the ImageView and setting it as the graphic is reusable wiring.
Make it your own:
- Change the image file and the
setFitWidth/setFitHeightvalues to suit your icon. - The button can keep its text as well: with both a graphic and text set, the icon sits next to the label.
Watch out for:
- The
fx:idbtnSavemust match the@FXMLfield name exactly, or the screen will not load. - Size the
ImageView(as above), or a large image will blow the button out of shape. - Keep icons small and consistent in size across a toolbar so the buttons line up.
Mix with: Make your app look finished, Show an image.
Play a sound
What this does: plays audio from a file that ships with your project. AudioClip is best for short effects; MediaPlayer is for longer music.
When you would use it in your IA: a short confirmation or error sound, or background music in a game-style app. Sound is optional, so only add it if it serves the project.
In SceneBuilder (the layout): nothing to add beyond whatever control triggers the sound (a button, say). The audio is loaded in code.
In the controller (the .java file):
Short effect with AudioClip:
import javafx.scene.media.AudioClip;
// your IA logic here: which sound to play and when
AudioClip click = new AudioClip(getClass().getResource("click.wav").toExternalForm());
click.play();
Longer music with MediaPlayer:
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
Media media = new Media(getClass().getResource("theme.mp3").toExternalForm());
MediaPlayer player = new MediaPlayer(media); // keep player as a field, see below
player.play();
Where your own logic goes: which sound to play and when, marked // your IA logic here. Loading and playing are reusable wiring.
Make it your own:
- Change the file names to your own audio, and keep those files in the project so they travel with it.
- Use
AudioClipfor quick sounds you trigger often, andMediaPlayerwhen you need play, pause, and stop on a longer track.
Watch out for:
- The audio file must ship with the project. If
getResource(...)returnsnull, the file is missing or in the wrong place. - Store a
MediaPlayerin a field, not a local variable. If it is only a local variable, it can be cleared by the garbage collector and the sound stops unexpectedly. - Media support depends on the file format and the system. Stick to common formats like
.wavfor effects and.mp3for music.
Mix with: Do something on a repeating beat, Run a smooth animation or game loop.