Listbox (JList) Не будет обновляться динамически из пользовательской ListModel
Я работаю над приложением с графическим интерфейсом в Clojure, используя Seesaw, и у меня возникают проблемы при получении списка (JList в Java) для обновления при обновлении моего пользовательского ListModel.
Вот часть моего кода:
(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 "\n" "Event: " event "\n"))
(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
происходит, но список не хочет обновлять
Любые идеи о том, что может пойти не так? Это что-то со смесью использования EDT и обратного вызова?
Дайте мне знать, если нужно больше кода.
1 ответ
Пользовательские модели всегда сложны, особенно в отношении уведомлений о событиях, поэтому трудно сказать, насколько хорошо это будет работать. Тем не менее, моя лучшая догадка о том, почему ничего не уведомляется о том, что вы используете map
который ленивый, т.е. последняя форма в вашем notify
метод на самом деле ничего не делает. Попробуйте это вместо этого:
(doseq [listener listeners]
(invoke-later (notification listener)))
Удачи.