Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 102736

Summary: [Viewers] deleting last tree item fires unobserved select event
Product: [Eclipse Project] Platform Reporter: Tanya Jenkin <Tanya.Jenkin>
Component: UIAssignee: Platform UI Triaged <platform-ui-triaged>
Status: CLOSED WONTFIX QA Contact:
Severity: normal    
Priority: P3 CC: bpasero, tom.schindl
Version: 3.1Keywords: helpwanted
Target Milestone: ---   
Hardware: PC   
OS: Windows 2000   
Whiteboard: stalebug

Description Tanya Jenkin CLA 2005-07-05 10:40:07 EDT
Create a tree viewer containing a tree with 2 or more (root) items, and some 
means for user to delete selected tree item.  Deleting the last (bottom) root 
item fires a selection event for the new last item, but (a) the selection is 
not shown in the tree control and (b) this event is not fired when any other 
item is deleted.

Example code (createContents is from an ApplicationWindow derivation) :

@Override
protected Control createContents(Composite arg0) {
	Composite contents = new Composite(arg0, SWT.NONE);
	contents.setLayout(new FillLayout());
		
	treeView = new TreeViewer(contents, SWT.SINGLE | SWT.BORDER);
	treeView.setContentProvider(new TreeContent());
	treeView.setLabelProvider(new TreeLabel());
		
	data = new TreeNode("root");
	data.addChild(new TreeNode("alpha"));
	data.addChild(new TreeNode("beta"));
	data.addChild(new TreeNode("gamma"));
		
	treeView.setInput(data);
		
	treeView.getTree().addSelectionListener(new SelectionAdapter() {
		public void widgetSelected(SelectionEvent event) {
			System.out.println("Selected "+event.item.getData
().toString());
		}
	});
		
	Button button = new Button(contents, SWT.PUSH);
	button.setText("Delete Selected Item");
	button.addSelectionListener(new SelectionAdapter() {
		public void widgetSelected(SelectionEvent event) {
			TreeItem[] selected = treeView.getTree().getSelection();
			for(TreeItem item : selected) {
				System.out.println("Deleting "+item.getData
().toString());
				data.removeChild((TreeNode)item.getData());
			}
		}
	});
		
	return contents;
}

public class TreeContent implements ITreeContentProvider {

	public TreeContent() {
		super();
	}

	public Object[] getChildren(Object arg0) {
		return ((TreeNode)arg0).getChildren().toArray();
	}

	public Object getParent(Object arg0) {
		return ((TreeNode)arg0).getParent();
	}

	public boolean hasChildren(Object arg0) {
		return (((TreeNode)arg0).getChildren().size() > 0);
	}

	public Object[] getElements(Object arg0) {
		return ((TreeNode)arg0).getChildren().toArray();
	}

	public void dispose() {
	}

	public void inputChanged(Viewer arg0, Object oldInput, Object newInput) 
{
		if (oldInput != null) {
			((TreeNode)oldInput).removeChangeListener(arg0);
		}
		if (newInput != null) {
			((TreeNode)newInput).addChangeListener(arg0);
		}
	}

}
Comment 1 Steve Northover CLA 2005-07-07 22:59:28 EDT
Here is an SWT only program that WORKSFORME.  Can you make it fail?

import org.eclipse.swt.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;

public class PR_102736 {

public static void main(String[] args) {
	Display display = new Display ();
	final Shell shell = new Shell (display);
	shell.setLayout (new FillLayout (SWT.VERTICAL));
	final Tree tree = new Tree(shell, SWT.SINGLE | SWT.BORDER);
	TreeItem root = new TreeItem(tree, SWT.NONE);
	root.setText ("root");
	TreeItem item = new TreeItem(root, SWT.NONE);
	item.setText ("alpha");
	item = new TreeItem(root, SWT.NONE);
	item.setText ("beta");
	item = new TreeItem(root, SWT.NONE);
	item.setText ("gamma");	
	tree.addSelectionListener(new SelectionAdapter() {
		public void widgetSelected(SelectionEvent event) {
			System.out.println("Selected "+event.item);
		}
	});
	tree.setSelection(new TreeItem [] {item});
	Button button = new Button(shell, SWT.PUSH);
	button.setText("Delete Selected Item");
	button.addSelectionListener(new SelectionAdapter() {
		public void widgetSelected(SelectionEvent event) {
			TreeItem[] selected = tree.getSelection();
			for(int i=0; i<selected.length; i++) {
				TreeItem item = selected [i];
				System.out.println("Deleting "+item);
				item.dispose();
			}
		}
	});
	shell.pack ();
	shell.setSize (200, 200);
	shell.open ();
	while (!shell.isDisposed ()) {
		if (!display.readAndDispatch ()) display.sleep ();
	}
	display.dispose ();
}
}
Comment 2 Tanya Jenkin CLA 2005-07-11 05:37:34 EDT
(In reply to comment #1)
No, it WORKSFORME too, even when I get rid of 'root' so is a 3-item multiple-
rooted tree.  Guess bug is in JFace or my use of it.  Here is the TreeNode data 
class from my original example.  Pressing the delete button eventually calls 
the tree viewer refresh() method.

import java.util.ArrayList;
import java.util.List;

import org.eclipse.jface.viewers.Viewer;

public class TreeNode {
    private String name;
    private List<TreeNode> children;
    private TreeNode parent;
    private List<Viewer> changeListeners;
	
    public TreeNode(String name) {
        super();
        this.name = name;
        this.children = new ArrayList<TreeNode>();
        this.changeListeners = new ArrayList<Viewer>();
        this.parent = null;
    }
    @Override
    public String toString() {
        return getName();
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
        notifyChangeListeners();
    }
    public TreeNode getParent() {
        return parent;
    }
    public void addChild(TreeNode child) {
        children.add(child);
        child.parent = this;
        notifyChangeListeners();
    }
    public List<TreeNode> getChildren() {
        return children; 
    }
    public void removeChild(TreeNode child) {
        children.remove(child);
        child.parent = null;
        notifyChangeListeners();
    }
    public void addChangeListener(Viewer listener) {
	changeListeners.add(listener);
    }
    public void removeChangeListener(Viewer listener) {
	changeListeners.remove(listener);
    }
    public void notifyChangeListeners() {
        for(Viewer viewer : changeListeners) viewer.refresh();
    }
}

> Here is an SWT only program that WORKSFORME.  Can you make it fail?
> import org.eclipse.swt.*;
> import org.eclipse.swt.events.*;
> import org.eclipse.swt.layout.*;
> import org.eclipse.swt.widgets.*;
> public class PR_102736 {
> public static void main(String[] args) {
> 	Display display = new Display ();
> 	final Shell shell = new Shell (display);
> 	shell.setLayout (new FillLayout (SWT.VERTICAL));
> 	final Tree tree = new Tree(shell, SWT.SINGLE | SWT.BORDER);
> 	TreeItem root = new TreeItem(tree, SWT.NONE);
> 	root.setText ("root");
> 	TreeItem item = new TreeItem(root, SWT.NONE);
> 	item.setText ("alpha");
> 	item = new TreeItem(root, SWT.NONE);
> 	item.setText ("beta");
> 	item = new TreeItem(root, SWT.NONE);
> 	item.setText ("gamma");	
> 	tree.addSelectionListener(new SelectionAdapter() {
> 		public void widgetSelected(SelectionEvent event) {
> 			System.out.println("Selected "+event.item);
> 		}
> 	});
> 	tree.setSelection(new TreeItem [] {item});
> 	Button button = new Button(shell, SWT.PUSH);
> 	button.setText("Delete Selected Item");
> 	button.addSelectionListener(new SelectionAdapter() {
> 		public void widgetSelected(SelectionEvent event) {
> 			TreeItem[] selected = tree.getSelection();
> 			for(int i=0; i<selected.length; i++) {
> 				TreeItem item = selected [i];
> 				System.out.println("Deleting "+item);
> 				item.dispose();
> 			}
> 		}
> 	});
> 	shell.pack ();
> 	shell.setSize (200, 200);
> 	shell.open ();
> 	while (!shell.isDisposed ()) {
> 		if (!display.readAndDispatch ()) display.sleep ();
> 	}
> 	display.dispose ();
> }
> }

Comment 3 Steve Northover CLA 2005-07-11 12:37:38 EDT
Ok, I'm going to move this bug to UI for them to investigate.  They can move 
it back if it turns out to be an SWT problem.
Comment 4 Boris Bokowski CLA 2009-11-26 09:54:49 EST
Hitesh is now responsible for watching bugs in the [Viewers] component area.
Comment 5 Eclipse Webmaster CLA 2019-09-06 15:32:21 EDT
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet.

If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.
Comment 6 Eclipse Genie CLA 2021-10-14 16:44:32 EDT
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. As such, we're closing this bug.

If you have further information on the current state of the bug, please add it and reopen this bug. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.

--
The automated Eclipse Genie.