JavaFXPorts - Changing scene results in Invalid Touch point ID error - javafxports

I have an app with 2 scenes. The app starts with the first scene (set to full screen mode), and when I tap a point on the screen, it then switches to the second scene (which is also set to full screen).
When I run it on Windows, it works fine. When I run it on Android, I get an error after switching to the second scene. The second scene pops up on the screen briefly and then crashes with the following exception in the logcat:
java.lang.RuntimeException: Platform reported wrong touch point ID
at javafx.scene.Scene$TouchMap.get(Scene.java:5455)
at javafx.scene.Scene$ScenePeerListener.touchEventNext(Scene.java:2716)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$null$361(GlassViewEventHandler.java:1148)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.access$lambda$20(GlassViewEventHandler.java)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$$Lambda$23.run(Unknown Source)
at java.security.AccessController.doPrivileged(AccessController.java:52)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleNextTouchEvent$362(GlassViewEventHandler.java:1127)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.access$lambda$17(GlassViewEventHandler.java)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$$Lambda$20.get(Unknown Source)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:391)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleNextTouchEvent(GlassViewEventHandler.java:1126)
at com.sun.glass.ui.View.handleNextTouchEvent(View.java:579)
at com.sun.glass.ui.View.notifyNextTouchEvent(View.java:1050)
at com.sun.glass.ui.TouchInputSupport.notifyNextTouchEvent(TouchInputSupport.java:141)
at com.sun.glass.ui.monocle.TouchInput.dispatchPoint(TouchInput.java:131)
at com.sun.glass.ui.monocle.TouchInput.lambda$postPoint$82(TouchInput.java:155)
at com.sun.glass.ui.monocle.TouchInput.access$lambda$3(TouchInput.java)
at com.sun.glass.ui.monocle.TouchInput$$Lambda$4.run(Unknown Source)
at com.sun.glass.ui.monocle.RunnableProcessor.runLoop(RunnableProcessor.java:92)
at com.sun.glass.ui.monocle.RunnableProcessor.run(RunnableProcessor.java:51)
at java.lang.Thread.run(Thread.java:818)
Any suggestions on solving this would be great.
Here's the build.gradle file as requested:
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.javafxports.jfxmobile'
dependencies {
compile project(':Util')
compile files('D:/DevTools/minimal-json/minimal-json7.jar')
compile files('D:/DevTools/sqlite-jdbc/sqlite-jdbc-3.8.11.2.jar')
androidRuntime 'org.sqldroid:sqldroid:1.0.3'
}
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'org.javafxports:jfxmobile-plugin:1.0.8'
}
}
apply plugin: 'org.javafxports.jfxmobile'
repositories {
jcenter()
}
mainClassName = 'com.myapp.Client'
jfxmobile {
javafxportsVersion = '8.60.7'
android {
manifest = 'src/android/AndroidManifest.xml'
}
ios {
forceLinkClasses = [ 'com.myapp.**.*', 'SQLite.**.*']
infoPList = file('src/ios/Default-Info.plist')
}
}
Thanks!

I can reproduce your crash and I'll file a bug.
While on Desktop it is pretty common having several scenes or even stages, that's not the case on mobile.
Instead, we have one single stage, and we don't change the scene all the time, we just change its content.
Using Gluon Mobile, there are View nodes, that allow you precisely that: use as many views as you need to have different content, and switch between then when you need.
You can have a look at the GluonSQLite sample, that includes SQLite but it only has one View, or to other multi-view samples here like Notes or Comments.

Related

Read build script blocks from gradle plugin

There is a gradle plugin with id ("com.my.plugin").
The project using this plugin has the following build.gradle file:
...
apply plugin: 'com.my.plugin'
...
android {
    ...
    defaultConfig {
        ...
        testInstrumentationRunner "com.my.plugin.junit4.MyCustomRunner"
        ...
    }
    ...
}
...
dependencies {
    ...
    androidTestImplementation com.my:plugin-junit4:1.0.0-alpha04
    ...
}
...
The class implementing the plugin is as follows:
class MyPlugin: Plugin <Project> {
    override fun apply (project: Project) {
        project.afterEvaluate {
            // here I need to read testInstrumentationRunner value declared
            // in the defaultConfig block of the build.gradle file
            // also here I need to read androidTestImplementation value declared
            // in the dependencies block of the build.gradle file
        }
    }
}
In the project.afterEvaluate {...} block of the plugin I need to check for the values ​​of testInstrumentationRunner and androidTestImplementation declared in the build.gradle file of the project using this plugin. How to do it?
Since you're using Kotlin for your plugin implementation, you'll need know the type of the android { } extension. Otherwise you will run into compilation errors.
Essentially, you need to retrieve a reference of the android extension in your plugin like so:
project.afterEvaluate {
// we don't know the concrete type so this will be `Object` or `Any`
val android = project.extensions.getByName("android")
println(android::class.java) // figure out the type
// assume we know the type now
val typedAndroid = project.extensions.getByType(WhateverTheType::class.java)
// Ok now Kotlin knows of the type and its properties
println(typedAndroid.defaultConfig.testInstrumentationRunner)
}
I'm not familar with Android or its Gradle plugin. Google only led me to its Javadocs here which didn't help. So the above may or may not work.

Are pmd, repositories etc tasks in Gradle

I am creating basic custom tasks in Gradle and learning how to extend them to do more complicated actions (Learning from here: https://docs.gradle.org/current/userguide/tutorial_using_tasks.html).
One of my reference projects, which I am extending to learn Gradle looks something like this
// pmd config
pmd {
ignoreFailures = false
reportsDir = file("$globalOutputDir/pmd")
toolVersion = toolVersions.pmdVersion
}
repositories {
mavenCentral()
}
task listSubProjects{
doLast{
println 'Searching in root dir `'
}
}
My question is around the pmd and repositories sections and why they don't have a clear qualifier like "task" on them but my listSubProjects requires a task qualifier? Are these inherited tasks from plugins and don't need a task qualifier?
The blocks that you see are task extensions, also discussed here.
A plugin creator can define extensions to allow users to configure a plugin:
// plugin code
class GreetingPluginExtension {
// default value
String message = 'Hello from GreetingPlugin'
}
// plugin code
class GreetingPlugin implements Plugin<Project> {
void apply(Project project) {
// Add the 'greeting' extension object
def extension = project.extensions.create('greeting', GreetingPluginExtension)
// Add a task that uses configuration from the extension object
...
}
}
In project.extensions.create('greeting',... the greeting block to be used later in build.gradle files is defined.
Then in user build.gradle files
apply plugin: GreetingPlugin
// Configure the extension
greeting.message = 'Hi from Gradle'
// Same effect as previous lines but with different syntax
greeting {
message = 'Hi from Gradle'
}
Often the name of the extension is chosen to be the same as the plugin and/or the task, which can make things confusing.

How do I re-use gradle definitions across projects

I am working on a set of projects that each uses Gradle as the build tool. This is not a multi-project setup although I want to be able to re-use some common Gradle scripts across each project for consistency as the projects are related.
For example, for the Java component, I want the manifest file in the generated JAR file to have the same information. In particular, all the projects will have the same major and minor versions numbers, while the patch version will be project specific.
Here's what I've tried so far:
master.gradle - to be shared across projects
group 'com.example'
ext.majorVersion = 2
ext.minorVersion = 3
ext.patchVersion = 0; // Projects to override
def patchVersion() {
return patchVersion;
}
apply plugin: 'java'
jar {
manifest {
attributes 'Bundle-Vendor': 'Example Company',
'Bundle-Description': 'Project ABC',
'Implementation-Title': project.name,
'Implementation-Version': majorVersion + '.' + minorVersion + '.' + patchVersion()
}
}
build.gradle - for one of the projects
apply from: 'master.gradle'
patchVersion = 3
task hello {
println 'Version: ' + majorVersion + '.' + minorVersion + '.' + patchVersion
}
If I run gradle hello jar from the command line, I get Version: 2.3.3 from the hello task. However, the JAR file manifest contains 2.3.0 which is not what I want. How do I get the correct patch version into the manifest? And more generally, how do I let projects supply information to the master scripts?
Based on #Oliver Charlesworth's suggestion I came up with the following. I had to write a simple plugin to hold the version information and use it as an extension object. Please note (as suggested by the comments in the gradle files), the order in which items are applied and set is very important. Different orderings result in compiler errors or values used before they are set.
If anyone wants to suggest improvements, please do so.
master.gradle
group 'com.example'
// N.B. The individual project must have applied the semantic version
// plugin and set the patch version before applying this file.
// Otherwise the following will fail.
// Specify the major and minor version numbers.
project.semver.major = 2
project.semver.minor = 3
project.version = project.semver
apply plugin: 'java'
jar {
manifest {
attributes 'Bundle-Vendor': 'Example Company',
'Bundle-Description': project.description,
'Implementation-Title': project.name,
'Implementation-Version': project.semver
}
}
build.gradle
// Describe the project before importing the master gradle file
project.description = 'Content Upload Assistant'
// Specify the patch version
apply plugin: SemanticVersionPlugin
project.semver.patch = 3
// Load the master gradle file in the context of the project and the semantic version
apply from: 'master.gradle'
The simple plugin can be found below. At the moment it is with the application source code, but it should be moved out into a library, along with the master gradle file.
buildSrc/src/main/groovy/SemanticVersionPlugin.groovy
import org.gradle.api.Plugin
import org.gradle.api.Project
class SemanticVersionPlugin implements Plugin<Project> {
void apply(Project project) {
project.extensions.create('semver', SemanticVersion)
}
}
class SemanticVersion {
int major
int minor
int patch
String toString() {
return major + '.' + minor + '.' + patch
}
}

How to add to a plugin task the dependencies comming from build.grade script?

I Have a task from my plugin that need mysql or postgres drivers.
currently I hardcoded into FooPlugin::apply method this:
configuration.dependencies.add(project.dependencies.create('mysql:mysql-connector-java:5.1.34'))
But I would like to let users, to choose their drivers.
So for this I would like to grab all dependencies from gradle build script (build.gradle) which applying my plugin to inject these dependencies to the task dynamically.
Resolved: add a piece of code
I tried this:
class FooPlugin implements Plugin<Project>{
#Override
void apply(Project project) {
project.afterEvaluate {
def configuration = project.configurations.create('bar')
configuration.extendsFrom(project.configurations.findByName('compile'))
…
}
}
}
If you do not put into project.afterEvaluate block below error is raised:
Cannot change dependencies of configuration ':bar' after it has been resolved.
I'm not sure exactly what your trying to accomplish so I'm going to guess at a couple things.
Looks like your trying to add a dependency or react based on a dependency added. I think you can accomplish either through the resolutionStrategy
project.configurations {
compile.resolutionStrategy {
// adds a dependency to a project, always.
force 'commons-io:commons-io:2.5'
// loop through all the dependencies to modify before resolution
eachDependency { DependencyResolveDetails details ->
// here you can change details about a dependency or respond however needed
if (details.requested.group == 'mysql' && details.requested.name == 'mysql-connector-java') {
// for example we can force a specific version
details.useVersion '5.1.34'
}
// you could also add a if block for postgres if needed
}
}
}

Gradle plugin for XML Beans

I am trying to write a Gradle plugin for XML Beans. I have started with one of the 'Hello from Gradle' plugin examples, and also a plugin published by R. Artavia here. That plugin went straight to jar - I am trying to only generate source. The generated source must then be compiled with other project source and included in a single jar. Other goals include
- full plugin - all I should need is "apply plugin: 'xmlbean'"
- I can configure source/code gen location and some features if I want to
- It detects whether it needs to be rebuilt. (well, eventually!!!)
I am off to a pretty good start, but am blocked defining a new sourceSet. I am getting an error "No such property 'srcDirs'" (or 'srcDir'). It seems there is something I have to define someplace to make a new sourceSet work but I cannot find it. I have tried several different syntaxes (with/without equal sign, brackets, srcDir/srcDirs, etc. - nothing is working...
What do I need to do inside a plugin to make a new sourceSet entry be properly recognized?
Thank you!
JKE
File: xmlbean.gradle (includes greeting plugin for the moment for debugging)
apply plugin: xmlbean
apply plugin: 'java'
xmlbean {
message = 'Hi'
greeter = 'Gradle'
}
class xmlbean implements Plugin<Project> {
void apply(Project project) {
project.extensions.create("xmlbean", xmlbeanExtension)
Task xmlbeanTask = project.task('xmlbean')
xmlbeanTask << {
project.configurations {
xmlbeans
}
project.dependencies {
xmlbeans 'org.apache.xmlbeans:xmlbeans:2.5.0'
}
project.sourceSets {
main {
java {
srcDirs += '$project.buildDir/generated-source/xmlbeans'
}
}
xmlbeans {
srcDirs = ['src/main/xsd']
}
}
ant.taskdef(name: 'xmlbean',
classname: 'org.apache.xmlbeans.impl.tool.XMLBean',
classpath: project.configurations.xmlbeans.asPath)
ant.xmlbean(schema: project.sourceSets.xmlbean.srcDir,
srconly: true,
srcgendir: "$project.buildDir/generated-sources/xmlbeans",
classpath: project.configurations.xmlbeans.asPath)
println "${project.xmlbean.message} from ${project.xmlbean.greeter}"
}
project.compileJava.dependsOn(xmlbeanTask)
}
}
class xmlbeanExtension {
String message
String greeter
}
File: build.gradle
apply from: '../gradle/xmlbeans.gradle'
dependencies {
compile "xalan:xalan:$ver_xalan",
":viz-common:0.0.1",
":uform-repository:0.1.0"
}
Console: Error message:
:idk:xmlbean FAILED
FAILURE: Build failed with an exception.
* Where:
Script 'C:\jdev\cpc-maven\try.g2\comotion\gradle\xmlbeans.gradle' line: 32
* What went wrong:
Execution failed for task ':idk:xmlbean'.
> No such property: srcDirs for class: org.gradle.api.internal.tasks.DefaultSourceSet_Decorated
...
BUILD FAILED
Gradle info: version 2.5 / groovy 2.3.10 / JVM 7u55 on Windows 7 AMD64
You should try to become familiar with the Gradle DSL reference guide, because it's a huge help in situations like this. For example, if you click on the sourceSets { } link in the left navigation bar, you're taken to this section on source sets.
From there, you'll discover that the sourceSets {} block is backed by a class, SourceSetContainer. The next level of configuration nested inside is backed by a SourceSet object, and then within that you have one or more SourceDirectorySet configurations. When you follow the link to SourceDirectorySet, you'll see that there are getSrcDirs() and setSrcDirs() methods.
So how does this help? If you look closely at the exception, you'll see that Gradle is saying it can't find a srcDirs property on DefaultSourceSet_Decorated, which you can hopefully infer is an instance of SourceSet. That interface does not have an srcDirs property. That's because your xmlbeans {} block is configuring a SourceSet, not a SourceDirectorySet. You need to add another nested configuration to gain access to srcDirs.
At this point, I'm wondering whether a new source set is the appropriate solution. Unfortunately it's not clear to me exactly what the plugin should be doing, so I can't offer any alternatives at this point.

Resources