The EntityApplicationPanel class serves as the main application UI. When extending this class you must provide a constructor with a single application model parameter, as seen below.
The constructor takes the application’s root entity panels, and optionally a set of lookup panel builders: panels for supporting entities — lookup and reference data — which appear in the application’s View menu and open on demand, in their own windows, rather than occupying a tab.
public class StoreApplicationPanel extends EntityApplicationPanel<StoreApplicationModel> {
public StoreApplicationPanel(StoreApplicationModel applicationModel) {
super(applicationModel, createPanels(applicationModel), createLookupPanelBuilders());
}
private static List<EntityPanel> createPanels(StoreApplicationModel applicationModel) {
CustomerModel customerModel = (CustomerModel)
applicationModel.models().get(Customer.TYPE);
CustomerAddressModel customerAddressModel = (CustomerAddressModel)
customerModel.detail().get(CustomerAddress.TYPE);
EntityPanel customerPanel = new EntityPanel(customerModel,
new CustomerEditPanel(customerModel.editModel()),
new CustomerTablePanel(customerModel.tableModel()));
EntityPanel customerAddressPanel = new EntityPanel(customerAddressModel,
new CustomerAddressEditPanel(customerAddressModel.editModel()));
customerPanel.detail().add(customerAddressPanel);
return List.of(customerPanel);
}
private static List<EntityPanel.Builder> createLookupPanelBuilders() {
EntityPanel.Builder addressPanelBuilder = EntityPanel.builder()
.entityType(Address.TYPE)
.panel(connectionProvider -> {
SwingEntityModel addressModel =
new SwingEntityModel(Address.TYPE, connectionProvider);
return new EntityPanel(addressModel,
new AddressEditPanel(addressModel.editModel()));
});
return List.of(addressPanelBuilder);
}
public static void main(String[] args) {
Locale.setDefault(new Locale("en", "EN"));
EntityPanel.Config.TOOLBAR_CONTROLS.set(true);
ReferentialIntegrityErrorHandling.REFERENTIAL_INTEGRITY_ERROR_HANDLING
.set(ReferentialIntegrityErrorHandling.DISPLAY_DEPENDENCIES);
EntityApplication.builder(StoreApplicationModel.class, StoreApplicationPanel.class)
.domain(Store.DOMAIN)
.defaultUser(User.parse("scott:tiger"))
.start();
}
}
1. Starting the application
An application is assembled and started with the EntityApplication builder, which handles the startup sequence: look and feel, login (unless a user is provided), connection, application model and panel construction, and the main frame. The main method is also the natural place to configure framework defaults — configuration values apply to every panel created after them. The Chinook demo exercises a good portion of the configuration surface:
public static void main(String[] args) throws CancelException {
String language = UserPreferences.get(LANGUAGE_PREFERENCES_KEY, Locale.getDefault().getLanguage());
Locale.setDefault(LANGUAGE_IS.equals(language) ? LOCALE_IS : LOCALE_EN);
UIManager.put("PasswordField.showRevealButton", true);
FrameworkIcons icons = FrameworkIcons.instance();
icons.put("plus", ChinookAppPanel.class.getResource("plus.svg"));
icons.put("minus", ChinookAppPanel.class.getResource("minus.svg"));
icons.put("graph-pie", ChinookAppPanel.class.getResource("graph-pie.svg"));
Completion.COMPLETION_MODE.set(Completion.Mode.AUTOCOMPLETE);
EntityApplicationPanel.CACHE_ENTITY_PANELS.set(true);
EntityApplicationPanel.SQL_TRACING.set(true);
EntityPanel.Config.TOOLBAR_CONTROLS.set(true);
EntityPanel.Config.WINDOW_TYPE.set(WindowType.FRAME);
EntityEditPanel.Config.MODIFIED_WARNING.set(true);
EntityEditPanel.Config.INCLUDE_INSPECTOR.set(true);
// Add a CTRL modifier to the DELETE key shortcut for table panels
EntityTablePanel.ControlKeys.DELETE.defaultKeystroke().update(keyStroke ->
keyStroke(keyStroke.getKeyCode(), MENU_SHORTCUT_MASK));
EntityTablePanel.Config.COLUMN_SELECTION.set(SelectionMode.MENU);
EntityTablePanel.Config.AUTO_RESIZE_MODE_SELECTION.set(SelectionMode.MENU);
EntityTablePanel.Config.INCLUDE_FILTERS.set(true);
EntityTablePanel.Config.INCLUDE_INSPECTOR.set(true);
EntityTablePanel.Config.INCLUDE_EXPORT.set(true);
FilterTable.AUTO_RESIZE_MODE.set(JTable.AUTO_RESIZE_ALL_COLUMNS);
FilterTable.ROWS_FILL_VIEWPORT.set(true);
FilterTable.STOP_EDIT_ON_FOCUS_LOST.set(false);
FilterTableCellRenderer.NUMERICAL_HORIZONTAL_ALIGNMENT.set(SwingConstants.CENTER);
FilterTableCellRenderer.TEMPORAL_HORIZONTAL_ALIGNMENT.set(SwingConstants.CENTER);
FilterTableHeaderRenderer.FOCUSED_COLUMN_INDICATOR.set(true);
ValidIndicator.INDICATOR_CLASS.set("is.codion.plugin.flatlaf.indicator.FlatLafValidIndicator");
CalendarPanel.WEEK_NUMBERS.set(true);
ReferentialIntegrityErrorHandling.REFERENTIAL_INTEGRITY_ERROR_HANDLING
.set(ReferentialIntegrityErrorHandling.DISPLAY_DEPENDENCIES);
EntityApplication.builder(ChinookAppModel.class, ChinookAppPanel.class)
.domain(Chinook.DOMAIN)
.version(ChinookAppModel.VERSION)
.defaultLookAndFeel(MaterialTheme.class)
.defaultUser(User.parse("scott:tiger"))
.start();
}
2. Layout
The root entity panels are laid out by an ApplicationLayout — by default a TabbedApplicationLayout, one tab per root panel, initialized lazily as they are first displayed. Supply a custom layout via the EntityApplicationPanel constructor to arrange the root panels differently.
3. SQL Tracing
|
Note
|
SQL Tracing is only available when using a local EntityConnection. |
Application SQL Tracing can be enabled via the EntityApplicationPanel.SQL_TRACING configuration value.
This configures the underlying EntityConnection to trace its queries and adds a SQL Trace item under Help → Log main menu, with actions to enable tracing and view the trace log.
Disabling SQL Tracing clears the trace log.
EntityApplicationPanel.SQL_TRACING.set(true);