ggeorg / gwt-mosaic

Automatically exported from code.google.com/p/gwt-mosaic
1 stars 0 forks source link

New Widget : a ManyToMany Editor #91

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Hi,

I wrote a simple new editor widget that edits a @ManyToMany field. The purpose 
is to able to select one or many fields from a reference table. I publish this 
because it's a lack of GWT basic editors. I really love Mosaic because it's the 
only library that provides real layout system by implementing GWT standards 
(versus other like GXT, ...) that provide their own global system wich do not 
evoluate with versions ...

Here is the simple code :

import java.util.ArrayList;
import java.util.List;

import org.gwt.mosaic.ui.client.CaptionLayoutPanel;

import com.google.gwt.cell.client.Cell;
import com.google.gwt.cell.client.CheckboxCell;
import com.google.gwt.cell.client.CompositeCell;
import com.google.gwt.cell.client.FieldUpdater;
import com.google.gwt.cell.client.HasCell;
import com.google.gwt.cell.client.TextCell;
import com.google.gwt.editor.client.LeafValueEditor;
import com.google.gwt.user.cellview.client.CellList;
import com.google.gwt.view.client.MultiSelectionModel;

public abstract class ListEditor<T> extends CaptionLayoutPanel
        implements LeafValueEditor<List<T>> {

    private final CellList<T> table;
    private final MultiSelectionModel<T> sel = new MultiSelectionModel<T>();

    public ListEditor(String title) {
        super(title);

        List<HasCell<T, ?>> cells = new ArrayList<HasCell<T, ?>>();

        cells.add(new HasCell<T, Boolean>() {

            private final CheckboxCell cell = new CheckboxCell(true, true);

            @Override
            public Cell<Boolean> getCell() {
                return cell;
            }

            @Override
            public FieldUpdater<T, Boolean> getFieldUpdater() {
                return new FieldUpdater<T, Boolean>() {

                    @Override
                    public void update(int index, T object, Boolean value) {
                        sel.setSelected(object, value);
                    }
                };
            }

            @Override
            public Boolean getValue(T object) {
                return sel.isSelected(object);
            }
        });

        cells.add(new HasCell<T, String>() {
            private final TextCell cell = new TextCell();

            @Override
            public Cell<String> getCell() {
                return cell;
            }

            @Override
            public FieldUpdater<T, String> getFieldUpdater() {
                return null;
            }

            @Override
            public String getValue(T object) {
                return getStringValue(object);
            }
        });

        table = new CellList<T>(new CompositeCell<T>(cells));
        table.setSelectionModel(sel);
        add(table);
    }

    @Override
    protected void onAttach() {
        super.onAttach();

        populateCellList(table);
    }

    abstract protected String getStringValue(T object);

    abstract protected void populateCellList(CellList<T> cellList);

    abstract protected boolean isEqual(T cellItem, T valueItem);

    @Override
    public void setValue(List<T> value) {
        sel.clear();

        if (value != null) {
            for (T obj : value) {
                for (T o : table.getVisibleItems()) {
                    if (isEqual(o, obj)) {
                        sel.setSelected(o, true);
                        continue;
                    }
                }
            }
        }
    }

    @Override
    public List<T> getValue() {
        List<T> list = new ArrayList<T>();
        list.addAll(sel.getSelectedSet());
        return list;
    }

}

And here is a sample specific implementation from an editor :

public class MyEntityEditor implements Editor<MyEntity> {
    TextBox aStringField = new TextBox();
    ListEditor<ASubEntity> theSubEntityListField = new ListEditor<ASubEntity>("Lits affectés") {

            @Override
            protected void populateCellList(final CellList<ASubEntity> cellList) {
                ClientController.request().lit().findAll().fire(new Receiver<List<ASubEntity>>() {
                    @Override
                    public void onSuccess(List<ASubEntity> response) {
                        cellList.setRowCount(response.size());
                        cellList.setRowData(response);
                    }
                });
            }

            @Override
            protected String getStringValue(ASubEntity object) {
                return object.getNom();
            }

            @Override
            protected boolean isEqual(ASubEntity cellItem, ASubEntity valueItem) {
                return cellItem.stableId().equals(valueItem.stableId());
            }
        };
}

Hope this help :)

Original issue reported on code.google.com by Creati...@gmail.com on 15 Apr 2011 at 11:06

GoogleCodeExporter commented 9 years ago
And got the same thing with a ManyToOne field :

The code :

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.editor.client.LeafValueEditor;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.ListBox;

public abstract class ComboxBoxEditor<T> extends Composite implements 
LeafValueEditor<T> {

    private T value;
    private List<T> liste = new ArrayList<T>();

    private final ListBox listBox = new ListBox();

    public ComboxBoxEditor() {
        initWidget(listBox);

        listBox.addChangeHandler(new ChangeHandler() {

            @Override
            public void onChange(ChangeEvent event) {
                value = liste.get(listBox.getSelectedIndex());
            }
        });
    }

    @Override
    protected void onAttach() {
        super.onAttach();

        retrieveData();
    }

    abstract protected String getTextValue(T obj);
    abstract protected void retrieveData();

    protected final void dataCallback(List<T> data) {
        liste = data;

        listBox.clear();
        for (int i = 0; i < liste.size(); i++) {
            listBox.addItem(getTextValue(liste.get(i)));
        }

        listBox.setSelectedIndex(liste.indexOf(value));
    }

    @Override
    public void setValue(T value) {
        this.value = value;
        listBox.setSelectedIndex(liste.indexOf(value));
    }

    @Override
    public T getValue() {
        return value;
    }
}

The implementation :

class MyEntityEditor implements Editor<MyEntity> {
    ComboxBoxEditor<LitProxy> lit = new ComboxBoxEditor<LitProxy>() {

            @Override
            protected void retrieveData() {
                ClientController.request().lit().findAll().fire(new Receiver<List<LitProxy>>() {
                    @Override
                    public void onSuccess(List<LitProxy> response) {
                        dataCallback(response);
                    }
                });
            }

            @Override
            protected String getTextValue(LitProxy obj) {
                return obj.getNom();
            }
        };
}

Original comment by Creati...@gmail.com on 15 Apr 2011 at 11:11