Tutorials‎ > ‎

Object Inspection with Reflection


The JavaFX language offers a Reflection API to let developers inspect the members of loaded classes at runtime.  You may be familiar with similar functionalities available in other languages such as Java.  In JavaFX the Reflection API which let you discover members such as function and variable types attached to a class definition.  The Reflection API is housed in the javafx.reflect package and provide several classes needed to introspect loaded classes including FXLocal, FXContext, and ClassType.  The following shows how the API works by creating a JavaFX application that lists the declared variables and functions on a given class.

Reflecting on Classes
Before you dive into the code, this is how the reflection API works:
  • FXLocal.Context - this class is intended to provide runtime information about the running JavaFX application.  
  • FXLocal.Context.findClass(className:String) - First, you use the findClass() function to load metadata about your target class by returning an instance of ClassType
  • ClassType - . this class contains introspective information about the target class.  You can get access to variable members function getVariables() or access a list of function attached to the class using function getFunctions().
The following application uses the reflection API to display introspective information about a class:

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.HBox;
import javafx.scene.control.Label;
import javafx.scene.control.TextBox;
import javafx.scene.control.Button;
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.layout.VBox;
import javafx.reflect.FXLocal;
import javafx.stage.Alert;
import javafx.scene.control.ListView;

def w = 640;
def h = 480;
var scene:Scene;

var inspItems:String[];
def txtBox = ListView {width:w-60 height:h-40 items: bind inspItems}

def inputControl = HBox {
    fillHeight:true
    width:w
    height:h
    spacing:7
    nodeVPos:VPos.CENTER
    content:[
        Label {text:"Class Name:"},
        TextBox{id:"className" promptText:"Full class name" columns:70},
        Button{
            text:"Inspect"
            action:function() {
                introspect((scene.lookup("className")as TextBox).text)
            }
        }
    ]
}

function introspect(className:String) {
    if(className == null) {
        Alert.inform("Provide valid class name");
        return;
    }
    try{
        def runtime = FXLocal.Context.getInstance();
        def clazz =  runtime.findClass(className);
        for(variable in clazz.getVariables(false)) {
            insert "{variable.getName()}: {variable.getType()}" into inspItems;
        }
        for(fun in clazz.getFunctions(false)) {
            insert "{fun.getName()}: {fun.getType()}" into inspItems;
        }
    }catch(ex){
       Alert.inform("Unable to lookup class {className}, see trace.");
       ex.printStackTrace();
    }

}

Stage {
    title: "Introspector"
    scene: scene = Scene {
        width: w
        height: h
        content: [
            VBox{
                fillWidth:true
                width:w
                spacing:7
                hpos:HPos.CENTER
                vpos:VPos.CENTER
                content:[
                    inputControl,
                    txtBox
                ]
            }
        ]
    }
}

When you run the application locally, you can get access to class information as shown in the figure below:

The materials on this website represent a small sample of content loosely based on the book JavaFX Application Development Cookbook.  The book offers far more content with over 80 recipes covering a range of topics from basics to advanced concepts.  

Buy the Book

You can get your copy of the book directly from the publisher. Click here to order!
Comments