Page tree

Versions Compared


  • This line was added.
  • This line was removed.
  • Formatting was changed.

Core changes

Hibernate 3.6.10 upgraded to Hibernate 5.2.10.Final

Most of this change should be transparent as long as you use DomUI's generic access layer. The one exception is configuring Hibernate where some changes have been made. The most important one is the part that facilitates participating in the Hibernate bootstrap process. The method HibernateConfigurator.addConfigListener now needs an interface implementation with methods for the different phases of Hibernate's bootstrap process. This was needed because 5.2 removed most functionality from the Configuration class.

The new interface has a set of methods that can be implemented to change parts of the configuration at the time these are done. See the IHibernateConfigListener for details.

Basic Hibernate JPA support

DomUI works with Hibernate in JPA mode. It does assume that JPA initialization and bootstrap has been done, and provides the method

Code Block

to initialize access to the data functions within DomUI. Support is basic as more than one factory is not directly supported, but as you have the source code it should be easy to see where that can be fixed.

Javascript replaced by TypeScript


The IProgress interface, used in all asynchronous tasks, has been replaced by the Progress implementation from to.etc.alg. The interface was completely useless as all async code created a specific implementation anyway, and the implementation was very limited in what it could do. The Progress implementation is fully threadsafe and allows nested accounting of progress.

Using enums as message bundle constants

Using BundleRef's with String constants for the message names is very deprecated and will be removed. The replacement is to use enum classes that implement the new interface IBundleCode interface. The enum values act as key names for the messages, and because an enum is a class the BundleRef is associated directly with the enum too. It makes it way easier to work with message bundles. See the localisation page for more details.

Rendering through a HTML template

For cases where you want to embed DomUI pages inside a complex existing HTML page you can now render DomUI pages through a HTML template. You set the template to use per page, for instance:

Code Block
getPage().setRenderTemplate(DomApplication.get().getResource("/mytemplate.html", ResourceDependencyList.NULL));

Inside the html template you need to place special constructs to indicate where DomUI can render its <head> and <body> information, by using:

Code Block
<% r.renderHeadContent(); %>


Code Block
<% r.renderBody(); %>

Metadata changes

Initialization of metadata


  • The tab() chain is now the preferred way to build new tabs
  • All old "add" methods now return an ITabHandle.
  • The builder now gives errors if its build method is not called.
  • The TabBuilder and TabInstance classes are now final.
  • The IDisplayListener class (of which the usage was one big bug) has been removed and has been replaced with onDisplay and onHide listeners that can be set on a tab.
  • The setOnClose method in ITabHandle has been removed and has moved to the tab builder.
  • Images used in the tab header can now be either a string or some supported font icon set name (like a constant from FaIcon).
  • The ITabHandle interface now represents a tab, and all operations possible on it:
    • close() closes the tab associated with the handle
    • select() makes the tab the current tab
    • updateLabel() sets a new label name and optionally an image
    • updateContent sets new content into a tab. If the tab was defined as lazy the new content will be rendered only when the tab is made visible.
  • The TabPanel.setLabel() method has been removed and is replaced with updateLabel() on a ITabHandle.

The look- and feel of the tab panel has changed from the sad, austere squares used before to a rounded look:

Image Added

The tab panel html structure has changed too: the code now generates just the ul/li structure for the header, without "empty" li's. The basic structure is:

Code Block
<div class="ui-tab-c">
  <div class="ui-tab-hdr>
  <div class="ui-tab-c">
    <div>...content for tab 1</div>
    <div>...content for tab 2</div>

The content part of the tab is now a single div that contains the individual tab's content divs. This makes it easy to style the panels separately from the tab content area itself.

The whole look of the tab panel is now controlled by scss.

Form layout and form builders

FormBuilder changes

All "old" form builders like VerticalFormBuilder, HorizontalFormBuilder, TabularFormBuilder and the old form2 package FormBuilders have moved to Legacy and should be removed from existing code.

The FormBuilder in package form4 has been extended:

  • It has methods to also bind the readOnly and disabled properties of created controls automatically. This allows binding all controls to a single model property that for instance controls whether a user can change data.
  • Several bugs have been fixed

In addition the form builder now uses a separate IFormLayouter to handle the actual generation of the form layout as DOM nodes. FormBuilder defaults to the ResponsiveFormLayouter for layout, this can be changed by passing a layouter instance when the form builder is created.

The old layout code in FormBuilder created a html table. This caused quite some issues because controlling layout and behavior of a table is hard. The ResponsiveFormLayouter renders the form as a simple set of div nodes. The structure generated is very simple: for each label and control pair the layouter generates:

Code Block
<div class="ui-f5-pair ui-f5-pair-v">
  <div class="ui-f5-lbl ui-f5-lbl-v"><label xxxxx></div>
  <div class="ui-f5-ctl ui-f5-ctl-v">..... control....</div>

The -v is added for a vertical form, a horizontal form uses -h instead.

The entire form is inside a <div class="ui-f5 ui-f5-v"> div.

The stylesheet takes care of laying out the form which is done in a responsive way.

Look and feel

The following things have changed regarding themes, styles and look-and-feel.


The new method MetaManager#query() and the new class ListQueryHandler make it possible to run QCriteria queries on collections.

QCriteria API

Changed generic parameter for QRestrictor

The basic classes for QCriteria have been changed so that the return type for all chaining calls is now a generic parameter. This removed a whole lot of duplicated code, but with some small side effects...

The most important one is that QRestrictor<T> is now QRestrictor<T, R>, where R stands for the return type for all methods in the restrictor. This parameter is used in the definition of QCriteria and QSelection and others so that chained methods return the proper type. But QRestrictor<T> is also the result returned by or(), so all those calls need to change from:

QRestrictor<EvServer> or = c.or();


QRestrictor<EvServer, ?> or = c.or();

Addition of typed properties to all QCriteria methods

With the completion of typed properties we can now have fully typed properties without any extra work. All QCriteria related objects now have two forms for all calls: the existing form that used a String to contain a property name, and a new form that uses a QField<I, V> instance which is a typed property. This allows queries like:

Code Block
public void testFindAlbumsByArtist() throws Exception {
   List<Album> query = dc().query(QCriteria.create(Album.class).eq(Album_.artist().name(), "AC/DC"));
   System.out.println("Got " + query.size() + " results");
   Assert.assertNotEquals(0, query.size());