Problem with deleteRow in FlexTable

886 views
Skip to first unread message

guille

unread,
May 26, 2006, 4:04:01 PM5/26/06
to Google Web Toolkit
Version: gwt-windows-1.0.21
When I delete a table row with the removeRow method, sometimes the
following exception is thrown (it doesn't happen all the times, seems a
ramdom behaviour).

[ERROR] Uncaught exception escaped
java.lang.RuntimeException: JavaScript method
'@com.google.gwt.user.client.impl.DOMImpl::removeChild(Lcom/google/gwt/user/client/Element;Lcom/google/gwt/user/client/Element;)'
threw an exception
at
com.google.gwt.dev.shell.ie.ModuleSpaceIE6.invokeNative(ModuleSpaceIE6.java:394)
at
com.google.gwt.dev.shell.ie.ModuleSpaceIE6.invokeNativeVoid(ModuleSpaceIE6.java:283)
at
com.google.gwt.dev.shell.JavaScriptHost.invokeNativeVoid(JavaScriptHost.java:127)
at
com.google.gwt.user.client.impl.DOMImpl.removeChild(DOMImpl.java:222)
at com.google.gwt.user.client.DOM.removeChild(DOM.java:716)
at
com.google.gwt.user.client.ui.HTMLTable.removeWidget(HTMLTable.java:957)
at
com.google.gwt.user.client.ui.HTMLTable.internalClearCell(HTMLTable.java:829)
at
com.google.gwt.user.client.ui.HTMLTable.cleanCell(HTMLTable.java:915)
at
com.google.gwt.user.client.ui.HTMLTable.removeRow(HTMLTable.java:882)
at
com.google.gwt.user.client.ui.FlexTable.removeRow(FlexTable.java:166)
Caused by: com.google.gwt.core.client.JavaScriptException: JavaScript
Error exception: Argumento no válido.
at
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:274)
at
com.google.gwt.dev.shell.ModuleSpace.createJavaScriptException(ModuleSpace.java:267)
at
com.google.gwt.dev.shell.ie.ModuleSpaceIE6.exceptionCaught(ModuleSpaceIE6.java:105)
at
com.google.gwt.dev.shell.JavaScriptHost.exceptionCaught(JavaScriptHost.java:31)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at
com.google.gwt.dev.shell.StaticJavaDispatch.callMethod(StaticJavaDispatch.java:45)

I think is a bug in GWT. Thanks

java_coder

unread,
Jun 16, 2006, 12:13:31 AM6/16/06
to Google Web Toolkit
I have the same problem. Do you know of any workaround or fix ??.
Thanks

java_coder

unread,
Jun 17, 2006, 12:36:53 AM6/17/06
to Google Web Toolkit
I figured out a work around. Used Grid instead.

use grid.resizeRows(newRowCount);

Feng Jiang

unread,
Jun 19, 2006, 12:36:20 PM6/19/06
to Google Web Toolkit
I did not got the same problem, but I found another probable bug of
FlexTable about removeRow too.

If I remove the 2nd-last row from FlexTable, the cells of last row are
NULL. The real last row will not be moved up automatically. Then when I
use getWidget(lastIndex, 0) to access the widiget following the removed
row, GWT said outof bounds...

sac

unread,
Jun 28, 2006, 5:36:02 AM6/28/06
to Google Web Toolkit
hi
i am also facing the same problem when we want to delete teh row
from the following
code.
for(int i=0;i<keys.length;i++){
flexTable.removeRow(keys[i]);
}

Javascript Error :

[ERROR] Uncaught exception escaped
java.lang.RuntimeException: JavaScript method
'@com.google.gwt.user.client.impl.DOMImpl::removeChild(Lcom/google/gwt/user/client/Element;Lcom/google/gwt/user/client/Element;)'
threw an exception
at
com.google.gwt.dev.shell.ie.ModuleSpaceIE6.invokeNative(ModuleSpaceIE6.java:394)
at
com.google.gwt.dev.shell.ie.ModuleSpaceIE6.invokeNativeVoid(ModuleSpaceIE6.java:283)
at
com.google.gwt.dev.shell.JavaScriptHost.invokeNativeVoid(JavaScriptHost.java:127)
at
com.google.gwt.user.client.impl.DOMImpl.removeChild(DOMImpl.java:222)
at com.google.gwt.user.client.DOM.removeChild(DOM.java:716)
at
com.google.gwt.user.client.ui.HTMLTable.removeWidget(HTMLTable.java:957)
at
com.google.gwt.user.client.ui.HTMLTable.internalClearCell(HTMLTable.java:829)
at
com.google.gwt.user.client.ui.HTMLTable.cleanCell(HTMLTable.java:915)
at
com.google.gwt.user.client.ui.HTMLTable.removeRow(HTMLTable.java:882)
at
com.google.gwt.user.client.ui.FlexTable.removeRow(FlexTable.java:166)
Caused by: com.google.gwt.core.client.JavaScriptException: JavaScript

Error exception: Invalid argument.


at
com.google.gwt.dev.shell.ModuleSpace.createJavaScriptException(ModuleSpace.java:267)
at
com.google.gwt.dev.shell.ie.ModuleSpaceIE6.exceptionCaught(ModuleSpaceIE6.java:105)
at
com.google.gwt.dev.shell.JavaScriptHost.exceptionCaught(JavaScriptHost.java:31)
at

com.google.gwt.dev.shell.StaticJavaDispatch.callMethod(StaticJavaDispatch.java:45)
at
com.google.gwt.dev.shell.ie.IDispatchProxy.invoke(IDispatchProxy.java:127)
at
com.google.gwt.dev.shell.ie.IDispatchImpl.Invoke(IDispatchImpl.java:199)
at
com.google.gwt.dev.shell.ie.IDispatchImpl.method6(IDispatchImpl.java:108)
at
org.eclipse.swt.internal.ole.win32.COMObject.callback6(COMObject.java:117)
at
org.eclipse.swt.internal.ole.win32.IDispatch.Invoke(IDispatch.java:64)
at
org.eclipse.swt.ole.win32.OleAutomation.invoke(OleAutomation.java:487)

mP

unread,
Jun 30, 2006, 6:33:15 AM6/30/06
to Google Web Toolkit
A few (all?) HTMLTable have the same problem which is related to
mapping widgets to html elements. The way to fix the problem is to
delete the last row whilst looping.

A simple answer is to simply delete the last row until there are no
more rows. THis works.

ste...@gmail.com

unread,
Jul 14, 2006, 3:38:11 AM7/14/06
to Google Web Toolkit
it seems that removeRow() is buggy.
setWidget(row,col,w) will put widget to a map with key "row-col", when
a row is remove before the last row, the keys in map will be invalid.

here is codes to fix this bug. hope GWT can fix this bug in next
release.

public static void removeRow(FlexTable grid, int row) {
Map map = new HashMap();
for (Iterator iter = grid.iterator(); iter.hasNext();) {
Widget w = (Widget) iter.next();
int rowIndex = getRowIndex(w);
if (rowIndex > row){
map.put(myComputeKey(rowIndex-1, getColumnIndex(w)), w);
}
}
for (Iterator iter = map.values().iterator(); iter.hasNext();) {
Widget w = (Widget) iter.next();
grid.remove(w);
}
grid.removeRow(row);
for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) {
Map.Entry entry = (Map.Entry) iter.next();
long key = ((Long)entry.getKey()).longValue();
grid.setWidget((int)(key>>>32), (int)(key & 0xFFFF), (Widget)
entry.getValue());
}
}

private static Object myComputeKey(int row, int column) {
long r = ((long)row<<32) + column;
return new Long(r);
}

private static int getRowIndex(Widget w) {
Element td = DOM.getParent(w.getElement());
Element tr = DOM.getParent(td);
return DOM.getChildIndex(DOM.getParent(tr), tr);
}

private static int getColumnIndex(Widget w) {
Element td = DOM.getParent(w.getElement());
Element tr = DOM.getParent(td);
return DOM.getChildIndex(tr, td);
}

andreit

unread,
Jul 14, 2006, 12:36:36 PM7/14/06
to Google Web Toolkit
I have slightly differend (and hopefully simple) solution for this
problem.
Just change / override method computeKey() in HTMLTable:

private static final String REF_ATTR_NAME = "ref";
private static int _widgetCount;

protected String computeKey(int row, int column) {
// return row + "-" + column;
Element tr = DOM.getChild(getBodyElement(), row);
Element td = DOM.getChild(tr, column);
String ref = DOM.getAttribute(td, REF_ATTR_NAME);
if(ref == null) {
ref = String.valueOf(++_widgetCount);
DOM.setAttribute(td, REF_ATTR_NAME, ref);
}
return ref;
}

ste...@gmail.com

unread,
Jul 15, 2006, 10:36:40 AM7/15/06
to Google Web Toolkit
this patch works fine in shell, but got error out of shell. the int to
long force convertion seemed not work. so, just use int as key and
assert row<2exp16.

ste...@gmail.com wrote:
> it seems that removeRow() is buggy.
> setWidget(row,col,w) will put widget to a map with key "row-col", when
> a row is remove before the last row, the keys in map will be invalid.
>
> here is codes to fix this bug. hope GWT can fix this bug in next
> release.
>
> public static void removeRow(FlexTable grid, int row) {
> Map map = new HashMap();
> for (Iterator iter = grid.iterator(); iter.hasNext();) {
> Widget w = (Widget) iter.next();
> int rowIndex = getRowIndex(w);
> if (rowIndex > row){
> map.put(myComputeKey(rowIndex-1, getColumnIndex(w)), w);
> }
> }
> for (Iterator iter = map.values().iterator(); iter.hasNext();) {
> Widget w = (Widget) iter.next();
> grid.remove(w);
> }
> grid.removeRow(row);
> for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) {
> Map.Entry entry = (Map.Entry) iter.next();
> long key = ((Long)entry.getKey()).longValue();
> grid.setWidget((int)(key>>>32), (int)(key & 0xFFFF), (Widget)
> entry.getValue());

int key = ((Integer)entry.getKey()).intValue();
grid.setWidget(key>>>16), key & 0xFFFF, (Widget)


entry.getValue());
> }
> }
>
> private static Object myComputeKey(int row, int column) {
> long r = ((long)row<<32) + column;
> return new Long(r);

int r = (row<<16) + column;
return new Integer(r);

om.obosit

unread,
Jul 26, 2006, 4:43:18 PM7/26/06
to Google Web Toolkit
Here is the problem:

FlexTable tries to remove previous widget before adding a new one in a
new cell.
So it searches for the old one.

Old one is seeked in a Map by key "$row-$col". So if you remove a row,
some widgets will
have a decremented row index. This however do not change in the Map
that. They still have
the old key that they were added this.

Check this code insite HTMLTabel ( inherited by FlexTable)

protected boolean internalClearCell(int row, int column, Element td) {
Widget widget = (Widget) widgetMap.get(computeKey(row, column));
if (widget != null) {
// If there is a widget, remove it.
removeWidget(row, column, widget);
return true;
} else {
// Otherwise, simply clear whatever text and/or HTML may be
there.
DOM.setInnerHTML(td, "");
return false;
}
}


Here is the solution :


class GTable extends FlexTable{
public void removeRow(int row){
int total = this.getRowCount();
int rowsBellow = total - row - 1;

Widget [][]toMove = new Widget[rowsBellow][];

//store old widgets
for (int i = row+1; i < total; i ++){
int rCols = this.getCellCount(i);
Widget []wRow = new Widget[rCols];

for (int j = 0; j < rCols; j++){
Widget w = this.getWidget(i, j);
if (w != null)
this.remove(w);
wRow[j] = w;
}
toMove[i-row-1] = wRow;
}

super.removeRow(row);

//restore old widgets
for (int i = row; i < total-1; i ++){
int rCols = this.getCellCount(i);
Widget []wRow = toMove[i-row];

for (int j = 0; j < rCols; j++){
Widget w = wRow[j];
if (w != null)
this.setWidget(i, j, w);
}
}
}
}

Enjoy..

Let me know if your suffering is over :) (really :) )

EsOsO

unread,
Aug 11, 2006, 5:08:48 AM8/11/06
to Google Web Toolkit

om.obosit wrote:

> class GTable extends FlexTable{
> public void removeRow(int row){
> int total = this.getRowCount();
> int rowsBellow = total - row - 1;
>
> Widget [][]toMove = new Widget[rowsBellow][];

Hi om.obosit I'm still suffering the problem; when i try to remove a
row i get a NegativeArraySizeException caused by getRowCount that
returns a 0 row instead of 2 (total rows i've in the table).

Polina

unread,
Aug 23, 2006, 11:17:09 AM8/23/06
to Google Web Toolkit
Hi

also still have the problem with the GTable fix:

ERROR] Uncaught exception escaped
java.lang.IndexOutOfBoundsException: Row 4 does not exist, row size is
4
at
com.google.gwt.user.client.ui.HTMLTable.checkRowBounds(HTMLTable.java:891)
at
com.google.gwt.user.client.ui.HTMLTable.checkCellBounds(HTMLTable.java:869)
at com.google.gwt.user.client.ui.HTMLTable.getText(HTMLTable.java:557)
at
ru.lanit.btp.rft.gui.client.TransferChannels.setClickedChannelFieldsFromTable(TransferChannels.java:242)
at
ru.lanit.btp.rft.gui.client.TransferChannels.showChannelForEdit(TransferChannels.java:202)
at
ru.lanit.btp.rft.gui.client.TransferChannels.access$8(TransferChannels.java:197)
at
ru.lanit.btp.rft.gui.client.TransferChannels$5.onClick(TransferChannels.java:184)
at
com.google.gwt.user.client.ui.ClickListenerCollection.fireClick(ClickListenerCollection.java:36)
at
com.google.gwt.user.client.ui.Hyperlink.onBrowserEvent(Hyperlink.java:120)
at com.google.gwt.user.client.DOM.dispatchEventImpl(DOM.java:950)

Thanx,
Polina

r.cha...@gmail.com

unread,
Sep 5, 2006, 5:00:30 AM9/5/06
to Google Web Toolkit
Hi,

Iam facing the same problem with FlexTable. I see that if i remove a
row say "2" out of 10 rows and then try to access
flextable.getRow(2,0).. I see that the widget returned is "null". And
it also looses track of the last row(since it decreases the rowCount to
9)

Any solution?

Baloni

unread,
Sep 6, 2006, 11:55:52 AM9/6/06
to Google Web Toolkit
I think that there is allways an easier solution. And here is the same.
If you want to remove all rows from (Flex)Table use this code:

public void baloniClearData(FlextTable grid){
for (int i=grid.getRowCount()-1; i>=0;i--){
grid.removeRow(i);
}
}

Table is heap in gwt. LIFO...

Vivian Li

unread,
Sep 7, 2006, 3:40:49 AM9/7/06
to Google-We...@googlegroups.com

Hi,
  There used to be a bug in the way GWT mapped HTML elements to Widgets, but as of GWT1.1.10, the hash keys for Widgets are calculated differently, so there should no longer be any problem.

  However, FlexTable works just like any other collection such as java.util.Vector in that, if you remove elements in a loop, you must do it in reverse order.

  If you still find you are having a problem, such as a null returned when you didn't expect it (I could not reproduce this problem in a test case), please post some code which reproduces the problem. Also, it would be good to know which GWT version you are using.

-Vivian

Baloni

unread,
Sep 7, 2006, 9:09:59 AM9/7/06
to Google Web Toolkit
Maybe this is not a bug (I've never tought this way). It's just the
FlexTable's way holding data. I like it. Vivian thnx for explanation.

Reply all
Reply to author
Forward
0 new messages