Development/Architecture/KDE3/Java Integration: Difference between revisions

    From KDE TechBase
    No edit summary
    Line 7: Line 7:
    ==Simple Usage Example==
    ==Simple Usage Example==


    <nowiki>
    <code cppqt3>
    #include <kapp.h>
    #include <kapp.h>
    #include <kjavaappletwidget.h>
    #include <kjavaappletwidget.h>
    #include <qstring.h>
    #include <qstring.h>
     
    int main(int argc, char **argv)
    int main(int argc, char **argv)
    {
    {
      KApplication app( argc, argv );
      KApplication app( argc, argv );
     
      QString a,b,c,d,e,f;
      QString a,b,c,d,e,f;
     
      // The name of the applet
      // The name of the applet
      a = "fred";
      a = "fred";
      // The name of the class to be run
      // The name of the class to be run
      b = "Lake.class";
      b = "Lake.class";
      // The base url it can be found at. Note the trailing '/', we could
      // The base url it can be found at. Note the trailing '/', we could
      // also have written it as "file:/dos/pcplus/java/lake/Lake.html"
      // also have written it as "file:/dos/pcplus/java/lake/Lake.html"
      c = "file:/dos/pcplus/java/lake/";
      c = "file:/dos/pcplus/java/lake/";
     
      // Create the applet widget. We are using the default context and
      // Create the applet widget. We are using the default context and
      // server implicitly. We could have specified different ones. We
      // server implicitly. We could have specified different ones. We
      // could also specify a parent QWidget, but we might as well make
      // could also specify a parent QWidget, but we might as well make
      // the applet widget top level for this example.
      // the applet widget top level for this example.
      KJavaAppletWidget *applet = new KJavaAppletWidget();
      KJavaAppletWidget *applet = new KJavaAppletWidget();
      CHECK_PTR( applet );
      CHECK_PTR( applet );
     
      // You must set these BEFORE calling show()
      // You must set these BEFORE calling show()
      applet->setAppletName( a );
      applet->setAppletName( a );
      applet->setAppletClass( b );
      applet->setAppletClass( b );
      applet->setBaseURL( c );
      applet->setBaseURL( c );
     
      // My test applet needs an image to be specified as a parameter.
      // My test applet needs an image to be specified as a parameter.
      d = "image";
      d = "image";
      e = "arch.jpg";
      e = "arch.jpg";
      applet->setParameter( d, e );
      applet->setParameter( d, e );
     
      // We show the widget as normal
      // We show the widget as normal
      applet->show();
      applet->show();
     
      // Then start the event loop
      // Then start the event loop
      app.exec();
      app.exec();
    }
    }
    </nowiki>
    </code>


    ==Design==
    ==Design==
    Line 89: Line 89:
    </center>
    </center>


    An important advantage of the out of process approach is that it allows us to make use of the standard Motif implementation of the AWT, if we were using an in-process implementation this would require us to merge the Motif and Qt event loops which would be tricky to implement without the AWT peer class sources. Ultimately the plan is to remove the Motif dependency (and the associated memory hit) completely, but until the Qt port of the AWT is finished, this is impossible. The existing solution using swallowing is not perfect, but works reasonably well, when the QtAWT is finished it will be possible to use the QXEmbed API to provide a more polished embedding mechanism. It will also be possible to provide the option an in process JVM which may prove useful in some situations.
    An important advantage of the out of process approach is that it allows us to make use of the standard Motif implementation of the AWT, if we were using an in-process implementation this would require us to merge the Motif and Qt event loops which would be tricky to implement without the AWT peer class sources. Ultimately the plan is to remove the Motif dependency (and the associated memory hit) completely, but until the Qt port of the AWT is finished, this is impossible. The existing solution using swallowing is not perfect, but works reasonably well, when the QtAWT is finished it will be possible to use the {{class|QXEmbed|kdelibs|3.5}} API to provide a more polished embedding mechanism. It will also be possible to provide the option an in process JVM which may prove useful in some situations.


    ==Class overview==
    ==Class overview==

    Revision as of 13:02, 30 May 2007

    Warning
    This section needs improvements: Please help us to

    cleanup confusing sections and fix sections which contain a todo


    Introduction

    KDE makes it easy for application developers to add support for Java applets to their applications. The kdejava library provides a high level API that allows Java applets to be manipulated as if they were a normal QWidget. Lars and I added support for applets to khtml in a matter of hours at the KDE II conference - it really is that easy. KDE's Java support is in two parts, there is a pure Java server which provides the environment in which applets run etc. and a KDE library which handles the embedding of the applet window into the application. The Java and C++ code communicates via standard UNIX pipes using a simple text based protocol. It should be possible to use any Java VM with KJAS, including Java 2.

    Simple Usage Example

    1. include <kapp.h>
    2. include <kjavaappletwidget.h>
    3. include <qstring.h>

    int main(int argc, char **argv) {

     KApplication app( argc, argv );
    
     QString a,b,c,d,e,f;
    
     // The name of the applet
     a = "fred";
     // The name of the class to be run
     b = "Lake.class";
     // The base url it can be found at. Note the trailing '/', we could
     // also have written it as "file:/dos/pcplus/java/lake/Lake.html"
     c = "file:/dos/pcplus/java/lake/";
    
     // Create the applet widget. We are using the default context and
     // server implicitly. We could have specified different ones. We
     // could also specify a parent QWidget, but we might as well make
     // the applet widget top level for this example.
     KJavaAppletWidget *applet = new KJavaAppletWidget();
     CHECK_PTR( applet );
    
     // You must set these BEFORE calling show()
     applet->setAppletName( a );
     applet->setAppletClass( b );
     applet->setBaseURL( c );
    
     // My test applet needs an image to be specified as a parameter.
     d = "image";
     e = "arch.jpg";
     applet->setParameter( d, e );
    
     // We show the widget as normal
     applet->show();
    
     // Then start the event loop
     app.exec();
    

    }

    Design

    The diagram below shows the relationships between some of the more important classes involved in the KDE Java support. Those classes in libkdejava are C++ classes, all of the rest of the system is written in Java. There is no dependency other than the JVM for the KJAS server, this is the core of the KDE Java environment and could also be used to add Java support to other systems - you can control applets from a shell script using a KJAS server for example.

    KDE Java Architecture

    Unlike the Java support in Netscape or MS IE, KDE's support uses an out of process JVM - i.e. the JVM itself is not linked to the application that embeds the applet. The table below should explain some of the reasons behind this decision:

    In process Out of process
    Have to contend with threading issues No threading problems
    JVM crash will kill Konqueror JVM crash easy to handle
    JVM load may block the application UI No problem
    JVM cannot be unloaded JVM unload by killing child process
    Fairly easy to communicate with the JVM (JNI) Need custom communication mechanism
    Multiple VMs impossible Multiple VMs possible
    Depends on a working Qt AWT port Can use the standard AWT

    An important advantage of the out of process approach is that it allows us to make use of the standard Motif implementation of the AWT, if we were using an in-process implementation this would require us to merge the Motif and Qt event loops which would be tricky to implement without the AWT peer class sources. Ultimately the plan is to remove the Motif dependency (and the associated memory hit) completely, but until the Qt port of the AWT is finished, this is impossible. The existing solution using swallowing is not perfect, but works reasonably well, when the QtAWT is finished it will be possible to use the QXEmbed API to provide a more polished embedding mechanism. It will also be possible to provide the option an in process JVM which may prove useful in some situations.

    Class overview

    This section outlines the major classes in libkdejava, more detailed information is provided by the kdoc documentation.

    • KJavaAppletWidget
      This is the class responsible for the integration of the applet window into the KDE applications GUI. In simple cases, this is the only class you need to worry about and it provides a very straightforward API.
    • KJavaApplet
      This is the class responsible for managing an applet. It ensures the applet is downloaded and provides the ability to start and stop the applet etc.
    • KJavaAppletContext
      This is the environment in which applets exist. Applets in the same context can communicate with each other, those in different contexts cannot. In a web browser all the applets in a single frame will exist in the same context. The context can also be used by applets to communicate with the application they are embedded in, though this communication is currently very limited.
    • KJavaAppletServer
      This is the class that provides access to the KJAS server. Normally, you can ignore this class as you will be automatically assigned a default server.
    • KJavaProcess
      This is a wrapper for KProcess that provides a higher level API for invoking a JVM.

    There are a number of other classes in the library, but at the moment they should be regarded as internal parts of the implementation.

    The road ahead

    The current implementation of KDE-Java is not the end of the story, there are a number of other developments in the works. This section is simply intended to inform you of what to expect, if you want more detailed information then check out the kdejava CVS module where the code is kept.

    As I mentioned earlier I am working on QtAWT, a port of the AWT to the Qt toolkit. This is important for the future development of KDE Java, and has made significant progress. It is possible to create most of the predefined widgets, and to set properties such as the text of push buttons. There is currently no event dispatching, and no support for important classes such as the Canvas however, so the port cannot be considered even half complete. The port is now working with Qt 2.0, though the handling of Unicode strings is not optimal.

    In addition to support for standard Applets as used on the web, I also plan to support some extra facilities to allow applications to provide custom applet types/plugins. This facility is not currently very high priority, so it is unlikely to be ready for KDE 2.0, perhaps you'll see it in version 2.1.

    Help required

    There are a number of other projects that I would love to see someone working on, but which I don't have the time to do myself. If you know Java and are looking for a project then why not give one of these a try?

    • A Swing look and feel that integrates with KDE widget themes
    • A JNI binding to the KDE libraries
    • Java protocol handlers that provide access to the KIO library. This will allow Java to support SSL, tar files etc.

    In addition to the above, help with either the QtAWT , KJAS or libkdejava is always welcome.