Tag Archives: qt

QT Application with Java. Possible? Yes QT Jambi does it.

If you’ve never heard about it, you can build rich cross-platform GUIs with Qt Jambi., while coding in Java. What?
Yes, QT Jambi is a QT Binding to Java, allowing you to develop QT GUI using Java instead of C++.
It practically is the same thing as Java-Gnome library which is a GTK+ binding.

QT Jambi is still maintained as opposite to rumors. And the last snapshot was build on 11 November 2012.
If you want to give it a shot, the following is a ‘get started’ tuto:

Environment:

  • OS: Ubuntu 12.10 AMD64
  • Desktop: Unity
  • IDE 1: Netbeans 7.3
  • JDK: Oracle JDK 1.7.u10
  • IDE 2: Eclipse Juno

First, install Qt Jambi from its PPA:


sudo add-apt-repository ppa:qtjambi-community/libqtjambi-snapshots && sudo apt-get update && sudo apt-get install --install-suggests libqtjambi-snapshot qtjambi-examples-snapshot qtjambi-designer-snapshot ant-qtjambi-snapshot libqtjambi-redist-snapshot

Then, use this script, to tell your JDK where to find corresponding QT libraries used by QT Jambi:

#!/bin/bash

#| Title: CopyJambi
#| Author: Hanine HAMZIOUI
#| Contact: <hanynowsky@gmail.com>
#| Date:  Sat 15 Dec 2012 03:57:00 AM WET
#| License: GNU GPL v3+
#| Description: Create symlinks to QT libs in default JDK for Jambi.
#| Version: 1.0
#| Environment: Netbeans 7.3 on Ubuntu 12.10 AMD64
#| Compliance: bash, zsh, ksh, dash, sh

# sudo add-apt-repository ppa:qtjambi-community/libqtjambi-snapshots
# sudo apt-get update
#sudo apt-get install --install-suggests libqtjambi-snapshot qtjambi-examples-snapshot qtjambi-designer-snapshot ant-qtjambi-snapshot libqtjambi-redist-snapshot

OPERATION() {
# Pick the JDK path
if [ -n "${JAVA_HOME}" ]; then jdk=${JAVA_HOME}
else
    if [ -d "/usr/lib/jvm/default-java" ]; then jdk=/usr/lib/jvm/default-java
    else whiptail --msgbox "No JAVA_HOME was found. Script will abort." "$LINES" "$COLUMNS"; exit 0
    fi
fi

# Two Temporary files that receive names of libraries to be copied
tmp1=$HOME/tmp/qtlibslist.txt
tmp2=$HOME/tmp/qtjnilibslist.txt

# Get the names of libraries to be copied
ls /usr/lib/x86_64-linux-gnu/ | grep libQt | sed -e '/.prl$/g' -e '/.a$/g' -e '/[0-9].[0-9]$/g' | perl -ne 's/^$//g || print' > ${tmp1}
ls /usr/lib/x86_64-linux-gnu/ | tr '[:upper:]' '[:lower:]' | grep libqt | sed -e '/.prl$/g' -e '/.a$/g' -e '/[0-9].[0-9]$/g' | perl -ne 's/^$//g || print' >> ${tmp1}
ls /usr/lib/jni |  tr '[:upper:]' '[:lower:]' | grep trolltech > ${tmp2}
ls /usr/lib/jni |  tr '[:upper:]' '[:lower:]' | grep jambi >> ${tmp2}

# Create symbolic links to QT libraries
count=0
while read line; do
sudo ln -v -s /usr/lib/x86_64-linux-gnu/${line} /usr/lib/${line}
sudo ln -v -s /usr/lib/x86_64-linux-gnu/${line} ${jdk}/jre/lib/amd64/${line}
((count++))
done < ${tmp1}
echo "Copied ${count} QT libraries Symbolic links"

# Create symbolic links to Jambi Libraries
i=0
while read inline; do
sudo ln -v -s /usr/lib/jni/${inline} ${jdk}/jre/lib/amd64/${inline}
sudo ln -s -v /usr/lib/jni/${inline} /usr/lib/${inline}
((count++))
done < ${tmp2}
echo "Copied ${i} Jambi QT libraries Symbolic links"

# Remove temporary files
if [ -f ${tmp1} ] || [ -f ${tmp2} ]
    then rm -v ${tmp1}; rm -v ${tmp2}
fi
}

# Make sure the user system is amd64
arch=$(uname -i)
if [ "${arch}" = "x86_64" ]; then eval OPERATION
else whiptail --msgbox "Your system architecture is not AMD64. Script will not continue. Abort." "$LINES" "$COLUMNS"
fi
exit 0

The above script will create symbolic links in your JDK path. If you want you can copy the libraries instead of just symlinking them.

Next step is to create a Java Project in Netbeans and import Qt Jambi library in classpath as well as QT Jambi Demos library. (You’ll find them in /usr/share/java/)

jambi-netbeans

Here is a screenshot of a demo example :

Jambi-Example

You can test with a simpler example (Hello World):


package jambi;

import com.trolltech.qt.gui.*;

public class HellowWorld {

public static void main(String args[]) {
QApplication.initialize(args);
QPushButton hello = new QPushButton("Hello World!");
hello.resize(120, 40);
hello.setWindowTitle("Hello World");
hello.show();
QApplication.execStatic();
QApplication.shutdown();
}
}

Notice:

When running a QT Jambi java file, you might encounter this error :
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007f6b95e362ba, pid=10602, tid=140100171314944
#
# JRE version: 7.0_10-b18
# Java VM: Java HotSpot(TM) 64-Bit Server VM (23.6-b04 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# C [libQtGui.so.4+0x2602ba] QWidgetPrivate::deleteTLSysExtra()+0x3a
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /home/hanine/Workspace/test/jambi/hs_err_pid10602.log
#
# If you would like to submit a bug report, please visit:
# http://bugreport.sun.com/bugreport/crash.jsp

Yet, entering : ulimit -c unlimited does not help at all. It sounds like an old bug related to Java HotSpot, where a zip file is read and modified in the same time. In other situations this bug is overriden using -Xmx option (e.g. -Xmx2900m : Maximum Memory : 2.9 GB )
E.G: java -Xmx:1864m -Xms:1864m myapp.jar sets minimum & maximum java memory heaps to 1864 MB for myapp.jar.
So, it appears that in almost all cases, a java file with the following statements will produce this error:

 public static void main(String args[]) {
        QApplication.initialize(args);

        Wiggly d = new Wiggly(null);
        d.show();

        QApplication.execStatic();
        QApplication.shutdown();
    }

So to get rid of this error, change the code to look like this instead (Still investigating on the root problem though):

 public static void main(String args[]) {
        QApplication.initialize(args);
        new Wiggly(null).show();

        QApplication.execStatic();
        QApplication.shutdown();
    }

Running your Qt Application from terminal

When you clean and build with Netbeans, you’d get a Jar File in your project workspace, in a folder named dist.
Make this jar file executable : chmod +x /path/to/this/jar/file.jar
and run it from terminal: java -jar /path/to/this/jar/file.jar

Qt Application executed as a JAR file.

Qt Application executed as a JAR file.

Eclipse Juno IDE

You can achieve the same thing using Eclipse if it’s your preferred IDE. Just make sure you install qt-jambi from Launchpad PPA and run the above script:

  • – Use the script from above or just download it from here : QtJambiCopierSCript
  • – Save it in your Desktop and run : bash ~/Desktop/jambicopy.sh
  • – Follow instructions if any.
  • – Open Eclipse Juno, Create a Java Project and add external libraries from /usr/share/java/
  • – Adding the qtjambi.jar and qtjambi-examples.jar does the job.

jambi-eclipse

GUI Designer

Unlike Java-Gnome binding library which does not yet integrate with GUI designer GLADE, Qt Jambi integrates with QT Designer.
If you followed instructions above, go to your Terminal and type:

qtjambi-designer.sh

or

bash /usr/bin/qtjambi-designer.sh

This will launch QT Jambi Designer. Henceforth, you can start designing visually your GUI. Once finished, save the work as a "*.jui" file, which you would reuse as your Application UI.
Normally, Qt Designer produces a file with "*.ui" extension; but QT Jambi team has modified the thing with custom modifications that allow better integration and generation of UI java files.
qtjambi-designer
We will cover this later in this same post.
Thanks for reading.
—————
N.B: Qt Jambi Community website is down since yesterday (14th December).
You can browse other useful resources that will get you accustomed to QT Jambi quickly: QT JAMBI RESOURCES

Advertisements