tags:

views:

76

answers:

1

I have an SWT Tree in my application that contains an infinite data structure. Upon expanding an item, I generate its children. On Windows though, users can press "*", triggering an "expand all descendants" action, and my application hangs.

There are two acceptable behaviors for me when the user presses "*":

  1. Expand all children of the selected element, but only to the next level
  2. Do nothing

In either case, I will still need to be able to expand items as deep as required (by clicking on the [+] icon, or by pressing "+"), so limiting the tree depth is not a solution. Is there another way that I can achieve either of the above without modifying SWT classes?

+1  A: 

I got this far -- maybe it helps someone:

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

public class SWTInfiniteTree {
    private boolean expanding;

    public SWTInfiniteTree() {
        Display display = new Display();
        Shell shell = new Shell(display);
        shell.setLayout(new GridLayout());

        Tree tree = new Tree(shell, SWT.BORDER);
        tree.setLayoutData(new GridData(GridData.FILL_BOTH));

        createItem(tree, "ITEM1");
        createItem(tree, "ITEM2");
        createItem(tree, "ITEM3");

        tree.addTreeListener(new TreeListener() {
            @Override
            public void treeExpanded(TreeEvent e) {
                TreeItem parent = (TreeItem) e.item;
                if (expanding) {
                    e.doit = false;
                } else {
                    expanding = true;
                    parent.removeAll();
                    createItem(parent, ".1");
                    createItem(parent, ".2");
                    createItem(parent, ".3");
                }
            }

            @Override
            public void treeCollapsed(TreeEvent e) {
            }
        });
        tree.addKeyListener(new KeyListener() {
            @Override
            public void keyReleased(KeyEvent e) {
                expanding = false;
            }

            @Override
            public void keyPressed(KeyEvent e) {
            }
        });
        tree.addMouseListener(new MouseListener() {
            @Override
            public void mouseUp(MouseEvent e) {
                expanding = false;
            }

            @Override
            public void mouseDown(MouseEvent e) {
            }

            @Override
            public void mouseDoubleClick(MouseEvent e) {
                expanding = false;
            }
        });

        shell.setSize(300, 200);
        shell.open();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
        display.dispose();
    }

    private TreeItem createItem(Widget parent, String text) {
        TreeItem item;
        if (parent instanceof Tree) {
            item = new TreeItem((Tree) parent, SWT.NULL);
            item.setText(text);
        } else {
            item = new TreeItem((TreeItem) parent, SWT.NULL);
            item.setText(((TreeItem) parent).getText() + text);
        }
        // So that we have a [+] icon
        item.setItemCount(1);
        return item;
    }

    public static void main(String[] args) {
        new SWTInfiniteTree();
    }
}

What it does is it expands the first element, and then goes into "won't expand more" mode, which is lifted whenever a key or the mouse button is released. However, for some reason it will expand my freshly generated items.

I hope someone has a better solution.

Lóránt Pintér