1

在一个名为 的源文件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再次运行时,它会弹出一个新窗口,将旧窗口留在屏幕上。即使在刷新后,如何让我的(新更新的)代码在同一个窗口上运行?

4

2 回答 2

1

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

然而,在实践中,通常最好在重新加载时清理并重新启动应用程序。从某些命名空间的先前状态中保留过时的对象可能很危险。使用组件挂载来管理应用程序状态。

于 2017-10-26T06:25:12.827 回答
0

听起来您希望程序的有状态部分有一个“生命周期”,有点像

  1. 如果它不存在,让它存在
  2. 让它运行
  3. 清理

并希望在您重新加载时发生这种情况。您可以通过将代码添加到清除窗口的清理函数中来让相同的窗口继续存在并获取新内容,或者您​​可以关闭窗口并为每个循环创建一个新窗口。

我已经将组件库用于使用这种风格的大型项目,它非常有效,尽管习惯它有点改变生活方式。对于您的情况,您可能只想初始化一个原子来存储活动窗口,然后定义对该原子内容进行操作的三个基本生命周期函数。(并将实际原子放入 a defonce

于 2017-10-25T18:48:15.933 回答