I have recording and playback mostly working now.
Firstly, I build a class to contain a recording. Then I decoupled an input event like a button press from the action that should result. instead of
button push -> do thing
it is now
button push -> recording middleman -> do thing
then if recording is on, button pushes are saved. if playback is on, button pushes are ignored and instead the recorded value is used.
The last part that still bugs me is changing tools. As before, there is a list of tools obtained by using a ServiceLoader and I don't know what to do if, on playback, the ServiceLoader doesn't find the matching tools. Oops! I believe the easiest will be to run the SL once at the start and build a table of tools, then refer to them by index. that means on file start we can check all files are in place first. It would be extra clever if those tools had a URL so that they could be found by an automatic install system....but that's a tomorrow problem.