PDA

View Full Version : [FIXED] ClassCastException when calling SelectionChangedEvent<T>.getSource()



icfantv
26 Jan 2012, 5:17 PM
This is on the CheckBoxSelectionModel.

When I add a SelectionChangedHandler and call event.getSource, in the parent class it's trying to cast the source as a Component (line 57 of SelectionChangedEvent) and because my debugger isn't working at the moment, I can't be sure, but I suspect it is returning an instance of my model.

Here's the code (the exception is thrown on the event.getSource() line in onSelectionChanged):


import com.allen_sauer.gwt.log.client.Log;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.editor.client.Editor;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.Widget;
import com.sencha.gxt.cell.core.client.form.ComboBoxCell;
import com.sencha.gxt.core.client.IdentityValueProvider;
import com.sencha.gxt.core.client.Style;
import com.sencha.gxt.core.client.ValueProvider;
import com.sencha.gxt.data.shared.ListStore;
import com.sencha.gxt.data.shared.ModelKeyProvider;
import com.sencha.gxt.data.shared.PropertyAccess;
import com.sencha.gxt.data.shared.StringLabelProvider;
import com.sencha.gxt.widget.core.client.ContentPanel;
import com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer;
import com.sencha.gxt.widget.core.client.event.RowClickEvent;
import com.sencha.gxt.widget.core.client.event.RowMouseDownEvent;
import com.sencha.gxt.widget.core.client.form.SimpleComboBox;
import com.sencha.gxt.widget.core.client.grid.CheckBoxSelectionModel;
import com.sencha.gxt.widget.core.client.grid.ColumnConfig;
import com.sencha.gxt.widget.core.client.grid.ColumnModel;
import com.sencha.gxt.widget.core.client.grid.Grid;
import com.sencha.gxt.widget.core.client.selection.SelectionChangedEvent;
import com.sencha.gxt.widget.core.client.toolbar.LabelToolItem;
import com.sencha.gxt.widget.core.client.toolbar.ToolBar;

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


public class MyPageContents {

public MyPageContents() {
models = new ArrayList<Model>();
models.add(new Model("Foo", "foo"));
models.add(new Model("Bar", "bar"));
models.add(new Model("Bat", "bat"));
models.add(new Model("Baz", "baz"));
}

public Widget getContents() {

IdentityValueProvider<Model> identity = new IdentityValueProvider<Model>();
final CheckBoxSelectionModel<Model> sm = new CheckBoxSelectionModel<Model>(identity);
sm.addSelectionHandler(new SelectionHandler<Model>() {


@Override
public void onSelection(SelectionEvent<Model> event) {
Log.info("selection event: " + event);
Log.info("source: " + event.getSource());
}
});
sm.addSelectionChangedHandler(new SelectionChangedEvent.SelectionChangedHandler<Model>() {


@Override
public void onSelectionChanged(SelectionChangedEvent<Model> event) {


Log.info("selection changed event: " + event);
Log.info("source: " + event.getSource());
List<Model> selectedModels = sm.getSelectedItems();
if (!selectedModels.isEmpty()) {
}
else {
}


Log.info("source of event: " + event.getSource());
}
});


ColumnConfig<Model, String> nameCol = new ColumnConfig<Model, String>(props.name(), 200, "Name");
ColumnConfig<Model, String> symbolCol = new ColumnConfig<Model, String>(props.value(), 100, "Value");


List<ColumnConfig<Model, ?>> ccList = new ArrayList<ColumnConfig<Model, ?>>();
ccList.add(sm.getColumn());
ccList.add(nameCol);
ccList.add(symbolCol);
ColumnModel<Model> cm = new ColumnModel<Model>(ccList);


ListStore<Model> store = new ListStore<Model>(props.key());
store.addAll(this.models);


ContentPanel cp = new ContentPanel();
cp.setHeadingText("CheckBox Grid");
cp.setPixelSize(600, 320);
cp.addStyleName("margin-10");


final Grid<Model> grid = new Grid<Model>(store, cm);
grid.setSelectionModel(sm);
grid.getView().setAutoExpandColumn(nameCol);
grid.setBorders(false);
grid.setStripeRows(true);
grid.setColumnLines(true);
grid.setTrackMouseOver(false);


ToolBar toolBar = new ToolBar();
toolBar.add(new LabelToolItem("Selection Mode: "));


SimpleComboBox<String> type = new SimpleComboBox<String>(new StringLabelProvider<String>());
type.setTriggerAction(ComboBoxCell.TriggerAction.ALL);
type.setEditable(false);
type.setWidth(100);
type.add("Multi");
type.add("Simple");
type.setValue("Multi");
type.addValueChangeHandler(new ValueChangeHandler<String> () {


@Override
public void onValueChange(ValueChangeEvent<String> event) {
boolean simple = event.getValue().equals("Simple");
sm.deselectAll();
sm.setSelectionMode(simple ? Style.SelectionMode.SIMPLE : Style.SelectionMode.MULTI);
}
});
toolBar.add(type);


VerticalLayoutContainer con = new VerticalLayoutContainer();
cp.setWidget(con);


con.add(toolBar, new VerticalLayoutContainer.VerticalLayoutData(1, -1));
con.add(grid, new VerticalLayoutContainer.VerticalLayoutData(1, 1));


return cp;
}

static final ModelProperties props = GWT.create(ModelProperties.class);
static interface ModelProperties extends PropertyAccess<Model> {

@Editor.Path("name")
ModelKeyProvider<Model> key();
ValueProvider<Model, String> name();
ValueProvider<Model, String> value();
}


private final List<Model> models;


static class Model {


public Model(String name, String value) {
this.name = name;
this.value = value;
}


public String getName() {
return this.name;
}


public String getValue() {
return this.value;
}


private String name;
private String value;
}
}

Colin Alworth
27 Jan 2012, 3:20 PM
Yep, that doesn't look right. At some point this might have only been fired from Components, but that certainly isn't the case now.

In the future, especially if the bug isn't quite as obvious as this one, it can be a big help if the code you paste implements EntryPoint, and doesn't make use of other dependencies to compile - I'm not sure where I can get a copy of com.allen_sauer.gwt.log.client.Log.

Thanks for the report - If you need to get access to this property in the meantime, a possible workaround would be to build a JSNI method to read com.google.web.bindery.event.shared.Event.source.

icfantv
27 Jan 2012, 3:48 PM
Oh, sorry! I thought I'd removed all extraneous code. Just remove the Log commands and import and it'll work. Incidentally, it's the gwt-log project, great for client-side logging during development.

I can fix the code and repost if that helps. It was hard to remove everything in the forum editor window. I probably should have pasted into an editor first and cleaned it up.

At this point, I think I only need the selection changed event notification to enable/disable buttons in a toolbar - the log statements were to prove the events were firing due to another issue I was having.

Colin Alworth
27 Jan 2012, 4:48 PM
Nope, the issue is clear, so its just a matter of writing tests, fixing the bug, and getting it reviewed before it will be available in SVN, and the next release.

Thanks for the report - and check out the j.u.Logging emulation stuff, used internally by GWT and GXT - lets you compile out the logging if not needed, and works more or less like any server-side logging framework: http://code.google.com/webtoolkit/doc/latest/DevGuideLogging.html. It doesnt have the category support, but then again, gwt-log keeps all categories at runtime, and has to check each message to see if it gets removed, since those strings can't be known at compile time.

Colin Alworth
27 Jan 2012, 4:50 PM
Okay, the logging output of gwt-log beats the built in support by a mile... though I do wonder what it would take to build a good handler that gives all that and GWT/GXT log support...

icfantv
30 Jan 2012, 9:50 AM
...though I do wonder what it would take to build a good handler that gives all that and GWT/GXT log support...

time. and desire. :-)

personally, i'd like to see SLF4J-style log statements whereby strings are only evaluated should the logger determine that the log statement actually need to be logged. regardless, it's clear the developer put in a decent amount of thought to his framework.

darrellmeyer
30 Jan 2012, 11:45 AM
The bug is now fixed in SVN. getSource changed to return the selection model, not component. Changes will go out in next release.

icfantv
30 Jan 2012, 12:14 PM
Thanks Darrell!

WesleyMoy
28 Mar 2012, 2:53 PM
This bug has been fixed in the Ext GWT 3.0 Release Candidate. Please upgrade your copy of Ext GWT and try your test case again. While we're confident that we've addressed this issue, please reply if you notice any continued problems after upgrading. Again, thanks for taking the time to report this bug.