JackVimal
JackVimal

Reputation: 21

How to load FXML dynamically from webserver?

I am trying to replace the JSP,HTML and JavaScript by JavaFX, so I kept the FXML files and business logic in webserver. I can load the FXML from server and display them in client side by simple JavaFX(java) code, but I cannot load the event handler (Controller) dynamically. I want to make the client application as light weight application.

Can someone suggest a better way to do this?

Edited: we have to specify the event handler class name in fxml file. The object of event handler is instantiated at the time of loading the fxml by FXMLLoader. i kept the fxml and event handler class in tomcat server. i created one application that load the fxml from server by using URLConnection. now the fxml is loaded but i cannot handle the events for the controls defined in the fxml file. because while loading the fxml by FXMLLoader the event handler class is also instantiated by FXMLLoader. in my client application event handler classes not available. but the event handlers are available in tomcat server. is there any way to load the class files from server and dynamically instantiate the class file(Event handler) in client side.

Upvotes: 1

Views: 1025

Answers (2)

Nikita Lipsky
Nikita Lipsky

Reputation: 21

having a classloader that can load it from the server

You may also check my fork of WebFX (https://github.com/pjBooms/webfx) that allows to reference Java classes located on a remote server from FXML using my Java ReStart technology (https://github.com/pjBooms/Java-ReStart).

Upvotes: 1

jewelsea
jewelsea

Reputation: 159406

Using a scripting language such as JavaScript is a one way to load an fxml page with some associated control logic from a server such that compilation is not required on the client machine - it's pretty similar to the established html+JavaScript model.

You can try out WebFX for an example of this approach.

metronome.fxml

<?xml version="1.0" encoding="UTF-8"?>
<?language javascript?>

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.shape.*?>

<AnchorPane id="AnchorPane" prefHeight="370.0" prefWidth="320.0" xmlns:fx="http://javafx.com/fxml">
  <children>
    <HBox id="HBox" alignment="CENTER" layoutX="36.0" layoutY="328.0" spacing="5.0">
      <children>
        <Button fx:id="startButton" mnemonicParsing="false" onAction="handleStartButtonAction(event);" text="%start" />
        <Button fx:id="pauseButton" mnemonicParsing="false" onAction="handlePauseButtonAction(event);" text="%pause" />
        <Button fx:id="resumeButton" mnemonicParsing="false" onAction="handleResumeButtonAction(event);" text="%resume" />
        <Button fx:id="stopButton" mnemonicParsing="false" onAction="handleStopButtonAction(event);" text="%stop" />
      </children>
    </HBox>
    <Circle fx:id="circle" fill="RED" layoutX="64.0" layoutY="58.0" radius="7.0" stroke="BLACK" strokeType="INSIDE" strokeWidth="0.0" />
  </children>

  <fx:script source="metronome.js" />
</AnchorPane>

metronome.js

var webfx = {title: "Metronome WebFX Sample"};

var java = Packages.java;
var javafx = Packages.javafx;

var URL = java.net.URL;
var ResourceBundle = java.util.ResourceBundle;

var Animation = javafx.animation.Animation;
var Interpolator = javafx.animation.Interpolator;
var Timeline = javafx.animation.Timeline;
var TranslateTransitionBuilder = javafx.animation.TranslateTransitionBuilder;
var Duration = javafx.util.Duration;

var anim = TranslateTransitionBuilder.create()
        .duration(new Duration(1000.0))
        .node(circle)
        .fromX(0)
        .toX(200)
        .interpolator(Interpolator.LINEAR)
        .autoReverse(true)
        .cycleCount(Timeline.INDEFINITE)
        .build();

function handleStartButtonAction()  { anim.playFromStart(); }    
function handlePauseButtonAction()  { anim.pause(); }    
function handleResumeButtonAction() { anim.play();  }
function handleStopButtonAction()   { anim.stop();  }    
startButton.disableProperty().bind(anim.statusProperty().isNotEqualTo(Animation.Status.STOPPED));
pauseButton.disableProperty().bind(anim.statusProperty().isNotEqualTo(Animation.Status.RUNNING));
resumeButton.disableProperty().bind(anim.statusProperty().isNotEqualTo(Animation.Status.PAUSED));
stopButton.disableProperty().bind(anim.statusProperty().isEqualTo(Animation.Status.STOPPED));

If instead of a scripting language like JavaScript you wanted to use a static language like Java for your controller, you would need to find way to get a compiled class file on the client. For example by compiling on the server and having a classloader that can load it from the server or by shipping a java compiler with your client app and compiling the source code there.

Upvotes: 4

Related Questions