I made a Javafx application that works fine on PC. Now, I try to transfer it to Android Smartphone. To do that, I use JavaFXPorts (Gluon), with Eclipse and Gradle.
Now, I am stuck with a very simple example:
void showPopUp() {
Button button = new Button("Action do do"));
HBox.setMargin(button , new Insets(10, 30, 10, 30));
button .setOnAction(e -> {
actionToDo();
});
Scene scene = new Scene (button, 100, 200);
Stage stage = new Stage();
stage.initModality(Modality.APPLICATION_MODAL);
stage.setScene(scene);
stage.show();
}
Have you an idea of the reason?
Thanks
Here is the whole code with:
a periodic task (it works fine)
a delayed task (it works fine)
a button "btn" that displays the modal PopUp. The touchScreen on it works fine and allows to go to the PopUp
the PopUp with 2 buttons boutonPopUpA and boutonPopUpB that are added to the HBOX boutonsMenuPrincipal
and a stage with its scene "connected to" boutonsMenuPrincipal
In the popUp, boutonPopUpA and boutonPopUpB are displayed but inactive (No generated trace on a touchScreen)
package com.gluonapplication;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import javafx.stage.Stage;
public class GluonApplication extends Application {
private int nbAppuiToucheSetOnAction = 0;
private int nbAppuiTouchePopUp = 0;
static long BDTapplication = 110;
static long nbBDT = 0;
static long t0 = System.currentTimeMillis();
/********************************************************/
public static void periodicProcessing(String str) {
nbBDT++;
traceWithSystemTime("periodicProcessing of " + str + " / nbBDT: " + nbBDT);
}
/********************************************************/
public static void traceWithSystemTime(String comments) {
long t = System.currentTimeMillis();
long deltaT =t - t0;
System.out.println("time - t0: " + t0 + " / t: "+ t + " / detaT: " + deltaT + " ms --- " + comments);
}
/********************************************************/
public void start(Stage primaryStage) {
primaryStage.setTitle("Hello World sur Android! ");
// A PERIODIC TASK
Runnable runnable = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
for (int i=0; i < 10; i++) {
periodicProcessing("timer plus");
}
}
};
final ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
service.scheduleAtFixedRate(runnable, 0, BDTapplication, TimeUnit.MILLISECONDS);
// A DELAYED TASK
int TASK_DELAY = 1000; // ms
TimerTask task = new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i < 10; i++) {
periodicProcessing("timer task done");
}
}
};
new Timer().schedule(task, TASK_DELAY);
AnchorPane root = new AnchorPane();
root.setVisible(true);
Scene scene = new Scene(root);
// *********************** Button
// btn works fine
Button btn = new Button();
btn.setText("setOnAction 1");
btn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
nbAppuiToucheSetOnAction++;
traceWithSystemTime("SETonACTION: nbAppui = "+ nbAppuiToucheSetOnAction);
showPopUpMenuPrincipal();
}
});
HBox.setMargin(btn, new Insets(10, 30, 10, 30));
VBox zoneBtn= new VBox();
VBox.setMargin(zoneBtn, new Insets(30, 5, 1, 10));
zoneBtn.getChildren().add( btn);
zoneBtn.setAlignment(Pos.CENTER);
root.getChildren().addAll(zoneBtn);
primaryStage.setTitle("Title");
// ************************************* DISPLAY
root.requestFocus();
primaryStage.setScene(scene);
primaryStage.setTitle("Test4");
primaryStage.setFullScreen(true);
primaryStage.show();
traceWithSystemTime("End of test");
}
/*************************************/
void showPopUpMenuPrincipal(){
traceWithSystemTime("Beginning of showPopUpMenuPrincipal");
Button boutonPopUpA = new Button("setOnAction 2a");
boutonPopUpA.setOnAction(e-> {
nbAppuiTouchePopUp++;
traceWithSystemTime("Action sur setOnAction 2a: nbAppui: " + nbAppuiTouchePopUp);
});
Button boutonPopUpB = new Button("setOnAction 2b");
boutonPopUpB.setOnAction(e-> {
nbAppuiTouchePopUp++;
traceWithSystemTime("Action sur setOnAction 2b: nbAppui: " + nbAppuiTouchePopUp);
});
HBox.setMargin(boutonPopUpA, new Insets(10, 30, 10, 30));
VBox zonePopUp= new VBox();
VBox.setMargin(zonePopUp, new Insets(30, 5, 1, 10));
zonePopUp.getChildren().add( boutonPopUpA);
zonePopUp.setAlignment(Pos.CENTER);
Stage stagePopUpMenu = new Stage();
stagePopUpMenu.setTitle("Title");
stagePopUpMenu.initModality(Modality.APPLICATION_MODAL);
HBox boutonsMenuPrincipal = new HBox();
boutonsMenuPrincipal.setAlignment(Pos.CENTER);
boutonsMenuPrincipal.getChildren().addAll( zonePopUp, boutonPopUpB);
Scene sceneMenu = new Scene(boutonsMenuPrincipal, 400, 250);
stagePopUpMenu.setOpacity(0.8);
stagePopUpMenu.setResizable(false);
stagePopUpMenu.setScene(sceneMenu);
stagePopUpMenu.show();
traceWithSystemTime("End of showPopUpMenuPrincipal");
}
}
And my build gradle:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'org.javafxports:jfxmobile-plugin:1.0.0-b10'
}
}
apply plugin: 'org.javafxports.jfxmobile'
repositories {
jcenter()
}
mainClassName = 'com.gluonapplication.GluonApplication'
jfxmobile {
android {
applicationPackage = 'com.gluonapplication'
manifest = 'src/android/AndroidManifest.xml'
androidSdk = 'C:/Users/pascal/AppData/Local/Android/sdk'
resDirectory = 'src/android/res'
compileSdkVersion = '23'
buildToolsVersion = '22.0.1'
}
ios {
infoPList = file('src/ios/Default-Info.plist')
}
}
You need to update the jfxmobile plugin version. Many things have been fixed and updated since the 1.0.0-b10 version (from a year and a half ago).
Currently the version is 1.3.2. It is not only the plugin, but the mainly the javafxports version that the plugin includes.
If you use the Gluon plugin on your favorite IDE, selecting a Single View project you will get the minimum project template and a valid
build.gradle
file.This is an updated build script:
You can add all your code to the BasicView, deploy it on mobile and test it.
I've just done it and everything works fine: the task runs fast, and the buttons are responsive.
Using JavaFXPorts it's not recommended creating a second
Stage
. You can use aDialog
(either built-in JavaFX dialog or Gluon Mobile dialog) instead.You can test Gluon Mobile library for free, you will get only a nag screen at startup.
Anyway, you can remove the Gluon Mobile library (just remove
com.gluonhq:charm:4.3.0
from dependencies), and you'll have to port backMobileApplication
to a regular JavaFXApplication
and remove the BasicView class (mostly as you have now).