Views
8 months ago

tornadofx-guide

Workspaces As mentioned,

Workspaces As mentioned, you never need to do this and should always use the connectWorkspaceActions call, but you might want to override one of onSave , onDelete or onRefresh to perform some action in the main editor before calling the same action inside the active tab by calling root.onXXX . Let's say that the refresh call in the main editor reloads the customer, but you also want to have the contact list refresh if that view is currently active. This could be done like this: class CustomerEditor : View() { val customerController : CustomerController by inject() val customer: CustomerModel by inject() override val root = tabpane { tab(CustomerBasicDataEditor::class) tab(ContactListEditor::class) connectWorkspaceActions() } } override val onRefresh() { runAsync { customerController.getCustomer(customer.id.value) } ui { customer.item = it root.onRefresh() } } This little trick enables you to handle the actual reload of the customer in the main view instead of reimplementing it in every tab. Forwarding button state and actions As we have seen, the currently docked View controls the Workspace buttons. Some times you dock nested Views inside the main View, and you would like that nested View to control the buttons and actions instead. This can easily be done with the forwardWorkspaceActions function. You can change the forwarding however you see fit, for example on focus or on click on some component inside the nested View. class CustomerEditor : View() { override val root = hbox { val basicDataEditor = find() add(basicDataEditor) forwardWorkspaceActions(basicDataEditor) add(ContactListEditor::class) } } 230

Workspaces Modifying the default workspace The default workspace only gives you basic functionality. As your application grows you will want to suplement the toolbar with more buttons and controls, and maybe a MenuBar above it. For small modifications you can augment it in the onBeforeFunction as we did above, but you will most probably want to subclass as the customizations become more advanced. The following code and image is taken from a real world CRM application: class CRMWorkspace : Workspace() { init { add(MainMenu::class) add(RestProgressBar::class) add(SearchView::class) } } The CRMWorkspace loads three other views into it. One providing a MenuBar , then the default RestProgressBar is added, and lastly a SearchView providing a search input field is added. The Workspace has a pretty good idea about where to place whatever you add to it. For example, buttons will by default be added after the four default buttons, while other components are added to the far right of the ToolBar. The MenuBar is automatically added above the ToolBar, at the top of the screen. Figure 16.3 shows how it looks in production, with a little bit of custom styling and a CustomerEditor docked into it. This application happens to be in Norwegian, and some of the information in the Customer card has been removed. Figure 16.3 231

GUIDE
GUIDE
GUIDE
Guide
GUIDE
Guide
GUIDE
GUIDE
Guide
GUIDE
Guide
GUIDE
Guide
GUIDE
GUIDE
GUIDE