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).