Is there a SWT Combo Box with any object as data and a LabelProvider to display?

I am looking for an implementation of Combo Box in SWT, which will allow me to install records with a list of any object in it, similar to trees and tables.

Ideally, I want String to drop out to be able to be different from the final string after selecting it. IE uncheck to select the person who shows their age next to their name in the list, but only their name when selecting and placing in the field.

All I can find is existing String-based Combo Boxs without describing the various display options, so I think I will need to create a new component if I want this to work, but I was hoping someone would already ( since I saw such functionality in some applications), and I just can’t find it?

I hope to create something like this.

enter image description here

+7
source share
2 answers

JFace ComboViewer seems to be what you want. It is supported by ModelProvider , which contains your objects. A LabelProvider used to display text inside combos.

Here is a great tutorial from Vogella.

Here is an example that does what you want. This basically saves the current combined selection if the logical value of the displayed objects is:

 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; } } 
+8
source

Many thanks to Baz for putting me on the right path and providing me with the source code. But taking all of this, I wanted something cleaner in my RCP view, and although a common instance of the combo box would be nice in the future, so I wrapped all the templates in a new class, you can use the following:

  List<Person> persons = new ArrayList<Person>(); persons.add(new Person("Baz",26)); persons.add(new Person("Glen",27)); persons.add(new Person("Jimmy",18)); TypedComboBox<Person> box = new TypedComboBox<Person>(parent); box.addSelectionListener(new TypedComboBoxSelectionListener<Person>() { @Override public void selectionChanged(TypedComboBox<Person> typedComboBox, Person newSelection) { System.out.println(newSelection); } }); box.setLabelProvider(new TypedComboBoxLabelProvider<Person>() { @Override public String getSelectedLabel(Person element) { return element.getName(); } @Override public String getListLabel(Person element) { return element.getName() + " | " + element.getAge(); } }); box.setContent(persons); box.selectFirstItem(); 

For my presentation, where I will need several boxes for choosing with different objects, I am much happier with the help of the printed box, because I do not sketch material and do not reproduce the template code in the body of the presentation code.

You do not need to install a tag provider if you just want to use the toSting () method, otherwise there are two shortcuts, one for the selected item and one for all the others.

Just in case, someone stumbles upon this question with the same question as me, here is my code, feedback will be greatly appreciated.

 import java.util.ArrayList; import java.util.List; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.ComboViewer; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; public class TypedComboBox<T> { private ComboViewer viewer; private TypedComboBoxLabelProvider<T> labelProvider; private List<T> content; private List<TypedComboBoxSelectionListener<T>> selectionListeners; private T currentSelection; public TypedComboBox(Composite parent) { this.viewer = new ComboViewer(parent, SWT.READ_ONLY); this.viewer.setContentProvider(ArrayContentProvider.getInstance()); viewer.setLabelProvider(new LabelProvider() { @Override public String getText(Object element) { T typedElement = getTypedObject(element); if (labelProvider != null && typedElement != null) { if (typedElement == currentSelection) { return labelProvider.getSelectedLabel(typedElement); } else { return labelProvider.getListLabel(typedElement); } } else { return element.toString(); } } }); viewer.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { IStructuredSelection selection = (IStructuredSelection) event .getSelection(); T typedSelection = getTypedObject(selection.getFirstElement()); if (typedSelection != null) { currentSelection = typedSelection; viewer.refresh(); notifySelectionListeners(typedSelection); } } }); this.content = new ArrayList<T>(); this.selectionListeners = new ArrayList<TypedComboBoxSelectionListener<T>>(); } public void setLabelProvider(TypedComboBoxLabelProvider<T> labelProvider) { this.labelProvider = labelProvider; } public void setContent(List<T> content) { this.content = content; this.viewer.setInput(content.toArray()); } public T getSelection() { return currentSelection; } public void setSelection(T selection) { if (content.contains(selection)) { viewer.setSelection(new StructuredSelection(selection), true); } } public void selectFirstItem() { if (content.size()>0) { setSelection(content.get(0)); } } public void addSelectionListener(TypedComboBoxSelectionListener<T> listener) { this.selectionListeners.add(listener); } public void removeSelectionListener( TypedComboBoxSelectionListener<T> listener) { this.selectionListeners.remove(listener); } private T getTypedObject(Object o) { if (content.contains(o)) { return content.get(content.indexOf(o)); } else { return null; } } private void notifySelectionListeners(T newSelection) { for (TypedComboBoxSelectionListener<T> listener : selectionListeners) { listener.selectionChanged(this, newSelection); } } 

And a shortcut provider interface.

 public interface TypedComboBoxLabelProvider<T> { public String getSelectedLabel(T element); public String getListLabel(T element); } 

And the listener of choice:

 public interface TypedComboBoxSelectionListener<T> { public void selectionChanged(TypedComboBox<T> typedComboBox, T newSelection); } 
+5
source

All Articles