[Kde-java] QtJava api via Dynamic Proxies progress - part 1
Richard Dale
Richard_Dale at tipitina.demon.co.uk
Wed Aug 20 05:36:54 CEST 2003
I've got kalyptus correctly auto-generating the QtJava sources so that they
compile without error, all 60000 lines! So there shouldn't be any need to put
the autogenerated code in the cvs anymore, it can be generated on demand.
The proxy based api has come out looking quite 'pretty' - I think it's worked
well. Here is an example of how C++ multiple inheritance maps onto the
QWidget.java class:
public class QWidget extends QObject implements QPaintDeviceInterface {
public interface QWidgetPublicInterface {
QMetaObject metaObject();
...
}
protected interface QWidgetProtectedInterface {
void newQWidget(QWidget parent, String name, int f);
...
}
Two internal interfaces are created, on for all the public methods (both
static and instance ones), and another interface for the protected methods.
A QWidget constructor looks like this pair of methods:
protected void newQWidget(QWidget parent, String name) {
proxyProtectedQWidget().newQWidget(parent,name);
}
public QWidget(QWidget parent, String name) {
super(new Class[] {QWidgetPublicInterface.class,
QWidgetProtectedInterface.class, null, null, null, null },
2);
newQWidget(parent,name);
}
The call to super() creates an array of Classes large enough to hold all the
interfaces for the superclasses of QWidget, ie QObject and Qt in this case.
There are two entries for each class, for the public and the protected
interfaces.
Next the constructor in QObject is called, and adds its two interfaces to the
array:
private static Class[] addInterfaces(Class[] interfaces, int index) {
interfaces[index] = QObjectPublicInterface.class;
interfaces[index+1] = QObjectProtectedInterface.class;
return interfaces;
}
protected QObject(Class[] interfaces, int index) {
super(addInterfaces(interfaces, index), index+2);
}
The new proxy instance is created at the top level of the heirarchy (Qt in
this case) with the complete array of interfaces.
public class Qt implements QtSupport {
protected Object _proxy = null;
...
protected Qt(Class[] interfaces, int index) {
interfaces[index] = QtPublicInterface.class;
interfaces[index+1] = QtProtectedInterface.class;
_proxy = Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),
interfaces,
new SmokeInvocation(this) );
}
Back in the QWidget constructor, the actual C++ instance can be created by
invoking the C++ constructor via the newly created proxy:
newQWidget(parent,name);
QPaintDeviceInterface is just an empty 'marker interface', which both
QWidget.java and QPaintDevice.java implement, and any method expecting a
QPaintDevice in C++, will be converted to expect a java QPaintDeviceInterface
type argument.
The instance methods for QPaintDevice are copied into the QWidget.java code,
as they can't be muliply inherited as for C++.
I attached the kalyptusDataDict.pm to a second mail, as it would exceed the
limit for this list.
-- Richard
Here are the build instructions from the README file, to try it out:
A Java SMOKE adaptor based on Dynamic Proxies
* Copy kalyptusCxxToJava.pm and kalyptusDataDict.pm to kdebindings/kalyptus.
* Build and install kalyptus
* Run the Qt headers through kalyptus, copy the generated sources to a new
directory 'qt' and compile:
$ kalyptus -fjava $QTDIR/include/*.h
$ mkdir qt
$ cp `cat java_sources` QtSupport.java SmokeInvocation.java qt
$ javac qt/*.java
..it should compile without error. The whole Qt api now maps onto a single
InvocationHandler.invoke() method in SmokeInvocation.java. Instead of 7500
JNI method calls in the first release of QtJava, just that one native method
is needed.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: qtjava-0.2.tar.gz
Type: application/x-tgz
Size: 25151 bytes
Desc: not available
Url : http://mail.kde.org/pipermail/kde-java/attachments/20030820/7dae3b12/qtjava-0.2.tar-0001.bin
More information about the Kde-java
mailing list