Class ThemeEditorFiles

java.lang.Object
limn.themeeditor.ThemeEditorFiles

public final class ThemeEditorFiles extends Object
Open and Save As for a ThemeEditor, through the platform's own chooser.

Separate from the editor, and optional, because where a palette lives is the application's decision: a file is one answer, but a preferences store, a document bundle and a server are all as likely, and a widget that assumed the first would have to be worked around by everyone who meant one of the others. The editor itself moves a palette through the clipboard and needs nothing from the platform at all.

Two different things block here, and only one of them is avoidable. The chooser is a system-modal panel (on macOS and Linux it is not even drawn by this process), so the application stops while it is up, and FileDialogs explains at length why no asynchronous form of that would be honest. Reading and writing the bytes is a different matter: that is disk work with no user in it, so it goes through Ui.work(limn.concurrent.Work.Body<T>) and lands back on the UI thread, which is what this repository asks of anything that touches a file.

Every outcome, including every failure, is reported on the editor's own status line. Nothing here throws at the caller: a chooser the user cancelled, a file that turned out not to be a palette and a disk that was full are all ordinary, and none of them is a bug in the application that opened the editor.

  • Method Details

    • buttons

      public static Widget buttons(ThemeEditor editor)
      A row of the two buttons, for an application that wants them in its own toolbar.
    • open

      public static void open(ThemeEditor editor)
      Asks for a palette file and loads it into editor. The chooser blocks; the read does not. A cancelled chooser does nothing at all, silently, which is what cancelling means.
    • saveAs

      public static void saveAs(ThemeEditor editor)
      Asks where to put the palette and writes it there. The text is produced here, on the UI thread, before any of it goes to a worker: it is read out of live widget state, and a worker that read the editor while the user kept typing would be reading widget state off the UI thread, which throws, and rightly.