eskil
Qt
Qt Jambi
Posted by eskil
 in Qt, Qt Jambi
 on Wednesday, March 12, 2008 @ 13:03

The Qt 4.4 beta was released on February 26th, and, true to form, the corresponding Qt Jambi release comes a couple of weeks later.

In honor of the 4.4 release, we’d like to go through some of the new features you should look out for.

WebKit integration
WebKit is an open source web browser engine which is the basis of, among other things, the Safari web browser on Mac OS X. The engine has been integrated in Qt, and is available to Qt Jambi programmers in the package com.trolltech.qt.webkit. This means that you can easily integrate web content in your applications, and jump on the whole acronym-bandwagon by using AJAX methodology in your code. HÃ¥vard did a whole blog teasing this feature a while back, so instead of rewriting all that, we’ll just point you in the right direction. Benjamin wrote a blog a few days ago that goes into more detail, so take a look at that as well if you’re interested. On the WebKit Integration announcement page you’ll find lots more information, and some very cool videos that illustrate some of its awesome powers.

Multimedia framework
Qt and Qt Jambi 4.4 gets full-blown multimedia support through the Phonon framework adopted from KDE. This gives easy access to playing and manipulating movies and music in all the nice file formats for which the underlying media framework has codecs. The framework defaults to using Gstreamer (Linux), Microsoft DirectShow (Windows) and Quicktime (Mac OS X). There’s also this teaser blog about Qt Jambi and Phonon with an example for those interested.

New deployment system (Qt Jambi specific)
While we’ve always been recommending a .jar based deployment method, we’ve required people to build their own .jar files containing the necessary native libraries, and a meta-info approach to specifying which dependencies exists in a given project. This system has proven not only to be easy to misunderstand, but to have some fundemental flaws that could cause crashes and general discomfort if you did it wrong. In fact, in order to deploy previous versions on Mac, it was required that you were either Eskil, Gunnar, or someone with direct e-mail contact with either of us. In Qt Jambi 4.4 we’ve hopefully fixed this once and for all, by defining a default .jar based deployment system which avoids problems with mixing libraries and in which deploying to a different platform is as easy as replacing a single platform specific .jar file. In fact, if size is irrelevant, it’s possible to ship a single distribution of your application which will run on all platforms, as long as the platform .jar file for the given platform is in the class path when running the application.

If you are building from source and require extra libraries to be included, this can be achieved simply by editing the ant script.

JDBC support (Qt Jambi specific)
A drawback in our SQL framework in previous versions of Qt Jambi has been that you needed to have access to a Qt/C++ source distribution in order to use it. The reason was that we could not provide binaries that were compatible with all the different database drivers out there. In Qt Jambi 4.4 we support the Java DataBase Connectivity API which is the industry standard for database access in Java. This has been available on Trolltech Labs for a while, but now it has finally been integrated in Qt Jambi and is available in the com.trolltech.qt.sql package. Gunnar wrote a blog about it back when it was put up on labs.

XML patterns
XML support has been greatly improved in Qt and Qt Jambi 4.4. An example for this is the added support for XQuery 1.0 and XPath 2.0. In Qt Jambi, it is available in the package com.trolltech.qt.xmlpatterns. For more information, see Frans’s blogs about the C++ version of the API.

Qt Concurrent
One of the greater challenges in terms of mapping C++ to Java was the Qt Concurrent framework. This is a set of classes and functions that will help you parallelize tasks (e.g. to optimize for multicore cpus) without having to worry about many of issues the ordinarily related to multithreaded programming. In C++ it uses a lot of very language specific constructs, like templates and function pointers, making it hard to automatically map the API to Java. Indeed, we had to write part of the bindings layer by hand, replacing the use of function pointers with interfaces instead. We also implemented support in the Qt Jambi Generator for mapping C++ template classes to Java’s generic classes (under certain conditions) in order to get the correct API for classes such as QFuture. The underlying, generated code for binding this class uses a general, reference counting wrapper for java.lang.Object where the Java API (and the original C++ API) uses a generic parameter. Since generics in Java is a static, syntactic mechanism, there is no need to worry about it in the JNI code.

Other stuff
There are many more changes in Qt Jambi 4.4, bug fixes and new features. In order to get an overview of them all, you should see both the change logs for Qt Jambi 4.4 and Qt 4.4 (which will be out when the release is final.) From the top of our heads, we can mention an enhanced network API, QMetaObject introspection for Java objects, and numerous improvements to Designer.


Gunnar and Eskil

eskil
Qt Jambi
Posted by eskil
 in Qt Jambi
 on Tuesday, March 04, 2008 @ 09:12

The Qt Jambi team has, as have all devs in Trolltech, been busy preparing two separate releases the past few weeks slash months (Qt Jambi 4.3.4_01 and Qt Jambi 4.4.0_01.)

In the midst of this, someone reminded me that I promised I’d post a blog when we added prebuilt Windows binaries to the repository for QtJambiAwtBridge. This has now been done (Gunnar actually added it a while ago), so it should be possible to use the bridge without having a Qt source package ready. It’s in QtJambiAwtBridge lab in the directory “prebuilt”. For maximum compatibility, please use the binary together with a Qt Jambi binary package.

As far as the code goes, not much has happened to the QtJambiAwtBridge, and there probably won’t be much time to work on it until the two upcoming releases are ready and out the door. At that point, I will sit down and see what I can do about the outstanding issues (mainly regarding focus handling and window activation as far as I know, please post a report if you find other problems.)

Since I’m already posting this, I might as well add that Qt Jambi JDBC has been target of a few bug fixes lately: The standard Java SQL types are now automatically displayable and editable in views of the database models, a bug has been fixed where the contents of cells in a view looking at a JDBC-based model would sometimes rearrange or blank out, and finally: We’ve added a few changes that greatly increase the number of JDBC drivers with which we are compatible. We previously required that the underlying driver supported returning autogenerated keys, which is optional in the JDBC specs, and there was also a bug with certain unforgiving drivers when trying to do random access on the result sets. One of the drivers for which these bug fixes adds compatibility is the pgsql one.

As far as Qt Jambi JDBC goes, the driver will be integrated into Qt Jambi 4.4 and become permanent part of the Qt Jambi library.

eskil
Qt
KDE
Qt Jambi
Posted by eskil
 in Qt, KDE, Qt Jambi
 on Thursday, January 10, 2008 @ 12:58

It’s been a happy few weeks. Right before the Christmas holidays, Qt Jambi was nominated for the Jolt awards (”the Oscars of the industry”, we’re more or less nominated for an Oscar, tell your friends), and, as you may well be aware, Qt 4.4 will ship with the excellent Phonon Multimedia framework as announced in the beginning of December.

For those of you who hadn’t heard, the Phonon framework is a cross-platform class library which can (among other things) enable your application to play any media files supported by a system backend. By default, this backend is Microsoft DirectShow on Windows, GStreamer on Linux and QuickTime on Mac OS X.

Now, where it makes sense and is possible, we make the Qt Jambi APIs “identical” to the Qt APIs. This means that if you have experience with one framework, you should be able to learn the other one with very little effort, granted, of course, that you already know both programming languages well enough. In fact, porting examples from Qt for C++ to Qt Jambi (which I’ve done a fair number of times by now) is primarily a search/replace of arrows to dots, and is so simple it’s comparable to what scientists call “doing nothing.” The latest addition to Qt Jambi 4.4 is the com.trolltech.qt.phonon package, and this blog is mainly a celebration of the fact that I just finished porting the Media Player demo from C++ to Java, and that it works.

So, without further ado, here’s a brief low-res video of what you can expect. It shows the Qt Jambi media player running through Eclipse, the application playing a movie, and me moving some sliders to alter the brightness, contrast, saturation etc. of the movie stream. I forgot to turn off my microphone, which is why the audio is terrible, so please disregard that.

That’s it. I hope you find it impressive and I hope you will have some use for it when Qt 4.4 and Qt Jambi 4.4 are out later this year.

eskil
Qt
KDE
Qt Jambi
Posted by eskil
 in Qt, KDE, Qt Jambi
 on Wednesday, December 12, 2007 @ 10:43

Qt Jambi is all about breaking away the barriers between Qt in Java and Qt in C++. In fact, ideally you should be able to sit inside of either language and throw anything you want over to the other side, and somewhere along its parabolic path over the wall, this thing should magically transform to whatever the destination expects it to be. In that sense, Qt Jambi is kind of like Shakespeare futilely trying to marry a Capulet with a Montague (a plague o’ both your language designers!)

Definitely, there’s a lot of drama and tragedy involved, and there are certainly always things you can throw over that wall which anyone sitting on the other side will consider mysterious and meaningless. Most of the time, though (and the emphasis is very much on “most”) this works. Despite the many differences between the two programming languages, the APIs in Qt Jambi are almost identical to the C++ APIs, and, most importantly, the intention of the APIs is intact.

Right now, though, I want to focus on one thing which has so far not been supported: the Qt meta-object system. The meta-object system is an extension to C++ which adds introspection, dynamic method invocation and similar concepts to the language (which otherwise lacks any such features.) It is also the basis of the signals and slots inter-object communication mechanism which is featured heavily in both the Qt and Qt Jambi APIs.

We never implemented an equivalent of the meta-object system in Java. The main reason for this was, quite simply, that it wasn’t necessary. Java already has a more or less complete reflection API with all the meta-info you could ever ask for. Thus, we decided to implement signals and slots in Java on top of Java’s reflection API, and create a small binding layer in between which ensures the grittiest of the details work (emitting a signal in C++ emits the equivalent signal in Java etc.)

Still, we lacked one gritty detail: In some cases, Qt relies on introspecting objects through the meta-object system without going through the signals and slots mechanism. An example of this is when you register a mandatory field in a wizard. In this particular case, Qt Jambi currently does not support custom widgets as editors for the mandatory fields. There are very few places in Qt where this is actually relevant, but even so, in principle it’s a pretty big gap, so following our quest to fill as many holes as possible, in Qt Jambi 4.4 we will introduce the fake meta object.

Fake meta-object pictured on right

As you can see from my illustration of what a screen shot of the fake meta-object would look like, if it was indeed possible to take a screen shot of it, it is not all that different from the regular meta-object. The main difference is that the fake meta-object is generated at run-time rather than be a statically compiled unit, and also that it may at some point rob a train using only dynamite and a hot air balloon. We generate the meta-object on request, and only once per class, and only for user subclasses, as all the C++ classes will already have proper meta-objects of their own. For compatibility with the general expectations Qt has to meta-objects, we also convert all Java signatures into C++ signatures before stuffing them into the fake meta-object. Of course, not all Java classes have C++ equivalents known to us (any class featured in the type system used to generate the Java code is handled automatically), in which case we use the JNI type jobject as a general fall back, meaning that you can potentially use this together with other JNI-based frameworks.

So, in conclusion: In Qt Jambi 4.4 you can, among other things, look forward to cool-looking beards and even more complete mappings of the Qt APIs. The fake meta-object also allows us to remove a bunch of hacky hacks e.g. to make Java classes blend in with Qt Designer (you don’t want to know) so expect it to give a general boost in stability and readability as well. We really like it, hope you will too.

eskil
Qt
KDE
Qt Jambi
Posted by eskil
 in Qt, KDE, Qt Jambi
 on Thursday, October 18, 2007 @ 16:12

For a while now, I’ve been spending my non-bug-fixing time on the Qt Jambi AWT Bridge, an integration layer which will make it possible for you to place your favorite AWT and Swing component hierarchies inside your Qt windows and the other way around. This should hopefully prove to be at least a very convenient tool for anyone who wishes to port their Swing applications to Qt Jambi (which is something I, with the best of intentions, encourage people to do on a regular basis.) It should also allow you to use any of the GUI components out there which were written to be used together with AWT or Swing.

The Qt Jambi AWT Bridge began its life in a hotel bar in San Francisco during JavaOne 2007, almost like a game of chicken. Gunnar started writing the QComponentHost, I started writing the QWidgetHost, and at least for my part the primary goal of this was to see if he’d give up before I did. It was fun and the code was an awful mess, which is a side effect of fun.

Hey, here’s proof of how much fun we had and also an example of QWidgetHost in use (I’ve used this screenshot before, but it’s so much more relevant this time):
Proof of funcept
(click for big)

Then, at some point, Gunnar must have decided it was a good idea to formalize it, because it suddenly showed up as a scheduled task in my task manager. I started working on it, and then product management started asking me on a regular basis whether it was done, which means it had become serious business, and, more importantly, that Gunnar chickened out before me.

So, long story short, I just made some finishing touches on the focus handling today, and I decided it was time to let people try it out, so that we can catch the bugs early. This means, of course, that it’s a far from a perfect solution at the moment, but it works pretty well for the examples I have, and I’d like feedback to know where to proceed. See the project page for a list of known issues.

Technically, it’s not very complicated. The current incarnation consists of a few lines of OS specific code which reparents a native window handle, thus placing it inside another native window without the toolkit’s interference. This takes care of showing the widgets in the right place on screen, and the OS takes care of most of the other stuff, like delivering the correct events to the correct event queue. The most challenging thing was to connect the Qt and AWT focus subsystems, because, quite frankly, the latter is a complete and utter mystery to me, and I don’t know if I’ll ever fully understand that immense and intricate collection of concepts and awesome method names which are synonyms. I sincerely hope I have something which works now, though, but I anticipate getting a lot of bug reports for this particular part, so if you want to help out, please try navigating through your application with the keyboard and see if the tab order makes any sense at all. If it doesn’t, let me know, and please send me a compilable example if you can.

Questions and feedback can be addressed to our Qt Jambi Interest mailing list and the project page is right here. Have fun with it and let us know how it went.

(PS. Samuel came up with the title of this post, and it sums everything up perfectly so I stole it.)

Comments Off
eskil
Qt
KDE
Qt Jambi
Posted by eskil
 in Qt, KDE, Qt Jambi
 on Friday, August 24, 2007 @ 12:35

Say you are a C++ programmer who has a heartfelt passion for writing plugin based applications in Qt. One day, during a brief loss of your senses, you decide that you want to expand the plugin support in your latest creation to include contributions from both C++ and Java programmers. Riddled with idealism and optimism, you cross out a week in your calendar, sit down and start reading the JNI specification. At some point during this week, you’ll probably realize that nothing is as easy as it seems, and that the road to hell is paved with the differences between C++ and Java. Next, you’ll either give up, set off an indefinite amount of time to write elaborate bindings for your interfaces, or you’ll read this blog and see that you were right all along and life still comes with happy endings.

All dramatic phrasing aside, in Qt Jambi we have already solved a bunch of the problems that arise when you are binding C++ with Java, and it’s actually pretty easy and convenient to use the Qt Jambi generator and framework to import classes and objects back and forth across the boundaries of the language. In this blog, I’d like to go through some simple code that allows you to make a custom widget in Java using Qt Jambi, instantiate this in C++, and then add it to a C++-based layout. I have a bit of a cold, and I didn’t really feel like putting together an example that makes any sense, but I’ve posted some code that you can download, which will create a window with a button and the Qt Jambi Colliding Mice example. The latter is written in Java, and can easily be replaced by any other Qt Jambi widget you might write. To get the same convience from your own classes and interfaces, you would simply use the Qt Jambi generator.

The prerequisites for compiling and using the code is: an installation of Qt Jambi, the JDK, and a Qt version matching your Qt Jambi version.

To build the code, set the JAVADIR environment variable to point to your JDK, the JAMBIDIR environment variable to point to your Qt Jambi installation and qmake away. You may have to tweak the .pro file a little for different platforms, because I’ve only tested it locally. Also make sure that you have both the Qt Jambi class files (e.g. in qtjambi.jar) and the root of the Qt Jambi installation in your CLASSPATH.

Building and running the javafromcpp application will show you a window with a push button on top and the colliding mice below it. The push button is a plain Qt/C++ widget, while the colliding mice are implemented in Qt Jambi, i.e. in Java. Here’s what it will look like, and following that is all the magic explained:

Java widget inside C++ widget

In the start of the main() function in the code, you’ll see the following function call:

    // Make sure the JVM is loaded
    qtjambi_initialize_vm();

This single line makes Qt Jambi search for your dynamic JVM library and instantiate a virtual machine for the process. Note that there is only space for a single VM in each process, so don’t expect this to work twice. (If there are problems in this call, you’ll get a warning. In that case we’d really like to know about it, plus which platform you are on, so we can figure out what’s failing.)

Anyway, initializing the VM is required to get access to JNI.

The code then sets up a window with a push button and some snacks, and it makes the function call which actually instantiates the java widget and returns a C++ pointer to it:

    QWidget *colliding_mice = qtjambi_instantiate_widget("com/trolltech/examples/CollidingMice");

The returned pointer is handled like any regular QWidget-pointer in Qt. We specify the fully qualified name of the class we wish to instantiate, in this case com.trolltech.examples.CollidingMice. In JVM syntax, the dots are replaced by forward slashes.

All the actual work is done inside qtjambi_instantiate_widget(), which I’ll now go through in detail.

The first paragraph of code retrieves a JNIEnv-pointer, which is your access point to JNI for the current thread and virtual machine.

    JNIEnv *env = qtjambi_current_environment();
    if (env == 0) {
        qWarning("Cannot get current JNI environment. Was the JVM loaded correctly?");

        // Make sure a possible exception is removed from the stack
        qtjambi_exception_check(env);
        return 0;
    }    

If we do not get a pointer to the JNI environment, we have to bail out. In case there is an exception on the stack, we call qtjambi_exception_check() which will print any pending exception and clear the stack. The next step is to create a frame for local references using JNIEnv::PushLocalFrame() (which will be pop’ed at the end of the function to make sure we don’t retain references to temporary objects.)

We go on by locating the class that was specified in the function call. The class will have to be available on the class path, or this call will return null.

    jclass clazz = qtjambi_find_class(env, qualified_name);

Using the same function, we find Qt Jambi’s QWidget-class, and use JNI to make sure the specified class is actually a QWidget subclass (this could help prevent some horrific crashes.)

Using some more JNI code, we get the ID of an assumed constructor in the specified class which takes a reference to a QWidget-parent:

    jmethodID constructor_id = env->GetMethodID(clazz, "<init>", "(Lcom/trolltech/qt/gui/QWidget;)V");

You have to design your classes by this convention in order to use the example code to instantiate them.

Next, we have to convert the supplied parent pointer to a Java object in order to pass it to the Java constructor.

    jobject java_parent = parent != 0 ? qtjambi_from_QWidget(env, parent) : 0;

The qtjambi_from_QWidget() call will either create a new Java widget if the parent widget was created in C++, or it will return the existing Java object if the parent was created in Java. If it has to create a new java object, the type of this will be the closest Java supertype known to Qt Jambi. If you have mapped your own C++ widgets and want to use them correctly in calls such as these, you have to make sure the initialization code of your generated library is called prior to the conversion takes place. Also note that in qtjambi_core.h you will find several other convenient conversion functions that can be used to convert back and forth between C++ and JNI, as well as other convenient, JNI-based code.

We instantiate our new widget using JNI, create a global reference to it to make sure it isn’t garbage collected before it can be hooked up to our hierarchy, and finally we convert the java object to C++ using the following call:

    return qobject_cast(qtjambi_to_qobject(env, java_widget));

And that does the trick. If the class was available, had the right supertype and constructor, then we will now return a fully operational C++ pointer to the object.

By the way, here’s another link to the downloadable code for those of you who skimmed everything up until the crazy screenshot.

Comments Off
eskil
Qt Jambi
Posted by eskil
 in Qt Jambi
 on Wednesday, July 11, 2007 @ 09:51

A common question I get when I’m doing talks on Qt Jambi is how well it plays with other toolkits, specifically Swing and AWT. There’s a lot of code out there written in either or both, and people who want to port their projects to Jambi or build new components on top of existing legacy code require some sort of migration layer.

So far, our answer to the question has been that top level windows in Qt Jambi and Swing play well together, while window components are more reluctant to partake in any sort of social activity.

It has, however, been our goal all along to change this, and implement migration classes that allow a Qt Jambi widget to be adopted by a AWT/Swing component, vice versa, and in general make it even more convenient to use Qt Jambi together with existing Java code.

Yesterday I had some time to sit down and sketch up a crude solution for part of this migration layer. It currently works on Windows and Linux, only supports putting Jambi into AWT (not the other way around), and is not at all perfect. It’s quite functional already, though.

On the technical side, it uses JAWT to access OS specific data about a Canvas-subclass that I’ve called QAwtWidget. The QAwtWidget also takes a reference to a QWidget, which is the Qt component it will bind into AWT/Swing. It will then use all this information to have the operating system reparent the Qt widget to the QAwtWidget-canvas. This means that all event handling is automatically delegated to the correct widget, so the widget will immediately be fully operational.

There are snags, however, and a solution like this will never be completely perfect. I’m not sure if we will ever be able to make it work on Mac, and there will be some oddities in focus handling, window activation, etc. that I don’t think we’ll be able to remove entirely. But it’ll be a great tool for parts of a project where it’s unnoticable, and it will definitely be a great tool to have for porting existing AWT/Swing-code to Qt Jambi.

Here’s an example of the image viewer demo running on Windows inside a GridLayout with a couple of buttons for extra evidence.

Qt and Awt running side by side

The code for making this happen:

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

    JFrame f = new JFrame();
    f.setBounds(0, 0, 500, 100);

    GridLayout flayout = new GridLayout(2, 2);
    f.setLayout(flayout);

    // The widget to embed
    QWidget w = new com.trolltech.demos.ImageViewer();

    // The migration layer
    QAwtWidget awtWidget = new QAwtWidget(w);

    JButton swingButton = new JButton();
    swingButton.setText("Swing button");

    Button awtButton = new Button();
    awtButton.setLabel("AWT button");

    f.add(swingButton);
    f.add(awtWidget);
    f.add(awtButton);
    f.setVisible(true);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.pack();

    // Run Qt event loop in main thread
    QApplication.exec();
}
 
Comments Off
eskil
Qt Jambi
Posted by eskil
 in Qt Jambi
 on Tuesday, February 27, 2007 @ 12:58

One of the most annoying things about developing Qt Jambi has so far been the Java Virtual Machine’s tendency to intercept exceptions in the native code, thus disabling any mechanism installed in the OS serving to handle these. Instead of your application crashing violently, it outputs a message to the console apologizing intently that such an awful thing would ever occur, and it also dumps a helpful .log file to the disk, containing stack traces and environment details that can be helpful in debugging the problem.

The problem is, however, that Windows users of tools such as Visual Studio are used to having a debugger registered with the operating system, so that, in cases where an application crashes, they can simply hit the “Debug” button in the default dialog that pops up, attach to the process, and jump directly into the source code at the exact location where the problem occurred. There are no limits to how useful this mechanism is, and I suspect it literally saves me hours of work every week.

When writing JNI-based applications that run on top of the virtual machine, however, this is simply not supported. Apparently, Sun made an attempt to fix this themselves, but there were some problems in the integration process [edit: The URL seems to have gone dead. Here’s a cached version.]

Having complained about the problem for much too long, I finally had some extra time last week, and decided to fix the problem myself. I set out to patch the JVM. My goals were: 1. Keep the current logging facility. 2. Get back the default exception handler. 3. Do as little work as possible.

Since you’re supposed to have screen shots in these blog-things, here’s how it looks when it’s done:

Yeeh!

Patching and building the JVM is suprisingly simple. The code is well-organized, and the build system is as good as fool proof. So kudos to the developers for that :-)

My patch is by no means elegant. In fact, it’s downright stupid. I also make no guarantee that it won’t break earth or anything. However, I thought there might be other people out there who would like to do this, so here it is in case you’re interested:

--- src\share\vm\utilities\vmError.cpp-backup   2007-02-16 15:39:41.760875000 +0100
+++ src\share\vm\utilities\vmError.cpp  2007-02-16 16:01:57.104625000 +0100
@@ -664,10 +664,11 @@
     } else {
       if (recursive_error_count++ &gt; 30) {
         out.print_raw_cr("[Too many errors, abort]");
-        os::die();
+        //os::die();
+        return ;
       }
 
-      jio_snprintf(buffer, sizeof(buffer),
+      /*jio_snprintf(buffer, sizeof(buffer),
                    "[error occurred during error reporting, step %d, id 0x%x]",
                    first_error ? first_error-&gt;_current_step : -1,
                    _id);
@@ -679,7 +680,7 @@
         out.cr();
         out.print_raw_cr(buffer);
         out.cr();
-      }
+      }*/
     }
   }
 
@@ -791,11 +792,11 @@
   static bool skip_os_abort = false;
   if (!skip_os_abort) {
     skip_os_abort = true;
-    os::abort();
+    //os::abort();
   }
 
   // if os::abort() doesn't abort, try os::die();
-  os::die();
+  //os::die();
 }
Comments Off
eskil
Qt
KDE
Qt Jambi
Posted by eskil
 in Qt, KDE, Qt Jambi
 on Wednesday, February 07, 2007 @ 13:32

Yay, the latest Qt Jambi pre-release went out today. In addition to the regular supply of bug fixes and new example code, there are some changes to integral parts of the API and semantics in this version, and also some major improvements to Qt Designer and the Qt Jambi Eclipse Integration. It also contains bindings for the XML and Network modules, meaning that all relevant parts of Qt are now accessible from Java.

Qt Jambi Designer
In previous Qt Jambi releases, we’ve been using the original Qt Designer without any modifications. Since large parts of Qt Designer are written to be language independent, we’ve been able to generate Java code based on the original C++-based .ui files that Qt Designer has produced. This has worked to an acceptable degree, but it was definitely far from ideal, both for technical solutions and for the user experience.

For this beta, we wanted to have a complete Jambi-interface in Qt Designer. We wanted to give Qt Jambi developers the same possibilities in Designer as Qt developers, and we wanted Designer to feel completely like a tool for creating a Java GUI.

The issues in previous versions was, specifically:

  • There was no way of accessing the Qt Jambi resource system in Designer, so all images would have to be addressed with paths on the disk. The usual workaround for this was to handwrite code to set the icons for buttons, labels, etc. after the user interface had been established.
  • The only way to deploy Qt Jambi based custom widgets in Designer was to use the “Promote to custom widget” feature. This meant the custom widget would have to share APIs with a standard widget type, and when previewed in Designer it would be painted as the standard widget.
  • Signatures of types and functions were all in C++ syntax. This would mainly be a cosmetic problem, since the generated Java code would still be compatible.
  • These issues have all been addressed in the Qt Jambi Beta, using a slightly modified .ui format (.jui files), and a couple of Designer plugins.

    Resource Browser in Qt Jambi Beta

    You can now use any icons located somewhere in your class path, and the correct paths (relative to the class path) will be generated for them in the resulting code, so that they can be e.g. bundled in .jar files when your application is packaged. You can write complete custom widgets in Qt Jambi and import them in Designer, where you will be able to modify their custom properties, connect their custom signals and slots, and preview them exactly as they will appear in the finished application. And finally, Java syntax will be used throughout the application.

    How to use the new Qt Designer
    In order to use the new Designer as a standalone application, you will need to set your QT_PLUGIN_PATH environment variable to point to the path/to/jambi/plugins directory beforehand. To make this a little bit simpler, there is a command line script (designer.bat/designer.sh) which sets the right environment and starts up Designer for you.

    The Eclipse Integration will attempt to load the plugins automatically using the path you set as the location of your Jambi installation. The plugins should be initialized when you open a form, and the resource browser and widget box will be populated based on the settings of the current project.

    Generator Example
    Some happy news for users of the Qt Jambi Generator! In previous releases, we’ve had a very minimal one-class example for use of the generator. For the beta, we’ve written a fresh example where we’ve attempted to use as many of the generator features as possible. We’ve also written documentation for the example where we propose what we believe is an efficient way of working with type systems for the generator, and where we’ve tried to pinpoint common pitfalls.

    Screenshot of the generator example

    In order to use the generator with Qt Jambi, you should get our special Qt 4.3.0 snapshot made for Qt Jambi and set your QTDIR to this. This is needed because Qt Jambi is based on a stable branch of the unreleased Qt 4.3, and it is not guaranteed that it will be compatible with regular snapshots of Qt. Use our snapshot to keep out of trouble :) More about this on the release page.

    Once this is done, you should be able to run the generator_example command line script, and then you will have a nice little (emphasis on little) game with which to play around.

    Things to be aware of for existing users
    In this beta release, we have made some changes to the library which may affect existing applications, so current users of Qt Jambi should be aware of them. The most relevant change in this respect is that objects of all types are now automatically garbage collected when the objects become unrechable.

    In previous versions, we had a distinction between “normal” types and subclasses of com.trolltech.qt.core.QObject. QObject is the class used for event handling, and the superclass for all widgets in Qt Jambi. We believed objects of this class would live in a hierarchy, and designed Qt Jambi so that the programmer would have to explicitly dispose the root of such hierarchies. However, feedback has indicated that this pattern can be confusing and lead to unnecessary memory leaks, so in the beta, we have removed the distinction, and any object without a parent will now be collected and disposed automatically. This means that you will have to keep a reference to the root in a hierarchy for the tree to remain in memory. Usually this is already the case, but be aware that you may get exceptions if your code relied on memory leaks to work properly.

    In addition, we have detached signals from the QObject class. Previously you would have to subclass QObject in order to have signals in your class. We realised that, as QObject is a relatively heavy class with special rules for multithreaded programming, this design worked poorly for short lived objects. In the beta, in order to use signals in your class, you should extend the class com.trolltech.qt.QSignalEmitter. Existing code will work fine, since QObject is a subclass of QSignalEmitter, but if you are only using QObject in order to get signal support, be aware that extending QSignalEmitter instead will be more memory efficient.

    A third thing to keep your eyes open for is initialization of signals. Qt Jambi would previously initialize all signal objects automatically, but we have since decided that this magic was too unclear and not really correct in the spirit of the Java language. If your code depends on this feature, you can expect to get some null pointer exceptions that need to be sorted out.

    You should also be aware of the improved error checking. If your code has certain types of hard-to-find bugs, you can now expect to be alerted of them, either through runtime exceptions or warnings printed to stderr. It should be much easier to stabilize complicated code using the Qt Jambi beta.

    Finally, you should look at the changes-file contained in the root of the package. There are some renamings and changes to API that may affect compilation of your project. They should easy to debug, but if you e.g. are using the QNativePointer in you application, you can expect the API your are using to have changed to something which is easier to use.

    That’s it
    Feature-wise, this is a big release for us, and I hope people will be happy with the changes. Don’t forget to sign up for the qt-jambi-interest mailing list if you haven’t already. We will do our best to be quick in addressing any issues and answering any questions that are raised on that list.

    eskil
    Qt
    KDE
    Qt Jambi
    Posted by eskil
     in Qt, KDE, Qt Jambi
     on Thursday, October 26, 2006 @ 12:15

    Today, we released the third and final tech preview of Qt Jambi. At the same time, Trolltech announced a contest for Qt Jambi developers, so if you’re interested in getting some loot, go download the new package, make something awesome and send it to us.

    About the release, though, I’m especially excited about this one, primarily because it’s based on Qt 4.2, and thus gets to benefit from all the nifty new features in Qt. On Windows and Linux, you can still use Java Webstart to run the demo launcher without manually unpacking and installing anything. The link is on the download page, and here’s a quick run-down of what to look out for:

    QGraphicsView
    One of the highlights of Qt Jambi TP3 is the 2D canvas QGraphicsView. It’s an extremely useful, item-based canvas API capable of handling millions of items efficiently. The items can be vector graphics, text, pixmaps, et cetera, collision detection is built-in, it’s based on a model/view architecture, and everything about it is in general very pleasing. Here’s a bunch of colliding mice:

    This example itself is hours and hours of fun

    com.trolltech.qt.svg
    Although SVG support was introduced to Qt in version 4.1, it has not been included in previous Qt Jambi releases. We’ve added this package as well in TP3, and there’s even a hot new example of how well it plays together with graphics view.

    Javadocs
    One common request from our users so far, has been to add javadocs to the Qt Jambi packages. This has been our plan all along, and in this latest release, we finally have documentation for the Qt Jambi API in javadoc format. This means that, if you are using Eclipse for your Qt Jambi development, you can get easy access to documentation in the code completion list as you write your code. All you need to do is edit the build path entry for your qtjambi.jar file in the properties of your project, and add the location of the javadoc there. Here’s a screenshot to make it easier:

    Browse for doc/html under your Qt Jambi root

    What else?
    There’s actually so much new stuff in TP3 that giving everything a separate paragraph would make the blog infinitely long (approx.) Some of the stuff you might want to read more about though, is

  • The introduction of “real enums” to the API, which Gunnar blogged about exactly one month ago.
  • The widget style sheets, which allow you to style your widgets using CSS.
  • Improved integration with the desktop on all platforms, such as, e.g., the new QSystemTrayIcon class.
  • There’s a lot more as well. You could read the Qt 4.2 intro to see some of it. Hope you have fun trying out all the new stuff and don’t forget to enter the contest.

    Comments Off