This website uses cookies for visitor traffic analysis. By using the website, you agree with storing the cookies on your computer.More information

Posts tagged: JVx

EPlug 1.2.43 is out

We are happy to announce that our EPlug 1.2.43 is out.

EPlug is our Eclipse plugin for JVx applications and also for our low-code platform VisionX.

The main improvements were a complete redesign and a big performance tuning.
For sure, we have some great new features like:

  • Support for ColumnViews
  • Support for MasterReferences
  • Support for SortDefinitions
  • Support for new Var(...)
  • Metadata cache improvements
  • Avoid compile Errors when columns cannot be checked
  • Show element in tree (one click)
  • Bugfixes

Feel free to try out our new version and send us your feedback.

-> Eclipse Marketplace

Es fluttert gewaltig - Artikel

Es gibt seit kurzem einen neuen Artikel über unsere brandneue Flutter App in der deutschen Presse. Hier das Intro:

Wer eine App für mobile Geräte entwickeln möchte, steht zumindest vor einer wichtigen Frage: Mit welcher Technologie soll die App realisiert werden? Da es aktuell verschiedenste Möglichkeiten gibt, ist die Antwort nicht sofort klar. Mit diesem Problem war das Framework-Team von SIB Visions ebenfalls konfrontiert, als es darum ging, einen Client für das Open Source Application Framework JVx zu entwickeln. Wie
vor allem was umgesetzt wurde, wird ...

Der vollständige Artikel ist hier zu finden. Prädikat lesenswert :)

JVx 2.8 is available

We're happy to announce that JVx 2.8 is available. It's a big release with lots of important bug fixes and some awesome new features. The last release of JVx was in January. It was version 2.7 which was more or less a small bugfix release with few new features. We took more time for JVx 2.8 to make it awesome.

What's new?

  • Placeholder/Prompt support

    This feature is available for input fields and cell editors. Simply enable this feature:


    to get

    Prompt support

    Prompt support

  • New popup menu button

    This new button reduces the visible components. It's a must have for modern applications:

    Menu button

    Menu button

  • Savepoints for transaction handling in PostgreSql
  • Components have a unique name

    This is an important feature fore UI tests and our headless UI as well. It's now possible to address components in vaadin UI by their id to apply custom css.

  • Configurable REST services
  • Mac OS UI improvements

The full changelog is available here.

Start with JVx

JVx' REST interface Update for JVx 2.8

Our generic REST interface in JVx is well documented and different examples for different technologies are available. The generic approach itself is smart but not super specific because the implementation follows the CoC paradigm. It's awesome for "REST out-of-the-box" without additional coding effort, but the flexibility is sometimes missing.

We tried to break some of this restrictions and get more flexibility. Here is a list of new features to explain some details:

  • Fetch on demand

    The old implementation always returned all records from the database. It wasn't possible to implement paging or lazy loading. To solve this problem, we introduced new request parameters:


    With _firstRow (starts from 0) you define the start record number. The _maxRows defines the amount of records for the resultset, e.g. start from 0 and return max. 20 records, start from 20 and return 20 records

  • Configure visible columns

    The old implementation returned the same column list for the REST call and the GUI/frontend. But sometimes the REST call should return a different list of columns because some internal columns aren't relevant or should be hidden. The new implementation got a new property in the metadata object: visibleColumnNames. If you set this property, the REST interface will return only the configure columns. The GUI won't recognize the new property because GUI controls have own visible column properties.

  • Actions with Array parameters

    The old implementation didn't support simple Arrays like BigDecimal[] as parameter types for action calls. Only List was supported. The new implementation supports Arrays but it's not possible to mix Array and List parameters. An example:

    public String createPerson(String[] name, String[] title)
    public String createPerson(List<String> name, List<String> title)
    public String createPerson(String[] name, List<String> title)
  • New admin zone

    We introduced a new admin zone for generic admin options. The URLs are:


    Currently, we support following actions (POST requests): changePassword, testAuthentication

    The request needs a JSON object with username, oldpassword, newpassword or password properties.

  • Configurable zones

    We now allow custom zones. The current default zones are:


    The zone names are: _admin, data, action, object
    It's possible to set custom names with following parameters in the deployment descriptor: zone.admin,, zone.action, zone.object

  • Hide object names

    If you want to hide the object name(s), e.g.


    The URL contains the Lifecycle Name (Customers) and the object name (customer). Both are easy to understand. In this example, we return the customer list from our customers object. If you want to use different names, it's possible to change the name in the lifecycle object code, e.g.

    public class Customers extends Session
        public IStorage getCustomer()

    With above code, it'll be possible to request:


The updated implementation is still a generic solution but it's now more flexible than before and should help you to offer new services. To use the new features, simply use our nightly JVx builds.

Workflow Engine for Oracle Forms

I'm happy to announce that our Workflow Engine will work with Oracle Forms.

The current state is beta but we'll release our Workflow engine in the next days. We found some time to test the integration in Oracle Forms and the result is soo cool. It works like a charm.

So it will be possible to embed our Workflow engine in your oracle Forms. It'll be possible for your users to design custom flows and processes. The engine itself is database driven and will work with your Oracle Forms application.

More details will follow in the next days, but here's a first impression:

Workflow Engine - Oracle Forms

Workflow Engine - Oracle Forms

It's a standard Oracle Forms window/canvas with our Workflow Designer, embedded as Java Bean.

Feel free to ask your questions ;-)

MacOS Swing Look and Feel

We improved the support for standard MacOS LaF in our Swing UI and VisionX. The LaF has a lot of rendering problems. We tried to use another LaF implementation but had other problems. So we decided to keep the standard Java MacOS LaF.

The problems

  • The InternalFrame border problem
  • The field border problem
    Field border problem

    Field border problem

    A simple JTextField has a 5 pixel focus border. This is horrible because the focus is about 2 pixel. The other problem is that a JTextArea wrapped in a JScrollPane doesn't have the 5 pixel border. This makes it hard to create nice looking layouts.

    We fixed this problem:

    Field border without gap

    Field border without gap

    Looks better. One problem is that the JScrollPane doesn't paint the focus if the JTextArea has the focus. This is a LaF problem and we didn't find a workaround for this problem.

  • Application Menubar

    Standard Java appliacations show the menubar in the same frame

    Application menu

    Application menu

    If you set the system property:

    System.setProperty("apple.laf.useScreenMenuBar", "true");
  • the menu will be placed in the menu bar of MacOS:

    macOS Menu

    macOS Menu

    We fixed the problem that setting the menu to null will keep the menu as it was.

  • Comboboxes

    The height of Standard Comboboxes is wrong:

    Combobox wrong

    Combobox wrong

    We fixed the problem as good as possible:

    Combobox fixed

    Combobox fixed

  • VisionX Toolbar height

    The toolbar height was wrong because of layout calculation problems:

    Wrong Toolbar height

    Wrong Toolbar height

    We fixed the problem and the toolbar height is correct:

    Toolbar fixed

    Toolbar fixed

  • VisionX Wizard gaps

    The image gaps in VisionX wizards was not recognized:

    Wrong gaps

    Wrong gaps

    It looks better without gaps:

    No gaps

    No gaps

  • Wrong button rendering

    If you had a button without an image and a button with an image, the height of the button without image was higher than the button with an image. This is a LaF rendering bug:

    Wrong size and font

    Wrong size and font

    The fonts are also different. We didn't know why there has to be such a difference, but we fixed the problem in Swing UI:

    Button with correct size and font

    Button with correct size and font

All changes are available in our nightly JVx builds

JVx and PostgreSQL, supporting Savepoints

Transactions are an integral mechanism of databases, without them we could hardly ensure data consistency. Well, we could of course, but it would be a lot more work. JDBC has of course support for transactions, but it also supports so called "Savepoints", which we will have a look at today.

What are transactions?

Normally, I'd assume that everyone of you knows what transactions are and what they are used for, but today I will quickly rehash it to make sure. Transactions enable us to define groups of statements to be executed on a database with all either succeeding or all failing. Imagine the following statements which might be executed on a database as one action:

1: Insert record into A
2: Update record of B
3: Update another record of B
4: Insert record into C

This might happen in the background if you click a button or do something similar. This example is straightforward but if we start thinking about possible problems we will soon realize that there is a lot of potential for things going wrong. For example if statement #3 would fail we would miss records in the tables B and C. Overall, our data would be in an inconsistent state after that. To make sure that it does not happen, we can define these statements as a single transaction.

  |-Insert record into A
  |-Update record of B
  |-Update another record of B
  |-Insert record into C

If one of these statements fail, all changes done by previous statements can be undone and the database will return to the state before we started manipulating it. That is great, because we can now guarantee that even though an error has happened, the data will remain in a consistent state.

We could even extend that with additional application logic, for example we insert three records and then we check if the values of all records add up to a certain threshold, if yes, we simply undo the changes. Or if we notice that a constraint has been violated (though, pretty much all databases support constraint definitions in one way or the other). Additionally, transactions are completely isolated from all other connected clients. That means that if we start a transaction and insert a record into table A, all other clients will not see this record until we commit our changes. So the data is never in an inconsistent state, not even temporarily or transiently.

What are Savepoints?

Savepoints are sub-transactions within another transaction. It allows to undo parts of an ongoing transaction.

Another example:

  |-Insert record into A
  |-Insert child record into B
  |-Insert child record into B
  |-Insert another record into A
  |-Insert child record into B
  |-Insert child record into B
  |-Insert another record into A
  |-Insert child record into B
  |-Insert child record into B

This is a little bit more fabricated and complicated, assume we want to insert three master records with two detail records each. The following conditions apply:

  • If a master record fails to insert, nothing should be inserted.
  • If a detail record fails to insert, the corresponding master record should also not be inserted.

This is hard to do with a simple transaction, but is quite easy when it comes to using savepoints:

  |-Savepoint 1
  |   |-Insert record into A
  |   |-Insert child record into B
  |   \-Insert child record into B
  |-Savepoint 2
  |   |-Insert another record into A
  |   |-Insert child record into B
  |   \-Insert child record into B
  |-Savepoint 3
  |   |-Insert another record into A
  |   |-Insert child record into B
  |   \-Insert child record into B

We create a savepoint before the insert of the master record, if the insert of the master record fails we rollback the transaction, if the insert of a detail record fails we rollback to the savepoint we created earlier. This allows quite complicated and nested transactions, especially because there is no defined limit to how deep savepoints can be nested.

Error behavior

Of course it can always happen that a statement fails for one reason or another, so it is important to know how the database behaves once an error occurred. We built ourselves another simple example:

  |-Insert record into A
  |-Insert record into B (this fails)
  |-Insert record into C

We insert three records, and the second one fails to insert. How should the database behave in such a situation? Turns out that this differs between different database systems.

Silent/Automatic restore to a previous state

Many databases perform a simple "silent/automatic restore to a previous state", all changes done (if any) of the current statement are undone and the transaction can be treated like the failing statement never happened. With the example above, and assuming that we do not cancel the transaction on an error, the records would be inserted into A and C.

In our tests Oracle, MySQL/MariaDB, H2 and SQLite were all behaving this way.

Requiring manual recovery

PostgresSQL requires to perform a "manual recovery" from a failed statement. So that once an error occurred during a transaction, the user has to revert to a (manually) set savepoint or rollback the complete transaction. We will go into details on that later.

Reverting everything and happily continuing

MS SQL on the other hand has a quite different approach. When an error occurs during a transaction, all changes are (automatically) rolled back but the transaction can still be used. So in our example, only the record in C would be inserted.

PostgreSQL JDBC and Savepoints

Back to PostgresSQL and how it requires manual recovery. When a statement fails within a transaction in PostgreSQL, the transaction enters the aborted state and one can then see an error like the one below if further statements are issued:

Current transaction is aborted, commands ignored until end of transaction block.

What that means is simple that the connection/server is still waiting on input on what to do with the transaction. There are three possible ways to recover from there:

  1. Rollback the complete transaction
  2. Commit, which will be transformed into a rollback at this point
  3. Rollback to a savepoint

But these actions must be initiated by the user before the transaction can be further used (or not, if it is being rolled back completely). If one wants to emulate the behavior of other databases in PostgreSQL, every statement that is executed within a transaction has to be "wrapped" with a savepoint, in pseudo-code:

begin transaction
        execute statement
        release savepoint
        rollback to savepoint

Even though that seems tedious, that is not the case. If you have such a requirement you already have central point through which all statements pass before being executed, so this can be implemented easily.

JVx and Savepoints

In our case it is DBAccess, our main datasource. Because every database interaction has to pass through DBAccess (in one way or the other), we could easily implement such emulation at a low-level and it is automatically available to all users. To be exact, DBAccess has received internal support to wrap all statements in savepoints when configured to do so. This configuration possibility is protected and is currently only used by the PostgresSQL DBAccess extension. It does exactly what it says on the tin and is only active when enabled and automatic commits have been turned off. So this change does have no effect on any other database but PostgreSQL.

We already have plans to extend this basic savepoint support with a public API which allows users of JVx to utilize this new functionality. One of the ideas that we are currently discussing is to provide the ability to create named savepoints. A simple mockup of that idea:

  1. // Switch off auto commit to use transactions.
  2. dbAccess.setAutoCommit(false);
  4. // Insert some data.
  5. dbStorage.insert(aRecord);
  6. dbStorage.insert(anotherRecord);
  8. // This part is optional.
  9. try
  10. {
  11.     dbAccess.setSavepoint("NAME");
  13.     dbStorage.insert(yetAnotherRecord);
  14.     dbStorage.update(someOtherRecord);
  15. }
  16. catch (DataSourceException dse)
  17. {
  18.     log.error(dse);
  19.     dbAccess.rollbackTo("NAME");
  20. }
  22. dbAccess.commit();

As said, we are currently in the process of discussing such possibilities but definitely want to provide such an API at one point.


As it turns out, the "special" behavior of PostgreSQL isn't as special as it seems to be. It is a design decision that was taken and that is understandable. Changing this behavior now, 20+ years in, is out of the question as it would require a substantial effort to make sure that this behavior is backwards compatible. The gains from such a change on the other hand would be very little, as it is a quite specialized case in which this behavior matters and the "fix" is rather easy.

JVx 2.7 is available

We're happy to announce that JVx 2.7 is available. It's a bigger bugfix release with a small number of new features.

What's new?

  • Tibero Database Support
  • boolean support

    Our DBAccess implementation now supports boolean as parameter.

  • SimpleJavaSource

    It's now possible to create java objects from java source code, see our REST interface

  • Struct support

    Struct support for Oracle DB in procedures and functions.

  • Session timeouts

    We fixed the problem of session timeouts with long up/downloads.

  • WorkScreen

    It's now possible to open a work-screen with additional parameters. A new (optional) Parameter class is available.

  • Mac OS

    We fixed the problems with internal frame borders.

  • Many improvements

The full changelog is available here.

Start with JVx

VisionX, JVx and native Vaadin

If you create an application with VisionX, it's always a JVx based application. You get all advantages of JVx and its GUI independency, but sometimes the GUI indepency is not important and you want to use native GUI controls in your JVx application because JVx doesn't contain the GUI control or you need a commercial control. This is a very simple use-case and it's not a problem to mix JVx components with native components. We have different examples, with different GUI technologies, for this use-case.

Here are some links:

But we don't have a link for our Vaadin implementation. But no problem, here it is!

Simply create a new application with VisionX and a dummy screen like this one:

Simple screen

Simple screen

The screen contains a simple table and two editors. Nothing special. Now we want to add a custom Vaadin component in the empty space. It doesn't matter which component you use. Every vaadin component or AddOn component can be used. JVx doesn't do specific things, it's only an UI abstraction layer.

So, lets add an Accordion to the screen:

Integrated Accordion

Integrated Accordion

The Accordion component is a standard Vaadin component, simply added to the screen. But more... Do you see the "Show Vaadin Notification" Button? This is a standard JVx component. So we mix native vaadin components with standard JVx components and get the full power of both. One advantage of the JVx components is that the automatic translation works without additional hacks, or what about JVx' layouts, event handling, ...

Interested in the source code?

No worries, it's super simple to understand :)

Lets have a look at the custom code:

UIButton butNotification = new UIButton("Show Vaadin Notification");
butNotification.eventAction().addListener(new IActionListener()
        public void action(UIActionEvent arg0) throws Throwable
                Notification noti = new Notification("Message",
                                                     "Description", Type.WARNING_MESSAGE);

UIFormLayout flJVxPanel = new UIFormLayout();

UIPanel panJVxPanel = new UIPanel();


if (getApplication().getLauncher().isWebEnvironment())
        Accordion acc = new Accordion();
        acc.setHeight(100.0f, Unit.PERCENTAGE);

        for (int i = 1; i < 8; i++)

                if (i >= 2)
                        final Label label = new Label("Welcome sheet!", ContentMode.HTML);
                        label.setWidth(100.0f, Unit.PERCENTAGE);

                        final VerticalLayout layout = new VerticalLayout(label);

                        acc.addTab(layout, "Tab " + i);

                        acc.addTab(((Component)panJVxPanel.getResource()), "Tab " + i);

        groupPanelOverview.add(new UICustomComponent(acc), formLayout1.getConstraints(0, 2, -1, -1));

The Accordion source code was copied from Vaadin Sampler:

sample = new Accordion();
sample.setHeight(100.0f, Unit.PERCENTAGE);
for (int i = 1; i < 8; i++) {
    final Label label = new Label(TabSheetSample.getLoremContent(), ContentMode.HTML);
    label.setWidth(100.0f, Unit.PERCENTAGE);
    final VerticalLayout layout = new VerticalLayout(label);
    sample.addTab(layout, "Tab " + i);

So, what are the most interesting parts in our code?

First, we add the JVx panel to another JVx panel. This is important to get support for translation. If it's not important for your, simply ignore the line:


The groupPanelOverview is a simple UIGroupPanel with UIFormLayout:

UIFormLayout formLayout1 = new UIFormLayout();

UIGroupPanel groupPanelOverview = new UIGroupPanel();


groupPanelOverview.add(labelName, formLayout1.getConstraints(0, 0));
groupPanelOverview.add(editOverviewName, formLayout1.getConstraints(1, 0));
groupPanelOverview.add(labelDescription, formLayout1.getConstraints(0, 1));
groupPanelOverview.add(editOverviewDescription, formLayout1.getConstraints(1, 1, -1, 1));

Our JVx button will be added to the native vaadin Accordion with following code:

acc.addTab(((Component)panJVxPanel.getResource()), "Tab " + i);

We don't add the JVx component itself, we use the wrapped resource. This is a simple vaadin component: com.vaadin.ui.Button

And finally, we add the Accordion as custom component to our JVx group panel:

groupPanelOverview.add(new UICustomComponent(acc), formLayout1.getConstraints(0, 2, -1, -1));

This code:

if (getApplication().getLauncher().isWebEnvironment())

is important for VisionX because the vaadin components aren't available in Swing, so we use this check for the supported environment.

So far, we mixed native vaadin components with JVx components. It's super easy to use, isn't it?

But it's also possible to use CSS for JVx components:

Css style for Button

Css style for Button

The button got the friendly style, which is defined in Vaadin CSS. Check some examples.

To add the friendly style class to the JVx button, simple add:

Style.addStyleNames(butNotification, "friendly");

This example is using predefined CSS from vaadin. It's also possible to set custom styles in your own css file. Simple follow this instructions.

This article covered the integration of native vaadin components into an existing JVx application with all advantages of vaadin.

JVx Reference, CellEditors

Let's talk about CellEditors, and how they are decoupled from the surrounding GUI.

What are they?

While we've already covered large parts of how the GUI layer and the model of JVx works, the CellEditors have been left completely untouched and unmentioned. One might believe that they can be easily explained together with the Editors, however, they are a topic on their own, and a complex one from time to time that is.

The difference between Editors (the UIEditor for the most part) and CellEditors is that the Editors only provide the high-level GUI control, while the CellEditors provide the actual functionality. Let's take a look at a quite simple screen.

The layout of a simple screen with a table and a few editors.

We see a window with a table on the left and some editors on the right, simple enough. Now these components we are seeing are UIEditors, not CellEditors. The CellEditors themselves are only added as child components to the Editors, so the Editors are basically just panels which contain the actual CellEditor.

The same scree but with the CellEditors differentiated from the UIEditors which contain them.

So technically every UIEditor is just another panel which gets the CellEditor added. The CellEditors themselves follow the same pattern as all GUI components in JVx, there is the base interface, an eventual extension of technology components, the implementation and finally the UI object. They are, however, rarely directly used in building the GUI, but mostly only referenced when building the model.

Why are they?

If you want to make GUI editor components, I know of two possible ways from the top of my head to achieve that: You create dedicated editor components for the datatypes that are available, for example a NumberEditor, TextEditor and so forth. Or you create one editor component which acts as a mere container and allows to plug in any wanted behavior for the type you're editing.

We've opted for the second option, because it means that the GUI is actually decoupled from the datatypes (and in extension the data) of the model. If we'd have separate components for each datatype, changing the datatype of a single column would mean that you'd have to touch all editors associated with that column and change that code, maybe with rippling effects on the rest of the GUI. With the CellEditors, one can change the datatype of a column and not worry about the GUI that is associated with that column. The CellEditor is changed on the model once and that change is automatically picked up by all Editors. Which also means that one can define and change defaults very easily and globally.

Of course one can also set the preferred or wanted CellEditor directly on the Editor, instead of using the one defined in the model, should the need arise.

And the table?

The same applies to the Table. Theoretically, every cell of the Table can be viewed as a single Editor, for this context at least. So a single cell behaves the same as an Editor when it comes to how the CellEditors are handled.

How many are there?

JVx comes with a variety of CellEditors out of the box:

  • Boolean
  • Choice
  • Date/Time
  • List
  • Number
  • Text
    • HTML
    • Multiline
    • Password
    • Standard

With these nearly all needs can be covered. If there is need for a new one, it can be created and added like any other UI component.

Using CellEditors

As said previously, which CellEditor is used is defined primarily with the model, for example:

  1. private void initiliazeModel() throws ModelException
  2. {
  3.     dataBook = new MemDataBook();
  5.     ICellEditor cellEditor = new UITextCellEditor();
  6.     IDataType dataType = new StringDataType(cellEditor);
  7.     ColumnDefinition column = new ColumnDefinition("COLUMN", dataType);
  9.     RowDefinition rowDefinition = dataBook.getRowDefinition();
  10.     rowDefinition.addColumnDefinition(column);
  13. }
  15. private void initializeUI() throws ModelException
  16. {
  17.     editor = new UIEditor(dataBook, "COLUMN");
  19.     add(editor);
  20. }

We can see that every column has a datatype and every datatype has a CellEditor. That allows the model to provide the actual editing functionality without changing the GUI code. The Editor, when notifyRepaint() is called, will fetch the CellEditor from the datatype and use it. Additionally, there is a technology dependent default mechanism which allows this system to work even when the UI classes are not used.

Let's do a step by step explanation of what happens:

  1. The model is created.
  2. The GUI is created.
  3. The model invokes notifyRepaint() on all bound controls.
  4. The Editor gets the CellEditor from the model and adds it to itself.

One moment, instance sharing?

If we revisit at the example code from above, we will notice that the CellEditor instance is set on the model and must then be used by the Editor. That means that a single CellEditor instance is used for all bound Editors. We all know that sharing instances in such a way can be fun, but in this case it is not a problem because CellEditors are only "factories" for the actual editing components.

The ICellEditor interface does actually only specify two methods, whether it is a direct cell editor, and the factory method for creating an ICellEditorHandler. The CellEditorHandler is the manager of the instance of the component that is going to be embedded into the Editor.

  1. notifyRepaint() is called on the editor.
  2. The Editor gets the CellEditorHandler from the CellEditor.
  3. The Editor gets the component from the CellEditorHandler and embeds it.

This mechanism makes sure that no component instances end up shared between different GUI components.

A closer look at the CellEditorHandler

If we take a good look at the CellEditorHandler interface, we see that it contains everything that is required for setting up a component to be able to edit data coming from a DataRow. One method is especially important, the getCellEditorComponent() function. It returns the actual technology component that is to be embedded into the Editor. That means that even though there are implementations for the CellEditors on the UI layer, the actual components which will provide the functionality for editing the data are implemented on the technology layer. A short refresher:

The different layers of JVx.

Revisiting our simple screen from above, we'd actually need to represent it as something like this:

FormLayout with one added component.

Because the embedded components in the Editor are actually on the technology layer.


There is another small topic we need to discuss, CellRenderers. They follow nearly the same schematics as CellEditors but are used to display values directly, for example values in a table cell. The Table is also the primary component which uses them to display the cell values until the editing is started. For simplicity reasons, most CellEditors implement ICellRenderer directly and provide management of the created component. That is because the reuse of components for barely displaying values is easier does not contain as much error potential.


CellEditors provide an easy mechanic to allow to edit data, and more important, they are decoupled from the GUI code in which they are used in a way which allows the model to change, even dynamically. That enables programmers to create and edit screens and models quickly without the need to check if the GUI and the model fit together, they always do.