Omnis Technical Note TNOO0005 May 2011

Encapsulation of GUI Objects

For Omnis Studio 4/5
By Andreas Pfeiffer

Clean up your class method $construct

When a window is opened, some lists have to be loaded. I assume you are already using data objects such as lists from table classes or object classes. Still it can be a problem that the $construct method of a window class gets longer and longer, as specific conditions have to be met. But as soon as five or more lines of code are included in a method it can get quite confusing. This is especially true when you need to scroll your methods in the Method Editor when looking at your code. There may be better ways of doing it.

Use your own $construct methods for your GUI objects

Each object in a window can have its own $construct method. Simply add such a method to the object. In a normal window (fat client) all field related $construct methods are executed before the $construct method of the window class. The advantage of this technique is that all lists can be loaded, for example, before the detail record is loaded. In a remote form (Web Client) however, we don’t have this automation. But this is not really a problem as we can activate all $construct methods of the remote form with a $sendall from the $construct method of the class:

Do $cinst.$objs.$sendall($ref.$construct())

Please note that is not necessary in a normal window – in fact you would execute the different $construct methods twice.

Use the field methods to fetch, synchronize and store data

However, a field can have other methods, other than its own $construct method. You can greatly improve clarity when, for example, you could create a $build, $sync, and maybe a $save method for a list field and store the methods in the field object itself. Your code will get much shorter in other places and you only need to send the message to the appropriate GUI object.

To be able to call from other fields you should make such methods “public”: to do this, the method name must start with a “$” sign. So the method can be called from other places with a message sending:

Do $cinst.$objs.myGrid.$build()

This method sends a message to the field “myGrid” to execute the method “$build” in the current window instance ($cinst in this case).

Sending a message to another GUI object
Sending a message to another GUI object

Please note that each field can have its own methods that can be called in any way. This way you don’t have to think afterwards how for example a certain $build method of a field works. You just have to call it when you want a list of an object to be loaded.

Fields to display a single record get a container...

For entry fields, radio buttons and check boxes that are displaying a single record, it may not be obvious where such $build or $save methods should be placed. It is a good trick to group these fields in a group box so that you can then place the methods inside the group box. A nice side effect of this solution is that it is also very helpful for the arrangement of the GUI components as it makes it much easier for the user to recognize what belongs together.

... or a subwindow

Alternatively you can place such a data unit in a subwindow. However, in this case you need to have the described methods in its window class to make sure they can be called from the main window.

No SQL in a window!

Now you might think that the $build methods could contain the SQL code. Please don’t! Separate the SQL code and either use table classes or put your SQL code in separate object classes.

The individual field methods should be clear and succinct. You will realize that this coding strategy will make it much easier for you to maintain it and to re-use the class when appropriate.

Message to an object variable to send a list for the tree object
Message to an object variable to send a list for the tree object.