Raspberry Pi B4J UI Applications with Liberica JDK

Tutorials related to develop with B4J.
rwblinn
Site Admin
Posts: 224
Joined: 07 Oct 2017, 12:16

Raspberry Pi B4J UI Applications with Liberica JDK

Postby rwblinn » 13 May 2018, 15:23

Tutorial Raspberry Pi B4J UI Applications with Liberica JDK
v20180513

Objectives
To build B4J UI applications, using the Liberica JDK10, running on the Raspberry Pi.
This tutorial covers setup of the Raspberry Pi, Liberica, development hints and few sample applications.

The B4J UI applications have been tested with:
* Raspberry Pi 3B+ with HDMI connected monitor Philips 223V
* Raspberry Pi 2Bv1.1 with 7" touchscreen display

Especially the 7" touchscreen solution is interesting for f.e. Information Display, Dashboards, Control GPIO and the likes.

Image
Prototype with 7" touchscreen running the CPU-Temperature-Dashboard sample application.

Image
Screenshot of the prototype with 7" touchscreen running the HomeAutomation-Dashboard sample application.

Credits
For the shown sample applications, the jGauges library and the xChart class are used. Many thanks to the authors.

Liberica Information
As taken from here, Liberica is a 100% open-source Java 10 implementation for Raspberry Pi.
It is built from the OpenJDK to which BellSoft contributes. Recommend to read the release notes.
The source is on GitHub.

Hardware
Raspberry Pi 3B+ with HDMI connected monitor Philips 223V
Raspberry Pi 2 with 7" Touchscreen Display

Software
Raspberry Pi Raspbian Stretch (Linux raspberrypi 4.14.30-v7+ #1102 SMP Mon Mar 26 16:45:49 BST 2018 armv7l).
B4J v6.01
Liberica JDK 10
Note: Newer software versions might be available after writing this tutorial.

Raspberry Pi Setup
For the testing, installed the latest, at the time of developing, Raspberry Pi NOOBS.
Configuration Modifications
Increase the GPU Memory: Menu Preferences > Raspberry Pi Configuration > Tab Performance > Field GPU Memory: 512.

Disable Monitor Sleep

Code: Select all

sudo nano /etc/lightdm/lightdm.conf

Add the following lines to the [Seat*] section:

Code: Select all

# Disable monitor sleep
xserver-command=X -s 0 dpms


Prior Liberica installation run an Raspberry Pi software upgrade and update:
sudo apt-get update && sudo apt-get upgrade

Liberica Installation
On the Raspberry Pi, open a terminal, login as user pi and execute next steps.
// Create a folder java to store the downloads.

Code: Select all

mkdir /home/pi/java

// Set the created java folder as default

Code: Select all

cd /home/pi/java

// Download the Liberica JDK10 package from BellSoft
// Note: This example shows JDK10. In the mean time there might be newer versions, i.e. JDK10.0.1.

Code: Select all

wget https://github.com/bell-sw/Liberica/releases/download/10/bellsoft-jdk10-linux-arm32-vfp-hflt.deb
Logging information snippet ...
--2018-04-18 09:33:42--  https://github.com/bell-sw/Liberica/releases/download/10/bellsoft-jdk10-linux-arm32-vfp-hflt.deb
Saving to: ‘bellsoft-jdk10-linux-arm32-vfp-hflt.deb’
bellsoft-jdk10-linu 100%[===================>] 209.58M   752KB/s    in 4m 48s
2018-04-18 09:38:31 (745 KB/s) - ‘bellsoft-jdk10-linux-arm32-vfp-hflt.deb’ saved [219758630/219758630]

// Install the Liberica JDK10 package

Code: Select all

sudo apt install ./bellsoft-jdk10-linux-arm32-vfp-hflt.deb

// Check the installed java and javac versions

Code: Select all

java -version
resulting in: java version "1.8.0_162"
javac -version
resulting in: javac 1.8.0_162

// Set the right javac version (compiler)
// The list of javac options depends on the installed java versions.
// Note: Prior using the Liberica JDK (BellSoft) tested also the jdk8.0_161/162.

Code: Select all

$sudo update-alternatives --config javac

There are 4 choices for the alternative javac (providing /usr/bin/javac).

Code: Select all

  Selection    Path                                                   Priority   Status
------------------------------------------------------------
  0            /usr/lib/jvm/jdk-10-bellsoft-arm32-vfp-hflt/bin/javac   1902      auto mode
  1            /opt/jdk1.8.0_161/bin/javac                             1         manual mode
* 2            /opt/jdk1.8.0_162/bin/javac                             1         manual mode
  3            /usr/lib/jvm/jdk-10-bellsoft-arm32-vfp-hflt/bin/javac   1902      manual mode
  4            /usr/lib/jvm/jdk-7-oracle-arm-vfp-hflt/bin/javac        317       manual mode
Press <enter> to keep the current choice[*], or type selection number: 3
update-alternatives: using /usr/lib/jvm/jdk-10-bellsoft-arm32-vfp-hflt/bin/javac to provide /usr/bin/javac (javac) in manual mode

// Set the right java version (runtime)
// The list of options depends on the installed java versions.

Code: Select all

$sudo update-alternatives --config java

There are 4 choices for the alternative java (providing /usr/bin/java).

Code: Select all

  Selection    Path                                                  Priority   Status
------------------------------------------------------------
  0            /usr/lib/jvm/jdk-10-bellsoft-arm32-vfp-hflt/bin/java   1902      auto mode
  1            /opt/jdk1.8.0_161/bin/java                             1         manual mode
* 2            /opt/jdk1.8.0_162/bin/java                             1         manual mode
  3            /usr/lib/jvm/jdk-10-bellsoft-arm32-vfp-hflt/bin/java   1902      manual mode
  4            /usr/lib/jvm/jdk-7-oracle-arm-vfp-hflt/jre/bin/java    317       manual mode
Press <enter> to keep the current choice[*], or type selection number: 3
update-alternatives: using /usr/lib/jvm/jdk-10-bellsoft-arm32-vfp-hflt/bin/java to provide /usr/bin/java (java) in manual mode

// Check the java and javac versions again = should be the BellSoft java 10 versions

Code: Select all

$javac -version
javac 10-BellSoft

Code: Select all

$java -version
openjdk version "10-BellSoft" 2018-03-20
OpenJDK Runtime Environment (build 10-BellSoft+0)
OpenJDK Server VM (build 10-BellSoft+0, mixed mode)

The downloaded deb file is not required anymore and can be deleted to freeup space.

Liberica Installation Folder
The Liberica JDK is installin folder: /usr/lib/jvm/jdk-10-bellsoft-arm32-vfp-hflt
Recommend to read the file readme.txt. The file release contains release version and module information.

Setup Hints
Performance GPU Memory

To state again = ensure to set the Raspberry Pi GPU memory from default 64 to at least 256 or 512.
If not the case, then a memory glGetError occurs:

Code: Select all

Memory Error glGetError 0x505 or the B4J IDE Logs, like
java.lang.NullPointerException
  at com.sun.prism.impl.ps.PaintHelper.initGradientTextures(PaintHelper.java:131)
  at com.sun.prism.impl.ps.PaintHelper.getGradientTexture(PaintHelper.java:141)

Note:
Be carefull using resources, i.e. a Label with a Big Font size consumes high amount of GPU memory.

Error Message Failed to write to /sys/class/input/mice/uevent
Message

Code: Select all

Udev: Failed to write to /sys/class/input/mice/uevent – Check that you have permission to access input devices

This message occurs when executing a JavaFX application on a Raspberry Pi using a user other than root, i.e. user pi.

Cause
JavaFX requires direct write access to device hardware.

Solution Option 1
Execute the application as sudo, i.e. sudo java -jar myjavafxapp.jar

Solution Option 2
Modify settings to grant write access to the devices all users that belongs to the input group.
Edit the 99-com.rules file:

Code: Select all

$sudo nano /etc/udev/rules.d/99-com.rules

Add at the bottom:

Code: Select all

SUBSYSTEM=="input*", PROGRAM="/bin/sh -c '\
 chown -R root:input /sys/class/input/*/ && chmod -R 770 /sys/class/input/*/;\
'"

Run the application without root: java -jar myjavafxapp.jar

Application Test - B4J-Bridge
To test the application developed on a device, i.e. Windows 10 PC, use the B4J Bridge.
Install
by creating a B4J folder, set as default, delete any previous versions, then download the B4J-Bridge:

Code: Select all

mkdir /home/pi/b4j
cd /home/pi/b4j                     
rm b4j-bridge.jar
wget http://www.b4x.com/b4j/files/b4j-bridge.jar


Alternative to wget
Transfer (via f.e. WinSCP) the B4J-Bridge from a development device to the RPi folder /home/pi/b4j.

Run
To run as root (do not forget esp, when using Pi4j) when logged in as user Pi:
sudo <path to java> -jar b4j-bridge.jar

If the path to java is set in the environment path, then call

Code: Select all

sudo java -jar b4j-bridge


It is useful to run the B4J-Bridge from a dedicated terminal, like f.e. from the development device using Putty.
When doing so, the output of the running application can be watched.

Application Test - Full Screen Mode
On the Raspberry Pi, the JavaFX application runs in Full Screen Mode and captures all Linux input devices.
When using VNC, the application is not visible - only on the monitor connected to the Raspberry Pi.
There is no titlebar for forms & dialogs and Control-C is not working, means has to be catered for in the application.

Autostart the B4J UI Application at Boot
As an example application jar: dashboard.jar located in folder /home/pi/b4j

Bash Script
Create a bash script dashboard.sh in folder /home/pi/b4j

Code: Select all

sudo nano dashboard.sh

Content:

Code: Select all

#!/bin/bash
cd /home/pi/b4j
sudo java -jar dashboard.jar

Make the bash script executable:

Code: Select all

sudo chmod +x dashboard.sh


Edit autostart

Code: Select all

nano ~/.config/lxsession/LXDE-pi/autostart

add at file end:

Code: Select all

@/home/pi/b4j/dashboard.sh

Resulting in example:

Code: Select all

@lxpanel --profile LXDE-pi
@pcmanfm --desktop --profile LXDE-pi
@xscreensaver -no-splash
@point-rpi
@/home/pi/b4j/dashboard.sh


... and reboot the Raspberry Pi to test if working.

B4J UI Application Development Hints
Merge Libraries
When using additional libraries (i.e. Pi4J, SQLite ...), set the Project Attribute MergeLibraries:True.
Example for a SQLite driver which is set by using a Conditional Symbol:

Code: Select all

#Region Project Attributes
   #MainFormWidth: 1000
   #MainFormHeight: 800
   ' SQLite driver - located in the B4J core libraries folder - ensure to set the correct version
   #If PC
       #AdditionalJar: sqlite-jdbc-3.7.2
   #Else
       #AdditionalJar: sqlite-raspberry.jar
   #End If
   #MergeLibraries: True
   ' #CommandLineArgs: -l
#End Region


Application Close
In the B4J application, ensure to implement a close button to exit the application as the generated application has not titlebar.
Example of using a Close Button at the form bottom right and a Close [X] Button at the top right.

Code: Select all

Sub Process_Globals
   Private btnClose As Button
   Private btnCloseX As Button
...

Sub AppClose
   MainForm.Close
   ExitApplication
End Sub

' Close the app using X Button top right corner
Sub btnCloseX_Action
   AppClose
End Sub

' Close the app using close button bottom right
Sub btnClose_Action
   fx.Msgbox(MainForm, "Hello World", "Information")
   AppClose
End Sub


MsgBox
The fx.MsgBox is displayed without titlebar and borders. The background color is white.
Instead using the fx message boxes, consider to build an own class with a message box having a titlebar and other options.

Snapshot
To make a snapshot of a form, the jfxrt.jar (i.e. from JDK8) is required and must be added to the B4J additional libraries folder.
Example:

Code: Select all

'Make a snapshot of the mainform. The png file is stored in the dirapp folder.
'Requires #AdditionalJar: jfxrt with jfxrt.jar located in the B4J additional libraries folder
Sub FormSnapShot   'ignore
   Dim img As Image = MainForm.RootPane.Snapshot
   Dim Out As OutputStream = File.OpenOutput(File.DirApp, "snapshot.png", False)
   img.WriteToStream(Out)
   Out.Close
End Sub

Hint:
Use the conditional snapshot to enable snapshots

Code: Select all

#Region Project Attributes
   'Set the conditional snapshot to enable snapshots
   #If snapshot
       'The jar jfxrt is required for the class SwingFXUtils to make a screenshot of the mainform when running on the RPi.
       'This to avoid runtime error: java.lang.NoClassDefFoundError: javafx/embed/swing/SwingFXUtils
       'Copy c:\Program Files (x86)\Java\jdk8\jre\lib\ext\jfxrt.jar to the B4J additional libraries folder.
       'Note: Check your JDK path prior copying to the B4J additional library folder.
       #AdditionalJar: jfxrt
   #End If
#End Region

Code: Select all

Sub AppClose_Action
   #If snapshot
       FormSnapShot("snapshot.png")
   #End If
   MainForm.close
   ExitApplication
End Sub


Maximize Screen
As mentioned, the application runs in full screen.
When setting the Project Attributes MainFormWidth and MainFormHeight to a certain value, which is smaller then the full screen size, the form is displayed as sub window from the full screen.
Recommend to set the form to full screen.
Example sub routine setting to full screen with an offset.
The offset was used to handle an openJDK error, where the cursor disappears when moving to the far right of the form. In newer JDK versions, this error did not show up anymore.

Code: Select all

' Set the form to fill the screen with an offset
Sub SetFormFillScreenOffset(frm As Form, offset As Int)   'ignore
   Dim ps As Screen = fx.PrimaryScreen
   frm.WindowLeft = ps.MinX + offset
   frm.WindowWidth = ps.MaxX - frm.WindowLeft - offset
   frm.WindowTop = ps.MinY + offset
   frm.WindowHeight = ps.MaxY - frm.WindowTop - offset
End Sub

Code: Select all

'Set the form to fill the screen with an offset - comment if want to use the window dimensions defined in the project attributes
SetFormFillScreenOffset(MainForm, 50)


Java Version
If want to know or display the Java version on the Raspberry Pi:

Code: Select all

Private lblStatus As Label
lblStatus.Text = $"Java ${GetSystemProperty("java.version","0.0.0_00")}"$


Raspberry Pi 7" Touchscreen
The sample applications have been tested esp. on the Raspberry Pi 7" touchscreen with dimensions 800*480.
In the B4J Visual Designer, defined a new Variant 800*480,scale=1 (160dpi).
Layout used for the samples:

Code: Select all

[Top Pane [Label Title][Button CloseX] ]
[CONTENT]
[Bottom Pane [Label Info][Button Close] ]

View Properties

Code: Select all

Top Pane=Parent:Main,Hor Anchor:Both,Ver Anchor:Top,Left:5,Top:5,Right:5,Height:50
Label Title=Parent:Top Pane,Hor Anchor:Both,Ver Anchor:Both,Left:10,Top:10,Right:10,Bottom:10
Button CloseX:Parent:Top Pane,Hor Anchor:Right,Ver Anchor:Both,Right:10,Top:0,Width;50,Bottom:0. Used Fontawesome close icon Chr(0xF2D4) with size 18.

Code: Select all

Bottom Pane=Parent:Main,Hor Anchor:Both,Ver Anchor:Bottom,Left:5,Top:5,Right:5,Height:50
Label Info=Parent:Bottom Pane,Hor Anchor:Both,Ver Anchor:Both,Left:10,Top:10,Right:10,Bottom:10
Button CloseX:Parent:Bottom Pane,Hor Anchor:Right,Ver Anchor:Both,Right:20,Top:10,Width;100,Bottom:10


Application Samples
Build a few sample B4J UI applications - Download B4J source code.
As mentioned, tested the samples esp. with the 7" touchscreen.

IMPORTANT: For tests, please check if the conditional symbol snapshot is set and take out as required - used for making snapshots.

01-HelloWorld - The classic one to start with
02-LEDSwitch - Switch an LED connected to GPIO ON/OFF
03-LCDClock - Simple label showing time
04-Look4HowViewer - View Look4How databases ([url='http://make.rwblinn.de/viewtopic.php?f=24&t=231']more[/url])
06-CPU-Temperature-Dashboard - Display & log the Raspberry CPU temperature (Gauge)
07-HomeAutomationDashboard - Weather information displayed in Gauges and logged in a listview on a 7" touchscreen
99-WebView - Currently not supported by Liberica JDK v10. Awaiting update information.

Image

Return to “Tutorials”



Who is online