如何将SeeSaw小部件替换为Clojure中动态创建的小部件



我是Clojure、Java和函数式编程的新手。我开始使用SeeSaw制作GUI,并且很喜欢它。使用Dave Ray的例子,我创建了一个小部件:

(defrecord Col-definition [id col-name col-position])

与相关的函数创建组合框,标签和文本框,最明显的是使用extend-type:

(extend-type Col-definition  
  MakeWidget 
  (make-widget* [col-definition] 
    (mig-panel 
      :constraints ["", "[][grow]"]
      :border [(line-border :thickness 1) 2]
      :items [["Column Name"        "gap 10"]
              ;;[(col-name-field (:id col-definition) col-definition :col-name)  "growx, wrap"]
              [(:col-name col-definition) "growx, wrap"]
              ["Ordinal Position" "gap 10"]
              [(col-name-field (:id col-definition) col-definition :col-position)  "growx"]])))

小部件通过defrecord的实例构建,绑定到屏幕区域,如下所示:

(def second-combocoll '("Col0" "Col1" "Col2"))
(def second-bottom (vertical-panel :items (vec (col-defs second-combocoll))))
(def areabottom second-bottom)

其中areabottom为房地产分割区域。这一切都很好。

但是我想从数据库中读取,并动态地将小部件替换为新的组合框集合。

我似乎不能删除小部件,(remove! areabottom second-combocol)(replace! areabottom new-combocol)或任何其他聪明的想法都没有出现。

那么问题来了:在触发事件之后(比如点击文件路径加载),如何替换或删除自定义小部件?

经过一个星期的各种尝试,我有一个解决方案,虽然有点hack。

关键思想是具体使用id关键字作为标记和查找小部件的方法。

首先,为了进行操作,我创建了一个"虚拟"小部件,将其添加到名为areabottom的JFrame区域。这是因为以后必须有东西来代替。

(def initcombos (combobox  :id "newcombo" :model [ 1 2 3 ]))
(add! areabottom initcombos)

-I随后修改了listbox监听器并实现了replace!使用id关键字如下:

 (listen lb 
         :selection
        (fn [e]
          (when-let [s (selection e)]
           (let [ncombo (vertical-panel :id "newcombo" :items (get-col-defs (.getPath s)))]
          ; (replace! areabottom initcombos ncombo)
          (replace! areabottom (select areabottom [:#newcombo]) ncombo)
           )))) 

注意,let中的ncombo与之前的"假"小部件(即"newcombo")具有相同的id。这是一个神奇的hack,因此使用相同的id来查找旧的小部件,并且新小部件具有相同的id,以确保在进一步调用时可以找到它。

你发这个已经有一段时间了。我看了这篇文章几分钟前,因为我有同样的问题与replace!不做我所期望的。我没有继续使用replace!,而是使用了(do (config! my-container :items (build-new-items)) (repaint! my-container))之类的东西。如果你仍然想整理你的代码,你可能想尝试一下。

相关内容

  • 没有找到相关文章

最新更新