Hello, I was wondering if anyone could help me with using fx/ext-many
. I am trying to use this in order to show dialog windows above the main window.
I currently am creating my app like this:
(def app
(do
(event-handler {:event/type ::events/initialize
:fx/sync true})
(fx/create-app *state
:event-handler event-handler
:desc-fn views/desc)))
And my desc-fn
is this:
(defn desc
[{:keys [scene] :as state}]
{:fx/type fx/ext-many
:desc [{:fx/type root
:state state}
{:fx/type select-categories
:state state}
{:fx/type alert
:state state}
{:fx/type about
:state state}]})
root
, select-categories
, alert
, and about
are all functions returning descriptions.
I am getting this exception though, and I am not entirely sure what’s going wrong.
java.lang.NullPointerException
at clojure.core$deref_future.invokeStatic(core.clj:2300)
at clojure.core$deref.invokeStatic(core.clj:2320)
at clojure.core$deref.invoke(core.clj:2306)
at cljfx.context$sub_ctx.invokeStatic(context.clj:107)
at cljfx.context$sub_ctx.doInvoke(context.clj:106)
at clojure.lang.RestFn.applyTo(RestFn.java:142)
at clojure.core$apply.invokeStatic(core.clj:669)
at clojure.core$apply.invoke(core.clj:660)
at cljfx.context$sub.invokeStatic(context.clj:165)
at cljfx.context$sub.doInvoke(context.clj:161)
at clojure.lang.RestFn.invoke(RestFn.java:442)
at cljfx.lifecycle$sub_context_fn.invokeStatic(lifecycle.clj:473)
at cljfx.lifecycle$sub_context_fn.invoke(lifecycle.clj:471)
at cljfx.lifecycle$fn__1379.invokeStatic(lifecycle.clj:479)
at cljfx.lifecycle$fn__1379.invoke(lifecycle.clj:478)
at cljfx.lifecycle$eval1067$fn__1089$G__1054__1098.invoke(lifecycle.clj:17)
at cljfx.lifecycle$create_dynamic_component.invokeStatic(lifecycle.clj:32)
at cljfx.lifecycle$create_dynamic_component.invoke(lifecycle.clj:29)
at cljfx.lifecycle$reify__1139.create(lifecycle.clj:39)
at cljfx.lifecycle$wrap_many$fn__1229$fn__1233$fn__1234.invoke(lifecycle.clj:280)
at clojure.core$update.invokeStatic(core.clj:6196)
at clojure.core$update.invoke(core.clj:6188)
at cljfx.lifecycle$wrap_many$fn__1229$fn__1233.invoke(lifecycle.clj:279)
at clojure.lang.PersistentVector.reduce(PersistentVector.java:343)
at clojure.core$reduce.invokeStatic(core.clj:6827)
at clojure.core$reduce.invoke(core.clj:6810)
at cljfx.lifecycle$wrap_many$fn__1229.invoke(lifecycle.clj:278)
at cljfx.lifecycle$eval1067$fn__1089$G__1054__1098.invoke(lifecycle.clj:17)
at cljfx.lifecycle$wrap_map_desc$fn__1357.invoke(lifecycle.clj:446)
at cljfx.lifecycle$eval1067$fn__1089$G__1054__1098.invoke(lifecycle.clj:17)
at cljfx.lifecycle$create_dynamic_component.invokeStatic(lifecycle.clj:32)
at cljfx.lifecycle$create_dynamic_component.invoke(lifecycle.clj:29)
at cljfx.lifecycle$reify__1139.create(lifecycle.clj:39)
at cljfx.lifecycle$fn__1143.invokeStatic(lifecycle.clj:58)
at cljfx.lifecycle$fn__1143.invoke(lifecycle.clj:56)
at cljfx.lifecycle$eval1067$fn__1089$G__1054__1098.invoke(lifecycle.clj:17)
at cljfx.lifecycle$wrap_map_desc$fn__1357.invoke(lifecycle.clj:446)
at cljfx.lifecycle$eval1067$fn__1089$G__1054__1098.invoke(lifecycle.clj:17)
at cljfx.lifecycle$wrap_context_desc$fn__1366.invoke(lifecycle.clj:458)
at cljfx.lifecycle$eval1067$fn__1089$G__1054__1098.invoke(lifecycle.clj:17)
at cljfx.renderer$render_component.invokeStatic(renderer.clj:57)
at cljfx.renderer$render_component.invoke(renderer.clj:47)
at cljfx.renderer$create$fn__1691.invoke(renderer.clj:77)
at cljfx.renderer$perform_render$fn__1642.invoke(renderer.clj:23)
at cljfx.renderer$perform_render.invokeStatic(renderer.clj:22)
at cljfx.renderer$perform_render.invoke(renderer.clj:14)
at cljfx.renderer$request_render$fn__1668$fn__1672.invoke(renderer.clj:44)
at cljfx.renderer$request_render$fn__1668.invoke(renderer.clj:44)
at clojure.lang.AFn.run(AFn.java:22)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
I tried calling the root
and other description functions directly inside the fx/ext-many
description, but after an event would happen, the main window would be duplicated instead of updating the current main window.
What am I doing wrong, or is there a better way to show dialogs windows?
Previously, I was simply returning a different description each time, so only one window could only be on the screen at once, but I didn’t really like this approach. I wanted to be able to keep the main window open with the dialog popping up above.
Doing this seemed to help:
(defn desc
"Chooses which description to create"
[{:keys [scene] :as state}]
{:fx/type fx/ext-many
:desc [(root state)
(select-categories state)
(alert state)
(about state)]})
But still the main window gets duplicated once an event handler is fired and stuff is rendered again 👀It’s only getting duplicated once, and then on subsequent events, it’s not being duplicated
Looks like I was able to resolve the problem myself. What I did above worked, but I had some application initialization errors that caused duplicate windows to be created. I fixed those and everything works now!