package org.eclipse.ufacekit.ui.jfx.databinding.controls;
import java.util.ArrayList;
import java.util.List;
import javafx.beans.property.ObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.SingleSelectionModel;
public class ChoiceBoxViewer<T> {
public interface LabelConverter<T> {
public String getLabel(T label);
}
public static class StringWrapper<T> {
private final T domainObject;
private final ChoiceBoxViewer<T> viewer;
public StringWrapper(ChoiceBoxViewer<T> viewer, T domainObject) {
this.viewer = viewer;
this.domainObject = domainObject;
}
public String toString() {
return viewer.getLabel(domainObject);
}
@Override
public boolean equals(Object obj) {
@SuppressWarnings("unchecked")
StringWrapper<T> o = (StringWrapper<T>) obj;
if( o != null ) {
return o.domainObject.equals(domainObject);
}
return false;
}
@Override
public int hashCode() {
return domainObject.hashCode();
}
}
private ChoiceBox<StringWrapper<T>> box;
private LabelConverter<T> labelConverter;
private ObservableList<T> list;
private ListChangeListener<T> changeListener = new ListChangeListener<T>() {
@Override
public void onChanged(
javafx.collections.ListChangeListener.Change<? extends T> arg0) {
ChoiceBoxViewer.this.handleChange(arg0);
}
};
private ObjectProperty<T> selectedItem = new ObjectProperty<T>();
public ChoiceBoxViewer() {
this.box = new ChoiceBox<StringWrapper<T>>();
this.box.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<StringWrapper<T>>() {
@Override
public void changed(
ObservableValue<? extends StringWrapper<T>> arg0,
StringWrapper<T> arg1, StringWrapper<T> arg2) {
if( arg2 == null ) {
selectedItem.setValue(null);
} else {
selectedItem.setValue(arg2.domainObject);
}
}
});
}
public T getSelectedItem() {
return selectedItem.get();
}
public void setSelectedItem(T selectedItem) {
this.selectedItem.set(selectedItem);
if( selectedItem != null ) {
this.box.getSelectionModel().select(new StringWrapper<T>(this, selectedItem));
} else {
this.box.getSelectionModel().clearSelection();
}
}
public ObjectProperty<T> selectedItemProperty() {
return selectedItem;
}
public ChoiceBox<StringWrapper<T>> getChoiceBox() {
return box;
}
public void setLabelConverter(LabelConverter<T> labelConverter) {
this.labelConverter = labelConverter;
}
public void setItems(ObservableList<T> list) {
if( this.list != null ) {
this.list.removeListener(changeListener);
}
this.list = list;
this.list.addListener(changeListener);
List<StringWrapper<T>> l = new ArrayList<StringWrapper<T>>(list.size());
for( T t : list ) {
l.add(new StringWrapper<T>(this,t));
}
box.getItems().setAll(l);
}
private void handleChange(javafx.collections.ListChangeListener.Change<? extends T> change) {
List<StringWrapper<T>> list = new ArrayList<StringWrapper<T>>();
for( T t : change.getRemoved() ) {
list.add(new StringWrapper<T>(this,t));
}
box.getItems().removeAll(list);
list.clear();
for( T t : change.getAddedSubList() ) {
list.add(new StringWrapper<T>(this,t));
}
box.getItems().addAll(list);
}
private String getLabel(T item) {
if( labelConverter == null ) {
return item.toString();
} else {
return labelConverter.getLabel(item);
}
}
}