| Summary: | [Viewers] deleting last tree item fires unobserved select event | ||
|---|---|---|---|
| Product: | [Eclipse Project] Platform | Reporter: | Tanya Jenkin <Tanya.Jenkin> |
| Component: | UI | Assignee: | Platform UI Triaged <platform-ui-triaged> |
| Status: | CLOSED WONTFIX | QA Contact: | |
| Severity: | normal | ||
| Priority: | P3 | CC: | bpasero, tom.schindl |
| Version: | 3.1 | Keywords: | helpwanted |
| Target Milestone: | --- | ||
| Hardware: | PC | ||
| OS: | Windows 2000 | ||
| Whiteboard: | stalebug | ||
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 ();
}
}
(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 (); > } > } 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. Hitesh is now responsible for watching bugs in the [Viewers] component area. 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. 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. |
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); } } }