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

Category: Development

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

Our brand-new WorkFlow engine

This article is a short introduction of our brand-new product. It's a super simple workflow engine. Our workflow engine is database driven and can be configured and extended for your needs. The engine itself contains a simple board which allows you to create workflows. The configuration will be read from and saved into a database. The workflow steps are configured in the database and the engine simply executes the configured steps.

We tried to find a workflow solution for our needs or a simple product which supports drawing workflows. We found a lot of complex workflow engines and tools but not a simple one. We didn't like complex solutions so we started with our own workflow enigne.

And here are some impressions

Workflow Designer (loop)

Workflow Designer (loop)

Workflow Designer

Workflow Designer

The left area contains the list of available workflows and all used steps for each workflow. The search option is a full-text search for workflows and contained steps.

The right area contains all available/configured steps. The steps are configured in a database. We offer a simple Java interface which makes it possible to implement your own workflow steps. The area also contains a mini version of the board. This makes it smooth to search through the workflow.

The middle area, the board, contains the workflow designer. It supports Drag and Drop.

The created workflows can be used from any JVx based application. With next VisionX release, it'll be possible to use the new workflow engine.

The workflow engine will be available as AddOn for VisionX and as standalone version for product bundeling.

VisionX 5 update Release

We're happy to anounce that VisionX 5.1.8 is available!

It's a simple update release of VisionX 5 with smaller bugfixes and one awesome new feature.

The bugs fixed

  • Support for STARTS_WITH and CONTAINS Filter conditions

    We didn't save this conditions correctly.

  • Keyboard Navigation in HTML5 UI

    It wasn't possible to use arrow keys for navigation in HTML5 tables.

  • Floating License

    We had some problems with floating license check with 1 user and the HTML5 live preview.

The new feature

  • Swagger UI support

    We now create Swagger documentation for application' REST services. It's possible to test your REST services with your browser - super easy.

The download area already contains links to VisionX 5.1 binaries.

Xamarin Client (simple PoC)

What is Xamarin?

Read all details here.

It's a company and a really cool platform for mobile application development. It enables you to use one codebase for iOS and Android.

Since 2016, it's more or less free for everyone.

We tried Xamarin some years before 2016 and it wasn't free. So it wasn't an option for us. Not because it's using C# as programming language. We already have mobile clients for JVx applications but they don't share the same codebase. There is one client for Android and another one for iOS. The source code is licensed under Apache 2.0.

Our native clients work great but we think they could be better.

In the last days we made some tests with different tools, to create a new universal client with one technology. A HTML5 client wasn't an option for us because of different criterias. A real native client was important during our evaluation.

Some links to different opinions:

We made good first progress with Xamarin and because of its pricing, it was the winner of our evaluation. Sure, Xamarin is C# but it's better to write C# than JavaScript. Another plus was that we already have a simple JVx connection port to .NET based on C#. So we could reuse this code.

Why not JavaFX?

The problem with JavaFX is, that it's unclear what will happen with JavaFX in the future. There are different articles about the future of JavaFX, but the one from Jonathan Giles makes it clear

Sure, there's Gluon and some other individual developers, but the overall performance isn't relly comparable to native apps. It's awesome what happened in the last years, but the progress is missing.

We still have our JavaFX based UI, but we're not sure if JavaFX will survive or it will be commercialized. So it's better to have an option.

Why not CodenameOne?

It's a really cool technology and works great with some smaller performance glitches (simply try the current KitchenSink from the App stores)..
WORA just works!

The cloud build isn't what we prefer and the pricing is not good for our use-case. Our client should be free, open and easy to use for every developer.

Here is a simple test application for REST access to our Heroes application, used in our Angular test application.

iOS client

iOS client

Android client

Android client

The source code for this test:

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using Newtonsoft.Json;
using Xamarin.Forms;

namespace TableViewSamples
{
  public class RESTTable : ContentPage
  {
    public RESTTable()
    {
      GetData();
    }

    async void GetData()
    {
      this.Title = "REST Data";
      var table = new TableView() { Intent = TableIntent.Data };
      var root = new TableRoot();
      var section1 = new TableSection() { Title = "First Section" };

      var authData = string.Format("{0}:{1}", "user", "pwd");
      var authHeaderValue = Convert.ToBase64String(Encoding.UTF8.GetBytes(authData));

      HttpClient client = new HttpClient();
      client.DefaultRequestHeaders.Authorization =
        new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", authHeaderValue);
      HttpResponseMessage response = await client.GetAsync("https://...");

      if (response.IsSuccessStatusCode)
      {
          HttpContent content = response.Content;

          var result = await content.ReadAsStringAsync();

          var parsed = JsonConvert.DeserializeObject<List<HEROES>>(result);

          foreach (var record in parsed)
          {
              System.Diagnostics.Debug.WriteLine("Data: {0}", record);

              section1.Add(new TextCell { Text = record.NAME });
          }
      }

      table.Root = root;
      root.Add(section1);

      Content = table;
    }
  }

  public class HEROES
  {
    public int ID { get; set; }
    public string NAME { get; set; }
  }
}

VisionX 5 is available

visionx_five_small VisionX 5 is available

It's an awesome version with so many new features and new possibilities.
We had some hard months but now it's done and it's available for everyone.

We made the decision to wait a little bit longer with VisionX 5 because of changes in used frameworks.

The new Version is more web centric than any version before, but it's not a web tool. VisionX 5 still supports Desktop application creation.

So what's new?

  • Default Stylesheet

    All new applications will contain an empty application.css. This file could be used to add custom HTLM5 application styles.

  • New CSS Editor (Web settings)

    The new CSS editor makes it possible to change the style of the application directly within VisionX. The Editor supports Search/Replace/Goto line. It's also supported to reload the application in the browser. Simply test your style changes immediately.

    CSS Editor

    CSS Editor

    It supports syntax highlighting and auto completion. Read more...

  • New default Theme for HTML5

    Newly created applications will use the new default theme "valo" as standard theme. It's possible to change the theme in web settings wizard.

  • Additional Themes

    VisionX 5 is shipped with following themes: Standard, Valo, Valo (small), Mobile

  • Navigation

    The page navigation is now enabled by default. It support Back/Forward Browser navigation for the application.

  • New Tabset navigation

    It's also possible to enable tabset navigation. This feature enables Back/Forward navigation for tab sheets. This feature is disabled by default. It can be found in the web settings.

  • Favicon

    It wasn't easy to change the favicon for your application because it is stored in different locations. VisionX 5 solves this problem because it's possible to change the favicon directly in VisionX.

    Favicon support

    Favicon support

    It's also possible to use the favicon as icon for desktop applications. VisionX will extract the image directly from the favicon.

  • New GUI element: Menu Button

    The Menu Button is a simple button which shows a popup menu if you click the button. The component itself also supports a default action, but this is a new feature of JVx' UIPopupMenuButton. The component is available in the elements area.

    Menu Button

    Menu Button

  • New Web Elements

    The web elements is a new element area. The elements are preconfigured components like an Insert Button. This Button simply inserts a new record in a table. This web elements will work for desktop applications as well, but are often used in web applications.

    Web Elements

    Web Elements

  • New web element: Table Menu Button

    The Table Menu Button is a Menu Button with preconfigured menu items like Delete, Export. It's also possible to add custom menu items via menu customizer.

    Table Menu Button Items

    Table Menu Button Items

  • Menubar Image

    It's now possible to configure the web menus independent of the desktop menu. Every screen has a menu icon and a toolbar icon. The menu icon will be used for the menubar and the toolbar icon for the toolbar in Desktop applications.

    The HTML5 application has different layout modes. The standard, the corporation and the legacy mode. The standard mode shows the menu in a sidebar on the left or right of the browser frame. This sidebar was used as toolbar in versions before VisionX 5. If you did configure a toolbar image, the screen was shown as image in the toolbar of your Desktop application and in the sidebar of your HTML5 application. It wasn't possible to configure an image, only, for the HTML5 sidebar. This feature is now available in the menu settings wizard.

    Web Menubar

    Web Menubar

    The toolbar image will be used for the toolbar in the corporation mode, as usual.

  • New Edit Panel Customizer

    The Edit Panel now supports a Navigation mode: Single click, Double click and No navigation.

    Customizer

    Customizer

    It's also possible to morp an Edit Panel into a Tabset, a simple Panel or a Group Panel.

  • All/No columns

    It's now possible to show/hide all columns of a table via customizer. It wasn't nice to click through e.g. 50 columns. Now it's easy to show only 2 columns of e.g. 50 columns.

    Show/Hide all

    Show/Hide all

  • Default image mapping for HTML5

    It was possible to map desktop images for e.g. HTML5. It's better to use simple/flat images in web applications compared to desktop applications. The web style should be or is different to standard desktops.

    With VisionX 5, we did the default mapping for you and a standard web application will show different standard images.

    Image mapping

    Image mapping

    Same application, no changes necessary. Only some image mappings!

  • FontAwesome support

    JVx has FontAwesome support for a while, but this feature wasn't integrated in VisionX. The new image chooser supports FontAwesome.

    FontAwesome

    FontAwesome

  • Custom image libraries

    It's now supported to extend VisionX with custom image libraries. We have different commercial AddOns in our Solution store.

    Image library AddOns

    Image library AddOns

  • The libraries will extend the image chooser.

    Extended Image chooser

    Extended Image chooser

    It's also possible to integrate your own offline image libraries.

  • New tutorials

    We have new tutorials and new Tutorial Applications in our Store.

  • New Edit Panel features

    The integrated edit panel has new features like Tab Navigation by Buttons. The edit dialog now has OK and Cancel. It supports single our double click navigation.

  • Server actions and DB functions

    Our action editor now supports (Oracle) database function calls and server-side function calls.

    Server Actions

    Server Actions

  • Better Action Code Editor

    The source code editor now supports syntax highlighting and code folding.

    Action Code Editor

    Action Code Editor

  • New Button options

    It's now possible to change the button border behaviour.

    Button options

    Button options

  • New Search Options

    The search field now supports Contains and Starts with.

    Search options

    Search options

  • Better HTML5 default styling

    We improved the Split Panels and fixed some problems with focus.

    HTML5 Styling

    HTML5 Styling

    The split handle is now small.

  • Vaadin 8

    Our HTML5 GUI is now based on Vaadin 8.1 instead of Vaadin 7. With Vaadin 8, the UI is faster and supports all modern AddOns from the Vaadin Directory.

    We offer a Vaadin AddOn for VisionX to integrate AddOns from the directory.

  • New HTML5 layouting mechanism

    We rewrote the layout mechanism of our HTML5 UI because our Form Layout didn't support all available features. Now it's possible to overlap elements or to work with Anchors directly. The new layout mechanism can be disabled if necessary. In this case, the old mechanism will be used.

  • Documentation

    The online documentation is now available.

    Documentation

    Documentation

  • Library updates

    JVx changes, VaadinUI changes

VisionX 5 still contains Applet and Webstart support, but with VisionX 6 we will remove Applet support because the technology is EOL.

The new Version of VisionX will require a new license. Simply ask your sales contact to get a new one. The download area already contains links to VisionX 5 binaries.

Please report any problems as usual and have fun with VisionX 5.

Eclipse Oxygen.2 with ANT and JRE6

The support for ANT and JRE6 with Eclipse Oxygen.2 (December 2017).

The plugin was created for:

Version: Oxygen.2 Release (4.7.2)
Build id: 20171218-0600

Don't forget the -clean start (read the original article for more details)!

One more thing you should do:

Oxygen.1 and Oxygen.2 contain ANT 1.10.1. This version requires Java 8. In order to use Java 6, you have to download ANT 1.9.x. Simply download ANT and set the ANT Home to your version, via

Window >> Preferences >> ANT >> Runtime >> Ant Home...

If you try to use the bundled ANT with JRE 6, it will fail with an Exception.

Download the plugin from here. It works for us - no warranty!

More Details: Eclipse Oxygen.1 with ANT and JRE6

VisionX CSS Styling feature

The upcoming release of VisionX will support CSS styling. We'll show you a first impression with a short video:

Vaadin AddOn for VisionX

The editor supports autocompletion and syntax highlighting:

VisionX CSS Editor

VisionX CSS Editor

We did integrat the RSyntaxTextArea for this. If you want to know how this works, check the documentation.

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.

Transaction
  |-Insert record into A
  |-Update record of B
  |-Update another record of B
  |-Insert record into C
  \-Commit

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:

Transaction
  |-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
  \-Commit

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:

Transaction
  |-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
  \-Commit

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:

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

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
    savepoint
    try
        execute statement
        release savepoint
    catch
        rollback to savepoint
   
    ...
commit

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);
  3.  
  4. // Insert some data.
  5. dbStorage.insert(aRecord);
  6. dbStorage.insert(anotherRecord);
  7.  
  8. // This part is optional.
  9. try
  10. {
  11.     dbAccess.setSavepoint("NAME");
  12.    
  13.     dbStorage.insert(yetAnotherRecord);
  14.     dbStorage.update(someOtherRecord);
  15. }
  16. catch (DataSourceException dse)
  17. {
  18.     log.error(dse);
  19.     dbAccess.rollbackTo("NAME");
  20. }
  21.  
  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.

Conclusion

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.

DokuWiki XMLRPC with Java

DokuWiki

is a simple to use and highly versatile Open Source wiki software that doesn't require a database.

It's a really nice software for your documentation. The default theme isn't super modern, but it works. There are many custom themes available and styling is simple.

The really cool thing is the remote API of DokuWiki. It has a XML based RPC interface. Here are some details.

The documentation looks promise. There's a Java example :)
But the last update of the Java client was 2016 :(

After downloading and testing the client, it was clear that it doesn't work. It had a problem with cookie management. I tried to fix the problem in the base lib - aXMLRPC but it was tricky. The problem was the standard Http URL connection. After replacing it with Apache HttpClient, the dokujclient was working without problems.
I didn't try to find the root cause of the problem because it wasn't worth the time. It was faster to replace the communication part.

Here's a link to our patch and all required libraries (pre-built).

Here's a short snippet

DokuJClient client = new DokuJClient(url);
client.login(username, password);

client.putPage(pNamespace + ":" + pPageName, sText);

FileSearch fs = new FileSearch();
fs.search(dirImages, true);

for (String file : fs.getFoundFiles())
{
    client.putAttachment(pNamespace + ":" + pPageName + ":" + FileUtil.getName(file),
                         file, true);
}

client.logoff();

We use the remote interface for automatic article updates. It works great!

EPlug 1.2.7

We're happy to announce the release of EPlug 1.2.7. This minor update comes with a big performance improvement!

Major performance improvement

The most notable and important feature of this release is the major speed improvement when checking files. We've revisited how the build pipeline works and could determine quite a few bottlenecks which did not only encumber the build process, but also the live checks of databooks. After fixing these bottlenecks the databook live checks are blazing fast and one does not notice any more that these are active.

While reviewing the code, we also saw the possibility for a few more tweaks which we will incorporate into the next major release, to squeeze even more performance out of this.

Improved DataBook View

The DataBook view has also received some much needed attention. There is now a toolbar button which allows to sort the columns by their name (instead of their order as returned by the datasource). Additionally the view does no longer flicker when refreshing and will also clear itself when the last editor closes.

Other fixes

  1. There is no longer a sleeping EPlug job in the Progress View.
  2. The EPlug preferences are now only available on Java projects.
  3. If there is no screen lifecycle object, the session object is now used.
  4. Removed raw HTML in tooltips.

How to get it?

Simply update EPlug via Eclipse!