代码之家  ›  专栏  ›  技术社区  ›  paul

Listbox(JList)不会从自定义ListModel动态更新

  •  2
  • paul  · 技术社区  · 14 年前

    我正在使用Seesaw在Clojure中开发一个GUI应用程序,当我的自定义ListModel更新时,我很难获得要更新的列表框(Java中的JList)。

    以下是我的一些代码:

    (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 回复  |  直到 14 年前
        1
  •  1
  •   Dave Ray    14 年前

    自定义模型总是很棘手,尤其是在事件通知方面,所以很难说它能起到多好的作用。也就是说,我对为什么没有收到任何通知的最佳猜测是 map 哪个是懒惰的,即你 notify 方法实际上并没有任何作用。请尝试以下操作:

    (doseq [listener listeners] 
      (invoke-later (notification listener)))
    

    祝你好运