Thursday, October 30, 2014

JavaFX dialogs

The JavaFX project doesn't have dialog controls, so when I wanted to add dialogs to my project I used the dialog controls from the fxexperience project, they release you from all the trouble of creating your own control, but recently they announced that the dialog controls will be in a separate project (announcing-controlsfx-8-20-7) deprecating the current controls.

The new project is called openjfx dialogs and it is located right here Since right now it doesn't contain any documentation I will explain you how to start using it and ease the way to start adopting them.

To start working first download the project repository from here, in the left side there is a link to download, it downloads a zip file, unzip it wherever you wan to.

Next the project needs to be build, to do this we will need gradle, for thoose who don't know what is gradle here it is a brief description about it:

"Gradle combines the power and flexibility of Ant with the dependency management and conventions of Maven into a more effective way to build"

I'm not going to explain deeper gradle since it is another topic and this post wouldn't be enough to explain it.

You can download and install gradle form here, the project already contains a version of gradle you can just run the gradlew.bat file. Either you install it or use the version of the project, run the following command at the root of the project:

    gradle build

If the project is built correctly you will find the folders build/lib under the root of the project, under these folders the openjfx-dialogs-X.X.X.jar is located we will need this jar to add the dialog controls.

Now let's create an example to test the dialogs an see how they work, I'm going to use Netbeans to develop this example.

Let's create a javafx application project:

Let's name the project Dialogs, keep selected the checkbox "Create application class", then click finish.

Add to project the openjfx-dialogs jar, to do this over the project right click and select "properties" option. In the properties select the "libraries" option

Click over the Add Jar/Folder button, and select the jar previously built "openjfx-dialogs-X.X.X.jar".

With these steps everything is set to start creating dialogs, in the previous version the code to create a dialog was kind of messy and not intuitive from of my point of view, this is an example:

It uses the builder pattern, a single class did handle all the types of dialogs, but now this code is deprecated. You can find more about the deprecated dialogs right here

In the new version each type of dialog has its own class making the code clearer and more intuitive, this is from my point of view. At this point the types of dialogs are javafx.scene.control.Alert, javafx.scene.control.ChoiceDialog and javafx.scene.control.TextInputDialog.

Lets create an alert dialog, in the class created in the project change it to display the dialog as the following example:

From the example above an Alert object is created and it is passed a type of alert dialog, in this case is confirmation but there are others as error, information, warning, and so on.

In the button's click event the show() is called to display the dialog, but this method doesn't wait the dialog to close, the method showAndWait() waits the dialog to close and returns an Optional object with the button typed if that was the case.

The following example uses a text input dialog:

From the example above the only difference is that the showAndWait() method returns an Optional object with the content of the input element from the dialog.

The ChoiceDialog displays a dialog with a combo control with a set of values, the following example show how to use it:

From the example above you can see that the options are passed through the constructor and later through the items property and uses the same mechanism as the TextInputDialog to retrieve the value selected.

As I said before since the project is not finish and right now there is no documentation, I hope that with this post you can more easily adopt this new version or start using it.

Friday, October 17, 2014

JavaFX workaround for rotate text on tabpane tab

I have not much of experience with JavaFX, but I've been using it since almost over a year by now. I found that the tabs from the tabpane control have a restriction, when they are placed by a side either right or left the text can not be placed horizontal, the following image shows the behavior.

The issue is that the text is not displayed horizontally and it is hard to read, and javaFX does not provide a solution to it, actually there is feature request to it but it seems that it will not happen soon.

I found some workarounds to it, but they have many issues such as the text doesn't properly resize the tab width, so I'm going to describe the workaround that I did, hoping that it could be helpful to you.

A solution that I found from this post , mentions to add the following style:

Which works fine:

But what if you have multiple tabs in your application and this tabs do not have the tabs by a side, it will also rotate the text of this tabs and will complicate everything.

Another issue is, if the characters of the text increases the size also increases but not only its width but also its height:

Due to all this issues this workaround and others seem to work fine only in certain scenarios.
My workaround is not better than them, but it tries to avoid these issues.
First, only rotate the tabs you want to rotate, to do this create a CSS class:

Then add it to the tabs objects you want to rotate:

Then create a CSS class to handle the size for the TabPane in which you are rotating the tabs:

Add this class to the TabPane object:

With this you will restrict the size of your tabs and they will not get bigger if the text increases. The limitation it has is that the amount of characters depends on the size you set to the TabPane object.

As I said I'm not an expert on javaFX and I found this solution to this issue that seems to be different to others and might help you.
If you have a different solution before this issue is fixed tell me about it.