这个swing Table模型代码是否设计得很糟糕?
上下文:我有一个基于clojure的纵横字谜应用程序,它的主要ui是一个JTabbedPane,有两个选项卡,一个网格和一个线索表。线索表是线索向量的视图,但向量本身不是数据的权威存储,而是通过这个swing Table模型代码是否设计得很糟糕?,swing,clojure,Swing,Clojure,上下文:我有一个基于clojure的纵横字谜应用程序,它的主要ui是一个JTabbedPane,有两个选项卡,一个网格和一个线索表。线索表是线索向量的视图,但向量本身不是数据的权威存储,而是通过(活动cluelist)函数从两个内部数据结构动态生成的,该函数由正在选择的线索选项卡触发 这就是线索表的实现: (def cluelist []) (def update-cluelist) (def model) (defn make [] (let [column-names ["Sq" "W
(活动cluelist)
函数从两个内部数据结构动态生成的,该函数由正在选择的线索选项卡触发
这就是线索表的实现:
(def cluelist [])
(def update-cluelist)
(def model)
(defn make []
(let [column-names ["Sq" "Word" "Clue"]
column-widths [48 200 600]
table-model (proxy [AbstractTableModel] []
(getColumnCount [] (count column-names))
(getRowCount [] (count cluelist))
(isCellEditable [row col] (= col 2))
(getColumnName [col] (nth column-names col))
(getValueAt [row col] (get-in cluelist [row col]))
(setValueAt [s row col]
(let [word (get-in cluelist [row 1])]
(add-clue word s) ; editing a cell updates the main clue data
(def cluelist (assoc-in cluelist [row 2] s))
(. this fireTableCellUpdated row col))))
table (JTable. table-model)
]
; some pure display stuff elided
(def model table-model)
)
(defn update-cluelist []
(def cluelist (active-cluelist))
(.fireTableDataChanged model))
另一次讨论中有人指出,手动调用fireTableDataChanged
是(更新cluelist)
的主要代码气味,因为TableModel类之外的任何东西都不应该调用该方法。然而,我觉得这是从外部源动态生成表的不可避免的结果。这些文件并没有太大的帮助,他们说
您的自定义类只需调用以下函数之一
AbstractTableModel方法每次通过
外部来源
它隐式地假定CustomTableModel类是数据的权威源
这里还有一点clojure/java阻抗不匹配-在java中,我会让cluelist
和update cluelist
成为我的TableModel的私有成员和方法,而在clojurecluelist
中,表模型是动态作用域的变量,update cluelist
可以访问这些变量
我的主要问题是没有太多clojure/swing代码可供我寻找最佳实践。有人对最好的方法有什么建议吗?建议:使用atom作为cluelist。不断重新定义cluelist不是表示可变数据的正确方法。老实说,我希望它在第二次定义cluelist时抛出异常 如果将atom用于cluelist,则可以从观察者调用
fireTableDataChanged
方法,而不是手动调用它。这意味着无论何时何地更改atom,fireTableDataChanged
都将自动调用,而无需显式调用
def
的问题是多次调用def
在多线程环境中效果不佳,Clojure试图将所有内容默认为线程安全。据我所知,使用var的“正确”方法是不使用它的根绑定(即,不要再次调用def
),如果需要在本地更改它,则使用binding
def
可能按照您使用它的方式工作,但该语言的设置是为了在这种情况下支持atoms、ref或agent,并且这些语言在大多数情况下可能会工作得更好(例如,您有了监视者)。另外,如果以后添加线程,您根本不需要担心线程。atom显然是个好主意,因为正如您所注意到的,我可以向它添加一个观察者,但是为什么var是错误的呢?我见过在clojure代码中非常频繁地使用变量来存储不需要并发写入的“可变”数据结构。@MartinDeMello请参阅扩展的answerkleopatra:yep:)感谢您让我重新检查设计!