ActionsAndCommands

This interface is NOT USED, it is only here for Documentation.

Glok includes 4 utility classes help separate how : Action, Actions, Command and Commands.

Actions let you define the text, graphics, tooltip and shortcuts for every button, menu and menu item. Commands lets you add the behaviour for a subset of those Actions, and then use it to build the controls.

So instead of :

  • toolBar {

  • button( "Save", theSaveGraphic ) { onAction{ saveTheFile() } }

  • button( "Load", theLoadGraphic ) { onAction{ loadAFile() } } }

  • subMenu {

  • menuItem( "Save", theSaveGraphic ) { onAction{ saveTheFile() } }

  • menuItem( "Load", theLoadGraphic ) { onAction{ loadAFile() } } }

You'd have something like :

val commands = Commands().apply { with( myActions ) { FILE_SAVE { saveTheFile() } FILE_LOAD { loadAFile() } } }

  • toolBar { with(commands) { with(myActions) {

  • button(FILE_SAVE)

  • button(FILE_LOAD) } } }

  • menuBar { with(commands) { with(myActions) {

  • menuItem(FILE_SAVE)

  • menuItem(FILE_LOAD) } } }

Key points :

  1. We have split how buttons behave from how they appear. The GUI building code has no logic code in it.

  2. There is no duplication. saveTheFile() is only called from one place.

  3. I didn't show the extra work needed to handle keyboard shortcuts. Using the first approach, is a PITA, with yet more duplication of calls to saveTheFile() etc. In the seconds approach, it's as simple as : commands.attachTo( myNode ). The shortcuts will work whenever the input focus is within myNode's subtree.

  4. Tooltips and menu items will automatically include the keyboard shortcuts. If the user customises these shortcuts, the tooltips and menu items will reflect those changes.

Notes

  1. with(myActions) is only there so that you don't have to use the repetitive : myActions.FILE_SAVE, myActions.FILE_LOAD etc.

  2. button and menuItem are methods of Commands, which take an Action as their argument.

  3. When writing an I18N application, there is provision for changing language on the fly. Each Action has a single textProperty, that buttons' and menu items' textProperty is bound to. So to change languages, you need to update textProperty for each Action. I suggest you bind it like so : action.textProperty.bindTo( translation(languageProperty, text) ) Where translation is a StringUnaryFunction using resource bundles.

  4. To allow users to customise keyboard shortcuts, you'll need to write that GUI yourself. There is no one size fits all solution for this, so I don't intend providing one.