[Kde-java] KListViewItem problems

Richard Dale Richard_Dale at tipitina.demon.co.uk
Mon Jun 7 10:39:46 CEST 2004


On Monday 07 June 2004 01:16, Maik Schulz wrote:
> On Sunday 06 June 2004 20:28, Richard Dale wrote:
> > Please can you post full example code with suitable test cases so this
> > can be run and tried out? The example above is much too complex to just
> > read the source and 'think about it'.
> >
> > But I would be surprised if the java bindings managed to change the
> > semantics of KListViewItem insertion into a KListView.
> >
> > -- Richard
> > _______________________________________________
> > Kde-java mailing list
> > Kde-java at kde.org
> > https://mail.kde.org/mailman/listinfo/kde-java
>
> Hi Richard,
>
> took me a while, but here goes the code. The comments in the code explain
> what works and what doesn't.
Thanks for the example code. It took me a while to work out what's going on, 
but the problem is that since KDE 3.2 'copy constructor' methods have been 
generated for classes which didn't have them in C++. KListViewItem has one of 
these constructors:

	public KListViewItem(KListViewItem arg1) {
		super((Class) null);
		newKListViewItem(arg1);
	}
	private native void newKListViewItem(KListViewItem arg1);

But in the original klistview.h header, there is on such method - all the 
constructors take QListViewItems rather than KListViewItem. In this line:

            KListViewItem item3 = new KListViewItem(item0);

The copy constructor is called, and item3 becomes a copy of item0 instead of 
having item0 as its parent. 

On the other hand, this call works because firstChild() is a QListViewItem, 
not a KListViewItem and the correct constructor is called:

            KListViewItem item3 = new KListViewItem(kListView.firstChild());

The work round is to cast to a QListViewItem:
            KListViewItem item3 = new KListViewItem((QListViewItem) item0);

I think the best thing is to not generate these extra constructors as they're 
more trouble than they're worth. I'll do that for KDE 3.3.

Other Issues:

Sorting is turned on be default, so you need a line like this:
		kListView.setSorting(-1);


        public void buttonClicked() {
//I have to use QListViewItem because casting to KListViewItem throws
//a CLASSCASTEXCEPTION. Why is that? I only used KListViewItems...
                QListViewItem selectedItem = kListView.selectedItem();

The reason for this problem is that there were no java references to the 
KListViewItem, and the original java instance was garbage collected.
However, because it was 'owned' by the KListView, the underlying C++ instance 
wouldn't have been deleted. 

Then when you reference the listviewitem via selectedItem(), the qtjava 
runtime finds there is no corresponding java instance anymore for the C++ 
one. It then creates another java wrapper instance of type 'QListViewItem'. 
This is because KListViewItem doesn't reimplement the rtti() method, and 
there is no way of telling whether it is a QListViewItem or a KListViewItem.

The solution is to either put the listviewitems into an ArrayList as they're 
created and avoid gc:

	ArrayList itemList = new ArrayList();
	...
		itemList.add(item0);
	...
		itemList.add(item3);

Or use Qt.dynamicCast() to cast back to the correct type:

                QListViewItem selectedItem = 
Qt.dynamicCast("org.kde.koala.KListViewItem", kListView.selectedItem());

Anyway, thanks very much for the bug report and example. I've also found that 
the QtRuby bindings have the same problem (and probably PertQt too), because 
that's where I got the code for generating the extra copy constructors from.

-- Richard





More information about the Kde-java mailing list