对话框:success-fn未触发问题求助:按钮监听器关联异常排查
解决对话框Success-Fn未触发的问题
看起来你的问题根源在于对话框实例在按钮监听器的上下文里被过早回收了。当你直接调用connectionDialog时,函数执行后的上下文可能保留了对话框的引用,让它能正常触发success-fn;但在按钮的:action监听器里调用时,对话框实例没有被持久化引用,执行完connectionDialog后就被垃圾回收了,导致点击确认时找不到对应的回调函数。
修复方案:保留对话框实例的引用
你可以修改connectionDialog函数,让它返回对话框实例,然后在按钮监听器里保留这个实例的引用,避免被GC回收。
修改后的代码如下:
(def dbConnectionForm (grid-panel :columns 2 :items ["Database Driver" (combobox :id :dbdriver :model ["postgresql" "mysql"]) "Database" (text :id :dbname :text "postgres") "Port" (text :id :dbport :text "32768") "Username" (text :id :username :text "postgres") "Password" (text :id :password :text "postgres")])) (defn connectionDialog [] ;; 用let绑定对话框实例,确保有局部引用 (let [dlg (dialog :content dbConnectionForm :option-type :ok-cancel :type :plain :success-fn (fn [e] (println (value dbConnectionForm))))] (pack! dlg) (show! dlg) ;; 返回对话框实例,让调用者可以保留引用 dlg)) (def connectButton (button :text "Connect" :listen [:action (fn [e] ;; 在监听器里保留对话框实例的引用,防止被回收 (def ^:private *active-connection-dlg* (connectionDialog)))]))
关键说明:
- 用
let在connectionDialog里绑定对话框实例,确保函数执行期间有局部引用。 - 在按钮的监听器里,把返回的对话框实例赋值给一个变量(这里用
*active-connection-dlg*),让JVM不会马上回收它,直到对话框关闭或者你手动清理这个引用。 - 我把
print改成了println,方便在控制台看到输出结果,你可以根据需要改回去。
如果你担心全局变量的问题,也可以用原子变量来管理对话框实例,更规范:
(def active-dlg (atom nil)) (def connectButton (button :text "Connect" :listen [:action (fn [e] (reset! active-dlg (connectionDialog)))]))
内容的提问来源于stack exchange,提问作者arahfahrrad
相关产品推荐
相关产品推荐

