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

AngularJS with JVx in action

Our JVx library has REST support since 2011. It's not only support for using REST libraries, it's a generic solution for action calls and storage access (e.g. database records). This means that your whole business logic is usable via REST with same security restrictions as usual.

In 2011, REST wasn't as popular as today and not supported from soo many different frameworks than today. But now, in 2015, SOAP is legacy and REST is the thing to use. I'm sure you have heard about this modern JavaScript frameworks like AngularJS.

Not sure if it's so successful because it's from Google, but it's often used and developers love working with AngularJS. So we started a simple research project to connect an AngularJS app to our JVx backend application.

AngularJS and JVx is a perfect match because Angular was designed for JS frontends and JVx provides your business logic. Sure, JVx is a full-stack framework and you could create the whole web application, based on vaadinUI, but it's also open for all other UIs.

The most important thing is that everything works out-of-the-box. No additional coding for REST services or authentication, no special knowledge needed. Here's an example service for accessing a customer table (full CRUD support):

public class Customers extends Session
{
        public DBStorage getCustomer() throws Exception
        {
                DBStorage dbsCustomer = (DBStorage)get("customer");
                if (dbsCustomer == null)
                {
                        dbsCustomer = new DBStorage();
                        dbsCustomer.setWritebackTable("customer");
                        dbsCustomer.setDBAccess(getDBAccess());
                        dbsCustomer.open();

                        put("customer", dbsCustomer);
                }
                return dbsCustomer;
        }
}

The class was copied from our DemoERP application (Login as: manager with password: manager). The source code of the whole application is available here.

Yes, there are no more methods like save, update, delete, query, ... The DBStorage encapsulates all calls for you and our generic REST service handles the communication with your business logic.

We have a simple Angular app for you (click on the pencil to edit the record):

This solution is based on AngularJS 1.4.0, Bootstrap 3.3.4 on client-side and JVx with RESTlet on server-side. Here's the JS file:

(function()
{
    var app = angular.module('contactApp', ['ngResource', 'ngRoute']);

    app.config(function($routeProvider)
    {
      $routeProvider.when('/',
      {
        controller:'ListContactsController as contactList',
        templateUrl:'list.html',
        resolve: {contacts: function (Contacts)
                            {
                              return Contacts.fetch();
                            }}
      })
      .when('/edit/:contactId',
      {
        controller:'EditContactController as editContact',
        templateUrl:'edit.html'        
      })
      .otherwise({
      redirectTo:'/'
      });
    });
   
    app.factory('ContactsFactory', ['$resource', function($resource)
    {
       var auth = 'Basic ' + btoa("manager:manager");
       
       return $resource('/demoerp/services/rest/DemoERP/Customers/data/customer/:contactId',
                        null,
                        {'get':    {method:'GET', headers: {'Authorization':auth}},
                         'save':   {method:'POST', headers: {'Authorization':auth}},
                         'update': {method:'PUT', headers: {'Authorization':auth}},
                         'query':  {method:'GET', isArray:true,
                                    headers: {'Authorization':auth}},
                         'delete': {method:'DELETE', headers: {'Authorization':auth}}});
    }]);  

    app.service('Contacts', function($q, $http, ContactsFactory)
    {
      var self = this;
     
      this.fetch = function()
      {
        var deferred = $q.defer();

        return ContactsFactory.query(function(data, status, headers, config)
        {
            self.contacts = data;
           
            deferred.resolve(data);
        },
        function(data, status, headers, config)
        {
            console.log("Error while received data.");
            deferred.reject();
        });
       
        return deferred.promise;
      };
    });

    app.controller('ListContactsController', function(contacts)
    {
        var contactList = this;
        contactList.contacts = contacts;
    });
   
    app.controller('EditContactController', function($location, $routeParams,
                                                     Contacts, ContactsFactory)
    {
        var editContact = this;

        this.fillData = function()
        {
            var idx = Contacts.contacts.reduce(function(cur, val, index)
            {
               if (val.ID == $routeParams.contactId && cur == -1 )
               {
                  return index;
               }
               
               return cur;
            }, -1);
           
            editContact.contact = Contacts.contacts[idx];
           
            editContact.save = function()
            {
                ContactsFactory.update({contactId : $routeParams.contactId},
                                       editContact.contact, function()
                {
                    $location.path('/');
                });
            }
        };
       
        if (typeof Contacts.contacts == 'undefined')
        {
            Contacts.fetch().$promise.then(this.fillData);
        }
        else
        {
            this.fillData();
        }
    });    
})();

It's a useful script because it combines REST with Basic authentication for querying and updating remote database records. Sure, it's not a fat application but this wasn't our intention :)

We have a web application archive for you, if you're interested. Simply use this war together with our DemoERP application and install both applications on e.g. Tomcat application server.

JVx with official connection pooling support

The last black stain was removed. JVx didn't fully support connection pools. It was because of our internal statement cache mechanism and load-on-demand.
We had inofficial support for connection pooling but it wasn't a solution without problems (we weren't proud of it).

With next JVx release or next nightly build, you will be able to use connection pools with same caching mechanism and with full backwards compatibility. We still support load-on-demand for storage records and binary data e.g. BLOBs.

We've some documentation for you:

Connection pooling

and for another new JVx (server-side) feature:

Server-side Call events

Thanks for your patience ;-)

Java Framework comparison and JVx

In the last month we‘ve started a big research project. It is a comparison of Java frameworks for backend and frontend development. We knew that there are many different frameworks for the same job, but which one is the best? Is there one framework that would outpace all others? What are the pros and cons of each framework and how fast could we develop with them?

The idea was trivial: Implementing the same application or screen with different technologies with developers without prior knowledge of the specific technology, always from scratch. Afterwards we could compare the development time, functionality and complexity.

We tried to find out which framework saves most time during development because time is money, e.g. development with framework A needs 6 months and same solution needs 3 months with framework B. Which one is better?

Better doesn't mean that framework B is technological better than A and it doesn't tell us anything about the framework quality. As well, faster is not always better because code quality is very important. We tried to create comparable results and choosen frameworks fulfilled high quality standards. We also knew that every developer is different and development speed matters.

To keep results fair, we tried to find some fresh developers (students) with same experience and without prior knowledge in our framework candidates.

The results were really cool and it was great to get feedback from different developers without marketing slides and no buzzwords. Just reality!

One statistic has extremely amazed us:

Required time (2 passes)

Required time (2 passes)

We tried to use "top-ten frameworks" and our own selection.

Custom comboboxes with JavaFX

We got great feedback about our first beta release of our JavaFX UI. Many of our ideas were right but our comboxes weren't good enough. We had missing features and some technical problems. One missing feature was: Live search in comboboxes with list of values. Our old implementation of comboboxes was like this:

Combo Box

Combo Box

Our implementation didn't support live filtering, e.g. if you typed a key, the list wasn't shortened...

One problem with this feature was JavaFX' focus handling and popups. It was tricky to keep the focus in the right editor and to keep the popup open or to re-open the popup after every keypress. We had a solution but it was too dirty. So we tried to find a better solution. We moved the the editor in the popup, to avoid focus problems. We had crazy effects with two blinking cursors in two different text fields, very strange.

Our current solution is this:

Filterable combobox

Filterable combobox

The design is not perfect but we're working on it. The good thing is that we have no problems with focus and filtering is already working. Here's a screenshot of our date editor:

Date editor in combobox

Date editor in combobox

Our date editor needs a small redesign but it's working. The optimization was planned for release 1.1

If you're interested in our current state, check the source code. We're looking forward to your feedback!

Our code is open source and we still have a separete lib (.ext) for all custom FX controls. The UI implementation for JVx is based on this library. So we have JVx independent JavaFX extensions and our JVx UI implementation.

JVx' vaadinUI and CORS

CORS

All details about Cross-origin resource sharing.

Use-case

Embedd a vaadin application in your CMS (e.g. Joomla, Typo3). The CMS runs in an hosted environment without Java application server (standard and cheap web hosting).

Howto

There's an excellent blog post from vaadin. It's not rocket science to implement this, but you have to do it. We think this things could be done automatically and so we've added the support to our UI implementation for JVx.

It's really simple to use:

Add following parameter to your web.xml:

<init-param>
  <param-name>cors.origin</param-name>
  <param-value>http://www.hosteddomain.com</param-value>
</init-param>
   
<init-param>
  <param-name>pushmode</param-name>
  <param-value>automatic</param-value>
</init-param>
   
<async-supported>true</async-supported>

(be sure that async-support was enabled for all vaadin servlets/filters)

The cors.origin parameter can be a comma separated list.

And here's an example html file:

<!DOCTYPE html>

<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=11;chrome=1" />
    <link rel="shortcut icon" type="image/vnd.microsoft.icon"
          href="./VAADIN/themes/jvx/favicon.ico" />
    <link rel="icon" type="image/vnd.microsoft.icon"
          href="./VAADIN/themes/jvx/favicon.ico" />

    <title>Embedded Vaadin application</title>

    <script type="text/javascript"
             src="./VAADIN/widgetsets/com.sibvisions.rad.ui.vaadin.ext.ui.Widgetset/
                  com.sibvisions.rad.ui.vaadin.ext.ui.Widgetset.nocache.js?05202015200542"></script>

  </head>
 
  <body scroll="auto">
 
    <div id="content">
      <script type="text/javascript" src="./VAADIN/vaadinPush.js?v=7.4.5"></script>
      <script type="text/javascript" src="./VAADIN/vaadinBootstrap.js?v=7.4.5"></script>

      <div id="MyEmbeddedUI" class="v-app">
        <div class="v-app-loading"></div>
        <noscript>You have to enable javascript in your browser to use an application
                  built with Vaadin.</noscript>
      </div>
      <script type="text/javascript">

      if (!window.vaadin)
      {
        alert("Failed to load the bootstrap javascript:
               ./VAADIN/vaadinBootstrap.js?v=7.4.5");
      }
   
      vaadin.initApplication("MyEmbeddedUI",
                             {"browserDetailsUrl": "ui/" + appname + params,
                              "serviceUrl": "ui/",
                              "theme":"jvx",
                              "versionInfo":{"vaadinVersion":"7.4.5",
                                             "atmosphereVersion":"2.2.4.vaadin5"},
                              "widgetset":"com.sibvisions.rad.ui.vaadin.ext.ui.Widgetset",
                              "comErrMsg":{"caption":"Communication problem",
                                           "message":"Take note of any unsaved data,
                                                      and <u>click here</u> or press ESC to
                                                      continue.",
                                           "url":null},
                              "authErrMsg":{"caption":"Authentication problem",
                                            "message":"Take note of any unsaved data,
                                                      and <u>click here</u> or press ESC to
                                                      continue.",
                                            "url":null},
                              "sessExpMsg":{"caption":"Session Expired",
                                            "message":"Take note of any unsaved data,
                                                      and <u>click here</u> or press ESC key
                                                      to continue.",
                                            "url":null},
                              "vaadinDir":"./VAADIN/",
                              "standalone":false,
                              "debug":false,
                              "heartbeatInterval":300,
                              "comErrMsgDetails":true,
                              "authErrMsgDetails":true,
                              "sessExpMsgDetails":true});
      </script>
    </div>
  </body>
</html>

And the rest of our web.xml:

<servlet>
  <servlet-name>EmbeddedUI</servlet-name>
  <servlet-class>com.sibvisions.rad.ui.vaadin.server.VaadinServlet</servlet-class>
  <init-param>
    <param-name>UI</param-name>
    <param-value>com.sibvisions.rad.ui.vaadin.impl.VaadinUI</param-value>
  </init-param>
  <init-param>
    <param-name>widgetset</param-name>
    <param-value>com.sibvisions.rad.ui.vaadin.ext.ui.Widgetset</param-value>
  </init-param>
  <init-param>
    <param-name>main</param-name>
    <param-value>com.sibvisions.apps.MyEmbeddedApplication</param-value>
  </init-param>
  <init-param>
    <param-name>Launcher.uifactory</param-name>
    <param-value>com.sibvisions.rad.ui.vaadin.impl.VaadinFactory</param-value>
  </init-param>
  <init-param>
    <param-name>pushmode</param-name>
    <param-value>automatic</param-value>
  </init-param>

  <async-supported>true</async-supported>  </servlet>
</servlet>

<servlet-mapping>
  <servlet-name>EmbeddedUI</servlet-name>
  <url-pattern>/*</url-pattern>
</servlet-mapping>

The application was deployed in ROOT context of Tomcat8.

If you have a different context, simply change the URLs: browserDetailsUrl, serviceUrl and vaadinDir (see html page).

The CORS support is not available in our latest vaadinUI release (1.2), because its a very new feature. Simply use our nightly builds for testing.

Happy embedding.

Demo ERP 1.1, iOS & Android App updates

First, we've released version 1.1 of our Demo ERP application. The full source code is available on SourceForge. It doesn't have more features than 1.0 because it's a simple lib upgrade release with improvements for developers.

The DemoERP.zip now contains the whole project structure and not only the source files. Simply unzip the archive, import the project in your Eclipse IDE and start the DemoERP.launch file (sure, DB must be configured manually). The archive contains small README files with additional information.

We fixed code signing problems and you shouldn't have any problems with DemoERP.war. So, simply deploy the war and open http://localhost/DemoERP/web/ui in your browser (see README).

The release contains our latest vaadinUI based on 7.4.5 and our latest JVx.mobile lib. The mobile lib was needed for our updated mobile apps for iOS and Android.

Yepp, we've new apps in the stores (still native but not based on JavaFX). The apps have a buch of new features like custom view styles (based on style property of JVx), image viewer/editor or the new Form view. But the biggest improvement was offline support. It's now possible to switch to offline mode and back to online mode. Sure, we sync your offline data!

It's an awesome feature because it's a generic solution and you don't have to change anything in your application. It simply works!

Both applications have the same features but system specific.
Here's the iOS link.
The Android app via Google Play.

Both apps work great with latest VisionX releases and simply use it to test your VisionX application - LIVE - without redeployments - on your mobile devices!

Zoom support for applications

Some weeks ago, JavaFX links of the week contained a very interesting link: It was about ZoomFX 1.0.1.

It's a zoomable pane for your JavaFX application.
There's another small project, called MagniFiX. It's a "simple" magnifier but different than ZoomFX.

Why was this so interesting for us?

In the past we had a lot of requests from customers for automatic application scaling for simple touch devices (terminals). Usually we solved the problem with extra source code and specific fonts/control settings - horrible.

We had other requests about image zoom in/out features and charts, ...

So we thought that ZoomFX could be a very useful extension for our JavaFX UI. We tried the demo and configured a simple test application. But first: Maven. Not new: We aren't big fans.
Sure, it wasn't hard to start a test application but we were suprised about the dependencies:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-math3</artifactId>
</dependency>

<dependency>
    <groupId>com.github.dejv78.commons.jfx</groupId>
    <artifactId>jfx-binding</artifactId>
</dependency>

<dependency>
    <groupId>com.github.dejv78.commons.jfx</groupId>
    <artifactId>jfx-geometry</artifactId>
</dependency>

<dependency>
    <groupId>com.github.dejv78.commons.jfx</groupId>
    <artifactId>jfx-input</artifactId>
</dependency>

The overlays were saved as FXML and we thought that it's not a good idea for a library like ours. Anyway, we tried the integration in our lib and stopped suddenly because ZoomFX didn't work with our dynamic layouts. It simply didn't work out-of-the-box and it had too many dependencies for such a "simple" feature.

We had no luck... but we love researching new things. So we started with our own zoom implementation without any dependencies and also integrated in our UI. We made a short screencast of the result.

Application coder

Every application and internal frame has this zoom feature because it was integrated in the UI implementation. We need to do some fine tuning, but it works great!

JVx' JavaFX UI - first release

We're happy to announce our first beta release of JVx' JavaFX UI with version number 0.9 :)

The release is two weeks later than planned but we had some extra tasks to do. We didn't set 1.0 as version number because we have some open tickets which are important, in our opinion, for 1.0. The 0.9 beta is already feature complete with some known bugs.

We also released an extra library: JFXtensions
It contains all standalone controls and extensions which are independent of JVx. The MDI system, our layouts, styled scene and much more.

Here are the download links:

All libraries are available on maven central as well.

We've released DnDTabPane as external lib on maven central, because it wasn't available and our UI needs the dependency. The DnDTabPane is licensed under EPL 1.0 and JVxFX UI, JFXtensions are Apache 2.0 licensed.

The DnDTabPane is still based on Tom Schindls implementation for Efxclipse.

We've a very cool video of our work during the last 4 months. It's the visualizaton of our dev repository:

Respository visualization


The visualization was created with Gource.

Developer Information

The dev2015 branch was merged back to trunk. If you're working with our branch, please switch to trunk.

Application Coder

This article is about our new Research project: Application Coder.

The application is a very simple Java Code Editor. It shows a tree with Java files and has a Code Editor for modifying files. The code editor is the popular Ace Editor and we use Eclipse JDT for java compilation. The application was written as standard JVx application with vaadin UI.

We made tests as single-page vaadin application, embedded with iframes and embedded with div areas. All versions work without problems but the last one is preferred. If you embedd a vaadin application with divs, it's a little bit tricky because you have to configure the client-side on your own, but you get full access to the whole html page. This wouldn't be possible if you use an iframe because you can't access the main html page.

Some cool features of our editor are: error annotations and error markers. And the best feature is our LIVE Preview of code changes!

Annotations and marker

Annotations and marker


Watch this video:

Application coder


The application coder is not only a Java code editor, it was designed especially for JVx applications, because it groups client code and business logic. The preview also starts a JVx application and LIVE preview reloads the application.

Our coder application has a push mechanism and reloads every preview window automatically and immediate after compilation.

Above video shows multiple instances of our coder application, embedded in divs and it's possible to drag around and resize the applications (thanks to jquery-ui).

The application is a perfect showcase of JVx because it's not a database application as many other JVx applications. We've used vaadin, jquery-ui and vaadin-addons to create a great UX. JVx is technology independent and open for other technologies.

JavaFX Table and Tree lazy loading

JavaFX doesn't define a specific model for table or tree. The implementations are based on ObservableList which is not more than an extension of standard List interface with some additional listeners and sorting, filtering. The general design doesn't take care of one important feature: Lazy loading of records.

This is an important feature if you're working with databases or large datasets. If you have millions of records, it's not a good idea to show all records in your GUI. You shouldn't load more than needed and of course, not more than the user is able to handle.

We have a model in our JVx framework which supports lazy loading of records (not only database records). To use our model with JavaFX, we had to do some Trial and Error because an ObservableList is too lightweight. Sure it wasn't a problem to simulate more entries than the list really had. This was needed to load records on demand. If a "virtual" element was requested it was simply loaded from the datasource. Sounds simple enough. To be honest - it was that simple!

A bigger problem was the scrollbar handling of the controls because it didn't set the scrollhandle position correctly after loading "virtual" records. We didn't find a perfect solution for this problem but our current solution works and is user-friendly enough. We've used our JVx model implementation for TableView and TreeView.
Means: One model for all UI controls.

A simple screencast of our test application is available on YouTube. The video shows a simple TableView which loads records from a remote server via http. The remote server reads data from a HSQLDB. The table contains 317027 records with filenames and additional filesystem information. The remote server returns exactly 100 records, per request, for our test application.

LazyLoading JavaFX TableView


We have the same lazy loading mechanism for TreeView.

Our implementation was done for JVx' model (IDataBook), but the mechanism should work with any other model definition. The complete source code is available in our dev repository. Simply start with ObservableDataBookList.