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

From Swing to Vaadin?

Some days ago, vaadin released a Tutorial for Swing developers. It's a hitchhiker's guide to convert a Swing app to modern web app. It's a must-read if you plan to replace/migrate or modernize your Swing application.

We were mentioned in the last paragraph with our JVx framework, as possible conversion strategy. Thanks for that!

I want to hook in at this paragraph, because I totally agree with the rest of the tutorial.

It's true that a wrapper has pros, cons and limitations. You can't wrap everything. Sure you could try, but it needs so many developers and doesn't make sense because a wrapper shouldn't copy the underlying technology. The more features the wrapper has, the more problems will occur with new (different) technologies. The wrapper should be a subset of all technologies. But a subset is limited in functionality!

A wrapper should be focused on a specific domain, e.g. database/data driven applications or game development. A wrapper for multiple domains will fail!

I don't know many working wrappers. There were many attempts to create (UI) wrappers, in the past, but most were stopped because of complexity or the developers had other interests (if project was open source).

JVx is one working solution and in my opinion the most complete one because it contains an UI wrapper, has implementations for different technologies like Swing, JavaFX, Headless and Vaadin. The APIs are bulletproof and there are native applications for Android and iOS. JVx is a generic solution and doesn't generate additional source code.
But it has more than that, because it's full-stack and comes with different application frames for desktop, web and mobile applications.

But what is your advantage if you're using a wrapper?

You're (GUI) technology independent.

An example:

Your current business application is a Swing application and you plan the migration to a modern technology.
Your first migration decision should be: Desktop or Web
Next decision: which UI framework
Optional: Mobile support?

If your platform decision was: Desktop, then it's very simple to find the right UI framework: JavaFX and try JavaFXPorts for mobile support.
Fact: No real web and possible problems with mobile support

If your platform decision was: Web, then it's not an easy task to find the right UI framework, but vaadin should be the first choice because it's comparable to Swing and hides web technology for you!
Fact: No desktop but mobile support

Every decision has pros and cons. If you bet on one technology stack, you're fixed to this technology stack. In our example it was JavaFX or vaadin. And what will be the next preferred UI technology after JavaFX or vaadin?
You'll have the same problems again and it's never easy to migrate a (business) application.

You should bet on a technology independent solution, to be prepared for the future!
Means, you should use a wrapper. But don't use a wrapper which hides the technology from you. It should be possible to access the technology directly - if needed or if it's not important to be technology independent.

Sometimes it's not possible to be technology independent, e.g. some custom controls aren't available for all technologies.

The wrapper should allow technology dependent and independent development without any limitations!

Does it make sense to use the same application with different technologies?

Yes, but...

It's not a good idea to use e.g. Swing AND JavaFX because both technologies are desktop toolkits. But it makes sense to use JavaFX for your backend application and vaadin for your frontend or your mobile devices.

It's also a good idea to create only one application that works as desktop, web and mobile application - the same application. But show different screens/views on different platforms.

There's no big difference between desktop and a standard browser because resolution of a desktop pc is the same. A mobile browser has limited space and you shouldn't use the same screen/view on a mobile device as on the desktop pc.

Example
We use an ERP backend application to manage vacations. The appliation has about 10 screens for resource management, master data management and accounting. The application runs as desktop application with JavaFX. The same application runs in desktop browsers with 3 screens because the web frontend doesn't offer master data management and accounting. The same application runs on mobile devices with only 1 screen because mobile devices are used from employees to enter and view vacations.

We have only one application, started with different UI technologies and with different screens/views.

It would be possible to create 3 different applications with different screens and with dependencies between the applications and ... (complex to maintain, 3 different projects, application frame x 3).

If you'll create a "native" vaadin application and a JavaFX application you'll need different development teams with different know-how.

Don't waste time and resources, focus on the real problems of your application. A wrapper hides technology problems and allows fast development with few developers: Win-win situation!

Vaadin application frame design

Many of you probably know our application frame, for web applications: One application, different styles

We had a MDI variant for legacy applications with internal frames for screens. This is useful for applications with many screens and many records. The internal frames help to compare records from one screen with records from other screens.

For modern user interfaces, we use the SDI option. It looks fresh and simple and is great for applications with a small number of screens, because a scrolling menu is not nice - sure it will scroll if needed.

But what about application with e.g. 60 screens. Is MDI the only option? Yes and No, because we didn't have a variant for that kind of applications.... but now we have.

It's a mix of MDI and SDI, with a little bit CI:

Application frame SDI with menu

Application frame SDI with menu

The application frame is still the same as before, but with a different option. The name of the option is corporation, because the UI is meant for applications with many screens. It's still SDI with modal popups, because it shouldn't be too legacy!

Oh, do you see the small buttons on top/right? We use the FontAwesome feature of vaadin 7.2. We're already using vaadin 7.4.2 for our JVx vaadin UI!

We now have one application frame for many different application styles (I don't talk about visual attributes). The application frame is responsive and works well on mobile devices.

JavaFX FlowPane vs. FXFluidFlowPane

We're still working on our JavaFX UI implementation for JVx. Some weeks ago, we worked with standard JavaFX layouts (layout panes) like BorderPane and FlowPane. Both layouts are useful but don't work like BorderLayout or FlowLayout from AWT/Swing. There are small differences, e.g.

It was possible to resize a BorderLayout to any size. The BorderPane checks minimum and maximum size of its nodes and doesn't resize if bounds were reached. Sure, that's useful in theory but bad in practice because the content of a screen should always resize to the screen size (e.g internal frames).
The requirement wasn't hard to implement. We now have our own FXBorderPane which has its own min. and max. calculation.

The standard BorderPane was very useful but the standard FlowPane wasn't, because it has bigger problems/limitations:

  • Overlapping of Wrapped FlowPanes with other nodes
    Overlapping

    Overlapping

  • Size calculation depends on prefWrapLength if not stretched to full-size (BorderPane, SplitPane, ...). This means that the pane doesn't grow automatically if the parent has enough space.
    ABC

    Width calculation

  • The FlowPane doesn't support alignment of managed nodes
    Standard FlowPane (centered nodes)

    Standard FlowPane (centered nodes)

    but should:

    fluid flow pane (bottom aligned)

    Fluid flow pane (bottom aligned)

    fluid flow pane (stretched)

    Fluid flow pane (stretched)

We solved all problems with our FXFluidFlowPane because our applications won't work with standard FlowPane.

In JVx applications, we have more than two layouts. The most common layout is our FormLayout. We already have JavaFX implementations for all JVx layouts, like FXFormPane or FXNullPane.

Here's screenshot of our FXFormPane test application:

Form Pane

Form Pane

JavaFX, JVx, CalendarFX and Exchange Server

It's friday, and it's (still) sunny :)

Some days ago, CalendarFX was released. It's a commercial product and looks promising. Now and then, we play around with new commercial products/libraries because our dev teams should know which product will work in commercial projects. A calendar control is always useful and especially if you organize "something". Many ERP products do this.

In good old swing applications, we did use migcalendar for better UX and visualization. But it's not available for JavaFX, so we tried CalendarFX.

The control is still in an early development stage and has some bugs or missing APIs, but it's very polished and works great with JVx and our JavaFX UI:

JVx, JavaFX UI and CalendarFX

JVx, JavaFX UI and CalendarFX

We tried to implement a simple JavaFX calendar screen, for Outlook appointments. We already had a connector for Exchange servers, based on EWS Java API and our JVx' storage implementation.

The screen code was simple, and more or less a simply copy/paste of a CalendarFX tutorial application. Here it is:

private void initializeUI() throws ModelException
    {
        CalendarView calendarView = new CalendarView();
       
        Calendar work = new Calendar("Work");
        Calendar home = new Calendar("Home");

        work.setStyle(Style.STYLE1);
        home.setStyle(Style.STYLE2);

        CalendarSource calSources = new CalendarSource("Private");
        calSources.getCalendars().addAll(work, home);

        calendarView.getCalendarSources().addAll(calSources);

        calendarView.setRequestedTime(LocalTime.now());

        Thread updateTimeThread = new Thread("Calendar: Update Time Thread")
        {
            @Override
            public void run()
            {
                while (true)
                {
                    Platform.runLater(() ->
                    {
                        calendarView.setToday(LocalDate.now());
                        calendarView.setTime(LocalTime.now());
                    });

                    try
                    {
                        // update every 10 seconds
                        sleep(10000);
                    }
                    catch (InterruptedException e)
                    {
                        e.printStackTrace();
                    }

                }
            };
        };

        Thread thLoadData = new Thread(new Runnable()
        {
            public void run()
            {
                try
                {
                    RemoteDataBook rdb = new RemoteDataBook(apps);
                    rdb.setDataSource(getDataSource());
                    rdb.setName("calendar");
                    rdb.open();
                    rdb.fetchAll();
                   
                    ZonedDateTime zdt;
                   
                    for (int i = 0; i < rdb.getRowCount(); i++)
                    {
                        IDataRow row = rdb.getDataRow(i);
                       
                        Entry entry = new Entry(row.getValueAsString("SUBJECT"));
                       
                        zdt = ((Date)row.getValue("BEGIN")).toInstant().
                                     atZone(ZoneId.systemDefault());
                       
                        entry.setStartDate(zdt.toLocalDate());
                        entry.setStartTime(zdt.toLocalTime());
                       
                        if (((Boolean)row.getValue("ALLDAY")))
                        {
                            entry.setFullDay(true);
                            entry.setEndDate(entry.getStartDate());
                        }
                        else
                        {
                            zdt = ((Date)row.getValue("END")).toInstant().
                                         atZone(ZoneId.systemDefault());                                                        
                            entry.setEndDate(zdt.toLocalDate());
                            entry.setEndTime(zdt.toLocalTime());
                        }
                       
                        if (((Boolean)row.getValue("PRIVATE")))
                        {
                            Platform.runLater(() -> home.addEntry(entry));
                        }
                        else
                        {
                            Platform.runLater(() -> work.addEntry(entry));
                        }
                    }
                }      
                catch (Exception e)
                {
                    e.printStackTrace();
                }
            }
        });
       
        thLoadData.start();
        updateTimeThread.start();
       
        ((FXInternalWindow)getResource()).setContent(calendarView);
       
        setTitle("Calendar FX Demo");
    }

The storage definition for fetching appointments was trivial:

AppointmentsStorage apps = new AppointmentsStorage();
apps.setURL(new URI("<url>"));
apps.setUserName("<username>");
apps.setPassword("<password>");
apps.open();

Not more code!

The special thing in our screen was the integration of a custom control. Usually, we would integrate it like this:

add(new UICustomComponent(calendarView));

but our custom component integration for JavaFX UI wasn't ready. No problem, because it's always possible to access the real UI resource in JVx. So we did:

((FXInternalWindow)getResource()).setContent(calendarView);

and everything was as expected. Sure, the screen won't work with Swing because we made a direct access to a JavaFX resource, but this was not relevant for our test :)

JavaFX: Styled stage and MDI system

I'm happy to show you a first screenshot of our new Stage style and our MDI system:

Scene styling and MDI

Scene style and MDI

Compared to the standard stage:

Standard scene and MDI

Standard scene and MDI

Sure, the default stage is OK, but if you want to style the whole application, it won't work with standard stage. If you want a unique style, you need a custom solution. Our style is part of our JavaFX UI for JVx and already available in our repository at sourceforge.

The MDI system is already stable. It can be styled via css and works similar to JDesktopPane and JInternalFrame of Swing. Most problems were solved and we use the implementation in our dev projects.

JVx 2.2

Today is a great day because I'm very happy to announce JVx - version 2.2.
It's an awesome release with soo many new features.

First of all, the LoC analysis. Here are some very interesting numbers for you:

JVx library   Swing UI
LoC   Type
73.759   Code
62.025   Comments (~ 46% of Code)
19.662   Empty lines
155.446   Total
LoC   Type
34.032   Code
18.882   Comments (~ 36% of Code)
7.662   Empty lines
60.576   Total
 
JVx library (Test cases)  
LoC   Type
21.093   Code
11.441   Comments (~ 35% of Code)
7.300   Empty lines
39.834   Total

Not bad if you compare it with other releases: 0.8, 1.0, 2.0.
We've still a very small codebase, compared to the features. The code quality and test coverage are still "green".

Some additional numbers:

Files and Tests
JVx library source files   594
Swing UI source files   135
Test source files   140
Total   869
Still a small codebase ;) and still very easy to maintain. Here are more numbers, about testing:
 
Unit tests (no UI, without manual perf. tests)   958
Class coverage (without UI)   81%
Method coverage (without UI)   69%
Our coverage got better since 2.0 - well done.

TOP 10 classes

Classname   LoC
MemDataBook 4.028
DBAccess 3.772
JVxTable 2.510
ArrayUtil 2.224
StringUtil 1.738
Server 1.715
DBStorage 1.542
JVxFormLayout 1.243
FileUtil 1.182
SwingApplet 1.102

Sure, MemDataBook and DBAccess are our main classes but we should check if it'll be possible to reduce complexity!

And last but not least, a short overview of new features:

  • Performance tuning
    JVx got a boost. We pimped our model to be super fast. Sure, it was fast and we didn't have any problems... but during some code reviews, we found some lacks because of gc calls. The memory consumption wasn't perfect and not gc friendly. We created a lot of temporary String[] and event objects, even if the weren't needed.

    Long story, short: Inserting 2.000.000 records with 16 columns was done in about 23 seconds. Now: 1.5 seconds.

  • Support for IoT/M2M/Microservices

    We pimped our remote communication a little bit. It's now possible to embedd JVx, especially the server class, in any environment that supports Java. We had an implementation for Java application serves like Tomcat or Wildfly, but no solution for plain socket servers. We put a lot of work in this part of JVx. We now have out-of-the-box solutions for vert.x or plain socket servers. It've never been easier to write remote applications with JVx.

  • Better JNDI support

    We had JNDI support since JVx 1, but now it's bulletproof. Use JNDI to configure your database connection or the whole application. It's possible to load application config.xml via JNDI. Same is valid for server configuration. We allow, so called, virtual configurations.

  • @PostConstruct and @PreDestroy

    We've support for both annotations in our server-side Lifecycle objects. It's now possible to remove your workarounds like:

    if (getClass() == Application.class)

    to find out whether the application LCO or session LCO was created. The session LCO extends the application LCO and otherwise it wasn't possible to do things only if application LCO was created, because constructor was called for every session LCO again.

  • Lambda support

    It's soo much fun, working with lambdas and Java 8. We're happy to have full support for lambda expressions in JVx especially for event listener handling. And it's backwards compatible (Java 6, 7) without restrictions.
    Be sure that you recompile your JVx projects with JVx 2.2 library.

  • Log4j support

    We love using built-in Java APIs like Logging API - because it doesn't need extra libraries. But we're open for 3rd party libraries and log4j(2) is too popular to ignore it. So we have official support for it in JVx. Simply use the new log factory com.sibvisions.util.log.log4j.Log4jLoggerFactory for your application and configure your loggers via log4j.properties or log4j2.xml.

  • Spring security

    We had a customer request for supporting SAML 2.0 authentication. SAML what?
    Yes, we had the same question, but found that Spring framework had a solution for it: Spring Security SAML. We didn't reinvent the wheel and connected Spring security with our security mechanism. Here's the source code.

  • HanaDBAccess

    HANA is the in-memory db solution of SAP. We've a connector for it. But be careful, because we weren't allowed to tune the database :)

  • Bugfixes

The list isn't complete but contains some important features. The full changelog is available here.

Drag'n'Drop support for JavaFX' TabPane

We're currently working on our JavaFX UI for JVx. We're making good progress but sometimes, missing JavaFX functionality stops us, e.g. We need a Tab Pane with Drag and Drop support for Tabs. There's no support in current Java 8 versions :(

But Tom Schindl had the same requirement for his e(fx)clipse project. We thought that his implementation could be a simple solution for us as well!

But nothing is soo easy.

Our first problem was that we didn't need the whole project because it has "some dependencies" and consists of different jar files. So we thought that it would be a good idea to use only the relevant classes. Not so simple because of the license (EPL). The source code integration in our project wasn't possible, because we're Apache 2.0 licensed. But it was allowed to use some classes, create a new project with EPL and add the library to our project (thanks Tom for sharing your thoughts with us).
The result is our javafx.DndTabPane project, hosted on github.

The implementation of Tom worked great, but we had some extra requirements for our API:

  • Don't drag disabled tabs
  • It should be possible to disable dragging
  • Event if dragging

Sure, we made some smaller changes to allow customization.

In addition to Drag and Drop support, we found two problems with standard TabPane: RT-40149 and RT-40150.

We have one workaround and one dirty fix for the problems in our UI implementation: RT-40149 and RT-40150. (Not proud of it, but works)

News mix

The next release of JVx is coming!

It'll be version 2.2. We have 2 open tickets for this release but both are refactoring tasks, nothing too important. We're already feature complete.

It'll be an awesome release because we have a lot of performance improvements and some really cool features like lazy loading of BLOBs (binary content). The server implementation is now IoT ready and it's pluggable. Support for Lambda expressions with full backwards compatibility for our listener handling. And we have support for application monitoring, style definitions, streamed upload of large files, and much more.

We plan the release for the end of this week.

Our VaadinUI was based on vaadin 7.1.15 and 7.4 was released some days ago. We're happy to announce support for vaadin 7.4.

The repository of JVx' vaadin UI already contains 7.4 libraries and everything is available for you. We don't have an official release right now, because we do some tests and afterwards we'll release a new version of our UI. We don't have a date for you but hopefully in March.

We currently don't use the new Grid component, but we'll replace the current table implementation asap.

The last information is about the next release of VisionX 2.2 preview. It will contain JV' vaadin UI for vaadin 7.4 and some new features like exporting an application for embedded devices (run the application on embedded devices like Raspberry Pi, without application server - "Micro applications").

Oh, finally... Check our github page, because we have new projects for you.

A DesktopPane for JavaFX

If you plan to create desktop business applications, you'll miss one thing in JavaFX: A real desktop pane with internal frames.

The only comparable thing is the Window implementation of JFXtras. The implementation was a first step in the right direction, but not a real desktop/internal frame solution.

We did some experiments with Window and had following problems:

  • Mouse cursor was changed to resize but not back to default
  • Resize operation moved the window to totally different positions
  • It was possible to drag the window out of the parent node
  • Components were set to managed (false) -> a lot of layouting problems
  • Missing maximize functionality
  • Problems with focus handling
  • Title wasn't always shown
  • No tab/window mode switching option
  • Modality?

It was not a real internal frame, as we knew it from Swing. And a desktop pane/window manager wasn't available, which could be used to manage active/inactive windows/frames.

Our customers won't work without MDI because they need more than one frame, because of different reasons. Sure it depends on the application and use case but big applications without internal frames are a No-Go.

So we thought that it's the right time to start with a real desktop implementation with internal frames. Here are some imporessions:

Desktop + InternalFrames

Desktop + InternalFrames

 
Maximized frame

Maximized frame

Desktop with Tabs

Desktop with Tabs

We need better styles for the frames and some nice icons, but this isn't a big problem because we use stylesheets for everything. The implementation isn't production ready at the moment, but we solved most problems and made good progress.

The current desktop/frames knew the difference between active and inactive, it possible to minimize/iconify frames, focus handling works, maximization is possible and it's possible to switch between frame and tab mode. Dragging works like a charm.

Our implementation will be a real replacement for Swing' internal frames. It's part of our JavaFX UI implementation for JVx.

Application monitoring

You can build amazing applications with JVx. The framework is full-stack and supports your ALM. It has a flexible architecture, allows RAD, has built-in support for automated testing, deployment is an easy task and CI/CD are well supported.

But what happens with your applications after deployment?

Usually an application works different in production because the runtime environment is different and the amount of data grows. The number of users could be even more than in your test environment. You're well adviced if you check the deployed applications on their health, during the first few weeks or months. But it's not an easy task to check application health because reading log files or checking system parameters is not enough.
It would be best to use an application performance monitoring tool like Appdynamics or VisualVM. But such tools are complex, pro versions aren't cheap and such tools aren't specific for JVx applications.

It's horrible to check application health without a monitoring tool and it doesn't work with large applications. Or it's possible but you need too much time to find the problems.

We tried Appdynamics Lite for JVx applications and were impressed about the features, but shocked about the complexity. It's a dinosaur with millions of options. You should use a dedicated server for the tool and the machine should have extra power. Sure, the tool solves a problem but we won't use it for JVx application monitoring because it doesn't read all available information. It wasn't an option to create adapters for appdynamics because it's too complex and we love keeping things simple!

No worry, we have a simple solution for you!

It's our upcoming Application Monitoring tool. It was designed especially for JVx applications and it supports the whole server-side handling with life-cycle and server objects. The tool is a JVx application and runs with vaadin UI.
It will work with every standard Java application server and hardware requirements are as usual for JVx applications. Sure, some extra memory will be needed because analyzation of application metrics needs more resources.

Some impressions?

Monitoring Dashboard

Monitoring Dashboard

Monitoring memory

Monitoring memory

The first image shows the dashboard. It has an overview of general health and some server parameters. It shows memory consumption, concurrent user count and SQL statement statistics. This is one of the most important information about JVx applications because slow statements can slow down your application!

We show the top 10 of the slowest statements and other useful metrics.

The tool allows access to the metadata cache and shows all details about server calls. Here are more impressions for you:

Metadata overview

Metadata overview

 
Call details

Call details

The application monitoring tool was designed especially for JVx applications and the server-side implementation of JVx. It's perfect integrated and doesn't slow down your application. It helps you to find the problems before your customers will find them. And it also helps with performance tuning of your application during development or after deployment in production environment.

The tool itself is not open-source and not free to use. It's a commercial addon for your JVx applications. We don't offer a lite version because tools for quality assurance should be paid. If you're interested, feel free to send us an email.