JavaFX is a modern UI toolkit for building rich desktop applications. It replaces Swing as the standard GUI library for Java.
1. Basic JavaFX Application Structure
Maven Dependencies
<!-- pom.xml for JavaFX 17+ -->
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<javafx.version>17.0.2</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>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.8</version>
<configuration>
<mainClass>com.example.javafx.HelloJavaFX</mainClass>
</configuration>
</plugin>
</plugins>
</build>
Basic JavaFX Application
package com.example.javafx;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class HelloJavaFX extends Application {
@Override
public void start(Stage primaryStage) {
// Create the root layout
VBox root = new VBox(10); // 10 pixels spacing between children
root.setStyle("-fx-padding: 20; -fx-alignment: center;");
// Create UI controls
Label titleLabel = new Label("Welcome to JavaFX!");
titleLabel.setStyle("-fx-font-size: 24px; -fx-font-weight: bold;");
Button clickButton = new Button("Click Me!");
clickButton.setStyle("-fx-font-size: 14px; -fx-padding: 10 20;");
Label messageLabel = new Label();
messageLabel.setStyle("-fx-font-size: 16px; -fx-text-fill: blue;");
// Add event handler to button
clickButton.setOnAction(event -> {
messageLabel.setText("Hello JavaFX! Button clicked at: " +
java.time.LocalTime.now());
});
// Add controls to layout
root.getChildren().addAll(titleLabel, clickButton, messageLabel);
// Create scene and set it on stage
Scene scene = new Scene(root, 400, 300);
// Configure the primary stage
primaryStage.setTitle("JavaFX Basic Application");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
2. Layout Managers
Common Layout Panes
package com.example.javafx.layouts;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class LayoutExamples extends Application {
@Override
public void start(Stage primaryStage) {
TabPane tabPane = new TabPane();
// VBox and HBox examples
tabPane.getTabs().addAll(
createVBoxHBoxTab(),
createBorderPaneTab(),
createGridPaneTab(),
createFlowPaneTab(),
createStackPaneTab()
);
Scene scene = new Scene(tabPane, 600, 500);
primaryStage.setTitle("JavaFX Layout Examples");
primaryStage.setScene(scene);
primaryStage.show();
}
private Tab createVBoxHBoxTab() {
VBox mainLayout = new VBox(10);
mainLayout.setPadding(new Insets(15));
mainLayout.setStyle("-fx-background-color: #f0f0f0;");
// HBox example - horizontal layout
HBox hbox = new HBox(10);
hbox.setAlignment(Pos.CENTER);
hbox.setStyle("-fx-background-color: #e0e0e0; -fx-padding: 10;");
Button btn1 = new Button("Button 1");
Button btn2 = new Button("Button 2");
Button btn3 = new Button("Button 3");
hbox.getChildren().addAll(btn1, btn2, btn3);
// VBox example - vertical layout
VBox vbox = new VBox(10);
vbox.setAlignment(Pos.CENTER_LEFT);
vbox.setStyle("-fx-background-color: #d0d0d0; -fx-padding: 10;");
Label label1 = new Label("First Name:");
TextField firstName = new TextField();
Label label2 = new Label("Last Name:");
TextField lastName = new TextField();
vbox.getChildren().addAll(label1, firstName, label2, lastName);
mainLayout.getChildren().addAll(
new Label("HBox (Horizontal):"), hbox,
new Label("VBox (Vertical):"), vbox
);
return new Tab("VBox/HBox", mainLayout);
}
private Tab createBorderPaneTab() {
BorderPane borderPane = new BorderPane();
borderPane.setPadding(new Insets(10));
// Top region
Label topLabel = new Label("TOP - Header/ Navigation");
topLabel.setStyle("-fx-background-color: #ffcccc; -fx-padding: 10; -fx-alignment: center;");
borderPane.setTop(topLabel);
// Left region
VBox leftMenu = new VBox(5);
leftMenu.setStyle("-fx-background-color: #ccffcc; -fx-padding: 10;");
leftMenu.getChildren().addAll(
new Button("Home"),
new Button("Profile"),
new Button("Settings"),
new Button("Help")
);
borderPane.setLeft(leftMenu);
// Center region
TextArea centerText = new TextArea("CENTER - Main Content Area\n\nThis is where the main content goes.");
centerText.setStyle("-fx-background-color: #ccccff;");
borderPane.setCenter(centerText);
// Right region
VBox rightPanel = new VBox(5);
rightPanel.setStyle("-fx-background-color: #ffffcc; -fx-padding: 10;");
rightPanel.getChildren().addAll(
new Label("Notifications"),
new CheckBox("New messages"),
new CheckBox("Friend requests")
);
borderPane.setRight(rightPanel);
// Bottom region
Label bottomLabel = new Label("BOTTOM - Status Bar / Footer");
bottomLabel.setStyle("-fx-background-color: #ffccff; -fx-padding: 10; -fx-alignment: center;");
borderPane.setBottom(bottomLabel);
return new Tab("BorderPane", borderPane);
}
private Tab createGridPaneTab() {
GridPane gridPane = new GridPane();
gridPane.setPadding(new Insets(15));
gridPane.setHgap(10);
gridPane.setVgap(10);
gridPane.setStyle("-fx-background-color: #f5f5f5;");
// Create form labels and fields
Label nameLabel = new Label("Name:");
TextField nameField = new TextField();
Label emailLabel = new Label("Email:");
TextField emailField = new TextField();
Label phoneLabel = new Label("Phone:");
TextField phoneField = new TextField();
Label addressLabel = new Label("Address:");
TextArea addressArea = new TextArea();
addressArea.setPrefRowCount(3);
Button submitBtn = new Button("Submit");
Button cancelBtn = new Button("Cancel");
HBox buttonBox = new HBox(10, submitBtn, cancelBtn);
// Add components to grid
gridPane.add(nameLabel, 0, 0);
gridPane.add(nameField, 1, 0);
gridPane.add(emailLabel, 0, 1);
gridPane.add(emailField, 1, 1);
gridPane.add(phoneLabel, 0, 2);
gridPane.add(phoneField, 1, 2);
gridPane.add(addressLabel, 0, 3);
gridPane.add(addressArea, 1, 3);
gridPane.add(buttonBox, 1, 4);
// Set column constraints
ColumnConstraints col1 = new ColumnConstraints();
col1.setPrefWidth(100);
ColumnConstraints col2 = new ColumnConstraints();
col2.setPrefWidth(200);
gridPane.getColumnConstraints().addAll(col1, col2);
return new Tab("GridPane", gridPane);
}
private Tab createFlowPaneTab() {
FlowPane flowPane = new FlowPane();
flowPane.setPadding(new Insets(15));
flowPane.setHgap(10);
flowPane.setVgap(10);
flowPane.setStyle("-fx-background-color: #e8f4f8;");
// Add multiple buttons to demonstrate flow behavior
for (int i = 1; i <= 15; i++) {
Button btn = new Button("Button " + i);
btn.setStyle("-fx-padding: 8 15;");
flowPane.getChildren().add(btn);
}
return new Tab("FlowPane", flowPane);
}
private Tab createStackPaneTab() {
StackPane stackPane = new StackPane();
stackPane.setStyle("-fx-background-color: #f0f8ff;");
// Create layered components
Rectangle background = new Rectangle(200, 100, Color.LIGHTBLUE);
background.setArcWidth(20);
background.setArcHeight(20);
Label textLabel = new Label("Stacked Content");
textLabel.setStyle("-fx-font-size: 18px; -fx-font-weight: bold; -fx-text-fill: darkblue;");
Button overlayButton = new Button("Click Me!");
overlayButton.setStyle("-fx-background-color: rgba(255,255,255,0.8);");
stackPane.getChildren().addAll(background, textLabel, overlayButton);
StackPane.setAlignment(overlayButton, Pos.BOTTOM_CENTER);
return new Tab("StackPane", stackPane);
}
public static void main(String[] args) {
launch(args);
}
}
3. Basic Controls and Event Handling
Common UI Controls
package com.example.javafx.controls;
import javafx.application.Application;
import javafx.beans.property.*;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class BasicControls extends Application {
private final StringProperty statusMessage = new SimpleStringProperty("Ready");
private final IntegerProperty clickCount = new SimpleIntegerProperty(0);
@Override
public void start(Stage primaryStage) {
VBox root = new VBox(15);
root.setPadding(new Insets(20));
// Status label
Label statusLabel = new Label();
statusLabel.textProperty().bind(statusMessage);
// Buttons with different styles and events
VBox buttonSection = createButtonSection();
// Text input controls
GridPane inputSection = createInputSection();
// Selection controls
VBox selectionSection = createSelectionSection();
root.getChildren().addAll(
new Label("JavaFX Basic Controls Demo"),
statusLabel,
new Separator(),
buttonSection,
new Separator(),
inputSection,
new Separator(),
selectionSection
);
Scene scene = new Scene(root, 500, 600);
primaryStage.setTitle("JavaFX Controls Demo");
primaryStage.setScene(scene);
primaryStage.show();
}
private VBox createButtonSection() {
VBox section = new VBox(10);
// Basic button
Button basicButton = new Button("Basic Button");
basicButton.setOnAction(e -> {
clickCount.set(clickCount.get() + 1);
statusMessage.set("Basic button clicked! Count: " + clickCount.get());
});
// Styled button
Button styledButton = new Button("Styled Button");
styledButton.setStyle("-fx-background-color: #4CAF50; -fx-text-fill: white; -fx-font-weight: bold;");
styledButton.setOnAction(e -> statusMessage.set("Green button clicked!"));
// Toggle button
ToggleButton toggleButton = new ToggleButton("Toggle Me");
toggleButton.setOnAction(e -> {
if (toggleButton.isSelected()) {
statusMessage.set("Toggle button is ON");
toggleButton.setStyle("-fx-background-color: #2196F3; -fx-text-fill: white;");
} else {
statusMessage.set("Toggle button is OFF");
toggleButton.setStyle("");
}
});
section.getChildren().addAll(
new Label("Buttons:"),
basicButton, styledButton, toggleButton
);
return section;
}
private GridPane createInputSection() {
GridPane grid = new GridPane();
grid.setHgap(10);
grid.setVgap(10);
// TextField
TextField textField = new TextField();
textField.setPromptText("Enter text here...");
// PasswordField
PasswordField passwordField = new PasswordField();
passwordField.setPromptText("Enter password");
// TextArea
TextArea textArea = new TextArea();
textArea.setPromptText("Multi-line text here...");
textArea.setPrefRowCount(3);
// Slider
Slider slider = new Slider(0, 100, 50);
Label sliderValue = new Label("50");
slider.valueProperty().addListener((obs, oldVal, newVal) -> {
sliderValue.setText(String.format("%.0f", newVal));
});
grid.add(new Label("Text Field:"), 0, 0);
grid.add(textField, 1, 0);
grid.add(new Label("Password:"), 0, 1);
grid.add(passwordField, 1, 1);
grid.add(new Label("Text Area:"), 0, 2);
grid.add(textArea, 1, 2);
grid.add(new Label("Slider:"), 0, 3);
grid.add(slider, 1, 3);
grid.add(sliderValue, 2, 3);
return grid;
}
private VBox createSelectionSection() {
VBox section = new VBox(10);
// CheckBox
CheckBox checkBox1 = new CheckBox("Option 1");
CheckBox checkBox2 = new CheckBox("Option 2");
CheckBox checkBox3 = new CheckBox("Option 3");
// RadioButtons
ToggleGroup radioGroup = new ToggleGroup();
RadioButton radio1 = new RadioButton("Choice A");
radio1.setToggleGroup(radioGroup);
RadioButton radio2 = new RadioButton("Choice B");
radio2.setToggleGroup(radioGroup);
RadioButton radio3 = new RadioButton("Choice C");
radio3.setToggleGroup(radioGroup);
radio1.setSelected(true);
// ComboBox
ObservableList<String> options = FXCollections.observableArrayList(
"Java", "Python", "JavaScript", "C++", "C#", "Go"
);
ComboBox<String> comboBox = new ComboBox<>(options);
comboBox.setValue("Java");
// ListView
ListView<String> listView = new ListView<>();
listView.setItems(FXCollections.observableArrayList(
"Item 1", "Item 2", "Item 3", "Item 4", "Item 5"
));
listView.setPrefHeight(100);
section.getChildren().addAll(
new Label("Checkboxes:"),
checkBox1, checkBox2, checkBox3,
new Label("Radio Buttons:"),
radio1, radio2, radio3,
new Label("ComboBox:"),
comboBox,
new Label("ListView:"),
listView
);
return section;
}
public static void main(String[] args) {
launch(args);
}
}
4. Event Handling and Properties
Advanced Event Handling
package com.example.javafx.events;
import javafx.application.Application;
import javafx.beans.property.*;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.input.*;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class EventHandlingDemo extends Application {
private final StringProperty eventLog = new SimpleStringProperty("Event Log:\n");
private final DoubleProperty mouseX = new SimpleDoubleProperty();
private final DoubleProperty mouseY = new SimpleDoubleProperty();
@Override
public void start(Stage primaryStage) {
VBox root = new VBox(15);
root.setPadding(new Insets(20));
// Event log area
TextArea logArea = new TextArea();
logArea.textProperty().bind(eventLog);
logArea.setPrefHeight(200);
logArea.setEditable(false);
// Mouse coordinates display
Label mouseLabel = new Label();
mouseLabel.textProperty().bind(
new SimpleStringProperty("Mouse: ").concat(mouseX.asString("%.0f"))
.concat(", ").concat(mouseY.asString("%.0f"))
);
// Interactive rectangle for mouse events
Rectangle interactiveRect = new Rectangle(200, 100, Color.LIGHTBLUE);
interactiveRect.setStroke(Color.DARKBLUE);
setupMouseEvents(interactiveRect);
setupKeyboardEvents(root);
// Clear log button
Button clearButton = new Button("Clear Log");
clearButton.setOnAction(e -> eventLog.set("Event Log:\n"));
root.getChildren().addAll(
new Label("Event Handling Demo"),
mouseLabel,
interactiveRect,
new Label("Click on the rectangle or press keys:"),
logArea,
clearButton
);
Scene scene = new Scene(root, 400, 500);
primaryStage.setTitle("JavaFX Event Handling");
primaryStage.setScene(scene);
primaryStage.show();
}
private void setupMouseEvents(Rectangle rect) {
// Mouse click events
rect.setOnMouseClicked(event -> {
String clickType = "";
if (event.getClickCount() == 2) {
clickType = "Double ";
}
String button = event.getButton().toString();
logEvent(clickType + "Mouse Click: " + button + " at (" +
(int)event.getX() + ", " + (int)event.getY() + ")");
});
// Mouse movement events
rect.setOnMouseMoved(event -> {
mouseX.set(event.getX());
mouseY.set(event.getY());
});
// Mouse enter/exit events
rect.setOnMouseEntered(event -> {
rect.setFill(Color.LIGHTGREEN);
logEvent("Mouse entered rectangle");
});
rect.setOnMouseExited(event -> {
rect.setFill(Color.LIGHTBLUE);
logEvent("Mouse exited rectangle");
});
// Mouse drag events
rect.setOnMouseDragged(event -> {
logEvent("Mouse dragged: (" + (int)event.getX() + ", " + (int)event.getY() + ")");
});
}
private void setupKeyboardEvents(VBox root) {
// Key events on the scene
root.setOnKeyPressed(event -> {
String keyInfo = "Key Pressed: " + event.getCode();
if (event.isShiftDown()) keyInfo += " + Shift";
if (event.isControlDown()) keyInfo += " + Ctrl";
if (event.isAltDown()) keyInfo += " + Alt";
logEvent(keyInfo);
// Handle specific keys
switch (event.getCode()) {
case ESCAPE:
logEvent("Escape pressed - clearing log");
eventLog.set("Event Log:\n");
break;
case SPACE:
logEvent("Space bar pressed");
break;
}
});
root.setOnKeyReleased(event -> {
logEvent("Key Released: " + event.getCode());
});
}
private void logEvent(String message) {
eventLog.set(eventLog.get() + message + "\n");
}
public static void main(String[] args) {
launch(args);
}
}
5. CSS Styling in JavaFX
Styling with CSS
package com.example.javafx.styling;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class CSSStylingDemo extends Application {
@Override
public void start(Stage primaryStage) {
// Main container with CSS styling
VBox root = new VBox(20);
root.setPadding(new Insets(25));
root.setAlignment(Pos.TOP_CENTER);
root.getStyleClass().add("main-container");
// Title with CSS class
Label title = new Label("JavaFX CSS Styling Demo");
title.getStyleClass().add("title");
// Styled buttons
HBox buttonBox = new HBox(15);
buttonBox.setAlignment(Pos.CENTER);
Button primaryBtn = new Button("Primary");
primaryBtn.getStyleClass().add("btn-primary");
Button secondaryBtn = new Button("Secondary");
secondaryBtn.getStyleClass().add("btn-secondary");
Button successBtn = new Button("Success");
successBtn.getStyleClass().add("btn-success");
Button dangerBtn = new Button("Danger");
dangerBtn.getStyleClass().add("btn-danger");
buttonBox.getChildren().addAll(primaryBtn, secondaryBtn, successBtn, dangerBtn);
// Form with styled controls
GridPane form = new GridPane();
form.setHgap(15);
form.setVgap(10);
form.getStyleClass().add("form-pane");
TextField usernameField = new TextField();
usernameField.setPromptText("Enter username");
usernameField.getStyleClass().add("text-field");
PasswordField passwordField = new PasswordField();
passwordField.setPromptText("Enter password");
passwordField.getStyleClass().add("text-field");
CheckBox rememberMe = new CheckBox("Remember me");
Button loginBtn = new Button("Login");
loginBtn.getStyleClass().add("btn-login");
form.add(new Label("Username:"), 0, 0);
form.add(usernameField, 1, 0);
form.add(new Label("Password:"), 0, 1);
form.add(passwordField, 1, 1);
form.add(rememberMe, 1, 2);
form.add(loginBtn, 1, 3);
// Card layout example
VBox card = new VBox(15);
card.getStyleClass().add("card");
card.setPadding(new Insets(20));
Label cardTitle = new Label("Featured Content");
cardTitle.getStyleClass().add("card-title");
Label cardContent = new Label("This is a styled card component with shadow and rounded corners.");
cardContent.setWrapText(true);
Button cardButton = new Button("Learn More");
cardButton.getStyleClass().add("btn-card");
card.getChildren().addAll(cardTitle, cardContent, cardButton);
root.getChildren().addAll(title, buttonBox, form, card);
Scene scene = new Scene(root, 500, 600);
// Load CSS stylesheet
scene.getStylesheets().add(getClass().getResource("/styles.css").toExternalForm());
primaryStage.setTitle("JavaFX CSS Styling");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
CSS Stylesheet (styles.css)
/* styles.css */
.root {
-fx-font-family: "Segoe UI", Arial, sans-serif;
-fx-background-color: linear-gradient(to bottom, #f5f7fa, #c3cfe2);
}
.main-container {
-fx-background-color: transparent;
}
.title {
-fx-font-size: 28px;
-fx-font-weight: bold;
-fx-text-fill: #2c3e50;
-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.3), 2, 0.5, 1, 1);
}
/* Button Styles */
.btn-primary {
-fx-background-color: #3498db;
-fx-text-fill: white;
-fx-font-weight: bold;
-fx-background-radius: 5;
-fx-padding: 8 15;
-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.2), 3, 0, 1, 1);
}
.btn-primary:hover {
-fx-background-color: #2980b9;
-fx-scale-x: 1.05;
-fx-scale-y: 1.05;
}
.btn-primary:pressed {
-fx-background-color: #21618c;
}
.btn-secondary {
-fx-background-color: #95a5a6;
-fx-text-fill: white;
-fx-font-weight: bold;
-fx-background-radius: 5;
-fx-padding: 8 15;
}
.btn-secondary:hover {
-fx-background-color: #7f8c8d;
}
.btn-success {
-fx-background-color: #27ae60;
-fx-text-fill: white;
-fx-font-weight: bold;
-fx-background-radius: 5;
-fx-padding: 8 15;
}
.btn-success:hover {
-fx-background-color: #229954;
}
.btn-danger {
-fx-background-color: #e74c3c;
-fx-text-fill: white;
-fx-font-weight: bold;
-fx-background-radius: 5;
-fx-padding: 8 15;
}
.btn-danger:hover {
-fx-background-color: #c0392b;
}
/* Form Styles */
.form-pane {
-fx-background-color: white;
-fx-background-radius: 10;
-fx-padding: 20;
-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.1), 10, 0, 0, 2);
-fx-border-color: #bdc3c7;
-fx-border-width: 1;
-fx-border-radius: 10;
}
.text-field {
-fx-background-radius: 5;
-fx-border-radius: 5;
-fx-border-color: #bdc3c7;
-fx-border-width: 1;
-fx-padding: 8;
}
.text-field:focused {
-fx-border-color: #3498db;
-fx-effect: dropshadow(gaussian, rgba(52,152,219,0.3), 5, 0, 0, 2);
}
.btn-login {
-fx-background-color: linear-gradient(to bottom, #3498db, #2980b9);
-fx-text-fill: white;
-fx-font-weight: bold;
-fx-background-radius: 5;
-fx-padding: 10 20;
-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.3), 5, 0, 0, 2);
}
.btn-login:hover {
-fx-background-color: linear-gradient(to bottom, #2980b9, #21618c);
}
/* Card Styles */
.card {
-fx-background-color: white;
-fx-background-radius: 15;
-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.2), 15, 0, 0, 5);
-fx-border-color: #ecf0f1;
-fx-border-width: 1;
-fx-border-radius: 15;
}
.card-title {
-fx-font-size: 20px;
-fx-font-weight: bold;
-fx-text-fill: #2c3e50;
-fx-border-color: #3498db;
-fx-border-width: 0 0 2 0;
-fx-padding: 0 0 5 0;
}
.btn-card {
-fx-background-color: transparent;
-fx-text-fill: #3498db;
-fx-border-color: #3498db;
-fx-border-width: 2;
-fx-border-radius: 5;
-fx-background-radius: 5;
-fx-padding: 8 15;
-fx-font-weight: bold;
}
.btn-card:hover {
-fx-background-color: #3498db;
-fx-text-fill: white;
}
6. FXML and Controller Pattern
FXML Layout (sample.fxml)
<?xml version="1.0" encoding="UTF-8"?> <?import javafx.geometry.Insets?> <?import javafx.scene.control.*?> <?import javafx.scene.layout.*?> <?import javafx.scene.text.Font?> <VBox xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" alignment="TOP_CENTER" spacing="20.0" style="-fx-background-color: #f8f9fa;" fx:controller="com.example.javafx.controller.SampleController"> <padding> <Insets top="25.0" right="25.0" bottom="25.0" left="25.0" /> </padding> <Label text="FXML Demo Application" style="-fx-font-size: 24px; -fx-font-weight: bold; -fx-text-fill: #2c3e50;" /> <GridPane hgap="10.0" vgap="15.0"> <columnConstraints> <ColumnConstraints hgrow="SOMETIMES" minWidth="100.0" prefWidth="100.0" /> <ColumnConstraints hgrow="SOMETIMES" minWidth="200.0" prefWidth="200.0" /> </columnConstraints> <Label text="First Name:" GridPane.rowIndex="0" GridPane.columnIndex="0" /> <TextField fx:id="firstNameField" promptText="Enter first name" GridPane.rowIndex="0" GridPane.columnIndex="1" /> <Label text="Last Name:" GridPane.rowIndex="1" GridPane.columnIndex="0" /> <TextField fx:id="lastNameField" promptText="Enter last name" GridPane.rowIndex="1" GridPane.columnIndex="1" /> <Label text="Email:" GridPane.rowIndex="2" GridPane.columnIndex="0" /> <TextField fx:id="emailField" promptText="Enter email" GridPane.rowIndex="2" GridPane.columnIndex="1" /> <Label text="Country:" GridPane.rowIndex="3" GridPane.columnIndex="0" /> <ComboBox fx:id="countryComboBox" promptText="Select country" GridPane.rowIndex="3" GridPane.columnIndex="1" /> </GridPane> <HBox spacing="15.0" alignment="CENTER"> <Button text="Submit" fx:id="submitButton" style="-fx-background-color: #27ae60; -fx-text-fill: white; -fx-font-weight: bold; -fx-padding: 10 20;" /> <Button text="Clear" fx:id="clearButton" style="-fx-background-color: #e74c3c; -fx-text-fill: white; -fx-font-weight: bold; -fx-padding: 10 20;" /> </HBox> <TextArea fx:id="outputArea" promptText="Output will appear here..." prefRowCount="4" prefColumnCount="30" style="-fx-border-color: #bdc3c7; -fx-border-radius: 5;" /> </VBox>
Controller Class
package com.example.javafx.controller;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.*;
public class SampleController {
@FXML
private TextField firstNameField;
@FXML
private TextField lastNameField;
@FXML
private TextField emailField;
@FXML
private ComboBox<String> countryComboBox;
@FXML
private Button submitButton;
@FXML
private Button clearButton;
@FXML
private TextArea outputArea;
private ObservableList<String> countries = FXCollections.observableArrayList(
"United States", "Canada", "United Kingdom", "Australia",
"Germany", "France", "Japan", "Brazil", "India"
);
@FXML
public void initialize() {
// Set up the ComboBox
countryComboBox.setItems(countries);
// Set up button actions
submitButton.setOnAction(event -> handleSubmit());
clearButton.setOnAction(event -> handleClear());
// Add tooltips
submitButton.setTooltip(new Tooltip("Submit the form data"));
clearButton.setTooltip(new Tooltip("Clear all fields"));
}
private void handleSubmit() {
StringBuilder output = new StringBuilder();
output.append("Form Submission:\n");
output.append("First Name: ").append(firstNameField.getText()).append("\n");
output.append("Last Name: ").append(lastNameField.getText()).append("\n");
output.append("Email: ").append(emailField.getText()).append("\n");
output.append("Country: ").append(countryComboBox.getValue()).append("\n");
output.append("Submitted at: ").append(java.time.LocalTime.now()).append("\n");
outputArea.setText(output.toString());
// Show confirmation
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle("Submission Successful");
alert.setHeaderText("Form Submitted");
alert.setContentText("Your information has been submitted successfully!");
alert.showAndWait();
}
private void handleClear() {
firstNameField.clear();
lastNameField.clear();
emailField.clear();
countryComboBox.getSelectionModel().clearSelection();
outputArea.clear();
}
}
Main Application with FXML
package com.example.javafx;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.net.URL;
public class FXMLApplication extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
// Load FXML file
URL fxmlUrl = getClass().getResource("/sample.fxml");
Parent root = FXMLLoader.load(fxmlUrl);
// Create scene
Scene scene = new Scene(root, 500, 500);
// Set up stage
primaryStage.setTitle("JavaFX FXML Demo");
primaryStage.setScene(scene);
primaryStage.setMinWidth(400);
primaryStage.setMinHeight(450);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Key JavaFX Concepts:
- Stage: The main window
- Scene: Container for all content
- Nodes: UI components (buttons, labels, etc.)
- Layout Panes: Arrange nodes (VBox, HBox, BorderPane, etc.)
- Properties: Observable values for data binding
- Event Handling: Respond to user interactions
- CSS Styling: Customize appearance
- FXML: XML-based layout definition
- Controllers: Handle business logic for FXML
JavaFX provides a modern, hardware-accelerated UI framework that's perfect for building rich desktop applications with clean separation between layout (FXML) and logic (Java controllers).