How to reuse the same window after refreshing in the REPL?

153 Views Asked by At

In a source file called gui.clj, I define a frame, fr, that holds the window for my application, like this:

(def fr (frame ...))

and a run function that sets up fr and causes it to repaint when data changes, something like this (modeled on scribble.clj:

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

As I'm messing around in the REPL, I often modify a source file and then call c.t.n.repl/refresh. When I run run again, it puts up a new window, leaving the old window on the screen. How can I make my (newly updated) code operate on the same window even after a refresh?

2

There are 2 best solutions below

1
Arthur Ulfeldt On

It sounds like you want to have a bit of a "lifecycle" for the stateful parts of your program, somewhat like

  1. make it exist if it does not
  2. let it run
  3. clean it up

and would like this to happen when you reload. You can have the same window continue to exist and get new contents by adding code to your clean-it-up function that clears the window, or you can close the window and create a new one for each cycle.

I have used the component library for larger projects using this style and it was very effective, though it's a bit of a lifestyle change to get used to it. for your case you may just want to initialize an atom fro store the active window then define the three basic lifecycle functions that opperate on that atom's contents. (and put the actual atom in a defonce)

1
erdos On

You can put your application's state (containing the window object) into a defonce in a separate namespace and call disable-reload on the namespace. This will prevent the reloading of the namespace when (refresh) is called thus keeping the original state (containing the original window object).

In practice, however, it is usually better to clean up and restart the application on reloads. It can be dangerous to hold to obsolete objects from the previous state of some namespace. Use component or mount to manage the application state.