sfxcode / sapphire-core

Scala - JavaFX Application Framework (CDI, Binding, Expressions)
https://sfxcode.github.io/sapphire-javafx
Apache License 2.0
8 stars 1 forks source link

How to use this alongside @sfxml macro? #20

Closed rohan-sircar closed 4 years ago

rohan-sircar commented 4 years ago

Hi, I found this framework yesterday and I really like it. But is there a way to make it work with the @sfxml macro? If I annotate a ViewController with sfxml, I can no longer do getController[className]() on it.

The only place I could find sfxml used in this project is this - https://github.com/sfxcode/sapphire-core/issues/2

Thanks for your help

sfxcode commented 4 years ago

Good morning nova999, before i removed the direct dependency of scalafx in sapphire-core there was some experimental support of using sfxml. It was possible to integrate, but there were a lot of problems working with it. Code completion for properties in the IDE was gone, the code was harder to read and as main point sfxml had to little advantages. scalafx can operate without any boilerplate code because of implicit conversion from javafx to scalafx. Also using scala 2.13 and and Java 11+ makes the advantages of scalafx a little bit smaller. imho there is no really need of using sfxml. Have a nice coding time,

Tom

sfxcode commented 4 years ago

There will be no sfxml support in sapphire-core, because of the reasons above and the missing scalafx dependency.

rohan-sircar commented 4 years ago

Good morning and thanks for the quick response :)

I could see two reasons for using sfxml, one was that it allowed using scalafx.controls in the code, but that's overcome by using the implicit conversions as you said. But more importantly, it allowed settings the fx fields to be set as val's instead var's.

But of course, if it caused so much trouble as you said, then it probably isn't worth it and the fields could be set to private to prevent mutable access from outside.

Could you elaborate a bit on how using scala 2.13 and java 11 reduces the advantages of scalafx?

Thanks nova

sfxcode commented 4 years ago

Hi Nova,

Since Scala 2.13 scala-java8-compat is part of the standard library . Because of that java function syntax is more easy to write. Before Scala 2.12 scalafx was needed to write readable code for writing change listener and other functions with closures. In Scala 2.12 / 2.13 you can write readable listener as well, because of better java lambda support. Dont get me wrong, i like scalafx very much and use it in many projects. But also without usage of scalafx you can write very clean and readable code since scala 2.12 / 2.13. This was the reason i dropped direct dependency of scalafx in the sapphire-modules. On the framework level there was no direct need anymore. However, on Application level it will be a very helpful choice. All above is also true for Java 8 and Scala 2.12, but I prefer Java 11+ because it is no more bundled with JRE and it is easy to include as sbt dependency.

Greetings, Tom

rohan-sircar commented 4 years ago

Thanks for the explanation, Tom. I had a great time making a project with your framework.

sfxcode commented 4 years ago

Thx, glad to hear. This is the reason why i spend my time with OSS. And because i use my frameworks in my own projects. Actually i am working on a PDF report engine integration for FXBean (jasperreports) in sapphire extensions. Maybe this can be also be useful for you.

Have a nice coding time,

Tom

rohan-sircar commented 4 years ago

Your efforts are well appreciated. As of now, sapphire is the only javafx framework for scala it seems.

A PDF engine sounds nice, I would love to try it out but unfortunately, sapphire extensions does not seem to have much in the way of documentation/examples so I couldn't try it.

I had a few more questions and suggestions. Should I ask them here or should I create a new issue?

Also please feel free to check out my (small) project I made with sapphire, if you like here

sfxcode commented 4 years ago

Hi, the sapphire extension documentation is far behind functionality, I know ... I tried to explain as much as possible in the bundled showcase app. I added some sample code for using jasper reports in the PersonController and released 1.0.10 version. Please feel free to create new issues if there are problems or suggestions. Please use sapphire-extensions Issues for PDF specific issues. I created sapphire-extensions for faster development of complex JaxaFX Apps build with sapphire-core and i like to share my code for new users. Extensions should provide some solutions for standard application problems.

Hopefully I can manage to update the documentation soon ... (Documentation, UnitTests, ... require some extra time ;-)) I checked out your project, updated some of your dependencies and managed to start your application. Very nice work !

If you have some questions in general, it is no problem to answer in this thread.

Have a nice coding time,

Tom

rohan-sircar commented 4 years ago

Great, I'll check it out as soon as I can. I understand that documentation takes time. Thanks for your words of encouragement :)

I wanted to ask if there was any reason deltaspike was picked over say guice because deltaspike has quite a heavy startup time cost and low adoption among scala ecosystem.

Secondly, is there a tutorial for getting scala javafx working with dcevm/hot reloading? Because I could not get plain dcevm to work(it kept throwing random exceptions) and intellij debugger only supports reloading the most trivial changes.

sfxcode commented 4 years ago

Hi, deltaspike aka CDI Integration was more a proof of concept. It is indeed not being useful in many cases. I decided to remove CDI as core feature in the new 2.0.0 Version. Like ScalaFX you can use it by your own, if it make sende.

See https://github.com/sfxcode/sapphire-core/projects/1. and the new [2.0.0 Branch.] (https://github.com/sfxcode/sapphire-core/tree/2.0.0).

DCEVM Question:

Dcevm-11 on Trava OpenJDK works absolutly fine for me. I use it also at work for JSF & Play Applications at work and there are no problems most of the time. I use the DCEVM JDK in IntelliJ as default JDK without any problems. Maybe some of your dependencies prevent the usage. Check out Sapphire Core and try the examples with this setup. If that works, your problem will be in your actual project.

Greetings,

Tom

rohan-sircar commented 4 years ago

Hi, removing CDI from core would be a good idea, but Scala companion objects won't be a proper replacement for CDI because they cannot be used as constructor parameters. In my brief time of programming I have come to learn that constructor injection is a very good practice. Since FXML controllers are initialized using reflection, having a DI framework to inject dependencies like a REST client or DB connection is required if you want them as constructor arguments. I've used this technique myself in my project. Although it's been a while since I loaded fxml and controllers manually so I don't remember if it's possible pass constructor arguments to fxml controllers at initialization.

Thus removing Deltaspike from core and introducing a light weight DI framework like Guice as an optional component to the core would be a good idea I feel.

Yes, I used the Trava distribution of DCEVM as well. I will check again with sapphire projects.

I was also wondering what's a good way to manage application state in JavaFX. Web development frameworks are usually paired with concrete state management solutions like React and Redux. In my project I used an application scoped bean class but it had two problems -

  1. Synchronization between multiple thread accesses
  2. State was globally mutable and no safeguard in place to prevent accidental mutation

I was thinking of using read only observables to expose private mutable state, and using an Akka Actor to synchronize global mutable state.

I've been experimenting with Actors running on FX application thread, compile time DI and stuff here. Please let me know what you think.

sfxcode commented 4 years ago

Hi Rohan,

in case of sapphire-core scala objects replace CDIApplication Scoped Beans, that were only used because there was a CDI System available. In this cases no special CDI functionality was really needed.

Removing CDI makes this framework simpler to use, faster, ... in 90 % of all cases.

If the user decide to inject variables with Guice, MacWire, Dagger ... it can easily be done. I decided to make this framework to solve common problems (Value Bindings, Controller compositon, u.s.w) as simple as possible.

I like your aproach in your project, but to be honest, FP with Monix, Cats, ZIO etc. make things for UI Applications not easier by default. It is always no problem to build more complexity on top of any framework. I use FP in different kind of applications, but for most of my personal GUI applications it is simply not needed.

Common user problems are creating some UI (with an editor), bind database values to tables and editors, do some actions on button click, export some stuff and so on with as little code as possible in an easy way. That is the goal of this project and i hope it will be helpful for some people. I made a Framework for easy MongoDB handling (simple-mongo) for the same reasons. ScalaFX goes the same way, it wraps java components for easy integration in JavaFX applications with scala, nothing more or less. Low coolness factor but very good for productivity.

State handling can be a problem, but JavaFX with Property Bindings reflects changes in the UI very well. In database (SQL. NoSQL) driven applications the state is reflected in the database. I made some experiments with AKKA in different threads in sapphire-extensions, i think thread synchronzation can be solved.

Maybe you have some ideas for adding functionality in sapphire-extension, ideas, code or merge requests will be highly appreciated.

Have a nice coding day,

Tom

rohan-sircar commented 4 years ago

Hi Tom

Thanks for your explanation of the project's aim. It explains the features and design of the framework and I agree with everything you have said. It is true that functional programming to that degree is overkill for the use cases that you mentioned. I just did that project as an experiment, and because it's fun.

By state management I was referring to state synchronization between components/controllers and threads rather than synchronization with the UI(javafx observables take care of this well enough) but again, for simple projects it's not going to matter.

If I have any ideas that I think could be added to sapphire, I will definitely share them with you.

Regards Rohan