如何在REPL中刷新后重用相同的窗口?

时间:2017-10-25 12:31:48

标签: clojure seesaw

在名为gui.clj的源文件中,我定义了一个框架fr,它保存了我的应用程序的窗口,如下所示:

(def fr (frame ...))

run函数设置fr并使其在数据更改时重新绘制,如下所示(以scribble.clj为模型:

(defn run []
  (-> fr add-behaviors pack! show!)
  (when-data-changes
    (swap! state assoc :shapes (dot/g->seesaw t/ws))
    (repaint! fr)))

当我在REPL中乱搞时,我经常修改源文件,然后调用c.t.n.repl/refresh。当我再次运行run时,它会打开一个新窗口,将旧窗口保留在屏幕上。即使刷新后,如何使我的(新更新的)代码在同一窗口上运行?

2 个答案:

答案 0 :(得分:1)

您可以将应用程序的状态(包含窗口对象)放入单独命名空间中的defonce,并在命名空间上调用disable-reload。这将阻止在调用(refresh)时重新加载命名空间,从而保持原始状态(包含原始窗口对象)。

但实际上,通常最好在重新加载时清理并重新启动应用程序。从某个命名空间的先前状态持有过时的对象可能很危险。使用componentmount来管理应用程序状态。

答案 1 :(得分:0)

听起来你想对程序的有状态部分有一点“生命周期”,有点像

  1. 如果不存在则使其存在
  2. 让它运行
  3. 清理它
  4. 并希望在重新加载时发生这种情况。您可以通过向清除窗口的清理功能添加代码来使相同的窗口继续存在并获取新内容,也可以关闭窗口并为每个循环创建一个新窗口。

    我已经使用component library来使用这种风格的大型项目,它非常有效,虽然这是一种生活方式的改变,以适应它。 对于你的情况,你可能只想初始化一个原子来存储活动窗口然后定义三个基本生命周期函数来操作该原子的内容。 (并将实际原子放在defonce