Java Laboratory Activity For JavaFX Program
Java Laboratory Activity For JavaFX Program
Laboratory Module 7
Graphic User Interface (GUI)
By
Luis Miguel IV G. Perez, LBYCPEI-EQ6
1
INTRODUCTION
In this module we will be focusing on Graphical User Interface (GUI) programming using
JavaFX. You will learn how to create shapes, text, and graphics, and how to incorporate them into a
JavaFX application. We will also explore the use of event handling and sound to enhance the user
experience. In addition to learning the basics of JavaFX programming, we will also delve into application
styling with CSS (Cascading Style Sheets) and explore the use of SceneBuilder for GUI design. By the
end of the course, you will be able to create a user interface that allows users to interact with your
program and facilitate data gathering.
Objectives
1. To introduce Graphical User Interface (GUI) programming and utilize graphics, images, and sound
with event handling.
2. To be able to create shapes and text using JavaFX and display them in an application.
3. To familiarize basic application styling, e.g., CSS (Cascading Style Sheets).
4. To be able to utilize applications like SceneBuilder for GUI design.
5. To be able to provide an interface for the user to interact with the program.
6. To understand the basics of writing and creating a user interface to help facilitate data gathering from
the user.
Materials:
1. IntelliJ IDEA ( Java IDE)
2. Java SE
3. JavaFX SDK ( https://github.com/openjdk/jfx/ )
4. JavaFX documentation
5. JavaFX scene builder ( https://gluonhq.com/products/scene-builder )
2
PROCEDURES (Individual) / EXPERIMENTAL PLAN
To complete the Pokemon Card Collection in JavaFX, we had to replace the ACM graphics
program with JavaFx and modify the Pokémon card collection software from module 6. Using
Scene Builder, a straightforward GUI may be made that shows the user all available options.
Since the workflow would need to be significantly altered, but the assets would largely remain the
same, the truck part is switching the entire code over to JavaFX. If care is not taken, this transfer
could also result in numerous problems; therefore, it is crucial to check for these faults to make
the application work. Numerous failures occurred throughout the development of this application,
emphasizing the necessity of debugging in this activity.
II. SocialNet
In the second task, we were to develop a social networking application that could generate user
profiles depending on input from the user. Name, status, image, friends, and favorite quote are
some of these inputs. For the purpose of guiding the overall program's structure and flow, a
starting program was offered. The controller class, which manages the bulk of the code's
operations, contains the majority of the programming. According to user input, this provides the
ability to add, search for, and delete profiles. This class also deals with how individual profiles
are saved with profile data in them. This program has a user interface that is simple to use and
interactive, making it simple for users to manage, connect with others, and view their profiles.
3
RESULTS AND DISCUSSION
4
Explanation:
Each class has a number of instance variables that reflect UI elements in the layout of the application,
including labels, buttons, and image views. Additionally, there are instance variables for storing data, such
as the Object PokemonCard, which looks to be a data structure holding information about Pokémon, and
Object An object called a random generator produces random numbers. Numerous methods in the class
correspond to the event handlers for the application's UI elements. When a user presses the "Quit" button
5
and closes the application, for instance, the quitButtonOnAction method is a program's window When a
user wishes to view details about a Pokémon, the showPokemon method is invoked. A specific Pokémon
is selected, and the UI is updated to show the pertinent information. When a user wishes to view details
about a Pokémon, the showPokemon method is invoked. A specific Pokémon is selected, and the UI is
updated to show the pertinent information. There is a setPokeCard method as well for configuring the
PokemonCard object that houses the info for Pokémon.
2. Social Net
6
7
Explanation:
Users can create and maintain their own profiles using the graphical user interface (GUI) of this
Java social networking application. Users can update their status and profile photo, add and remove
friends from their friend list, search for profiles, and add and delete friends from their friend list, among
other tasks. The majority of the program's functionality is handled by a controller class, while the JavaFX
library is used to build the GUI and regulate user interactions.
8
CONCLUSION:
In this module, the students will learn how to use JavaFX to create Graphical User Interfaces
(GUIs) for your applications. The students learn how to incorporate graphics, images, and sound into their
GUI and how to handle events to enhance the user experience. The students also learn how to style their
application using CSS and how to use SceneBuilder to design GUI. By the end of the module, you will be
able to create a user interface that allows users to interact with your program and facilitate data gathering.
The main objectives of this module are to introduce GUI programming, create shapes and text using
JavaFX, familiarize yourself with basic application styling, use tools like SceneBuilder for GUI design,
provide an interface for user interaction, and understand the basics of writing and creating a user interface
for data gathering.
A common mistake that I encountered while working on this module was improperly relating the
classes to each other or using the wrong logic in my code. To overcome this, I found it helpful to
carefully check the error messages provided by the IDE and double-check the logic in my code. I also
found it helpful to have a strong understanding of how objects work and how they can be modified to
improve the program. In order to improve this module, it might be helpful to spend less time adjusting the
graphics and focus more on the core concepts and mechanics of JavaFX programming. Overall, I would
recommend that those who attempt this activity take the time to understand the underlying concepts and
mechanics of JavaFX programming in order to avoid common mistakes and build a strong foundation for
their work.
9
APPENDIX (Copy all source codes here per problem category)
1. PokemonDatabase
package com.example.pokemonfx;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
System.out.println(Arrays.toString(pokemonStats));
System.out.println(pokemonStats[0]); // Names
System.out.println(pokemonStats[1]); // Weights
System.out.println(pokemonStats[2]); // Heights
System.out.println(Double.parseDouble(pokemonStats[3]));//Attack
System.out.println(Double.parseDouble(pokemonStats[4]));//
Defense
System.out.println(Double.parseDouble(pokemonStats[5]));//
Stamina
System.out.println(pokemonStats[6]); // Types
pokedex.add(PokeCard);
}
} catch (
FileNotFoundException e) {
System.out.println("File does not Exist");
}
System.out.println(pokedex);
10
}
if (pokemonName.equalsIgnoreCase(names)){
return pokemonNum;
}
}
return pokemonNum;
}
11
int choice;
do {
println("Choose an Option:");
println("1-Remove a Pokemon");
println("2-View One Pokemon");
println("3-View slideshow of Pokemon");
println("4-Search a Pokemon");
println("5-Quit");
choice = readInt("Choice: ");
switch (choice) {
case 1:
int num;
12
}
else {
println("Sorry: " + name + " is not found in the
database!");
}
break;
case 5:
println("Thank you for using the Program");
break;
default:
println("Invalid Input");
break;
}
1.2 PokemonController
package com.example.pokemonfx;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
13
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;
import java.util.random.RandomGenerator;
int num = 0;
@FXML
private Button quitButton;
@FXML
private Label removePrompt;
@FXML
private Button enterView;
@FXML
private ImageView pokeImg;
@FXML
private ImageView pokeBg;
@FXML
private Label pokeName;
@FXML
private Label heightLabel;
@FXML
private Label weightLabel;
@FXML
private Label attackText;
@FXML
private Label defText;
@FXML
private Label stamText;
@FXML
private TextField nameField;
@FXML
private Rectangle blackBox;
@FXML
private Rectangle infoBox;
@FXML
private Rectangle atkBoxOne;
@FXML
private Rectangle atkBoxTwo;
14
@FXML
private Rectangle defBoxOne;
@FXML
private Rectangle defBoxTwo;
@FXML
private Rectangle stamBoxOne;
@FXML
private Rectangle stamBoxTwo;
@FXML
private Label singleTypeText;
@FXML
private Rectangle singleTypeBox;
@FXML
private Rectangle multiBoxOne;
@FXML
private Rectangle multiBoxTwo;
@FXML
private Label multiLabelOne;
@FXML
private Label multiLabelTwo;
@FXML
private Button removeButton;
@FXML
private Button searchButton;
@FXML
private Button slideshowButton;
@FXML
private Label removedText;
@FXML
private Button enterRemove;
@FXML
private Button viewButton;
15
Stage stage = (Stage) quitButton.getScene().getWindow();
stage.close();
}
} else {
String type = PokeData.getPokemon(index).getType().trim();
String name = PokeData.getPokemon(index).getName();
heightLabel.setOpacity(1);
weightLabel.setOpacity(1);
attackText.setOpacity(1);
defText.setOpacity(1);
stamText.setOpacity(1);
blackBox.setOpacity(1);
pokeName.setOpacity(1);
pokeImg.setOpacity(1);
if (type.contains("/")) {
singleTypeBox.setOpacity(0);
singleTypeText.setOpacity(0);
String[] typeTwo = type.split("/");
String firstType = typeTwo[0];
String secType = typeTwo[1];
pokeImg.setImage(new Image("file:src/main/resources/assets/" +
name + ".png"));
pokeBg.setImage(new Image("file:src/main/resources/assets/" +
firstType + ".png"));
16
multiBoxOne.setOpacity(1);
multiBoxTwo.setOpacity(1);
multiLabelOne.setText(firstType);
multiLabelTwo.setText(secType);
} else {
pokeImg.setImage(new Image("file:src/main/resources/assets/" +
name + ".png"));
pokeBg.setImage(new Image("file:src/main/resources/assets/" +
type + ".png"));
multiBoxTwo.setOpacity(0);
multiBoxOne.setOpacity(0);
singleTypeBox.setOpacity(1);
singleTypeText.setText(type);
}
pokeName.setText(name);
heightLabel.setText("HEIGHT: " +
PokeData.getPokemon(index).getHeight());
weightLabel.setText("WEIGHT: " +
PokeData.getPokemon(index).getWeight());
attackText.setOpacity(1);
atkBoxOne.setOpacity(1);
atkBoxTwo.setOpacity(1);
atkBoxTwo.setWidth(PokeData.getPokemon(index).getAttack());
defText.setOpacity(1);
defBoxOne.setOpacity(1);
defBoxTwo.setOpacity(1);
defBoxTwo.setWidth(PokeData.getPokemon(index).getDefense());
stamText.setOpacity(1);
stamBoxOne.setOpacity(1);
stamBoxTwo.setOpacity(1);
stamBoxTwo.setWidth(PokeData.getPokemon(index).getStamina());
blackBox.setOpacity(1);
infoBox.setOpacity(1);
}
@FXML
public void viewButtonOnAction(ActionEvent e) {
int index = rgen.nextInt(0, PokeData.getSize() - 1);
heightLabel.setOpacity(1);
weightLabel.setOpacity(1);
attackText.setOpacity(1);
defText.setOpacity(1);
stamText.setOpacity(1);
blackBox.setOpacity(1);
pokeName.setOpacity(1);
pokeImg.setOpacity(1);
17
if (type.contains("/")) {
multiLabelOne.setOpacity(1);
multiLabelTwo.setOpacity(1);
singleTypeBox.setOpacity(0);
singleTypeText.setOpacity(0);
String[] typeTwo = type.split("/");
String firstType = typeTwo[0];
String secType = typeTwo[1];
pokeImg.setImage(new Image("file:src/main/resources/assets/" + name
+ ".png"));
pokeBg.setImage(new Image("file:src/main/resources/assets/" +
firstType + ".png"));
multiBoxOne.setOpacity(1);
//multiBoxOne.setFill(Color.color(0.6, 0.1, 0.1));
multiBoxTwo.setOpacity(1);
// multiBoxTwo.setFill(Color.color(0.8, 0.4, 0.2));
multiLabelOne.setText(firstType);
multiLabelTwo.setText(secType);
} else {
pokeImg.setImage(new Image("file:src/main/resources/assets/" + name
+ ".png"));
pokeBg.setImage(new Image("file:src/main/resources/assets/" + type +
".png"));
multiBoxTwo.setOpacity(0);
multiBoxOne.setOpacity(0);
singleTypeBox.setOpacity(1);
singleTypeText.setOpacity(1);
// singleTypeBox.setFill(Color.color(0.6, 0.1, 0.1));
singleTypeText.setText(type);
}
pokeName.setText(name);
heightLabel.setText("HEIGHT: " +
PokeData.getPokemon(index).getHeight());
weightLabel.setText("WEIGHT: " +
PokeData.getPokemon(index).getWeight());
attackText.setOpacity(1);
atkBoxOne.setOpacity(1);
atkBoxTwo.setOpacity(1);
atkBoxTwo.setWidth(PokeData.getPokemon(index).getAttack());
defText.setOpacity(1);
defBoxOne.setOpacity(1);
defBoxTwo.setOpacity(1);
defBoxTwo.setWidth(PokeData.getPokemon(index).getDefense());
stamText.setOpacity(1);
stamBoxOne.setOpacity(1);
stamBoxTwo.setOpacity(1);
stamBoxTwo.setWidth(PokeData.getPokemon(index).getStamina());
blackBox.setOpacity(1);
@FXML
public void removePromptOnAction(ActionEvent e) {
removePrompt.setOpacity(1);
removePrompt.setText("Enter Pokemon to remove:");
18
nameField.setOpacity(1);
enterRemove.setOpacity(1);
removedText.setOpacity(0);
}
displayImg(index);
nameField.clear();
nameField.setOpacity(0);
enterView.setOpacity(0);
removePrompt.setOpacity(0);
}
if (type.contains("/")) {
singleTypeBox.setOpacity(0);
singleTypeText.setOpacity(0);
String[] typeTwo = type.split("/");
String firstType = typeTwo[0];
String secType = typeTwo[1];
pokeImg.setImage(new Image("file:src/main/resources/assets/" +
name + ".png"));
pokeBg.setImage(new Image("file:src/main/resources/assets/" +
firstType + ".png"));
multiBoxOne.setOpacity(1);
multiBoxOne.setFill(Color.color(0.6, 0.1, 0.1));
multiLabelOne.setOpacity(1);
multiBoxTwo.setOpacity(1);
19
multiBoxTwo.setFill(Color.color(0.8, 0.4, 0.2));
multiLabelTwo.setOpacity(1);
multiLabelOne.setText(firstType);
multiLabelTwo.setText(secType);
} else {
pokeImg.setImage(new Image("file:src/main/resources/assets/" +
name + ".png"));
pokeBg.setImage(new Image("file:src/main/resources/assets/" +
type + ".png"));
multiBoxTwo.setOpacity(0);
multiBoxOne.setOpacity(0);
multiLabelOne.setOpacity(0);
multiLabelTwo.setOpacity(0);
singleTypeBox.setOpacity(1);
singleTypeBox.setFill(Color.color(0.6, 0.1, 0.1));
singleTypeText.setOpacity(1);
singleTypeText.setText(type);
}
pokeName.setText(name);
heightLabel.setText("HEIGHT: " +
PokeData.getPokemon(num).getHeight());
weightLabel.setText("WEIGHT: " +
PokeData.getPokemon(num).getWeight());
attackText.setOpacity(1);
atkBoxOne.setOpacity(1);
atkBoxTwo.setOpacity(1);
atkBoxTwo.setWidth(PokeData.getPokemon(num).getAttack());
defText.setOpacity(1);
defBoxOne.setOpacity(1);
defBoxTwo.setOpacity(1);
defBoxTwo.setWidth(PokeData.getPokemon(num).getDefense());
stamText.setOpacity(1);
stamBoxOne.setOpacity(1);
stamBoxTwo.setOpacity(1);
stamBoxTwo.setWidth(PokeData.getPokemon(num).getStamina());
blackBox.setOpacity(1);
}));
timeline.setCycleCount(PokeData.getSize());
timeline.play();
}
20
1.3 PokeApp
package com.example.pokemonfx;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
PokeData.loadStats("assets/Pokemon.txt");
21
public String getWeight(){
return weight;
}
2.5 Pokemon
package com.example.pokemonfx;
22
public class Pokemon {
return name;
this.name = name;
return weight;
this.weight = weight;
23
public String getHeight() {
return height;
this.height = height;
return attack;
this.attack = attack;
return defense;
this.defense = defense;
return stamina;
24
public void setStamina(double stamina) {
this.stamina = stamina;
return type;
this.type = type;
2.1
import java.awt.Color;
import java.awt.event.*;
/** The main class responsible for managing the chess game */
public class Chess extends GraphicsProgram {
/**
* Object responsible for handling the graphical display on the screen
*/
ChessDisplay display;
/**
* Object that keeps track of the locations of all pieces
*/
ChessBoard board;
ChessFrame frame;
ChessPiece lastPieceClicked;
boolean isWhiteTurn;
25
boolean isBlackTurn;
boolean isPieceClicked;
/**
* Method called before run responsible for initializing the ChessDisplay
and
* ChessBoard objects
*/
public void init() {
frame = new ChessFrame(this);
frame.init();
display = ChessDisplay.getInstance(this); // This line is required,
don't change it
board = new ChessBoard();
mouseListenerAdded();
/**
* The main method that runs the program
*/
public void run() {
// You fill this in.
display.draw(board);
}
//@Override
//public synchronized void addMouseListener(MouseListener l) {
//super.addMouseListener(l);
//}
26
if(isWhiteTurn){
if (!isPieceClicked){
if (board.pieceAt(place[0],place[1]).getColor() ==
ChessPiece.WHITE){
display.selectSquare(place[0],place[1], Color.blue);
lastPieceClicked = board.pieceAt(place[0],place[1]);
display.draw((board));
isPieceClicked = true;
} else {
println("not your piece");
}
} else {
if (lastPieceClicked.canMoveTo(place[0],place[1], board)){
board.removePiece(lastPieceClicked.getRow(),
lastPieceClicked.getCol());
lastPieceClicked.moveTo(place[0], place[1]);
board.addPiece(lastPieceClicked);
display.unselectAll();
display.draw(board);
isWhiteTurn = false;
isBlackTurn = true;
lastPieceClicked = null;
isPieceClicked = false;
System.out.println("Black's turn");
}
}
} else if (isBlackTurn){
if (!isPieceClicked){
if (board.pieceAt(place[0],place[1]).getColor() ==
ChessPiece.BLACK){
display.selectSquare(place[0],place[1], Color.blue);
lastPieceClicked = board.pieceAt(place[0],place[1]);
display.draw((board));
isPieceClicked = true;
} else {
println("not your piece");
}
} else {
if (lastPieceClicked.canMoveTo(place[0],place[1], board)){
board.removePiece(lastPieceClicked.getRow(),
lastPieceClicked.getCol());
lastPieceClicked.moveTo(place[0], place[1]);
board.addPiece(lastPieceClicked);
display.unselectAll();
display.draw(board);
isWhiteTurn = true;
isBlackTurn = false;
lastPieceClicked = null;
isPieceClicked = false;
System.out.println("White's turn");
}
}
}
}
@Override
27
public ChessFrame getChessFrame() {
return frame;
}
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
2.2 Profile
package com.example.module7socialnet;
import javafx.scene.image.Image;
import java.util.ArrayList;
import java.util.List;
28
this.profilePicture = null;
this.friends = new ArrayList<>();
this.favoriteQuote = "";
}
public Profile() {
}
2.3 Controller
package com.example.module7socialnet;
29
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import java.util.ArrayList;
ObservableList<String> friendList;
public Controller() {
// Initialize instance variables here if needed
}
@FXML
private void initialize() {
friendList = FXCollections.observableArrayList();
listView.setItems(friendList);
}
30
public void handleDelete(ActionEvent actionEvent) {
if (!nameField.getText().trim().isEmpty()) {
String name = nameField.getText();
for (Profile profile : dataBase) {
if (profile.getName().equals(name)) {
dataBase.remove(profile);
statusLabel.setText(name + " deleted");
break;
}
}
}
}
31
}
}
}
}
32
33