3D (P3D) Box Rotation with JavaFX Sliders

Hello folks!

I am actively developing a versatile technical repertoire that includes several programming languages, libraries, and practical applications of AI (artificial intelligence) and sharing with the community.

This is a proof-of-concept showing the integration of a JavaFX UI for manipulating a 3D scene rendered in Processing. It features a clean separation between the JavaFX UI controller for interactivity and the P3D view for improved performance.

🛈 Note for new Processing users:

Click here to expand!

This sketch uses JavaFX and advanced Java features to extend Processing beyond its core functionality. Processing is “only commited to JavaFX as a renderer” (FX2D), but it can also be leveraged to create a wide range of features beyond rendering including separate windows, user interfaces, and much more. The integration of JavaFX in Processing is an area that is not extensively documented and still evolving, and much of the information comes from community contributions and experimentation. If you’re interested in exploring this further be prepared for a bit of trial and error, as the integration is not fully documented. Enjoy the ride!

Using this sketch requires installing the JavaFX library via Processing’s Contribution Manager, importing it, and manually adding JavaFX JAR files into your sketch’s code folder on Windows. There are related topics to assist with this for Windows.

This example is designed for users with a strong foundation in programming who want to explore how Processing can be extended with external libraries such as JavaFX. If you’re new to Processing, focus first on building solid basics before diving into advanced integrations like this.

Enjoy the journey and keep experimenting!

/**
 * Project Name: 3D Box Rotation with JavaFX Sliders
 * Author: glv (primary developer and prompt engineer, with assistance from ChatGPT)
 * Date: 2025-06-29
 * Description:
 *   Processing sketch using P3D renderer to draw a 3D box.
 *   Rotation controlled interactively via JavaFX sliders in a separate window.
 * Version: 1.0.0
 * 
 * Environment:
 *   Processing 4.4.4
 *   Windows 10
 *   JavaFX 4.0 beta 5 library
 *
 * Note:
 *   For W10 and Processing 4.4.4 the JavaFX JAR files
 *   need to be placed in the sketch’s 'code' folder
 *   to enable JavaFX functionality.
 *
 * Acknowledgement:
 *   This was a collaborative effort. ChatGPT was prompted with the initial project parameters
 *   and provided code suggestions and corrections. These were interpreted, guided, and refined
 *   by glv. The collaboration was effective because glv has a strong grounding in programming,
 *   prior experience with AI tools, prompt engineering, and a broad technical background.
 */

// Required to enable JavaFX support in Processing
import processing.javafx.*;

//Imports:
import javafx.application.Platform; // Corrects Type is ambiguous in Processing
import javafx.stage.Screen;         // Corrects Type is ambiguous in Processing

// All these needed in VSCode:
//import javafx.stage.Stage;
//import javafx.stage.StageStyle;
//import javafx.scene.Scene;
//import javafx.scene.layout.VBox;
//import javafx.scene.control.Slider;
//import javafx.scene.control.Label;
//import javafx.geometry.Pos;
//import javafx.geometry.Insets;

// Shared rotation values controlled by sliders
volatile float sliderX = 0;
volatile float sliderY = 0;
volatile float sliderZ = 0;

void settings() {
  // Set up the main 3D canvas with P3D renderer
  size(600, 600, P3D);
}

void setup() {
  surface.setTitle("Main P3D Window");

  // Start a separate FX2D sketch to initialize JavaFX
  Thread fxBoot = new Thread(() -> {
    PApplet.runSketch(new String[]{"FXBoot"}, new FXBoot());
  });
  fxBoot.start();
}

void draw() {
  background(0);
  lights();

  // Center and rotate the 3D box based on slider values
  translate(width / 2, height / 2, 0);
  rotateX(radians(sliderX));
  rotateY(radians(sliderY));
  rotateZ(radians(sliderZ));

  fill(255, 180, 0);
  box(200);
}

// ------------------------------------------------------------
// Inner class: FX2D sketch to launch JavaFX slider UI
public class FXBoot extends PApplet {

  public void settings() {
    // Minimal invisible sketch to trigger JavaFX initialization
    size(1, 1, FX2D);
  }

  public void setup() {
    surface.setVisible(false);  // Hide this FX2D sketch window

    // Launch the JavaFX UI on the JavaFX Application Thread
    Platform.runLater(this::launchUI);
  }

  // Creates the JavaFX window with sliders controlling rotation
  void launchUI() {
    Stage stage = new Stage();

    // VBox layout with labeled sliders for X, Y, Z rotation
    VBox box = new VBox(15,
      labeledSlider("X Rotation", val -> sliderX = val),
      labeledSlider("Y Rotation", val -> sliderY = val),
      labeledSlider("Z Rotation", val -> sliderZ = val)
    );

    box.setPadding(new Insets(20));
    box.setAlignment(Pos.CENTER_LEFT);

    Scene scene = new Scene(box, 300, 260);
    stage.setScene(scene);
    stage.setTitle("XYZ Sliders");
    stage.setAlwaysOnTop(true);
    stage.setX(Screen.getPrimary().getBounds().getWidth() - 320);  // Position top-right
    stage.setY(50);
    stage.initStyle(StageStyle.DECORATED);
    stage.show();
  }

  // Helper method: Create a VBox with bold label and slider
  VBox labeledSlider(String labelText, java.util.function.Consumer<Float> onChange) {
    Label label = new Label(labelText);
    label.setStyle("-fx-font-weight: bold;");

    Slider slider = makeSlider();
    slider.valueProperty().addListener(
      (obs, oldVal, newVal) -> onChange.accept(newVal.floatValue())
    );

    return new VBox(5, label, slider);
  }

  // Helper method: Configure a slider with tick marks and labels
  Slider makeSlider() {
    Slider s = new Slider(0, 360, 0);
    s.setShowTickLabels(true);
    s.setShowTickMarks(true);
    s.setMajorTickUnit(30);
    s.setMinorTickCount(2);
    s.setPrefWidth(260);
    s.setPrefHeight(50);
    return s;
  }
}

Processing P3D window:

JavaFX UI window:

References:

:)