Posts tagged: JavaFX

JavaFX UI and VisionX

Post to Twitter

We've good news for you. Since our JavaFX UI has reached version 1.0, we thought it might be a good idea to integrate the UI into VisionX. It wasn't that easy because JavaFX needs Java8 and VisionX runs with Java7. It wasn't enough to switch the JVM because VisionX had Eclipse JDT under the hood and the used version wasn't Java8 ready and also some other libraries had problems with Java8.

It was a lot of work to support JavaFX but now it's done. We have Java8 support in VisionX and all referenced projects were updated. We don't have a public version for you right now because the new features need some additional tests. But we're very happy with the current status. Our development version is very stable and all features are still working.

We have a short screencast for you:

JavaFX with VisionX


JVx' JavaFX UI 1.0

Post to Twitter

We're happy to announce that our JavaFX UI 1.0 was released.

The release contains all planned features and some more. We have the complete MDI implementation, Zoom support for windows and the scene, a custom scene style, custom comboboxes and much more.

MDI control

MDI control

Combobox

Combobox

Styled Scene

Styled Scene

Table format (cells)

Table format (cells)

Zoom

Zoom

Master/Detail with Tables and Tree

Master/Detail with Tables and Tree

All custom controls are available as separate library, JFXtensions. This library will work without JVx because it has no dependency to JVx. Simply use our MDI implementation or zoom feature for your own JavaFX application without using JVx.

Jar files are available at SourceForge or Maven central.

Our next steps?

We'll integrate the UI in our product VisionX to allow Live Preview with JavaFX. The first update release with version number 1.1. will contain smaller bugfixes and improvements based on user feedback.

So, send us your Feedback if you use our library.

Custom comboboxes with JavaFX

Post to Twitter

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.

Zoom support for applications

Post to Twitter

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

Post to Twitter

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.

JavaFX Table and Tree lazy loading

Post to Twitter

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.

JavaFX Tree with self-joined table

Post to Twitter

Trees are always tricky, because it's not easy to fill a tree with data. The problem is not the tree itself, but the preparation of data for the three. It's easy if your data is structured or if you have only few records to prepare. If you have differnet datasources, it could be very tricky to build a tree.

The official tree documentation from Oracle has some examples.

It's boring to create trees because it needs a lot of boilerplate code - per tree. You need more boilerplate code if your trees should be editable.

We solved the "boilerplate code problem" with JVx and the active model implementation. I'll show you a simple example with a self-joined database table. The database table contains all filesystem folders of our Linux test VM.

The table was created with following statement:

CREATE TABLE FOLDERS
(
  ID        INTEGER IDENTITY,
  FOLDER    VARCHAR(256) NOT NULL,
  FOLD_ID   INTEGER,
  constraint FOLD_UK UNIQUE (FOLD_ID, FOLDER),
  constraint FOLD_FOLD_ID_FK FOREIGN KEY (FOLD_ID) REFERENCES FOLDERS (ID) ON DELETE CASCADE
)

Not really tricky. The table contains an unique identifier, the folder name and the identifier of the parent folder. A simple self-joined table.

The UI code for the tree:

IDataBook dataBook = createDataBook();

FXDataBooksTree tree = new FXDataBooksTree();
tree.getDataBooks().addAll(dataBook);

Short and no boilerplate code!
The missing piece is the createDataBook() method, because it defines the access to our database table:

RemoteDataBook rdbData = new RemoteDataBook();
rdbData.setDataSource(getDataSource());
rdbData.setName("folders");
rdbData.setMasterReference(new ReferenceDefinition(new String[] {"FOLD_ID"},
                                                   rdbData,
                                                   new String[] {"ID"}));
rdbData.open();

The code is similar to other examples likeJavaFX, JVx and data binding or Plain JDBC vs. DBStorage.

The tree will look like this one:

Self-joined tree

Self-joined tree

The whole source code is available in our dev branch.

Above test application reads records from a remote database via http, but it could also use a memory databook without database access, like this one:

IDataBook dataBook = new MemDataBook();
dataBook.getRowDefinition().addColumnDefinition(new ColumnDefinition("ID",
                                                new BigDecimalDataType()));
dataBook.getRowDefinition().addColumnDefinition(new ColumnDefinition("PARENT_ID",
                                                new BigDecimalDataType()));
dataBook.getRowDefinition().addColumnDefinition(new ColumnDefinition("NAME",
                                                new StringDataType()));
dataBook.setMasterReference(new ReferenceDefinition(new String[] { "PARENT_ID" },
                                                    dataBook,
                                                    new String[] { "ID" }));
dataBook.setName("MASTER");
dataBook.open();

An example with a MemDataBook is available in our kitchensink application.

JavaFX custom controls

Post to Twitter

We started with our JavaFX UI in January and we are on the home stretch!
All features were implemented and we have some Feature Requests and known Bugs in our Ticketing system and some open Issues in the JavaFX ticketing system (JIRA, at the moment).

At the beginning we thought that 2 months will be sufficient to implement the whole UI :) We were very optimistic but not far away from the reality but we didn't know that JavaFX had a lot of missing pieces.

Missing pieces?

Don't get me wrong, because JavaFX is an awesome UI toolkit and will be a perfect replacement for Swing, but it needs some real world applications. Yes, applications and not fancy hello world examples. Sure, there are some great applications but most use custom controls because of problems with standard controls. The overall performance is still not perfect and there's still a lot of tuning potential. Currently a swing application acts faster without delays.

The biggest problem for us was that standard controls like Toolbar, Menus didn't work as expected and other controls like DesktopPane or Internal Frame weren't available. We didn't find a date + time combobox editor. Some standard controls like Button, CheckBox or RadioButon didn't offer specific alignment options and another problem was the coding philosophy because many useful methods are public final or private. You can't replace internal listeners or remove internal listeners because you can't access all list elements.

But this article shouldn't cover our development problems because many of them will be solved with Java8 u60 and we have custom controls for the rest. Currently we have many useful classes for our UI and also for you, because we tried to implement all extensions independent of JVx. This article gives a short overview.

Re-usable controls and classes

We have some additional classes without images:

  • FXNullPane

    Acts like a Swing panel with null layout.

  • FXSceneLocker

    From the javadoc: The FXSceneLocker is a static helper utility that allows to to lock a Scene, meaning that only events that belong to the locking Node or its children are processed. If a Scene is locked by multiple Nodes, that last one does receive events.

You'll find all other utilities and controls in the dev repositoriy. The ext Package is independent of JVx. We use it as base for our UI implementation.

JavaFX + Android + Live Preview

Post to Twitter

We had a lot of fun this week - with JavaFX :)

My last article was about JavaFX on mobile devices with JavaFXPorts. It was awesome that JavaFX worked without bigger problems on mobile devices but the number of needed re-deployments was high. The app build process needs some time (~2-3 mins) and if you do a lot of UI related changes in your application (CSS, layout, ...) you lose development time.

How to save deployment time?

Simply don't deploy!

We have our product VisionX and it has a Live Preview for applications while developing. Our idea was that we could use the existing functionality to show changes on mobile devices immediately. It should work with Android devices because dynamic class loading is possible with custom classloaders.

But as so often, things won't work as expected.

Android has support for URLClassLoader but it doesn't work because the implementation is "legacy" . This means that loading classes with URLClassLoader didn't work. Android has a DexClassLoader!

The DexClassLoader works great if you have the archive on the device. But it has no support for remote class loading. The other thing was that DexClassLoader needs a jar that contains a classes.dex archive. The classes.dex contains all class files (in dex format).

The first problem was: How to create the DEX archive?

Not too hard because Android comes with dx.bat and dx.jar. It's super easy to convert a jar file or a classes folder to a dex archive. After the hardest part was solved, it was simple to implement remote class loading with Android, for our JavaFX application! If you need more information, leave a comment!

Here's the result of our Live Preview experiment as Video:

Window shutter web control

It works great and reduces deployments to a bare minimum: 1

JVx' JavaFX UI with JavaFXPorts

Post to Twitter

A few hours ago, we published a screenshot from our Demo ERP application running on Nexus 9 (an Android tablet).
It wasn't a fake!

Before we'll show you more screenshots, we want say that we've reached a long awaited goal!

Use JVx and write an application for all polpular platforms and devices.
This is real "write once run anywhere".

Create an application for Windows, Linux, Mac, iOS, or Android, PS4, OUYA or WiiU. Run it as desktop application, as html5 application in web browsers, as native iOS or Android application or as JavaFX application on Android and iOS devices. There's nothing like JVx in the world - not with only one framework with such a small footprint as JVx and certainly not Open Source!

Here are the screenshots:

Maximized frame with charts

Maximized frame with charts

Frame with tree

Frame with tree

Also in portrait mode:

Portrait mode

Portrait mode


And now a very strange one. It's the application with our styled stage. It's crazy because you can drag the window around (makes no sense, but it just works):

Styled stage with tabset desktop

Styled stage

Sure, the application wasn't optimized for mobile devices. It has the same style as the desktop application. The mobile version should have bigger frame buttons and a bigger frame header :) To be honest - MDI on mobile devices? We were positively surprised about the usability. But, whatever. You have the option and decide what's best for your application (but please don't use MDI for smartphones).

Are you interested in some details?

We've used Netbeans IDE because there's a very useful plugin from gluon. We're Eclipse users but it was easier to use a preconfigured environment without doing everything manually. It was simple to configure Netbeans with gluon plugin and there's a video for your first steps. A "bigger" problem was gradle because the project was a gradle project and we've never used gradle. We love using ant.

We had a bad start with Hello World application because it didn't work. There were different problems: Missing ANDROID_HOME or DEX compiler problems. After reading the documentation it was possible to start compilation. The DEX problem was very strange because we had JVM 1.8 u31 and JVM 1.8 u40 configured in Netbeans, but Netbeans didn't use our configured JVM 1.8 u40. We removed the JVM 1.8 u31 from Netbeans and after that we successfully compiled our Hello World application. Very strange!

The next step was using JVx as library dependency for our project, but how did this work with gradle? We had the library in the libs directory of the project, in the file system. We didn't use a maven lib because it was easier to replace the library after recreation. We tried to find a solution in the official gradle documentation and found Chapter 51. C'mon gradle is a build tool and not a programming language! So much documentation means: complexity. Sure, ant wasn't the holy grale but it it's simple to understand and doesn't hide anything.

Our current gradle script:

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'org.javafxports:jfxmobile-plugin:1.0.0-b7'

    }
}

apply plugin: 'org.javafxports.jfxmobile'

repositories {
    jcenter()
}

dependencies {
    compile fileTree(dir: 'libs', include: '*.jar')
    runtime fileTree(dir: 'libs', include: '*.jar')
}

mainClassName = 'com.sibvisions.gluon.JVxGluonApp'
   
jfxmobile {
   
    ios {
        forceLinkClasses = [ 'com.sibvisions.gluon.**.*' ]
    }
   
    android {
      androidSdk = 'C:/tools/android/android-sdk_r04-windows'
      compileSdkVersion = 21  
    }
}

It's short but we ddin't know what happened behind the scenes without additional research. But if it works it's good enough for many developers.

The integration of JVx was simple because JVx was compiled with JVM 1.6. The Dalvik VM or DART do support 1.6 and 1.7 syntax. It was cool to see that JVx and especially the communication worked without problems - Great job from Johan Vos and all people behind JavaFXPorts!

Our next step was the integration of additional dependencies like our JavaFX UI. It was based on JVM 1.8 u40 and heavily used lambdas. But lambda expressions weren't supported from Dalvik or ART. We thought that gluon plugin solves the problem for us, but it didn't. It contains retrolambda but only for project source files and it doesn't touch your dependencies. There was no additional gradle build task for that, so we had to convert the libs manually. Not a problem but you must be aware of it.

After we solved all dependency problems, we had the first version of our desktop ERP running on our android device. But don't think everything was trouble-free. We had problems with method references, Java Preferences because of write problems, new Date API, forEach calls, scene size and much more. We did solve most problems but not all - yet.