Is there SWT Combo Box with any Object as data and LabelProvider for display?

Link19 picture Link19 · Sep 20, 2012 · Viewed 10k times · Source

I'm searching for an implementation of a Combo Box in SWT that will allow me to set the the entries in it with a list of any Object, in a similar way to Trees and Tables.

Ideally I want the String when dropped down to be able to be different to the final String once selected. IE a drop down to select a person that shows their age next to their name in the list, but only their name when selected and placed in the box.

All I can find that exists are String based Combo Boxes with no way of describing different display options, so I guess i's going to have to build a new component if I want the thing to work, but I was hoping someone has already implemented such a thing (since I've seen this sort of functionality in some applications) and I just can't find it?

I hope to create something like this.

enter image description here

Answer

Baz picture Baz · Sep 20, 2012

The JFace ComboViewer seems to be what you want. It is backed by a ModelProvider which holds your Objects. A LabelProvider is used to display the text inside the combo.

Here is an excellent tutorial by Vogella.

Here is an example that does what you want. It basically saves the current combo selection if a boolean of the displayed objects:

public static void main(String[] args) {
    final Display display = new Display();
    final Shell shell = new Shell(display);
    shell.setLayout(new FillLayout());

    final ComboViewer viewer = new ComboViewer(shell, SWT.READ_ONLY);

    viewer.setContentProvider(ArrayContentProvider.getInstance());

    /* if the current person is selected, show text */
    viewer.setLabelProvider(new LabelProvider() {
        @Override
        public String getText(Object element) {
            if (element instanceof Person) {
                Person current = (Person) element;

                if(current.isSelected())
                    return current.getName();
                else
                    return "";
            }
            return super.getText(element);
        }
    });

    final Person[] persons = new Person[] { new Person("Baz"),
            new Person("BazBaz"), new Person("BazBazBaz") };

    viewer.setInput(persons);

    /* within the selection event, tell the object it was selected */
    viewer.addSelectionChangedListener(new ISelectionChangedListener() {
        @Override
        public void selectionChanged(SelectionChangedEvent event) {
            IStructuredSelection selection = (IStructuredSelection) event.getSelection();
            Person person = (Person)selection.getFirstElement();

            for(Person p : persons)
                p.setSelected(false);

            person.setSelected(true);

            viewer.refresh();
        }
    });

    viewer.setSelection(new StructuredSelection(viewer.getElementAt(0)), true);

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

public static class Person {
    private String name;

    /* this will be true for the selected person */
    boolean isSelected;

    public Person(String name) {
        this.name = name;
        this.setSelected(false);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public boolean isSelected() {
        return isSelected;
    }

    public void setSelected(boolean isSelected) {
        this.isSelected = isSelected;
    }

}