This comprehensive guide provides step-by-step instructions for setting up and working with JavaFX projects in Visual Studio Code.
- One-Time Setup
- Creating a New JavaFX Project
- Running and Debugging
- Common Issues and Solutions
- Working with Existing Projects
- FXML and SceneBuilder Integration
These steps only need to be done once on your system.
# Install OpenJDK 21
sudo apt install openjdk-21-jdk
# Verify Java installation
java --version
javac --version# Create a directory for JavaFX
mkdir -p ~/javafx
# Download JavaFX (adjust version if needed)
cd ~/javafx
wget https://download2.gluonhq.com/openjfx/21.0.7/openjfx-21.0.7_linux-x64_bin-sdk.zip
# Extract the SDK
unzip openjfx-21.0.7_linux-x64_bin-sdk.zip
# Verify installation
ls -la ~/javafx/javafx-sdk-21.0.7/lib/Add these lines to your ~/.bashrc file:
# Java and JavaFX environment variables
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64
export JAVAFX_HOME=~/javafx/javafx-sdk-21.0.7
export PATH_TO_FX=$JAVAFX_HOME/lib
export JAVAFX_MODULES="javafx.controls,javafx.fxml,javafx.graphics,javafx.web,javafx.media,javafx.swing,javafx.base"Apply the changes:
source ~/.bashrc- Open VSCode
- Install the following extensions:
- Extension Pack for Java
- Maven for Java
- JavaFX Support
- Open Settings (Ctrl+,)
- Click the "Open Settings (JSON)" icon in the top-right corner
- Add these settings:
"java.home": "/usr/lib/jvm/java-21-openjdk-amd64",
"java.configuration.runtimes": [
{
"name": "JavaSE-21",
"path": "/usr/lib/jvm/java-21-openjdk-amd64",
"default": true
}
],
"java.jdt.ls.vmargs": "-XX:+UseParallelGC -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -Dsun.zip.disableMemoryMapping=true -Xmx1G -Xms100m --module-path=/home/milesbaack/javafx/javafx-sdk-21.0.7/lib --add-modules=ALL-MODULE-PATH",
"java.configuration.updateBuildConfiguration": "automatic",
"terminal.integrated.env.linux": {
"JAVA_HOME": "/usr/lib/jvm/java-21-openjdk-amd64",
"JAVAFX_HOME": "~/javafx/javafx-sdk-21.0.7",
"PATH_TO_FX": "~/javafx/javafx-sdk-21.0.7/lib",
"JAVAFX_MODULES": "javafx.controls,javafx.fxml,javafx.graphics,javafx.web,javafx.media,javafx.swing,javafx.base"
}# Create project directory
mkdir -p ~/my-javafx-project
cd ~/my-javafx-project
# Create Maven standard directory structure
mkdir -p src/main/java/com/myapp
mkdir -p src/main/resources
mkdir -p src/test/java/com/myapp
mkdir -p .vscodeCreate src/main/java/module-info.java:
module com.myapp {
requires javafx.controls;
requires javafx.fxml;
requires javafx.graphics;
exports com.myapp;
opens com.myapp to javafx.fxml;
}Create src/main/java/com/myapp/App.java:
package com.myapp;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class App extends Application {
@Override
public void start(Stage stage) {
String javaVersion = System.getProperty("java.version");
Label label = new Label("Hello, JavaFX!\nRunning on Java " + javaVersion);
StackPane root = new StackPane(label);
Scene scene = new Scene(root, 640, 480);
stage.setScene(scene);
stage.setTitle("My JavaFX Application");
stage.show();
}
public static void main(String[] args) {
launch();
}
}Create pom.xml in the project root:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.myapp</groupId>
<artifactId>my-javafx-project</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.release>21</maven.compiler.release>
<javafx.version>21.0.7</javafx.version>
</properties>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>${javafx.version}</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>${javafx.version}</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-graphics</artifactId>
<version>${javafx.version}</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-base</artifactId>
<version>${javafx.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<release>${maven.compiler.release}</release>
</configuration>
</plugin>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.8</version>
<configuration>
<mainClass>com.myapp/com.myapp.App</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>Create .vscode/settings.json:
{
"java.project.sourcePaths": ["src/main/java"],
"java.project.outputPath": "target/classes",
"java.project.referencedLibraries": [
"lib/**/*.jar"
],
"java.configuration.updateBuildConfiguration": "automatic"
}Create .vscode/launch.json:
{
"version": "0.2.0",
"configurations": [
{
"type": "java",
"name": "Launch JavaFX Application",
"request": "launch",
"mainClass": "com.myapp.App",
"vmArgs": "--module-path=${env:PATH_TO_FX} --add-modules=javafx.controls,javafx.fxml"
}
]
}code ~/my-javafx-project- Open
App.java - Click the "Run" button (play icon) that appears above the
mainmethod - Alternatively, go to Run > Start Debugging and select "Launch JavaFX Application"
In the VSCode terminal:
mvn clean javafx:run- Set breakpoints by clicking in the gutter (line number area)
- Start the application using the "Debug" button or Run > Start Debugging
- The application will pause when it hits a breakpoint
If VSCode shows errors like "cannot find symbol: class Application" but Maven builds and runs correctly:
- Open Command Palette (Ctrl+Shift+P)
- Select "Java: Clean Java Language Server Workspace"
- Choose "Restart and delete"
If you get "module not found" errors when running:
- Check your
module-info.javafile - Ensure the module name matches your package structure
- Verify that all required modules are listed in the
requiresstatements
If JavaFX classes are not recognized:
- Verify environment variables:
echo $PATH_TO_FX echo $JAVAFX_HOME
- Check that the JavaFX SDK is installed correctly:
ls -la $JAVAFX_HOME/lib/*.jar
- Ensure VSCode settings include the JavaFX module path
If the application won't start:
- Check console for error messages
- Verify the main class path in your pom.xml:
<mainClass>com.myapp/com.myapp.App</mainClass>
- Make sure your
module-info.javaproperly exports your package:exports com.myapp;
- Open VSCode
- File > Open Folder...
- Navigate to the project root directory and click "Open"
- Wait for Maven to import the project
If you're adding JavaFX to an existing project:
- Add JavaFX dependencies to pom.xml
- Create or update module-info.java to include JavaFX modules
- Create a .vscode folder with settings.json and launch.json files
- Clean the Java Language Server workspace
- Create a new file under
src/main/resourceswith.fxmlextension - Add a basic FXML structure:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Button?>
<VBox alignment="CENTER" spacing="20.0" xmlns="http://javafx.com/javafx/21" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.myapp.MainController">
<children>
<Label text="Hello, JavaFX!" />
<Button text="Click Me" onAction="#handleButtonClick" />
</children>
</VBox>Create src/main/java/com/myapp/MainController.java:
package com.myapp;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
public class MainController {
@FXML
private Label messageLabel;
@FXML
private void handleButtonClick() {
messageLabel.setText("Button clicked!");
}
}Update your App.java to load the FXML:
package com.myapp;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class App extends Application {
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("/com/myapp/main.fxml"));
Scene scene = new Scene(root, 640, 480);
stage.setScene(scene);
stage.setTitle("My JavaFX FXML Application");
stage.show();
}
public static void main(String[] args) {
launch();
}
}- Download SceneBuilder from Gluon website
- Install it according to your OS instructions
- Configure the path in VSCode settings:
"javafx.scenebuilder.home": "/path/to/SceneBuilder"- Right-click on an FXML file
- Select "Open with SceneBuilder"
- Edit the UI visually
- Save to update the FXML file