JavaFX和Clojure:将可观察对象绑定到不可变对象

23
我一直在尝试找到一种方法,允许JavaFX TableView(或任何其他JavaFX组件)表示一些Clojure数据,并允许用户通过GUI操作数据。
在本讨论中,让我们假设我有一个地图列表/向量,即类似于[{:col1“happy1”:col2“sad1”} {:col1“happy2”:col2“sad2”}]的东西,并希望它以以下方式显示在图形表中:
mykey1      mykey2
------------------
happy1      sad1
happy2      sad2

很简单。这在世界历史上已经做了无数次。
问题在于TableView坚持使用ObservableList等,这本质上是一个可变的东西,JavaFX中的所有Observables都是如此。这对于保持表格更新非常有用,在可变模型中,它也非常适合允许用户通过GUI直接操作数据。我不是专家,但在这种情况下,似乎JavaFX希望GUI对象实际包含真实数据。这对我来说似乎很有趣(不是哈哈)。通过某些API或接口维护自己的模型并在GUI和模型之间进行通信,这也意味着我在两个地方维护数据:在我的模型中和在GUI中。这是正确的做事方式吗?也许这是可以接受的,因为GUI只显示总数据的一小部分,并且它使我的模型数据只是正常的模型数据,而不是某个Java派生类型的实例。
因此,在尝试在无状态/不可变模型上放置GUI时,会出现以下三个一般性问题:
  1. 如果GUI允许更改事物,那么底层模型如何真正不可变呢?我特别考虑某种设计工具、编辑器等,用户明确地改变事物。例如LightTable是一个编辑器,但故事是它基于不可变数据。这怎么可能?我对FRP不感兴趣。

  2. 假设在某个级别上至少有一个Atom或其他Clojure可变类型(ref/var/agent等)(无论是包含整个内存中的设计数据库的单个Atom,还是设计数据库是一个不可变的可变Atoms列表),哪种[MVP,MCP,MVVM等]模型最适合这种创建方式?

  3. JavaFX在类层次结构中散布着各种可观察接口的变体(http://docs.oracle.com/javafx/2/api/javafx/beans/Observable.html),包括例如ObservableMap和ObservableMapValue等珠宝,然后是数十个实现类,如IntegerProperty和SimpleIntegerProperty...天哪!什么鬼?假设我必须在我的大多数不可变对象上创建一些Clojure对象(defrecord等)并实现一些Observable接口方法,我是否只能使用Observable,还是必须将每个接口实现到叶节点,例如ObservableIntegerValue等?

什么是正确的高级方法?每次用户更改值时维护一个单一的顶级原子?维护一千个低级原子?让我的值作为JavaFX Observables存在,忘记Clojure数据结构?使用一些reify/proxy/gen-class在Clojure中实现自己的Observables集合,但将它们实现为不可变的,每次更改都会被替换?Clojure的add-watch函数是否有需要或适用的地方?我非常希望我的数据只是Clojure中的普通数据,而不是任何"类型"或接口的实现。整数应该是整数等等。
谢谢。

2
也许这可以帮助你:https://github.com/halgari/fn-fx,视频介绍在这里:https://www.youtube.com/watch?v=hJ8GZxhsaVQ - Rodrigo Taboada
我认为ClojureScript领域中的_cursors_方法也是相关的:https://github.com/reagent-project/reagent-cursor#cursors - zarkone
我没有什么可以补充的,因为你已经在思考了。但是:一些Java库或某些Java库中的某些方法在Clojure中很容易使用,而有些则不是。在Java中完全合理的一些设计与Clojure设计者的意图相悖。使用这些设计的库将不会很好看。你可以这样做(我已经这样做了),但它不会是Clojure风格的。显然,这仍然可能比从头开始编写一个新的Clojure库更好。 - Mars
1个回答

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接