问题描述
我正在使用 Seesaw 在 Clojure 中开发一个 GUI 应用程序,并且在我的自定义 ListModel 更新时无法更新列表框(Java 中的 JList).
I'm working on a GUI app in Clojure using Seesaw and am having trouble getting a listbox (JList in Java) to update when my custom ListModel gets updated.
这是我的一些代码:
(deftype ActionHistoryListModel
[^{:unsynchronized-mutable true} listeners
^{:unsynchronized-mutable true} listening-to]
ListModel
(addListDataListener [this listener]
(set! listeners (conj listeners listener)))
(removeListDataListener [this listener]
(set! listeners (remove #(= % listener) listeners)))
(getSize [this]
(get-in (deref listening-to) [:count]))
(getElementAt [this index]
(get-in (deref listening-to) [:actions index]))
ActionHistoryListModelProtocol
(listen-to [this r]
(do
(set! listening-to r)
(add-watch r this (fn [_ _ _ new-state] (.notify this new-state)))))
(notify [this new-state]
(let [action ((meta new-state) :last-action)
const (cond
(= action :create) INTERVAL_ADDED
(= action :update) CONTENTS_CHANGED)
index (last ((meta new-state) :action-target))
event (ListDataEvent. this const index index)
notification (cond
(= action :create) #(.intervalAdded % event)
(= action :update) #(.contentsChanged % event))
]
(. (.. System out) print (str "Index: " index "
" "Event: " event "
"))
(map #(invoke-later (notification %)) listeners)))
)
(defn make-action-history-list-model []
(ActionHistoryListModel. #{} nil))
(def ahlm (make-action-history-list-model))
(.listen-to ahlm action-history)
(def undo-list (listbox :model ahlm))
; then put list in frame...
其中 action-history
是 ref
.
由于 System.out.print
正在发生,它应该更新列表,但列表框不想更新
It goes to the point where the list should be updated because the System.out.print
is happening, but the listbox doesn't want to update
任何关于可能出现问题的想法?是否混合使用 EDT 和 watch 回调?
Any ideas on what might be going wrong? Is it something with the mix of using the EDT and watch callback?
如果需要更多代码,请告诉我.
Let me know if more code is needed.
推荐答案
自定义模型总是很棘手,尤其是在事件通知方面,因此很难说它的效果如何.也就是说,我对为什么没有收到任何通知的最佳猜测是您使用的 map
是惰性的,即您的 notify
方法中的最后一个表单实际上没有做任何事情.试试这个:
Custom models are always tricky especially around event notification so it's hard to say how well this will work. That said, my best guess as to why nothing is being notified is that your using map
which is lazy, i.e. the last form in your notify
method doesn't actually do anything. Try this instead:
(doseq [listener listeners]
(invoke-later (notification listener)))
祝你好运.
这篇关于Listbox (JList) 不会从自定义 ListModel 动态更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!