How to implement TornadoFX WebEngine Callback in Kotlin - javafx

I am using Kotlin TornadoFX to create a browser. When I implement WebEngine setCreatePopupHandler, I get an error:
e: surfing\src\surfing.kt: (76, 13): Modifier 'override' is not
applicable to 'local function'
e: surfing\src\surfing.kt: (76, 13): Expected a value of type WebEngine!
I referenced this Java code using JavaFX:
webEngine.setCreatePopupHandler(
new Callback<PopupFeatures, WebEngine>() {
#Override
public WebEngine call(PopupFeatures config) {
smallView.setFontScale(0.8);
if (!toolBar.getChildren().contains(smallView)) {
toolBar.getChildren().add(smallView);
}
return smallView.getEngine();
}
});
Translated into Kotlin to use TornadoFX:
var wv = webview()
val br = wv.getEngine()
br.setCreatePopupHandler(Callback<PopupFeatures, WebEngine>() {
override fun call(pf: PopupFeatures): WebEngine {
var smallView = webview()
val stage = Stage(StageStyle.UTILITY)
stage.setScene(Scene(smallView))
stage.show()
val engine = smallView.getEngine()
return engine
}
})
I have been searching for a long time on the internet, but I didn't find anything. Please can somebody help me fix this error.

You're almost there :) To create an anonymous class much the same way you do in Java, you need to use the object keyword in front of the class statement:
br.createPopupHandler = object : Callback<PopupFeatures, WebEngine> {
However, Kotlin allows you to turn SAM types into lambdas. You can also utilize the property access pattern and immutable values to clean up the code a little. Here is a the code rewritten and Kotlinified:
val wv = webview()
val br = wv.engine
br.setCreatePopupHandler {
val smallView = webview()
val stage = Stage(StageStyle.UTILITY)
stage.scene = Scene(smallView)
stage.show()
smallView.engine
}
I haven't really evaluated what you're doing here or if that's a good idea, so only take my advice on the syntax :)

Related

When will spring fix abstract mapping on couchbase reactive

Is there any solution how to use super type (abstract class) in spring boot starter data couchbase reactive ?
My idea is to have super type and save this super type into couchabse bucket, and read from it.
Writing is working perfectly, but on read I got exception:
org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.entities.Report]: Class is abstract
Classes are implemented like:
Report:
#JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "documentType"
)
#JsonSubTypes(
JsonSubTypes.Type(value = TestReport::class, name = TestReport.DOCUMENT_TYPE),
JsonSubTypes.Type(value = Test2Report::class, name = Test2Report.DOCUMENT_TYPE)
)
#Document
abstract class Report : SyncDocument {
var inspectorId: String = ""
var reportNumber: String = ""
var reportDate: Long = 0
constructor() : super(null) {}
}
TestReport:
#Document
#TypeAlias(TestReport.DOCUMENT_TYPE)
class TestReport : Report {
companion object {
const val DOCUMENT_TYPE: String = "TestReport"
}
var string3: String = ""
constructor() : super() {}
}
Test2Report:
#Document
#TypeAlias(Test2Report.DOCUMENT_TYPE)
class Test2Report : Report {
companion object {
const val DOCUMENT_TYPE: String = "Test2Report"
}
var string2: String = ""
constructor() : super() {}
}
I have implemented code in this way on other android project where ReactiveCrudRepository is not used, and works perfectly. Now I want to use same schema on ReactiveCrudRepository.
Thank you on any sugestions :D
It might help to see the complete stack trace and to know what version you are using.
In Java, you could simply make Report not Abstract. Does that not work in Android?
Thanks,
Mike
This is addressed in https://github.com/spring-projects/spring-data-couchbase/issues/1315 which is in 4.3.2 that was released today.

Bound properties not working

I'm using TornadoFX 1.7.5 and I can't seem to get bound properties to work. I have the below ItemViewModels
class DynamicMenuViewModel : ItemViewModel<DynamicMenu>(DynamicMenu()) {
val title = bind { item?.title?.toProperty() }
val isBold = bind { item?.isBold?.toProperty() }
val routes = bind { item?.routes?.toProperty() }
}
data class DynamicMenu(var title: String = "", var isBold: Boolean = false, var routes: MutableList<MenuRouteViewModel> = mutableListOf())
class MenuRouteViewModel : ItemViewModel<MenuRoute>(MenuRoute()) {
val url = bind { item?.url?.toProperty() }
val title = bind { item?.title?.toProperty() }
val isBold = bind { item?.isBold?.toProperty() }
val showNew = bind { item?.showNew?.toProperty() }
}
data class MenuRoute(var url: String = "", var title: String = "", var showNew: Boolean = false, var isBold: Boolean = false)
Which are bound like this:
//routesController.dynamicMenu is an instance of DynamicMenuViewModel()
textfield(property = routesController.dynamicMenu.title) {
prefWidth = formWidth * .5
gridpaneConstraints {
columnRowIndex(0, 1)
marginLeft = 10.0
columnSpan = 2
marginBottom = 20.0
}
}
checkbox(property = routesController.dynamicMenu.isBold){
gridpaneConstraints {
columnRowIndex(2, 1)
marginLeft = 15.0
marginBottom = 20.0
}
}
Then the following functions commit the models and prints them to the screen when I click a button:
fun onClick(){
commitModel()
println(dynamicMenu.item.toString())
dynamicMenu.item.routes.forEach {
println(it.item.toString())
}
}
fun commitModel(){
dynamicMenu.item.routes.forEach {
it.commit()
}
dynamicMenu.commit()
}
The problem is that when I run the program and edit the textfields and checkboxes then click the button that runs onClick(), the backing item doesn't seem to be getting updated. So none of the updated values are printed to the console.
What am I doing wrong here?
The ViewModel can as you probably know only bind bidirectionally against JavaFX Properties. Your domain objects doesn't contain JavaFX properties, so you need to convert them. However, the toProperty() function you are using only operates on a value, and turns it into a Property. This property has no way of knowing about it's field owner, and hence cannot write back into the domain object.
Luckily, you can use the observable function to make your domain object properties writable as well:
val url = bind { item?.observable(MenuRoute::url) }
Since the observable function operates on a specific instance of a MenuRoute object, it now has enough information to write back into that instance when you commit() the model.
If you would consider changing the properties in your domain objects to be observable, you could write:
val url = bind(MenuRoute::url)
You can use the TornadoFX IDEA plugin inspection "Convert all properties to TornadoFX Properties" to automatically rework your properties. This would transform your MenuRoute object into:
class MenuRoute {
val isBoldProperty = SimpleBooleanProperty(false)
var isBold by isBoldProperty
val showNewProperty = SimpleBooleanProperty(false)
var showNew by showNewProperty
val urlProperty = SimpleStringProperty("")
var url by urlProperty
val titleProperty = SimpleStringProperty("")
var title by titleProperty
}
(You have to manually remove the data modifier on your class. Also beware that the current version of the plugin has a bug in the conversion function that would leave the old parameters - a new version will be released shortly).
If you don't want to do that for various reasons, I was just able to support that nice syntax even for mutable vars like you have, so from TornadoFX 1.7.6 you can use this syntax in your binding statements even if you don't want to change your data classes:
val url = bind(MenuRoute::url)

Adding entries to Dictionary (not NSDictionary) from Info.plist

In the following OS X application, how can I create a Dictionary in a similar way to how I create an NSDictionary?
I suppose I need to find a method on Dictionary that performs the same task as NSDictionary(contentsOfFile:infoPlist) but I am not sure what this Dictionary method is.
import Cocoa
class AppDelegate: NSObject, NSApplicationDelegate {
#IBOutlet weak var window: NSWindow!
func applicationDidFinishLaunching(aNotification: NSNotification?) {
var infoPlist = "/Applications/Calendar.app/Contents/Info.plist"
var nsDictionary = NSDictionary(contentsOfFile:infoPlist)
println("nsDictionary = \(nsDictionary)")
var dictionary = Dictionary<String, String>()
// TODO: How do I add entries from "infoPlist" to "dictionary"
// like I do above with the old "nsDictionary"?
println("dictionary = \(dictionary)")
}
func applicationWillTerminate(aNotification: NSNotification?) {
}
}
Many thanks in advance.
Sadly there is no way to do this in native swift dictionaries at the moment. However using NSDictionary is still quite fine.
For more info you can look at this similar question

Scala: How do I dynamically instantiate an object and invoke a method using reflection?

In Scala, what's the best way to dynamically instantiate an object and invoke a method using reflection?
I would like to do Scala-equivalent of the following Java code:
Class class = Class.forName("Foo");
Object foo = class.newInstance();
Method method = class.getMethod("hello", null);
method.invoke(foo, null);
In the above code, both the class name and the method name are passed in dynamically. The above Java mechanism could probably be used for Foo and hello(), but the Scala types don't match one-to-one with that of Java. For example, a class may be declared implicitly for a singleton object. Also Scala method allows all sorts of symbols to be its name. Both are resolved by name mangling. See Interop Between Java and Scala.
Another issue seems to be the matching of parameters by resolving overloads and autoboxing, described in Reflection from Scala - Heaven and Hell.
There is an easier way to invoke method reflectively without resorting to calling Java reflection methods: use Structural Typing.
Just cast the object reference to a Structural Type which has the necessary method signature then call the method: no reflection necessary (of course, Scala is doing reflection underneath but we don't need to do it).
class Foo {
def hello(name: String): String = "Hello there, %s".format(name)
}
object FooMain {
def main(args: Array[String]) {
val foo = Class.forName("Foo").newInstance.asInstanceOf[{ def hello(name: String): String }]
println(foo.hello("Walter")) // prints "Hello there, Walter"
}
}
The answers by VonC and Walter Chang are quite good, so I'll just complement with one Scala 2.8 Experimental feature. In fact, I won't even bother to dress it up, I'll just copy the scaladoc.
object Invocation
extends AnyRef
A more convenient syntax for reflective
invocation. Example usage:
class Obj { private def foo(x: Int, y: String): Long = x + y.length }
You can call it reflectively one of
two ways:
import scala.reflect.Invocation._
(new Obj) o 'foo(5, "abc") // the 'o' method returns Any
val x: Long = (new Obj) oo 'foo(5, "abc") // the 'oo' method casts to expected type.
If you call the oo
method and do not give the type
inferencer enough help, it will most
likely infer Nothing, which will
result in a ClassCastException.
Author Paul Phillips
The instanciation part could use the Manifest: see this SO answer
experimental feature in Scala called manifests which are a way to get around a Java constraint regarding type erasure
class Test[T](implicit m : Manifest[T]) {
val testVal = m.erasure.newInstance().asInstanceOf[T]
}
With this version you still write
class Foo
val t = new Test[Foo]
However, if there's no no-arg constructor available you get a runtime exception instead of a static type error
scala> new Test[Set[String]]
java.lang.InstantiationException: scala.collection.immutable.Set
at java.lang.Class.newInstance0(Class.java:340)
So the true type safe solution would be using a Factory.
Note: as stated in this thread, Manifest is here to stay, but is for now "only use is to give access to the erasure of the type as a Class instance."
The only thing manifests give you now is the erasure of the static type of a parameter at the call site (contrary to getClass which give you the erasure of the dynamic type).
You can then get a method through reflection:
classOf[ClassName].getMethod("main", classOf[Array[String]])
and invoke it
scala> class A {
| def foo_=(foo: Boolean) = "bar"
| }
defined class A
scala>val a = new A
a: A = A#1f854bd
scala>a.getClass.getMethod(decode("foo_="),
classOf[Boolean]).invoke(a, java.lang.Boolean.TRUE)
res15: java.lang.Object = bar
In case you need to invoke a method of a Scala 2.10 object (not class) and you have the names of the method and object as Strings, you can do it like this:
package com.example.mytest
import scala.reflect.runtime.universe
class MyTest
object MyTest {
def target(i: Int) = println(i)
def invoker(objectName: String, methodName: String, arg: Any) = {
val runtimeMirror = universe.runtimeMirror(getClass.getClassLoader)
val moduleSymbol = runtimeMirror.moduleSymbol(
Class.forName(objectName))
val targetMethod = moduleSymbol.typeSignature
.members
.filter(x => x.isMethod && x.name.toString == methodName)
.head
.asMethod
runtimeMirror.reflect(runtimeMirror.reflectModule(moduleSymbol).instance)
.reflectMethod(targetMethod)(arg)
}
def main(args: Array[String]): Unit = {
invoker("com.example.mytest.MyTest$", "target", 5)
}
}
This prints 5 to standard output.
Further details in Scala Documentation.
Working up from #nedim's answer, here is a basis for a full answer,
main difference being here below we instantiate naive classes. This code does not handle the case of multiple constructors, and is by no means a full answer.
import scala.reflect.runtime.universe
case class Case(foo: Int) {
println("Case Case Instantiated")
}
class Class {
println("Class Instantiated")
}
object Inst {
def apply(className: String, arg: Any) = {
val runtimeMirror: universe.Mirror = universe.runtimeMirror(getClass.getClassLoader)
val classSymbol: universe.ClassSymbol = runtimeMirror.classSymbol(Class.forName(className))
val classMirror: universe.ClassMirror = runtimeMirror.reflectClass(classSymbol)
if (classSymbol.companion.toString() == "<none>") // TODO: use nicer method "hiding" in the api?
{
println(s"Info: $className has no companion object")
val constructors = classSymbol.typeSignature.members.filter(_.isConstructor).toList
if (constructors.length > 1) {
println(s"Info: $className has several constructors")
}
else {
val constructorMirror = classMirror.reflectConstructor(constructors.head.asMethod) // we can reuse it
constructorMirror()
}
}
else
{
val companionSymbol = classSymbol.companion
println(s"Info: $className has companion object $companionSymbol")
// TBD
}
}
}
object app extends App {
val c = Inst("Class", "")
val cc = Inst("Case", "")
}
Here is a build.sbt that would compile it:
lazy val reflection = (project in file("."))
.settings(
scalaVersion := "2.11.7",
libraryDependencies ++= Seq(
"org.scala-lang" % "scala-compiler" % scalaVersion.value % "provided",
"org.scala-lang" % "scala-library" % scalaVersion.value % "provided"
)
)

Is it possible to define a generic type Vector in Actionsctipt 3?

Hi i need to make a VectorIterator, so i need to accept a Vector with any type. I am currently trying to define the type as * like so:
var collection:Vector.<*> = new Vector<*>()
But the compiler is complaining that the type "is not a compile time constant". i know a bug exists with the Vector class where the error reporting, reports the wrong type as missing, for example:
var collection:Vector.<Sprite> = new Vector.<Sprite>()
if Sprite was not imported, the compiler would complain that it cannot find the Vector class. I wonder if this is related?
So it looks like the answer is there is no way to implicitly cast a Vector of a type to valid super type. It must be performed explicitly with the global Vector.<> function.
So my actual problem was a mix of problems :)
It is correct to use Vector. as a generic reference to another Vector, but, it cannot be performed like this:
var spriteList:Vector.<Sprite> = new Vector.<Sprite>()
var genericList:Vector.<Object> = new Vector.<Object>()
genericList = spriteList // this will cause a type casting error
The assignment should be performed using the global Vector() function/cast like so:
var spriteList:Vector.<Sprite> = new Vector.<Sprite>()
var genericList:Vector.<Object> = new Vector.<Object>()
genericList = Vector.<Object>(spriteList)
It was a simple case of me not reading the documentation.
Below is some test code, I would expect the Vector. to cast implicitly to Vector.<*>.
public class VectorTest extends Sprite
{
public function VectorTest()
{
// works, due to <*> being strictly the same type as the collection in VectorContainer
var collection:Vector.<*> = new Vector.<String>()
// compiler complains about implicit conversion of <String> to <*>
var collection:Vector.<String> = new Vector.<String>()
collection.push("One")
collection.push("Two")
collection.push("Three")
for each (var eachNumber:String in collection)
{
trace("eachNumber: " + eachNumber)
}
var vectorContainer:VectorContainer = new VectorContainer(collection)
while(vectorContainer.hasNext())
{
trace(vectorContainer.next)
}
}
}
public class VectorContainer
{
private var _collection:Vector.<*>
private var _index:int = 0
public function VectorContainer(collection:Vector.<*>)
{
_collection = collection
}
public function hasNext():Boolean
{
return _index < _collection.length
}
public function get next():*
{
return _collection[_index++]
}
}
[Bindable]
public var selectedItems:Vector.<Category>;
public function selectionChange(items:Vector.<Object>):void
{
selectedItems = Vector.<Category>(items);
}
I believe you can refer to an untyped Vector by just calling it Vector (no .<>)
With Apache Flex 4.11.0, you can already do what you want. It might have been there since 4.9.0, but I have not tried that before.
var collection:Vector.<Object> = new Vector.<Object>()
maybe?
But i'm just speculating, haven't tried it.
var collection:Vector.<Object> = new Vector.<Object>()
but only on targeting flash player 10 cs4

Resources