Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Nebula » GalleryTreeViewer and model access through content and label provider --- strange
GalleryTreeViewer and model access through content and label provider --- strange [message #589569] Sat, 03 May 2008 15:55
Michael Vogt is currently offline Michael Vogt
Messages: 2
Registered: July 2009
Junior Member
This is a multi-part message in MIME format.
--------------030206090909000306000805
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit

Hi,

I am playing with the GalleryTreeViewer (latest CVS) and observe some
(lets say) inconsistencies compared to the Jface TreeViewer. I know that
the GalleryTreeViewer is somehow experimental. Mabe my comments help to
improve the class. I have not yet created bugzilla items out of it,
because some behavior may be intended. We may first discuss here...

Here is the setup:

(the whole thing is non virtual !!!)

To debug and analyze the situation I have created a simple ViewPart,
which contains a GallerTreeViewer and a TreeViewer. I am using two very
simple data models as input to the viewers

The data model's structures looks like this:

Base One (viewerInputOne)
|
+----Group One
| +-----Item OneOne
| +---- Item OneTwo
+----Group Two
+---- Item TwoOne
+---- Item TwoTwo

Base Two (viewerInputTwo)
|
+----Group Three
| +-----Item ThreeOne
| +---- Item ThreeTwo
+----Group Four
+---- Item FourOne
+---- Item FourTwo

Both viewers are set to the same data model (either Base One or Base
Two), but use independent content and label provider. Inside these
providers I log calls to the various methods and have seen the following
inconsistencies (or even real bugs).

------------

Situation 1:

Precondition: GalleryTreeViewer and TreeViewer are set to the same model
(viewerInputOne) and completely collapsed (closed), i.e. no items are
displayed.

Action: Change the input of the viewers to a different "input", like:

galleryViewer.setInput(viewerInputTwo);
treeViewer.setInput(viewerInputTwo);

Observation:

Both content providers receive the inputChanged() calls. Subsequently
the TreeViewer's content provider receives requests for the new model,
while the GalleryTreeViewer keeps receiving requests for the old model.
*This seems to be a bug*.

As a visible consequence, the GalleryTreeViewer still shows group
headers refering to the old model and (strangely) it is automatically
fully expanded (not intended...).

--------------

Situation 2:

Precondition: End of situation 1

Action: Now sending a refresh request to the viewers, like:

galleryViewer.refresh();
treeViewer.refresh();

Observation:

Now the GalleryTreeViewer starts to *use* the new model. It shows two
collapsed groups (identical to the tree viewer). However: It indicates
that each group contains exactly 1 item (on the group headers), which is
not correct (should be 2). Well, the viewer does not ask for the group's
children, so it can not know how many items are inside the group... This
may be a bug, or simply an enhancement request.

--------------

Situation 3:

Precondition: End of situation 2

Action: Now sending a "expandAll" request to the viewers, like:

galleryViewer.expandAll();
treeViewer.expandAll();

Observation:

Both viewers expand completely and show all groups and items correctly.

--------------

Doing more experiments, I found that without a refresh() call, the
GalleryTreeViewer continues to send requests about objects from the
first model to its content provider, although the input has been
changed. E.g. if sending a expandAll() just after the setInput() results
in corrupt view on the first model's data.

--------------

Another observation, showing up without changing input at all: Compared
to the TreeViewer, the GalleryTreeViewer sends much more requests to the
content provider than the tree viewer. It looks like the whole update is
done twice. For small models this may not matter, but for bigger models
this may result in performance drops.

--------------

Finally: Writing and reading all this text without seeing it, is a bit
odd. So I share a class, which implements a view part containing:

- a GalleryTreeViewer
- a TreeViewer
- Two models (as above)
- Two sets of content and label provider
- Four buttons to
- change model inputs (1 and 2)
- send refresh request
- send expand requests

Requests to the content providers are printed out, so that the behavior
is easy to observe.


If there are any questions, I am happy to answer....

Regards,
Michael



--------------030206090909000306000805
Content-Type: text/plain;
name="GalleryViewPart.java"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="GalleryViewPart.java"

package mv.sorter.ui.views;
import java.util.ArrayList;

import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.nebula.jface.galleryviewer.GalleryTreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.part.ViewPart;

/**
* This code was edited or generated using CloudGarden's Jigloo
* SWT/Swing GUI Builder, which is free for non-commercial
* use. If Jigloo is being used commercially (ie, by a corporation,
* company or business for any purpose whatever) then you
* should purchase a license for each developer using Jigloo.
* Please visit www.cloudgarden.com for details.
* Use of Jigloo implies acceptance of these licensing terms.
* A COMMERCIAL LICENSE HAS NOT BEEN PURCHASED FOR
* THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED
* LEGALLY FOR ANY CORPORATE OR COMMERCIAL PURPOSE.
*/
public class GalleryViewPart extends ViewPart {
public class GaItem {
public GaGroup myGroup;
public String myName;
public Image myImage;

public GaItem(GaGroup group, String name, Image image) {
myGroup = group;
myName = name;
myImage = image;
}

public String toString() {
return myGroup.toString() + " -> " + myName;
}
}

public class GaGroup {
public ArrayList<GaItem> items;
public GaBase myBase;
public String myName;

public GaGroup(GaBase base, String name) {
myBase = base;
myName = name;
items = new ArrayList<GaItem>();
}

public String toString() {
return myBase.toString() + " -> " + myName;
}
}

public class GaBase {
public ArrayList<GaGroup> groups;
private String myName;

public GaBase(String name) {
myName = name;
groups = new ArrayList<GaGroup>();
}

public String toString() {
return myName;
}
}

public class galleryLabelProvider implements ILabelProvider {

private String myViewer;

public galleryLabelProvider(String string) {
super();
myViewer = string;
}

public Image getImage(Object element) {
System.out.println(myViewer + ":: getImage of: " + element.toString());

if (element instanceof GaItem) {
GaItem gaItem = (GaItem) element;
return gaItem.myImage;
}

return null;
}

public String getText(Object element) {
System.out.println(myViewer + ":: getText of: " + element.toString());

if (element instanceof GaGroup) {
GaGroup gaGroup = (GaGroup) element;
return gaGroup.myName;
}
if (element instanceof GaItem) {
GaItem gaItem = (GaItem) element;
return gaItem.myName;
}
return null;
}

public void addListener(ILabelProviderListener listener) {
}

public void dispose() {
}

public boolean isLabelProperty(Object element, String property) {
return false;
}

public void removeListener(ILabelProviderListener listener) {
}

}

public class galleryContentProvider implements ITreeContentProvider {

private String myViewer;

public galleryContentProvider(String string) {
super();
myViewer = string;
}

public Object[] getChildren(Object parentElement) {
System.out.println(myViewer + ":: getChildren of: " + parentElement.toString());

if (parentElement instanceof GaGroup) {
GaGroup gaGroup = (GaGroup) parentElement;
return gaGroup.items.toArray();
}

return null;
}

public Object getParent(Object element) {
System.out.println(myViewer + ":: getParent of: " + element.toString());

if (element instanceof GaGroup) {
GaGroup gaGroup = (GaGroup) element;
return gaGroup.myBase;
}

if (element instanceof GaItem) {
GaItem gaItem = (GaItem) element;
return gaItem.myGroup;
}

return null;
}

public boolean hasChildren(Object element) {
System.out.println(myViewer + ":: hasChildren of: " + element.toString());

if (element instanceof GaBase) {
GaBase gaBase = (GaBase) element;
return ! gaBase.groups.isEmpty();
}

if (element instanceof GaGroup) {
GaGroup gaGroup = (GaGroup) element;
return ! gaGroup.items.isEmpty();
}

return false;
}

public Object[] getElements(Object inputElement) {
System.out.println(myViewer + ":: getElements of: " + inputElement.toString());

if (inputElement instanceof GaBase) {
GaBase gaBase = (GaBase) inputElement;
return gaBase.groups.toArray();
}

return null;
}

public void dispose() {
}

public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
System.out.println("\n" + myViewer + ":: inputChanged from: "
+ (oldInput == null ? "null" : oldInput.toString())
+ " to: "
+ (newInput == null ? "null" : newInput.toString())
+ "\n");
}
}

public static final String ID_VIEW =
"mv.sorter.ui.views.GalleryViewPart"; //$NON-NLS-1$

Composite composite;
private GalleryTreeViewer galleryViewer;
private TreeViewer treeViewer;

private Button button1;
private Button button2;
private Button button3;
private Button button4;

private GaBase viewerInputOne;
private GaBase viewerInputTwo;

/**
*
*/
public GalleryViewPart() {
super();
}

/* (non-Javadoc)
* @see org.eclipse.ui.IWorkbenchPart#createPartControl(org.eclipse. swt.widgets.Composite)
*/
public void createPartControl(Composite parent) {

viewerInputOne = new GaBase("Base One");

GaGroup groupOne = new GaGroup(viewerInputOne, "Group One");
viewerInputOne.groups.add(groupOne);
GaItem itemOneOne = new GaItem(groupOne, "Item OneOne", new Image(parent.getDisplay(), 50, 16));
groupOne.items.add(itemOneOne);
GaItem itemOneTwo = new GaItem(groupOne, "Item OneTwo", new Image(parent.getDisplay(), 50, 16));
groupOne.items.add(itemOneTwo);

GaGroup groupTwo = new GaGroup(viewerInputOne, "Group Two");
viewerInputOne.groups.add(groupTwo);
GaItem itemTwoOne = new GaItem(groupTwo, "Item TwoOne", new Image(parent.getDisplay(), 50, 16));
groupTwo.items.add(itemTwoOne);
GaItem itemTwoTwo = new GaItem(groupTwo, "Item TwoTwo", new Image(parent.getDisplay(), 50, 16));
groupTwo.items.add(itemTwoTwo);

viewerInputTwo = new GaBase("Base Two");

GaGroup groupThree = new GaGroup(viewerInputTwo, "Group Three");
viewerInputTwo.groups.add(groupThree);
GaItem itemThreeOne = new GaItem(groupThree, "Item ThreeOne", new Image(parent.getDisplay(), 50, 16));
groupThree.items.add(itemThreeOne);
GaItem itemThreeTwo = new GaItem(groupThree, "Item ThreeTwo", new Image(parent.getDisplay(), 50, 16));
groupThree.items.add(itemThreeTwo);

GaGroup groupFour = new GaGroup(viewerInputTwo, "Group Four");
viewerInputTwo.groups.add(groupFour);
GaItem itemFourOne = new GaItem(groupFour, "Item FourOne", new Image(parent.getDisplay(), 50, 16));
groupFour.items.add(itemFourOne);
GaItem itemFourTwo = new GaItem(groupFour, "Item FourTwo", new Image(parent.getDisplay(), 50, 16));
groupFour.items.add(itemFourTwo);


composite = new Composite(parent, SWT.NULL);
GridLayout compositeLayout = new GridLayout();
compositeLayout.makeColumnsEqualWidth = true;
compositeLayout.numColumns = 2;
composite.setLayout(compositeLayout);
{
GridData galleryViewerLayoutData = new GridData();
galleryViewerLayoutData.horizontalSpan = 2;
galleryViewerLayoutData.horizontalAlignment = GridData.FILL;
galleryViewerLayoutData.grabExcessHorizontalSpace = true;
galleryViewerLayoutData.verticalAlignment = GridData.FILL;
galleryViewerLayoutData.grabExcessVerticalSpace = true;
galleryViewer = new GalleryTreeViewer(composite, SWT.V_SCROLL | SWT.MULTI);
galleryViewer.getControl().setLayoutData(galleryViewerLayout Data);
galleryViewer.setContentProvider(new galleryContentProvider("gallery content provider"));
galleryViewer.setLabelProvider(new galleryLabelProvider("gallery label provider"));
galleryViewer.setInput(viewerInputOne);
}
{
GridData treeViewerLayoutData = new GridData();
treeViewerLayoutData.horizontalSpan = 2;
treeViewerLayoutData.grabExcessHorizontalSpace = true;
treeViewerLayoutData.horizontalAlignment = GridData.FILL;
treeViewerLayoutData.grabExcessVerticalSpace = true;
treeViewerLayoutData.verticalAlignment = GridData.FILL;
treeViewer = new TreeViewer(composite, SWT.V_SCROLL | SWT.MULTI);
treeViewer.getControl().setLayoutData(treeViewerLayoutData);
treeViewer.setContentProvider(new galleryContentProvider("tree content provider"));
treeViewer.setLabelProvider(new galleryLabelProvider("tree label provider"));
treeViewer.setInput(viewerInputOne);
}
{
button1 = new Button(composite, SWT.PUSH | SWT.CENTER);
button1.setText("Input 1");
button1.addMouseListener(new MouseAdapter() {
public void mouseDown(MouseEvent evt) {
System.out.println("---- Input 1 selected");
galleryViewer.setInput(viewerInputOne);
treeViewer.setInput(viewerInputOne);
}
});
}
{
button2 = new Button(composite, SWT.PUSH | SWT.CENTER);
GridData button2LayoutData = new GridData();
button2LayoutData.horizontalAlignment = GridData.END;
button2.setLayoutData(button2LayoutData);
button2.setText("Input 2");
button2.addMouseListener(new MouseAdapter() {
public void mouseDown(MouseEvent evt) {
System.out.println("---- Input 2 selected");
galleryViewer.setInput(viewerInputTwo);
treeViewer.setInput(viewerInputTwo);
}
});
}
{
button3 = new Button(composite, SWT.PUSH | SWT.CENTER);
GridData button3LayoutData = new GridData();
button3LayoutData.horizontalSpan = 2;
button3LayoutData.horizontalAlignment = GridData.FILL;
button3.setLayoutData(button3LayoutData);
button3.setText("Refresh");
button3.addMouseListener(new MouseAdapter() {
public void mouseDown(MouseEvent evt) {
System.out.println("---- Refresh Button pressed");
galleryViewer.refresh();
treeViewer.refresh();
}
});
}
{
button4 = new Button(composite, SWT.PUSH | SWT.CENTER);
GridData button4LayoutData = new GridData();
button4LayoutData.horizontalSpan = 2;
button4LayoutData.horizontalAlignment = GridData.FILL;
button4.setLayoutData(button4LayoutData);
button4.setText("Expand");
button4.addMouseListener(new MouseAdapter() {
public void mouseDown(MouseEvent evt) {
System.out.println("---- Expand Button pressed");
galleryViewer.expandAll();
treeViewer.expandAll();
}
});
}
}

/* (non-Javadoc)
* @see org.eclipse.ui.IWorkbenchPart#setFocus()
*/
public void setFocus() {
}

/**
* Cleans up all resources created by this ViewPart.
*/
public void dispose() {
super.dispose();
}

}

--------------030206090909000306000805--
Previous Topic:Alternate row coloring in Grid
Next Topic:Multi cell copy paste in nebula brid
Goto Forum:
  


Current Time: Thu Apr 24 01:29:19 EDT 2014

Powered by FUDForum. Page generated in 0.01542 seconds