GithubHelp home page GithubHelp logo

fn-fx / fn-fx Goto Github PK

View Code? Open in Web Editor NEW
386.0 25.0 33.0 418 KB

A Functional API around JavaFX / OpenJFX.

License: Eclipse Public License 1.0

Clojure 100.00%
javafx clojure gui dom openjfx gui-programming

fn-fx's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fn-fx's Issues

example application exit automatically

I run examples/other_examples/todo.clj with lein run on mac os sierra, when the window lose focus, the program will exit automatically with no error output.

Exception on Reflection while running examples

Apparently needs some updates. Checked the deps and fiddled with lein a bit, but can't even get the examples to run.

fn-fx$ java -version
java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)
fn-fx$ clj examples/getting_started/01_hello_word.clj 
Exception in thread "main" java.lang.ClassNotFoundException: org.reflections.Reflections, compiling:(fn_fx/util/reflect_utils.clj:1:1)
	at clojure.lang.Compiler.load(Compiler.java:7526)
	at clojure.lang.RT.loadResourceScript(RT.java:379)
	at clojure.lang.RT.loadResourceScript(RT.java:370)
	at clojure.lang.RT.load(RT.java:460)
	at clojure.lang.RT.load(RT.java:426)
	at clojure.core$load$fn__6548.invoke(core.clj:6046)
	at clojure.core$load.invokeStatic(core.clj:6045)
	at clojure.core$load.doInvoke(core.clj:6029)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.core$load_one.invokeStatic(core.clj:5848)
	at clojure.core$load_one.invoke(core.clj:5843)
	at clojure.core$load_lib$fn__6493.invoke(core.clj:5888)
	at clojure.core$load_lib.invokeStatic(core.clj:5887)
	at clojure.core$load_lib.doInvoke(core.clj:5868)
	at clojure.lang.RestFn.applyTo(RestFn.java:142)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$load_libs.invokeStatic(core.clj:5925)
	at clojure.core$load_libs.doInvoke(core.clj:5909)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$require.invokeStatic(core.clj:5947)
	at clojure.core$require.doInvoke(core.clj:5947)
	at clojure.lang.RestFn.invoke(RestFn.java:482)
	at fn_fx.render_core$eval159$loading__6434__auto____160.invoke(render_core.clj:1)
	at fn_fx.render_core$eval159.invokeStatic(render_core.clj:1)
	at fn_fx.render_core$eval159.invoke(render_core.clj:1)
	at clojure.lang.Compiler.eval(Compiler.java:7062)
	at clojure.lang.Compiler.eval(Compiler.java:7051)
	at clojure.lang.Compiler.load(Compiler.java:7514)
	at clojure.lang.RT.loadResourceScript(RT.java:379)
	at clojure.lang.RT.loadResourceScript(RT.java:370)
	at clojure.lang.RT.load(RT.java:460)
	at clojure.lang.RT.load(RT.java:426)
	at clojure.core$load$fn__6548.invoke(core.clj:6046)
	at clojure.core$load.invokeStatic(core.clj:6045)
	at clojure.core$load.doInvoke(core.clj:6029)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.core$load_one.invokeStatic(core.clj:5848)
	at clojure.core$load_one.invoke(core.clj:5843)
	at clojure.core$load_lib$fn__6493.invoke(core.clj:5888)
	at clojure.core$load_lib.invokeStatic(core.clj:5887)
	at clojure.core$load_lib.doInvoke(core.clj:5868)
	at clojure.lang.RestFn.applyTo(RestFn.java:142)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$load_libs.invokeStatic(core.clj:5925)
	at clojure.core$load_libs.doInvoke(core.clj:5909)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$require.invokeStatic(core.clj:5947)
	at clojure.core$require.doInvoke(core.clj:5947)
	at clojure.lang.RestFn.invoke(RestFn.java:436)
	at fn_fx.fx_dom$eval153$loading__6434__auto____154.invoke(fx_dom.clj:1)
	at fn_fx.fx_dom$eval153.invokeStatic(fx_dom.clj:1)
	at fn_fx.fx_dom$eval153.invoke(fx_dom.clj:1)
	at clojure.lang.Compiler.eval(Compiler.java:7062)
	at clojure.lang.Compiler.eval(Compiler.java:7051)
	at clojure.lang.Compiler.load(Compiler.java:7514)
	at clojure.lang.RT.loadResourceScript(RT.java:379)
	at clojure.lang.RT.loadResourceScript(RT.java:370)
	at clojure.lang.RT.load(RT.java:460)
	at clojure.lang.RT.load(RT.java:426)
	at clojure.core$load$fn__6548.invoke(core.clj:6046)
	at clojure.core$load.invokeStatic(core.clj:6045)
	at clojure.core$load.doInvoke(core.clj:6029)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.core$load_one.invokeStatic(core.clj:5848)
	at clojure.core$load_one.invoke(core.clj:5843)
	at clojure.core$load_lib$fn__6493.invoke(core.clj:5888)
	at clojure.core$load_lib.invokeStatic(core.clj:5887)
	at clojure.core$load_lib.doInvoke(core.clj:5868)
	at clojure.lang.RestFn.applyTo(RestFn.java:142)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$load_libs.invokeStatic(core.clj:5925)
	at clojure.core$load_libs.doInvoke(core.clj:5909)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$require.invokeStatic(core.clj:5947)
	at clojure.core$require.doInvoke(core.clj:5947)
	at clojure.lang.RestFn.invoke(RestFn.java:436)
	at getting_started.01_hello_word$eval147$loading__6434__auto____148.invoke(01_hello_word.clj:1)
	at getting_started.01_hello_word$eval147.invokeStatic(01_hello_word.clj:1)
	at getting_started.01_hello_word$eval147.invoke(01_hello_word.clj:1)
	at clojure.lang.Compiler.eval(Compiler.java:7062)
	at clojure.lang.Compiler.eval(Compiler.java:7051)
	at clojure.lang.Compiler.load(Compiler.java:7514)
	at clojure.lang.Compiler.loadFile(Compiler.java:7452)
	at clojure.main$load_script.invokeStatic(main.clj:278)
	at clojure.main$script_opt.invokeStatic(main.clj:338)
	at clojure.main$script_opt.invoke(main.clj:333)
	at clojure.main$main.invokeStatic(main.clj:424)
	at clojure.main$main.doInvoke(main.clj:387)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.lang.Var.applyTo(Var.java:702)
	at clojure.main.main(main.java:37)
Caused by: java.lang.ClassNotFoundException: org.reflections.Reflections
	at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
	at clojure.lang.DynamicClassLoader.findClass(DynamicClassLoader.java:69)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at clojure.lang.DynamicClassLoader.loadClass(DynamicClassLoader.java:77)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:348)
	at clojure.lang.RT.classForName(RT.java:2204)
	at clojure.lang.RT.classForNameNonLoading(RT.java:2217)
	at fn_fx.util.reflect_utils$eval629$loading__6434__auto____630.invoke(reflect_utils.clj:1)
	at fn_fx.util.reflect_utils$eval629.invokeStatic(reflect_utils.clj:1)
	at fn_fx.util.reflect_utils$eval629.invoke(reflect_utils.clj:1)
	at clojure.lang.Compiler.eval(Compiler.java:7062)
	at clojure.lang.Compiler.eval(Compiler.java:7051)
	at clojure.lang.Compiler.load(Compiler.java:7514)
	... 93 more

Bug with KeyFrame constructors

The constructors of KeyFrame are not being initialized correctly and we just get the default/empty constructor. It should actually have multiple constructor values (:time and :on-finished) https://docs.oracle.com/javase/8/javafx/api/javafx/animation/KeyFrame.html

I've narrowed down the issue a bit. Comparing something that works

 (fn-fx.util.reflect-utils/get-value-ctors javafx.scene.image.Image) 

output:

({:method #object[java.lang.reflect.Method 0x8876855 "public static javafx.scene.image.Image javafx.scene.image.Image.impl_fromPlatformImage(java.lang.Object)"], :is-ctor? false, :method-name impl_fromPlatformImage, :prop-names (image), :prop-types [java.lang.Object], :prop-names-kw [:image], :prop-names-sym [image]} {:method #object[java.lang.reflect.Constructor 0x49507ef5 "public javafx.scene.image.Image(java.io.InputStream,double,double,boolean,boolean)"], :is-ctor? true, :method-name javafx.scene.image.Image, :prop-names (is requestedWidth requestedHeight preserveRatio smooth), :prop-types [java.io.InputStream double double boolean boolean], :prop-names-kw [:is :requested-width :requested-height :preserve-ratio :smooth], :prop-names-sym [is requested-width requested-height preserve-ratio smooth]} {:method #object[java.lang.reflect.Constructor 0x70df4b07 "public javafx.scene.image.Image(java.io.InputStream)"], :is-ctor? true, :method-name javafx.scene.image.Image, :prop-names (is), :prop-types [java.io.InputStream], :prop-names-kw [:is], :prop-names-sym [is]} {:method #object[java.lang.reflect.Constructor 0x18cdfc45 "public javafx.scene.image.Image(java.lang.String)"], :is-ctor? true, :method-name javafx.scene.image.Image, :prop-names (url), :prop-types [java.lang.String], :prop-names-kw [:url], :prop-names-sym [url]} {:method #object[java.lang.reflect.Constructor 0x2b3bfac9 "public javafx.scene.image.Image(java.lang.String,double,double,boolean,boolean)"], :is-ctor? true, :method-name javafx.scene.image.Image, :prop-names (url requestedWidth requestedHeight preserveRatio smooth), :prop-types [java.lang.String double double boolean boolean], :prop-names-kw [:url :requested-width :requested-height :preserve-ratio :smooth], :prop-names-sym [url requested-width requested-height preserve-ratio smooth]} {:method #object[java.lang.reflect.Constructor 0x61568e8d "public javafx.scene.image.Image(java.lang.String,boolean)"], :is-ctor? true, :method-name javafx.scene.image.Image, :prop-names (url backgroundLoading), :prop-types [java.lang.String boolean], :prop-names-kw [:url :background-loading], :prop-names-sym [url background-loading]} {:method #object[java.lang.reflect.Constructor 0x6bdb66d3 "public javafx.scene.image.Image(java.lang.String,double,double,boolean,boolean,boolean)"], :is-ctor? true, :method-name javafx.scene.image.Image, :prop-names (url requestedWidth requestedHeight preserveRatio smooth backgroundLoading), :prop-types [java.lang.String double double boolean boolean boolean], :prop-names-kw [:url :requested-width :requested-height :preserve-ratio :smooth :background-loading], :prop-names-sym [url requested-width requested-height preserve-ratio smooth background-loading]})

To KeyFrame which is broken

(fn-fx.util.reflect-utils/get-value-ctors javafx.animation.KeyFrame) 

output:

({:method #object[java.lang.reflect.Constructor 0x28f769b2 "public javafx.animation.KeyFrame(javafx.util.Duration,javafx.event.EventHandler,javafx.animation.KeyValue[])"], :is-ctor? true, :method-name javafx.animation.KeyFrame, :prop-names (), :prop-types [javafx.util.Duration javafx.event.EventHandler [Ljavafx.animation.KeyValue;], :prop-names-kw [], :prop-names-sym []} {:method #object[java.lang.reflect.Constructor 0x64f9ddf1 "public javafx.animation.KeyFrame(javafx.util.Duration,java.lang.String,javafx.animation.KeyValue[])"], :is-ctor? true, :method-name javafx.animation.KeyFrame, :prop-names (), :prop-types [javafx.util.Duration java.lang.String [Ljavafx.animation.KeyValue;], :prop-names-kw [], :prop-names-sym []} {:method #object[java.lang.reflect.Constructor 0x5002e3ee "public javafx.animation.KeyFrame(javafx.util.Duration,javafx.animation.KeyValue[])"], :is-ctor? true, :method-name javafx.animation.KeyFrame, :prop-names (), :prop-types [javafx.util.Duration [Ljavafx.animation.KeyValue;], :prop-names-kw [], :prop-names-sym []} {:method #object[java.lang.reflect.Constructor 0x35c9f65a "public javafx.animation.KeyFrame(javafx.util.Duration,java.lang.String,javafx.event.EventHandler,javafx.animation.KeyValue[])"], :is-ctor? true, :method-name javafx.animation.KeyFrame, :prop-names (), :prop-types [javafx.util.Duration java.lang.String javafx.event.EventHandler [Ljavafx.animation.KeyValue;], :prop-names-kw [], :prop-names-sym []} {:method #object[java.lang.reflect.Constructor 0x26e0a3a8 "public javafx.animation.KeyFrame(javafx.util.Duration,java.lang.String,javafx.event.EventHandler,java.util.Collection)"], :is-ctor? true, :method-name javafx.animation.KeyFrame, :prop-names (), :prop-types [javafx.util.Duration java.lang.String javafx.event.EventHandler java.util.Collection], :prop-names-kw [], :prop-names-sym []})

It's really hard to see with GitHub's formatting, but there a semi-colon ";" that shows up near the beginning of the KeyFrame output It's very bizarre and makes most of the output effectively commented out.

Running:

(:method (first (fn-fx.util.reflect-utils/get-ctors javafx.animation.KeyFrame)))

Does give us something where we can see the constructor arguments are there

#object[java.lang.reflect.Constructor 0x67dc18da "public javafx.animation.KeyFrame(javafx.util.Duration,javafx.event.EventHandler,javafx.animation.KeyValue[])"]

Past that, I'm not sure. Something is not quite parsing in the values correctly. I haven't been able to figure out the rest of the internals of get-value-ctors b/c the code is a bit beyond me. Any help would be greatly appreciated

Support for WebView

Feature Request

fn-fx should support javafx.scene.web.WebView

Description of Problem:

With a WebView one needs to call .getEngine().load() or .getEngine().loadContent() to do something meaningfull. The problem is that the underlying WebEngine is not accessible via a property in JavaFX, but more importantly .load() and .loadContent() are actions that should happen on an event, and can't be called on each render cycle like the properties.

Potential Solutions:

Ideally the fn-fx's API should support this use case directly. As an alternative solution, fn-fx could have a standard way to access the underlying Java FX objects so that use cases like this are possible.

How to get pixelwriter from controls/canvas

I want to get the instance of PixelWriter because I want to draw images.
So , I need this function ...

PixelWriter writer = canvas.getGraphicsContext2D().getPixelWriter()

But I don't know how to do it in this api.
I think ...

(defui Image 
   (render [this]
        (controls/canvas
           (**something, but I cannot find solution**))))

So, can you give me some example?

using alternate hiccup syntax for defining dom

@halgari, @pmonks, @roti: I've been staring at the fn-fx.diff/defui code for the longest time and I can't quite figure out what it is doing.

I started on a simplified non-react wrapper for javafx that enables property bindings instead of a virtual dom. It's okay and found that I like the syntax but the app does becomes harder to control the bigger it gets.

So I'm looking deeper into fn-fx. However, I built the javafx wrapper to compile hiccup syntax and I quite like it:

(defn application [state]
  (let [output-img (derived-output state)]
    (fx/ui [:stage {:title (fx/get state [:window :title] str)
                    :width (fx/set state [:window :width])}
            [:scene
             [:border-pane
              {:bottom  [:label "hello"]
               :center  [:border-pane
                                {:center  [:anchor-pane
                                                  [:image-view
                                                   {:fit-width (fx/get state [:window :width] #(- % 300))
                                                    :preserve-ratio true
                                                    :image (fx/get output-img [])}]])}]
               :right  (cp/control-pane state)}]]]))

What I'm looking to do is to modify fn-fx slightly to get this type of syntax and I'm wondering how best to go about it.

Not being able to compile fn-fx

Maybe there is something wrong with my system by I'm not being able to use 0.2.0 or 0.3.0-SNAPSHOT.

Current system:

Leiningen 2.7.1 on Java 1.8.0_11 Java HotSpot(TM) 64-Bit Server VM

The first problem I was facing was compiling fn-fx.util.reflect-utils
Trying to def all-javafx-types it complains in the first line that it can't initialize javafx.stage.Screen in current thread, only in event thread.

To avoid initializing that class I changed

#(Class/forName %)

to

#(Class/forName % false (.getContextClassLoader (Thread/currentThread)))

so it doesn't try to initialize the class now, just loads it.

Now that part works but I get

Error compiling fn_fx/controls.clj at (27:3)
Caused by java.lang.ClassNotFoundException
   javafx.util.converter.LocalDateTimeStringConverter

Any ideas of what I'm doing wrong?

Add documentation for ui/file-chooser

Howdy, I am trying to use the ui/file-chooser macro, but I don't really know what parameters to give it since there is no documentation. Can you provide an example?

Using stylesheets

How can I add my to my scene? In Java it's done using a method, so I'm not sure how to translate that to fn-fx. Do you have an example?

Better Documentation

Right now if you call (doc fn-fx.diff/render) in a repl, you don't get any result. Many of fn-fx's functions lack usable documentation and it makes it more frustrating to program on the repl.

I understand that many of the items under fn-fx.controls can't easily have documentation, but it would be nice if other, more central functions did.

Endless changeloop for sliders

Support Question

I'm sure I'm doing something wrong, but I can't figure it out. The sliders I create get into an endless change loop if I make changes too fast. It seems like when the new value is put into the view, that triggers the handler again. How can I avoid this?

Here's what I do:

(defn- my-slider-value-changed-handler [my-app-state event-data]
  (swap! my-app-state assoc :my-slider-value (:fn-fx.listen/new event-data)))

(defui MySliderExample
  (render [this {:keys [my-slider-value] :as my-app-state}]
          [(ui/slider
            :value my-slider-value
            :listen/value {:event ::slider-value-changed})]))

FWIW, I tried rounding these values to lower the number of swaps on the atom, but that didn't have any effect.

problem with clojars package?

seems like a problem with clojars package?

my project.clj:

(defproject func "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.8.0"]
                 [fn-fx "0.1.0-SNAPSHOT"]]
  :main func.core)

my core.clj:

(ns func.core
  (:require [fn-fx.fx-dom :as dom]            
            [fn-fx.diff :refer [component defui render should-update?]]            
            [fn-fx.render :refer [ui]]))


(defn -main []  
  (let [u (ui :stage            
            :title "Hello World!"            
            :shown true            
            :scene (ui :scene                     
                     :width 300                     
                     :height 250                     
                     :root (ui :stack-pane                             
                             :children [(ui :button                                          
                                          :text "Say 'Hello World'"                                          
                                          :on-action {:say "Hello World!"})])))        
        handler-fn (fn [evt]                     
                     (println "Received Event: " evt))]    
    (dom/app u handler-fn)))

the error message:

java.io.FileNotFoundException: Could not locate fn_fx/fx_dom__init.class or fn_fx/fx_dom.clj on classpath. Please check that namespaces with dashes use underscores in the Clojure file name., compiling:(core.clj:1:1)

supporting openjfx

Openjfx is a months out and there are some significant changes:

  • Builders have been deprecated since JFX8 and are completely removed in OpenFX
  • There's a module system for JDK10+ that need some workarounds

are there plans for supporting openjfx?

nil cause for error

Been getting some errors when compiling my code with a singularly unhelpful stacktrace:

#error {
 :cause nil
 :via
 [{:type java.lang.NullPointerException
   :message nil
   :at [fn_fx.render_core$get_getter invokeStatic render_core.clj 320]}]
 :trace
 [[fn_fx.render_core$get_getter invokeStatic render_core.clj 320]
  [fn_fx.render_core$get_getter invoke render_core.clj 313]
  [fn_fx.render_core$get_property invokeStatic render_core.clj 104]
  [fn_fx.render_core$get_property invoke render_core.clj 103]
  [fn_fx.fx_dom.FXDom$fn__18478 invoke fx_dom.clj 32]
  [clojure.lang.AFn run AFn.java 22]
  [com.sun.javafx.application.PlatformImpl lambda$null$173 PlatformImpl.java 295]
  [java.security.AccessController doPrivileged AccessController.java -2]
  [com.sun.javafx.application.PlatformImpl lambda$runLater$174 PlatformImpl.java 294]
  [com.sun.glass.ui.InvokeLaterDispatcher$Future run InvokeLaterDispatcher.java 95]
  [com.sun.glass.ui.gtk.GtkApplication _runLoop GtkApplication.java -2]
  [com.sun.glass.ui.gtk.GtkApplication lambda$null$49 GtkApplication.java 139]
  [java.lang.Thread run Thread.java 745
]]}

The errors are most likely my fault, but a better error message (so I could find out what my mistake was), would be great.

Auto generate and deploy API docs from master

As a prelude to addressing issues #21, #26, #27, and #28, it would be great to autogenerate API docs from the master branch, and publish them on GitHub pages.

Even though those API docs will likely be *cough* "rough" to begin with, by airing our dirty laundry we create pressure on ourselves to fix the docstrings in the codebase.

UI not updating even though the model differs

Bug Report

Steps to Reproduce:

  1. Checkout https://github.com/Azzurite/fn-fx-update-bug/
  2. Run -main
  3. Click on "Goto Settings"

Expected Result:

Expect "MainPane content!" to change to "Settings content!"

Actual Result:

"MainPane content!" stays displayed

Environment:

Windows 10 x64, JDK 1.8.0_191 (also does not work under OpenJDK 11.0.1 with the other dependency)

Additional Context:

Happened in a more complex program of mine. I can get the change to work by wrapping one of the GridPanes with a StackPane, apparently that manages to "trick" the diff algorithm into thinking something actually changed.

You can see that in the example repository in the workaround branch.

I managed to trace the bug to somewhere in the diff-component fn in fn-fx.diff, but didn't manage to understand that fn.

Using mouse running other-examples.shapes-3d triggers assert

Using mouse running other-examples.shapes-3d triggers assert:

Can't convert 0 of type class java.lang.Long to int

Having this new function in render-core fixes the problem:

(defmethod convert-value
  [java.lang.Long Integer/TYPE]
  [value _]
  (int value)) 

CompilerException org.reflections.ReflectionsException: Couldn't find subtypes of Object.

CompilerException org.reflections.ReflectionsException: Couldn't find subtypes of Object.

Steps to Reproduce:

  1. Start an nREPL
  2. Navigate to exampes/getting_started/01_hello_world.clj
  3. Load the entire file

Expected Result:

Example should be running.

Actual Result:

Window opens, after that the following stacktrace:

Syntax error compiling at (reflect_utils.clj:36:32).
Couldn't find subtypes of Object. Make sure SubTypesScanner initialized to include Object class - new SubTypesScanner(false)
Oct 30, 2018 8:58:17 PM clojure.tools.logging$eval570$fn__573 invoke
SEVERE: Unhandled REPL handler exception processing message {:op stacktrace, :pprint-fn clojure.pprint/pprint, :print-length 50, :print-level 50, :session 133612c4-ddf3-449d-ba10-65f15bb837d9, :id 13}
java.lang.NullPointerException
at clojure.string$replace_first.invokeStatic(string.clj:165)
at clojure.string$replace_first.invoke(string.clj:138)
at cider.nrepl.middleware.stacktrace$relative_path.invokeStatic(stacktrace.clj:204)
at cider.nrepl.middleware.stacktrace$relative_path.invoke(stacktrace.clj:198)
at cider.nrepl.middleware.stacktrace$extract_location.invokeStatic(stacktrace.clj:219)
at cider.nrepl.middleware.stacktrace$extract_location.invoke(stacktrace.clj:206)
at clojure.core$comp$fn__5707.invoke(core.clj:2561)
at clojure.core$map$fn__5766.invoke(core.clj:2747)
at clojure.lang.LazySeq.sval(LazySeq.java:42)
at clojure.lang.LazySeq.seq(LazySeq.java:51)
at clojure.lang.RT.seq(RT.java:529)
at clojure.core$seq__5302.invokeStatic(core.clj:137)
at clojure.core$seq__5302.invoke(core.clj:137)
at cider.nrepl.middleware.stacktrace$handle_stacktrace.invokeStatic(stacktrace.clj:312)
at cider.nrepl.middleware.stacktrace$handle_stacktrace.invoke(stacktrace.clj:309)
at clojure.lang.Var.invoke(Var.java:388)
at cider.nrepl$wrap_stacktrace$fn__6591.invoke(nrepl.clj:436)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__877.invoke(middleware.clj:22)
at cider.nrepl$wrap_undef$fn__6623.invoke(nrepl.clj:495)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__877.invoke(middleware.clj:22)
at refactor_nrepl.middleware$wrap_refactor$fn__6169.invoke(middleware.clj:214)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__877.invoke(middleware.clj:22)
at cider.nrepl$wrap_classpath$fn__6475.invoke(nrepl.clj:166)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__877.invoke(middleware.clj:22)
at cider.nrepl$wrap_apropos$fn__6467.invoke(nrepl.clj:158)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__877.invoke(middleware.clj:22)
at cider.nrepl$wrap_complete$fn__6483.invoke(nrepl.clj:172)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__877.invoke(middleware.clj:22)
at cider.nrepl$wrap_version$fn__6631.invoke(nrepl.clj:503)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__877.invoke(middleware.clj:22)
at cider.nrepl$wrap_slurp$fn__6459.invoke(nrepl.clj:150)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__877.invoke(middleware.clj:22)
at cider.nrepl$wrap_trace$fn__6607.invoke(nrepl.clj:466)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__877.invoke(middleware.clj:22)
at cider.nrepl$wrap_ns$fn__6543.invoke(nrepl.clj:308)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__877.invoke(middleware.clj:22)
at cider.nrepl$wrap_info$fn__6517.invoke(nrepl.clj:236)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__877.invoke(middleware.clj:22)
at cider.nrepl$wrap_profile$fn__6559.invoke(nrepl.clj:345)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__877.invoke(middleware.clj:22)
at cider.nrepl$wrap_resource$fn__6575.invoke(nrepl.clj:408)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__877.invoke(middleware.clj:22)
at cider.nrepl$wrap_spec$fn__6583.invoke(nrepl.clj:420)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__877.invoke(middleware.clj:22)
at clojure.tools.nrepl.middleware.interruptible_eval$interruptible_eval$fn__1160.invoke(interruptible_eval.clj:247)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__877.invoke(middleware.clj:22)
at cider.nrepl$wrap_inspect$fn__6527.invoke(nrepl.clj:255)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__877.invoke(middleware.clj:22)
at cider.nrepl$wrap_debug$fn__6493.invoke(nrepl.clj:192)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__877.invoke(middleware.clj:22)
at cider.nrepl$wrap_enlighten$fn__6501.invoke(nrepl.clj:218)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__877.invoke(middleware.clj:22)
at clojure.tools.nrepl.middleware.session$add_stdin$fn__1243.invoke(session.clj:238)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__877.invoke(middleware.clj:22)
at clojure.tools.nrepl.middleware.load_file$wrap_load_file$fn__1286.invoke(load_file.clj:79)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__877.invoke(middleware.clj:22)
at cider.nrepl$wrap_content_type$fn__6451.invoke(nrepl.clj:139)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__877.invoke(middleware.clj:22)
at cider.nrepl$wrap_pprint$fn__6441.invoke(nrepl.clj:119)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__877.invoke(middleware.clj:22)
at cider.nrepl$wrap_refresh$fn__6567.invoke(nrepl.clj:382)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__877.invoke(middleware.clj:22)
at cider.nrepl$wrap_tracker$fn__6615.invoke(nrepl.clj:484)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__877.invoke(middleware.clj:22)
at clojure.tools.nrepl.middleware.pr_values$pr_values$fn__1076.invoke(pr_values.clj:22)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__877.invoke(middleware.clj:22)
at cider.nrepl$wrap_test$fn__6599.invoke(nrepl.clj:446)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__877.invoke(middleware.clj:22)
at cider.nrepl.middleware.pprint$handle_pprint_fn.invokeStatic(pprint.clj:61)
at cider.nrepl.middleware.pprint$handle_pprint_fn.invoke(pprint.clj:56)
at clojure.lang.Var.invoke(Var.java:388)
at cider.nrepl$wrap_pprint_fn$fn__6431.invoke(nrepl.clj:100)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__877.invoke(middleware.clj:22)
at cider.nrepl$wrap_out$fn__6551.invoke(nrepl.clj:336)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__877.invoke(middleware.clj:22)
at clojure.tools.nrepl.middleware.session$session$fn__1228.invoke(session.clj:192)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__877.invoke(middleware.clj:22)
at clojure.tools.nrepl.server$handle_STAR_.invokeStatic(server.clj:19)
at clojure.tools.nrepl.server$handle_STAR_.invoke(server.clj:16)
at clojure.tools.nrepl.server$handle$fn__1301.invoke(server.clj:28)
at clojure.core$binding_conveyor_fn$fn__5654.invoke(core.clj:2022)
at clojure.lang.AFn.call(AFn.java:18)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1135)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:844)

Environment:

  • Hash 6edd7a5 of the project.
  • macOS High Sierra
  • java 10 2018-03-20
    Java(TM) SE Runtime Environment 18.3 (build 10+46)
    Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10+46, mixed mode)
  • Clojure 1.9.0 (also went with a bare bone project with 1.10.0-beta2 and example 2 from getting started, same result)

Add documentation or example for combo-box

Howdy, I was trying to use the ui/combo-box macro, and I had a hell of a time since there was no documentation. I was able to figure out how to add list items by adding the :items ["my item"] thing, but I believe that that is something that should be documented, or at the very least, given an example.

I would be happy to help contribute to documentation if it would be useful.

Doesn't seem to work with Ubuntu out of the box

Bug Report

Steps to Reproduce:

On Ubuntu Cuttlefish (18.10)
Install leiningen from the repository
Install openjdk-8-jre from the repository
Try to run a fn-fx project and it will not find JavaFX

Expected Result:

Installing leiningen installs openjdk-8-jre-headless. But after installing openjdk-8-jre it should include JavaFX as I understand it.

Actual Result:

What I get instead is a crash:

Exception in thread "main" java.lang.NoClassDefFoundError: javafx/scene/Group, compiling:(asparapiss/svg2jfx.clj:16:3)
	at clojure.lang.Compiler.analyzeSeq(Compiler.java:6875)
	at clojure.lang.Compiler.analyze(Compiler.java:6669)
	at clojure.lang.Compiler.analyzeSeq(Compiler.java:6856)
	at clojure.lang.Compiler.analyze(Compiler.java:6669)
	at clojure.lang.Compiler.analyze(Compiler.java:6625)
	at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:6001)
	at clojure.lang.Compiler$FnMethod.parse(Compiler.java:5380)
[etc]

Additional Context:

I've also tried to install the openjfx package (which I think is for Java 11) as well as the openjdk-8-jdk

So I'm not sure if this is a bug or I'm missing something obvious here (like some additional package). I've had this project running before on a Debian system (using version 0.4.0), but unfortunately I don't remember how I set up then (but I remember it not being straightforward). I've lost that setup and had to switch to an Ubuntu system. When trying to get this old project running I ran into this crash. My project.clj has a

              [fn-fx/fn-fx-javafx "0.5.0-SNAPSHOT"]

I tried the old halgari 0.4.0 as well and have the same issue
And my namespace starts with a

If you point me to another fn-fx project to test I can do that as well

fn-fx doesn't work on OpenJDK 1.8

Steps to Reproduce:

  1. Install OpenJDK 1.8
  2. Run the tests (lein do version, test)

Expected Result:

Tests run, and pass (taking note of issue #45).

Actual Result:

$ lein do version, test
(Warning: profile :openjfx1.8 not found.)
Leiningen 2.8.1 on Java 1.8.0_192 OpenJDK 64-Bit Server VM
(Warning: profile :openjfx1.8 not found.)
Exception in thread "main" java.lang.ClassNotFoundException: javafx.application.Platform, compiling:(fn_fx/util.clj:1:1)
	at clojure.lang.Compiler.load(Compiler.java:7526)
	at clojure.lang.RT.loadResourceScript(RT.java:379)
	at clojure.lang.RT.loadResourceScript(RT.java:370)
	at clojure.lang.RT.load(RT.java:460)
	at clojure.lang.RT.load(RT.java:426)
	at clojure.core$load$fn__6548.invoke(core.clj:6046)
	at clojure.core$load.invokeStatic(core.clj:6045)
	at clojure.core$load.doInvoke(core.clj:6029)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.core$load_one.invokeStatic(core.clj:5848)
	at clojure.core$load_one.invoke(core.clj:5843)
	at clojure.core$load_lib$fn__6493.invoke(core.clj:5888)
	at clojure.core$load_lib.invokeStatic(core.clj:5887)
	at clojure.core$load_lib.doInvoke(core.clj:5868)
	at clojure.lang.RestFn.applyTo(RestFn.java:142)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$load_libs.invokeStatic(core.clj:5925)
	at clojure.core$load_libs.doInvoke(core.clj:5909)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$require.invokeStatic(core.clj:5947)
	at clojure.core$require.doInvoke(core.clj:5947)
	at clojure.lang.RestFn.invoke(RestFn.java:421)
	at fn_fx.diff$eval367$loading__6434__auto____368.invoke(diff.clj:1)
	at fn_fx.diff$eval367.invokeStatic(diff.clj:1)
	at fn_fx.diff$eval367.invoke(diff.clj:1)
	at clojure.lang.Compiler.eval(Compiler.java:7062)
	at clojure.lang.Compiler.eval(Compiler.java:7051)
	at clojure.lang.Compiler.load(Compiler.java:7514)
	at clojure.lang.RT.loadResourceScript(RT.java:379)
	at clojure.lang.RT.loadResourceScript(RT.java:370)
	at clojure.lang.RT.load(RT.java:460)
	at clojure.lang.RT.load(RT.java:426)
	at clojure.core$load$fn__6548.invoke(core.clj:6046)
	at clojure.core$load.invokeStatic(core.clj:6045)
	at clojure.core$load.doInvoke(core.clj:6029)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.core$load_one.invokeStatic(core.clj:5848)
	at clojure.core$load_one.invoke(core.clj:5843)
	at clojure.core$load_lib$fn__6493.invoke(core.clj:5888)
	at clojure.core$load_lib.invokeStatic(core.clj:5887)
	at clojure.core$load_lib.doInvoke(core.clj:5868)
	at clojure.lang.RestFn.applyTo(RestFn.java:142)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$load_libs.invokeStatic(core.clj:5925)
	at clojure.core$load_libs.doInvoke(core.clj:5909)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$require.invokeStatic(core.clj:5947)
	at clojure.core$require.doInvoke(core.clj:5947)
	at clojure.lang.RestFn.invoke(RestFn.java:421)
	at fn_fx.diff_test$eval361$loading__6434__auto____362.invoke(diff_test.clj:1)
	at fn_fx.diff_test$eval361.invokeStatic(diff_test.clj:1)
	at fn_fx.diff_test$eval361.invoke(diff_test.clj:1)
	at clojure.lang.Compiler.eval(Compiler.java:7062)
	at clojure.lang.Compiler.eval(Compiler.java:7051)
	at clojure.lang.Compiler.load(Compiler.java:7514)
	at clojure.lang.RT.loadResourceScript(RT.java:379)
	at clojure.lang.RT.loadResourceScript(RT.java:370)
	at clojure.lang.RT.load(RT.java:460)
	at clojure.lang.RT.load(RT.java:426)
	at clojure.core$load$fn__6548.invoke(core.clj:6046)
	at clojure.core$load.invokeStatic(core.clj:6045)
	at clojure.core$load.doInvoke(core.clj:6029)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.core$load_one.invokeStatic(core.clj:5848)
	at clojure.core$load_one.invoke(core.clj:5843)
	at clojure.core$load_lib$fn__6493.invoke(core.clj:5888)
	at clojure.core$load_lib.invokeStatic(core.clj:5887)
	at clojure.core$load_lib.doInvoke(core.clj:5868)
	at clojure.lang.RestFn.applyTo(RestFn.java:142)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$load_libs.invokeStatic(core.clj:5925)
	at clojure.core$load_libs.doInvoke(core.clj:5909)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$require.invokeStatic(core.clj:5947)
	at clojure.core$require.doInvoke(core.clj:5947)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.core$apply.invokeStatic(core.clj:659)
	at clojure.core$apply.invoke(core.clj:652)
	at user$eval233.invokeStatic(form-init3481129458187765184.clj:1)
	at user$eval233.invoke(form-init3481129458187765184.clj:1)
	at clojure.lang.Compiler.eval(Compiler.java:7062)
	at clojure.lang.Compiler.eval(Compiler.java:7052)
	at clojure.lang.Compiler.load(Compiler.java:7514)
	at clojure.lang.Compiler.loadFile(Compiler.java:7452)
	at clojure.main$load_script.invokeStatic(main.clj:278)
	at clojure.main$init_opt.invokeStatic(main.clj:280)
	at clojure.main$init_opt.invoke(main.clj:280)
	at clojure.main$initialize.invokeStatic(main.clj:311)
	at clojure.main$null_opt.invokeStatic(main.clj:345)
	at clojure.main$null_opt.invoke(main.clj:342)
	at clojure.main$main.invokeStatic(main.clj:424)
	at clojure.main$main.doInvoke(main.clj:387)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.lang.Var.applyTo(Var.java:702)
	at clojure.main.main(main.java:37)
Caused by: java.lang.ClassNotFoundException: javafx.application.Platform
	at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
	at clojure.lang.DynamicClassLoader.findClass(DynamicClassLoader.java:69)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at clojure.lang.DynamicClassLoader.loadClass(DynamicClassLoader.java:77)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:348)
	at clojure.lang.RT.classForName(RT.java:2204)
	at clojure.lang.RT.classForNameNonLoading(RT.java:2217)
	at fn_fx.util$eval427$loading__6434__auto____428.invoke(util.clj:1)
	at fn_fx.util$eval427.invokeStatic(util.clj:1)
	at fn_fx.util$eval427.invoke(util.clj:1)
	at clojure.lang.Compiler.eval(Compiler.java:7062)
	at clojure.lang.Compiler.eval(Compiler.java:7051)
	at clojure.lang.Compiler.load(Compiler.java:7514)
	... 97 more
Tests failed.

Non-deterministic unit test failure

When running the tests locally on JDK 8 (i.e. with bundled JavaFX), I periodically see the following error, and a similar error has shown up on TravisCI too.

I don't seem to have the same issue on JDK 11 / OpenJFX 11, though it has occurred on TravisCI with that version combo.

I haven't discovered a pattern to its occurrence - often just rerunning the tests will succeed (both locally and on TravisCI). This is especially puzzling on TravisCI, since the container the tests run in there is thrown away between every single test run, significantly reducing the possibility that some kind of state is being preserved between successive runs of the tests.

$ lein do clean, version, test, jar
Leiningen 2.8.1 on Java 1.8.0_192 Java HotSpot(TM) 64-Bit Server VM

lein test fn-fx.diff-test

lein test fn-fx.fx-dom-test

lein test :only fn-fx.fx-dom-test/static-member-tests

ERROR in (static-member-tests) (fx_dom_test.clj:10)
Uncaught exception, not in assertion.
expected: nil
  actual: java.lang.AssertionError: Assert failed: comp
 at fn_fx.fx_dom_test$get_prop.invokeStatic (fx_dom_test.clj:10)
    fn_fx.fx_dom_test$get_prop.invoke (fx_dom_test.clj:10)
    fn_fx.fx_dom_test$fn__4061.invokeStatic (fx_dom_test.clj:116)
    fn_fx.fx_dom_test/fn (fx_dom_test.clj:99)
    clojure.test$test_var$fn__9209.invoke (test.clj:716)
    clojure.test$test_var.invokeStatic (test.clj:716)
    clojure.test$test_var.invoke (test.clj:707)
    clojure.test$test_vars$fn__9235$fn__9240.invoke (test.clj:734)
    clojure.test$default_fixture.invokeStatic (test.clj:686)
    clojure.test$default_fixture.invoke (test.clj:682)
    clojure.test$test_vars$fn__9235.invoke (test.clj:734)
    clojure.test$default_fixture.invokeStatic (test.clj:686)
    clojure.test$default_fixture.invoke (test.clj:682)
    clojure.test$test_vars.invokeStatic (test.clj:730)
    clojure.test$test_all_vars.invokeStatic (test.clj:736)
    clojure.test$test_ns.invokeStatic (test.clj:757)
    clojure.test$test_ns.invoke (test.clj:742)
    user$eval233$fn__294.invoke (form-init3321944168700773224.clj:1)
    clojure.lang.AFn.applyToHelper (AFn.java:156)
    clojure.lang.AFn.applyTo (AFn.java:144)
    clojure.core$apply.invokeStatic (core.clj:659)
    clojure.core$apply.invoke (core.clj:652)
    leiningen.core.injected$compose_hooks$fn__163.doInvoke (form-init3321944168700773224.clj:1)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.core$apply.invokeStatic (core.clj:657)
    clojure.core$apply.invoke (core.clj:652)
    leiningen.core.injected$run_hooks.invokeStatic (form-init3321944168700773224.clj:1)
    leiningen.core.injected$run_hooks.invoke (form-init3321944168700773224.clj:1)
    leiningen.core.injected$prepare_for_hooks$fn__168$fn__169.doInvoke (form-init3321944168700773224.clj:1)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.lang.AFunction$1.doInvoke (AFunction.java:29)
    clojure.lang.RestFn.invoke (RestFn.java:408)
    clojure.core$map$fn__5587.invoke (core.clj:2747)
    clojure.lang.LazySeq.sval (LazySeq.java:40)
    clojure.lang.LazySeq.seq (LazySeq.java:49)
    clojure.lang.Cons.next (Cons.java:39)
    clojure.lang.RT.boundedLength (RT.java:1785)
    clojure.lang.RestFn.applyTo (RestFn.java:130)
    clojure.core$apply.invokeStatic (core.clj:659)
    clojure.test$run_tests.invokeStatic (test.clj:767)
    clojure.test$run_tests.doInvoke (test.clj:767)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.core$apply.invokeStatic (core.clj:657)
    clojure.core$apply.invoke (core.clj:652)
    user$eval233$fn__306$fn__339.invoke (form-init3321944168700773224.clj:1)
    user$eval233$fn__306$fn__307.invoke (form-init3321944168700773224.clj:1)
    user$eval233$fn__306.invoke (form-init3321944168700773224.clj:1)
    user$eval233.invokeStatic (form-init3321944168700773224.clj:1)
    user$eval233.invoke (form-init3321944168700773224.clj:1)
    clojure.lang.Compiler.eval (Compiler.java:7062)
    clojure.lang.Compiler.eval (Compiler.java:7052)
    clojure.lang.Compiler.load (Compiler.java:7514)
    clojure.lang.Compiler.loadFile (Compiler.java:7452)
    clojure.main$load_script.invokeStatic (main.clj:278)
    clojure.main$init_opt.invokeStatic (main.clj:280)
    clojure.main$init_opt.invoke (main.clj:280)
    clojure.main$initialize.invokeStatic (main.clj:311)
    clojure.main$null_opt.invokeStatic (main.clj:345)
    clojure.main$null_opt.invoke (main.clj:342)
    clojure.main$main.invokeStatic (main.clj:424)
    clojure.main$main.doInvoke (main.clj:387)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.lang.Var.applyTo (Var.java:702)
    clojure.main.main (main.java:37)

lein test :only fn-fx.fx-dom-test/test-basic-component-properties

FAIL in (test-basic-component-properties) (fx_dom_test.clj:23)
expected: (= (get-prop (clojure.core/deref root) :title) "Hello")
  actual: (not (= nil "Hello"))

Ran 9 tests containing 59 assertions.
1 failures, 1 errors.
Tests failed.

Can you show two more examples of fn-fx in you video

Can you show two more examples of fn-fx in your video?

One would be the settings to run it as a Java Application in Cursive.
The other would be the settings to run it as a Clojure Application in Cursive.

I've been able to run the examples via the REPL but have had issues trying to get them to run those two ways above. Doc updates with screenshots of the settings would be greatly appreciated if you have the time.

Thanks for the cool library.

Standardise how examples are run

Currently the examples are run in 2 different ways. It would be great to standardise on a single approach, to make it easier for newcomers to the library.

  • 01 Hello world: (require '[getting-started.01-hello-word]) (note: (-main) is automatically invoked)
  • 02 Form: (require '[getting-started.02-form :as form]) (form/-main)
  • Shapes 3d: (require '[other-examples.shapes-3d :as shapes-3d]) (shapes-3d/-main)
  • Todo: (require '[other-examples.todo :as todo]) (todo/-main)

How do you get the selected value from a choice-box

(defui Choice
  (render [this _]
          (ui/choice-box
           :on-action {:event :choose-env :this this  }
           :items ["development"
                   "staging"
                   "production"] )))

In the "choose-env" handle, I have no access to what item was chosen. I tried to pass "this" as an argument and call (.getSelectionModel this) in the event handler, but there's no such method. How are you supposed to get the chosen item ?

table-cell with button

Button inside cll

How can I use a button inside cell?
I tried with Java examples but that thing about extend is too dificult

(ui/text :fill (ui/color ...)) does not set fill property to said color

Bug Report

Steps to Reproduce:

  1. Create a (dom/app with a ui/text element and set the :fill to a ui/color as in the 02_form.clj example application.
  2. Look at the text color via your eyes or examining the properties.

Expected Result:

Color should have changed ie firebrick.

Actual Result:

Text remains black.

Environment:

master branch, ubuntu 19.04, javafx11

Error when hotswapping CSS file name

I have a setup where the name of my .css file is stored in the data-state atom. I tried using the method suggested by this blog post on how to dynamically update the style on the repl. However, about 50% of the time when I set the css file to a new string (with (swap! data-state assoc-in [:ui :stylesheets] ["main.css"])) the below error occurs. Even if the error doesn't occur, the window does not update its style. At the very least, I imagine the error message should be improved.

#error {
 :cause Assert failed: TODO: Implement this
(= idx (count lst))
 :via
 [{:type java.lang.AssertionError
   :message Assert failed: TODO: Implement this
(= idx (count lst))
   :at [fn_fx.fx_dom.FXDom$fn__18087 invoke fx_dom.clj 33]}]
 :trace
 [[fn_fx.fx_dom.FXDom$fn__18087 invoke fx_dom.clj 33]
  [clojure.lang.AFn run AFn.java 22]
  [com.sun.javafx.application.PlatformImpl lambda$null$173 PlatformImpl.java 295]
  [java.security.AccessController doPrivileged AccessController.java -2]
  [com.sun.javafx.application.PlatformImpl lambda$runLater$174 PlatformImpl.java 294]
  [com.sun.glass.ui.InvokeLaterDispatcher$Future run InvokeLaterDispatcher.java 95]
  [com.sun.glass.ui.gtk.GtkApplication _runLoop GtkApplication.java -2]
  [com.sun.glass.ui.gtk.GtkApplication lambda$null$49 GtkApplication.java 139]
  [java.lang.Thread run Thread.java 745]]}
 "Elapsed time: 3.601076 msecs"

Trouble editing TabPane.selectionModel.selectedIndex / Nested Modify

Overview

Hey Tim!

Great library. Thanks a million for providing it.

Here's a question for you and the community:

I'm having an issue adding a listener to TabPane.selectionModelProperty.selectedIndexProperty.

I've never had to go two layers deep in fn-fx before, so I may be missing something fairly obvious.

Details

Here's what I'm attempting to do in Java:

tabPane.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener<Number>() {
    @Override
    public void changed(ObservableValue<? extends Number> ov, Number oldValue, Number newValue) {
        // do something...
    }
});

1 - Dream Client Code

Here's my dream client code in Clojure with fn-fx:

(ui/tab-pane
 :selection-model {:selected-index/listener {:event :tab-changed}}
 :tabs tabs))

Error Running Dream Client Code

The error I encountered when writing the above code:

Can't convert {:selected-index/listener {:event :tab-changed}} of type class clojure.lang.PersistentArrayMap to class javafx.scene.control.SingleSelectionModel

^ Seems that my attempt at a nested modification [:selection-model :selected-index/listener] failed.

2 - Failure to Instantiate SingleSelectionModel

I attempted to instantiate a SingleSelectionModel, but it looks like this violates JavaFX's instantiation policy:

(ui/tab-pane
 :selection-model (SingleSelectionModel.)
 :tabs tabs))

Recap

I suspect that there may be something simple for doing a nested modify.

Is there a good workaround or perhaps an insight that I am missing? Many thanks!

Transfer to fn-fx org should now be possible

@halgari I've deleted the fork (fn-fx/fn-fx-openjfx) that was preventing the transfer of this repo to the fn-fx org - the transfer should be possible now.

Apologies for raising a new issue for this, but as part of deleting that fork I also deleted the issue where we had previously been discussing this. 😊

bind functionality

Support Question

Hello there, first of all, thank you for this wonderful library.
I've been using it instead of regular javafx for the fast few while and I really enjoy using it. However I have encountered a few roadblocks.
What would be the correct way to emulate the infamous "fit-to-parent" AnchorPane functionality? My so far unsuccessful approach was something like this:

(controls/anchor-pane
  :children 
    [(controls/some-control 
      :anchor-pane/top-anchor 0.0
      :anchor-pane/bottom-anchor 0.0
      :anchor-pane/left-anchor 0.0
      :anchor-pane/right-anchor 0.0)])

But for some controls (ImageView cough) I know, this just won't cut it in the long run. So are there major hurdles for the nested-properties branch to get merged? I looked at the source and am looking forward to the :bind/property syntax with [:id :prop] values. I don't really get the complete picture of what is depending on what right now, but with some pointers I would like to look into this and help if possible/necessary.

Need a way to define `:cell-value-factory` for `table-column` component

As far as I know, currently there is no idiomatic way to define :cell-value-property for table-column components. You have to jump through hoops to create an object which implement the java Callback interface. Currently I am using a custom function, thanks to this blogpost. Here's the code I am using:

(defn cell-value-factory [f]
  (reify javafx.util.Callback
    (call [this entity]
      (javafx.beans.property.ReadOnlyObjectWrapper. (f (.getValue entity))))))

(defui MyTable
  (render [this _]
      (ui/table-view
        :items [{:name "foo" :age 10}
                {:name "bar" :age 56}]
        :columns [(ui/table-column
                  :text "Name"
                  :cell-value-factory (cell-value-factory #(:name %)))
                  (ui/table-column
                   :text "Age"
                   :cell-value-factory (cell-value-factory #(:age %)))])))

While this works; ideally (IMO), the object creation should be handled by the table-column component itself and :cell-value-factory should accept plain clojure functions. Like this:

(defui MyTable
  (render [this _]
      (ui/table-view
        :items [{:name "foo" :age 10}
                {:name "bar" :age 56}]
        :columns [(ui/table-column
                  :text "Name"
                  :cell-value-factory #(:name %))
                  (ui/table-column
                   :text "Age"
                   :cell-value-factory #(:age %))])))

Special handling of :shown property prevents on-showing/on-shown events being triggered.

The special handling of the :shown property:

(let [^Method show-method (->> (.getDeclaredMethods Window)

on a Window/Stage immediately causes the show method to be called, potentially before any on-showing/on-shown event handler properties have been set on the component. In my opinion, there should be some sort of lifecycle callback done when the FX component has been fully instantiated where doing things like call show() should be done. I'm still trying to grok this codebase, so I'm not clear where this callback would be inserted.

Got Exception when run (-main) of other-example.todo in repl

Exception in thread "JavaFX Application Thread" 
java.lang.ClassCastException: javafx.stage.Stage cannot be cast to javafx.scene.Node
	at fn_fx.fx_tree_search$find_child_by_id.invokeStatic(fx_tree_search.clj:23)
	at fn_fx.fx_tree_search$find_child_by_id.invoke(fx_tree_search.clj:22)
	at fn_fx.fx_tree_search$find_nearest_by_id.invokeStatic(fx_tree_search.clj:37)
	at fn_fx.fx_tree_search$find_nearest_by_id.invoke(fx_tree_search.clj:34)
	at fn_fx.render_core$gather_event_data$fn__18684.invoke(render_core.clj:279)
	at clojure.lang.PersistentArrayMap.kvreduce(PersistentArrayMap.java:373)
	at clojure.core$fn__9354.invokeStatic(core.clj:6721)
	at clojure.core$fn__9354.invoke(core.clj:6706)
	at clojure.core.protocols$fn__9145$G__9140__9154.invoke(protocols.clj:174)
	at clojure.core$reduce_kv.invokeStatic(core.clj:6732)
	at clojure.core$reduce_kv.invoke(core.clj:6723)
	at fn_fx.render_core$gather_event_data.invokeStatic(render_core.clj:275)
	at fn_fx.render_core$gather_event_data.invoke(render_core.clj:269)
	at fn_fx.render_core$get_add_listener$fn$reify__18691.changed(render_core.clj:300)
	

Calling methods

Would it be possible to have an example of calling a method on a ui object? As an example this does not work:

(def transition (ui/parallel-transition a-rect a-translate))
(.play transition)

README example outdated

The example in the README is not working anymore (e.g. ui is not in fn-fx.render anymore).
I suggest to either just refer to the examples folder or replace it with a simple working example in the README itself.

lein uberjar gives an error ClassNotFoundException

Bug Report

Steps to Reproduce:

  1. ...step 1 lein new app xxx
  2. ...step 2 add dependency [fn-fx/fn-fx-javafx "0.5.0-SNAPSHOT"] the copy fn-fx-master 01_hello_word.clj code to xxx.core
  3. ...step 3 "lein run" works ok, but "lein uberjar" doesn't

Expected Result:

get jar files

Actual Result:

java.lang.ClassNotFoundException: javafx.application.Platform, compiling:(util.clj:1:1)
Exception in thread "main" java.lang.ClassNotFoundException: javafx.application.Platform, compiling:(util.clj:1:1)

Environment:

Leiningen 2.9.1 on Java 11 Java HotSpot(TM) 64-Bit Server VM

Additional Context:

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.