JVx' JavaFX UI with JavaFXPorts
A few hours ago, we published a screenshot from our Demo ERP application running on Nexus 9 (an Android tablet).
It wasn't a fake!
Use JVx and write an application for all polpular platforms and devices.
This is real "write once run anywhere".
Create an application for Windows, Linux, Mac, iOS, or Android, PS4, OUYA or WiiU. Run it as desktop application, as html5 application in web browsers, as native iOS or Android application or as JavaFX application on Android and iOS devices. There's nothing like JVx in the world - not with only one framework with such a small footprint as JVx and certainly not Open Source!
Here are the screenshots:
Also in portrait mode:
And now a very strange one. It's the application with our styled stage. It's crazy because you can drag the window around (makes no sense, but it just works):
Sure, the application wasn't optimized for mobile devices. It has the same style as the desktop application. The mobile version should have bigger frame buttons and a bigger frame header To be honest - MDI on mobile devices? We were positively surprised about the usability. But, whatever. You have the option and decide what's best for your application (but please don't use MDI for smartphones).
Are you interested in some details?
We've used Netbeans IDE because there's a very useful plugin from gluon. We're Eclipse users but it was easier to use a preconfigured environment without doing everything manually. It was simple to configure Netbeans with gluon plugin and there's a video for your first steps. A "bigger" problem was gradle because the project was a gradle project and we've never used gradle. We love using ant.
We had a bad start with Hello World application because it didn't work. There were different problems: Missing ANDROID_HOME or DEX compiler problems. After reading the documentation it was possible to start compilation. The DEX problem was very strange because we had JVM 1.8 u31 and JVM 1.8 u40 configured in Netbeans, but Netbeans didn't use our configured JVM 1.8 u40. We removed the JVM 1.8 u31 from Netbeans and after that we successfully compiled our Hello World application. Very strange!
The next step was using JVx as library dependency for our project, but how did this work with gradle? We had the library in the libs directory of the project, in the file system. We didn't use a maven lib because it was easier to replace the library after recreation. We tried to find a solution in the official gradle documentation and found Chapter 51. C'mon gradle is a build tool and not a programming language! So much documentation means: complexity. Sure, ant wasn't the holy grale but it it's simple to understand and doesn't hide anything.
Our current gradle script:
repositories {
jcenter()
}
dependencies {
classpath 'org.javafxports:jfxmobile-plugin:1.0.0-b7'
}
}
apply plugin: 'org.javafxports.jfxmobile'
repositories {
jcenter()
}
dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
runtime fileTree(dir: 'libs', include: '*.jar')
}
mainClassName = 'com.sibvisions.gluon.JVxGluonApp'
jfxmobile {
ios {
forceLinkClasses = [ 'com.sibvisions.gluon.**.*' ]
}
android {
androidSdk = 'C:/tools/android/android-sdk_r04-windows'
compileSdkVersion = 21
}
}
It's short but we ddin't know what happened behind the scenes without additional research. But if it works it's good enough for many developers.
The integration of JVx was simple because JVx was compiled with JVM 1.6. The Dalvik VM or DART do support 1.6 and 1.7 syntax. It was cool to see that JVx and especially the communication worked without problems - Great job from Johan Vos and all people behind JavaFXPorts!
Our next step was the integration of additional dependencies like our JavaFX UI. It was based on JVM 1.8 u40 and heavily used lambdas. But lambda expressions weren't supported from Dalvik or ART. We thought that gluon plugin solves the problem for us, but it didn't. It contains retrolambda but only for project source files and it doesn't touch your dependencies. There was no additional gradle build task for that, so we had to convert the libs manually. Not a problem but you must be aware of it.
After we solved all dependency problems, we had the first version of our desktop ERP running on our android device. But don't think everything was trouble-free. We had problems with method references, Java Preferences because of write problems, new Date API, forEach calls, scene size and much more. We did solve most problems but not all - yet.
Hello:
How did you fix the DEX error?
Thanks
Javier
Output file C:\DesarrollosAndroid\Portabilidad\demo\HelloPlatform\build\javafx
ports\tmp\android\dex\classes.dex has been removed.
[ant:java] Java Result: 1
:HelloPlatform:dex FAILED
:HelloPlatform:dex (Thread[main,5,main]) completed. Took 0.701 secs.
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':HelloPlatform:dex'.
> org.gradle.api.GradleException (no error message)
* Try:
Run with --stacktrace option to get the stack trace. Run with --debug option to
get more log output.
BUILD FAILED
Total time: 2 mins 54.237 secs
Stopped 0 compiler daemon(s).
We had a different DEX error!
Be sure that JVM 1.8 u40 is configured. In our case, the problem was 1.8 u31 altaugh we had 1.8 u40 as project JVM. Do you use SDK Version 21?
(We removed the JVM 1.8 u31 configuration).
We checked the prerequisites: http://javafxports.org/page/Getting_Started
and set the plugin version to: 1.0.0-b7 in our gradle build file. It was -b5 before.
RESOLVED!!!
I had JAVA_HOME pointing to 32bits and PATH pointing to 64bits.
Now both JAVA_HOME and PATH point to C:\Program Files\Java\jdk1.8.0_40
Another thing that I changed was JDK1.8. I had installed JDK1.8 U40 early access. I reinstaled the last U40
Thanks!!!
Javier
Hi, I am facing Problem
[ant:java] Java Result: 1
:dex FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':dex'.
> org.gradle.api.GradleException (no error message)
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
Total time: 1 mins 2.916 secs
Build failure (see the Notifications window for stacktrace): gradle :androidInstall
I can't tell you what's the main cause, but try same steps as Javier and:
Check if you have JDK 1.8 u40 installed properly and your gradle project is configured to use it!
In our case, the DEX problems were related to a wrong configured JVM/project.
i get this error after i run my project . pls help
Error: Could not find or load main class Main.java
:run FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':run'.
> Process 'command 'C:\Program Files\Java\jdk1.8.0_45\bin\java.exe'' finished with non-zero exit value 1
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
Do you use a JVx project or standard JavaFX project with JavaFXports libs?
If you need help for JavaFXPorts, simply use the google group: https://groups.google.com/forum/#!forum/javafxports
i use JavaFX project with JavaFXports libs
OK, so the best place for you is: https://groups.google.com/forum/#!forum/javafxports
We had a similar problem on a OSX with an EarlyAccess JDK, but the version looks good in your case. Be sure that your Main class was configured in your gradle build file. There's a nice example application: https://github.com/jperedadnr/Game2048FX
this is another error am getting
FAILURE: Build failed with an exception.
* What went wrong:
ANDROID_HOME not specified. Either set it as a gradle property, a system environment variable or directly in your build.gradle by setting the extension jfxmobile.android.androidSdk.
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
Please read: http://javafxports.org/page/Getting_Started
(Prerequisites, Android)
e.g.
android {
androidSdk = 'C:/tools/android/android-sdk'
compileSdkVersion = 21
}
this is the new error after following the steps
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':mergeClassesIntoJar'.
> Cannot expand ZIP 'C:\Tools\android\android-sdk_r24.3.3-windows\android-sdk-windows\extras\android\support\multidex\library\libs\android-support-multidex.jar' as it does not exist.
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
Please use https://groups.google.com/forum/#!forum/javafxports for JavaFXPorts questions!
please help with this error
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':androidInstall'.
> com.android.builder.testing.api.DeviceException: java.lang.RuntimeException: No connected devices!
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
Please use https://groups.google.com/forum/#!forum/javafxports for JavaFXPorts questions!
gluon convert to androin only in sdk new and for on 64bit
I try in 32bit os windows not yet ready
Not sure what you mean, but jdk with 32bit isn't a problem.
Issue 1
--------
Requested project: C:\Users\anu\Documents\NetBeansProjects\net
Stack trace:
org.gradle.tooling.BuildException: Could not execute build using Gradle distribution 'https://services.gradle.org/distributions/gradle-2.2.1-all.zip'.
at org.gradle.tooling.internal.consumer.ResultHandlerAdapter.onFailure(ResultHandlerAdapter.java:59)
at org.gradle.tooling.internal.consumer.async.DefaultAsyncConsumerActionExecutor$1$1.run(DefaultAsyncConsumerActionExecutor.java:57)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54)
at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:40)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
at org.gradle.tooling.internal.consumer.BlockingResultHandler.getResult(BlockingResultHandler.java:46)
at org.gradle.tooling.internal.consumer.DefaultBuildLauncher.run(DefaultBuildLauncher.java:72)
at org.netbeans.gradle.project.tasks.AsyncGradleTask.runBuild(AsyncGradleTask.java:369)
at org.netbeans.gradle.project.tasks.AsyncGradleTask.doGradleTasksWithProgressIgnoreTaskDefCancel(AsyncGradleTask.java:492)
at org.netbeans.gradle.project.tasks.AsyncGradleTask.doGradleTasksWithProgressIgnoreTaskDefCancel(AsyncGradleTask.java:402)
at org.netbeans.gradle.project.tasks.AsyncGradleTask.doGradleTasksWithProgress(AsyncGradleTask.java:393)
at org.netbeans.gradle.project.tasks.AsyncGradleTask.access$400(AsyncGradleTask.java:84)
at org.netbeans.gradle.project.tasks.AsyncGradleTask$BuildExecutionItem$1.run(AsyncGradleTask.java:775)
at org.netbeans.gradle.project.tasks.GradleDaemonManager.runBlockingGradleTask(GradleDaemonManager.java:52)
at org.netbeans.gradle.project.tasks.GradleDaemonManager.access$200(GradleDaemonManager.java:23)
at org.netbeans.gradle.project.tasks.GradleDaemonManager$2.execute(GradleDaemonManager.java:129)
at org.jtrim.concurrent.AbstractTaskExecutorService$FunctionWrapper.execute(AbstractTaskExecutorService.java:270)
at org.jtrim.concurrent.AbstractTaskExecutorService$TaskOfAbstractExecutor.execute(AbstractTaskExecutorService.java:340)
at org.jtrim.concurrent.Tasks$RunOnceCancelableTask.execute(Tasks.java:342)
at org.jtrim.concurrent.ThreadPoolTaskExecutor$ThreadPoolTaskExecutorImpl$QueuedItem.runTask(ThreadPoolTaskExecutor.java:1213)
at org.jtrim.concurrent.ThreadPoolTaskExecutor$ThreadPoolTaskExecutorImpl$Worker.executeTask(ThreadPoolTaskExecutor.java:1049)
at org.jtrim.concurrent.ThreadPoolTaskExecutor$ThreadPoolTaskExecutorImpl$Worker.run(ThreadPoolTaskExecutor.java:1179)
at org.jtrim.concurrent.ThreadPoolTaskExecutor$ThreadPoolTaskExecutorImpl$Worker$1.run(ThreadPoolTaskExecutor.java:998)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.gradle.internal.exceptions.LocationAwareException: Execution failed for task ':dex'.
at org.gradle.initialization.DefaultExceptionAnalyser.transform(DefaultExceptionAnalyser.java:77)
at org.gradle.initialization.MultipleBuildFailuresExceptionAnalyser.transform(MultipleBuildFailuresExceptionAnalyser.java:47)
at org.gradle.initialization.StackTraceSanitizingExceptionAnalyser.transform(StackTraceSanitizingExceptionAnalyser.java:30)
at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:108)
at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:86)
at org.gradle.launcher.exec.InProcessBuildActionExecuter$DefaultBuildController.run(InProcessBuildActionExecuter.java:80)
at org.gradle.tooling.internal.provider.BuildModelAction.run(BuildModelAction.java:43)
at org.gradle.tooling.internal.provider.BuildModelAction.run(BuildModelAction.java:30)
at org.gradle.tooling.internal.provider.ConfiguringBuildAction.run(ConfiguringBuildAction.java:119)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:36)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:26)
at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:47)
at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:34)
at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:119)
at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:35)
at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:119)
at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:24)
at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:119)
at org.gradle.launcher.daemon.server.exec.StartStopIfBuildAndStop.execute(StartStopIfBuildAndStop.java:33)
at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:119)
at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:71)
at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:69)
at org.gradle.util.Swapper.swap(Swapper.java:38)
at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:69)
at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:119)
at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:60)
at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:34)
at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:119)
at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:70)
at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:34)
at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:119)
at org.gradle.launcher.daemon.server.exec.DaemonHygieneAction.execute(DaemonHygieneAction.java:39)
at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:119)
at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:46)
at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:246)
at org.gradle.internal.concurrent.DefaultExecutorFactory$StoppableExecutorImpl$1.run(DefaultExecutorFactory.java:64)
Caused by: org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':dex'.
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:69)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:46)
at org.gradle.api.internal.tasks.execution.PostExecutionAnalysisTaskExecuter.execute(PostExecutionAnalysisTaskExecuter.java:35)
at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:64)
at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)
at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:42)
at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:53)
at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
at org.gradle.api.internal.AbstractTask.executeWithoutThrowingTaskFailure(AbstractTask.java:305)
at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.executeTask(AbstractTaskPlanExecutor.java:79)
at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:63)
at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:51)
at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.process(DefaultTaskPlanExecutor.java:23)
at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:88)
at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:29)
at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:62)
at org.gradle.execution.DefaultBuildExecuter.access$200(DefaultBuildExecuter.java:23)
at org.gradle.execution.DefaultBuildExecuter$2.proceed(DefaultBuildExecuter.java:68)
at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32)
at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:62)
at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:55)
at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:149)
at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:106)
... 32 more
Caused by: org.gradle.api.GradleException:
at org.javafxports.jfxmobile.plugin.android.task.Dex.dex(Dex.groovy:57)
at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:63)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.doExecute(AnnotationProcessingTaskFactory.java:218)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:211)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:200)
at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:579)
at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:562)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61)
... 55 more
help me please...
The better place for help is gluon forum: http://gluonhq.com/forums
Simply follow the documentation: http://docs.gluonhq.com/javafxports/
Could be a problem with your JRE or Android SDK version.