Не получайте clickEvent в моей таблице
В моем приложении GWT у меня есть очень раздражающая проблема.
Я собрал несколько собственных виджетов. Одна - это таблица с прокручиваемым содержимым и фиксированным заголовком. Для отображения данных я поместил в нее еще один FlexTable. Теперь, когда я регистрирую ClickHandler в DataFlexTable, я не получаю никакого события там.
Как я могу получить clickEvent в FlexTable внутри scrollTable? Код для ScrollTable и ResizingFunction находится ниже.
Я надеюсь, что кто-то может помочь мне.
Заранее спасибо;)
ScrollTable:
/**
* ScrollTable.java
*
import com.google.gwt.dom.client.Style.TextAlign;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.dom.client.TableCellElement;
import com.google.gwt.dom.client.TableRowElement;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.ComplexPanel;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.Widget;
/**
*
* @author warzok
*/
public class ScrollTable
extends ComplexPanel
implements ResizeableTableInterface
{
private Element mainElem;
private FlexTable headerTable;
private FlexTable dataTable;
private int headerColumn = 0;
private final String DATAATTRIBUTE = "data-column-width";
private Element headerWrapper;
private Element dataWrapper;
private Element absoluteElem;
private com.google.gwt.dom.client.Element mockScrollable;
private ResizeHandler resizeHandler;
/**
*
*/
public ScrollTable()
{
this( new FlexTable(), new FlexTable() );
}
public ScrollTable( FlexTable headerTable, FlexTable dataTable )
{
mainElem = DOM.createDiv();
setElement( mainElem );
mainElem.getStyle().setHeight( 600.0, Unit.PX );
setStylePrimaryName( "scrollFlexTable" );
this.headerTable = headerTable;
this.dataTable = dataTable;
}
/**
* Used to center the headertitle in the middle of column
*/
public void centerHeader()
{
headerTable.getElement().getStyle().setTextAlign( TextAlign.CENTER );
}
public void initTable()
{
// Create the main div container
DOM.setStyleAttribute( mainElem, "padding", "0px" );
DOM.setStyleAttribute( mainElem, "overflow", "hidden" );
DOM.setStyleAttribute( mainElem, "position", "relative" );
// Wrap the table wrappers in another div
absoluteElem = DOM.createDiv();
absoluteElem.getStyle().setProperty( "position", "absolute" );
absoluteElem.getStyle().setProperty( "top", "0px" );
absoluteElem.getStyle().setProperty( "left", "0px" );
absoluteElem.getStyle().setProperty( "width", "100%" );
absoluteElem.getStyle().setProperty( "padding", "0px" );
absoluteElem.getStyle().setProperty( "margin", "0px" );
absoluteElem.getStyle().setProperty( "border", "0px" );
absoluteElem.getStyle().setProperty( "overflow", "hidden" );
absoluteElem.getStyle().setProperty( "height", "100%" );
mainElem.appendChild( absoluteElem );
// Create the table wrapper and spacer
headerWrapper = createWrapper( "headerWrapper" );
dataWrapper = createWrapper( "dataWrapper" );
dataWrapper.getStyle().setProperty( "height", "100%" );
// Create an element to determine the scroll bar width
mockScrollable = com.google.gwt.dom.client.Element.as( dataWrapper.cloneNode( false ) );
mockScrollable.getStyle().setProperty( "position", "absolute" );
mockScrollable.getStyle().setProperty( "top", "0px" );
mockScrollable.getStyle().setProperty( "left", "0px" );
mockScrollable.getStyle().setProperty( "width", "100px" );
mockScrollable.getStyle().setProperty( "height", "100px" );
mockScrollable.getStyle().setProperty( "visibility", "hidden" );
mockScrollable.getStyle().setProperty( "overflow", "scroll" );
mockScrollable.getStyle().setProperty( "zIndex", "-1" );
absoluteElem.appendChild( mockScrollable );
// Adopt the header and data tables into the panel
adoptTable( headerTable, headerWrapper, 0 );
adoptTable( dataTable, dataWrapper, 1 );
dataTable.getElement().getStyle().setProperty( "height", "100%" );
dataTable.getElement().getStyle().setProperty( "paddingBottom", "20px" );
// Add some event handling
sinkEvents( Event.ONMOUSEOUT );
DOM.setEventListener( dataWrapper, this );
DOM.sinkEvents( dataWrapper, Event.ONSCROLL );
getResizeHandler().setCheckElem( dataWrapper );
DOM.sinkEvents( dataWrapper, Event.ONCLICK );
DOM.setEventListener( headerWrapper, this );
DOM.sinkEvents( headerWrapper, Event.ONMOUSEMOVE | Event.ONMOUSEDOWN | Event.ONMOUSEUP
| Event.ONCLICK );
}
@Override
public void onBrowserEvent( Event event )
{
adjustSize();
boolean callSuper = getResizeHandler().onBrowserEvent( event );
if ( callSuper )
{
super.onBrowserEvent( event );
}
}
/**
* Adopt a table into this {@link AbstractScrollTable} within its wrapper.
*
* @param table
* the table to adopt
* @param wrapper
* the wrapper element
* @param index
* the index to insert the wrapper in the main element
*/
private void adoptTable( Widget table, Element wrapper, int index )
{
DOM.insertChild( absoluteElem, wrapper, index );
add( table, wrapper );
}
/**
* @param styleName
* @return
*/
private Element createWrapper( String styleName )
{
Element elm = DOM.createDiv();
elm.setClassName( styleName );
return elm;
}
public FlexTable getHeader()
{
return headerTable;
}
public void setHeader( FlexTable header )
{
this.headerTable = header;
}
public void addHeaderWidget( Widget widget )
{
headerTable.setWidget( 0, headerColumn, widget );
headerColumn++;
}
public void addDataWidget( int row, int column, Widget widget )
{
dataTable.setWidget( row, column, widget );
}
/**
*
*/
private void adjustColumnSize()
{
for ( int i = 0; i < dataTable.getCellCount( 4 ); i++ )
{
Element elm = dataTable.getCellFormatter().getElement( 4, i );
dataTable.getColumnFormatter().getElement( i )
.setAttribute( DATAATTRIBUTE, "" + elm.getClientWidth() );
dataTable.getColumnFormatter().setWidth( i,
dataTable.getColumnFormatter().getElement( i ).getAttribute( DATAATTRIBUTE ) + "px" );
headerTable.getColumnFormatter().setWidth( i,
dataTable.getColumnFormatter().getElement( i ).getAttribute( DATAATTRIBUTE ) + "px" );
}
}
public void adjustSize()
{
DOM.setElementAttribute( dataTable.getElement(), DATAATTRIBUTE, "" + dataTable.getOffsetWidth() );
adjustColumnSize();
resizeHeader();
}
protected void resizeHeader()
{
for ( int i = 0; i < dataTable.getCellCount( 0 ); i++ )
{
String width = dataTable.getColumnFormatter().getElement( i ).getAttribute( DATAATTRIBUTE );
headerTable.getColumnFormatter().setWidth( i, width );
}
}
public FlexTable getDataTable()
{
return dataTable;
}
public void setDataTable( FlexTable dataTable )
{
this.dataTable = dataTable;
}
public FlexTable getHeaderTable()
{
return headerTable;
}
public void setHeaderTable( FlexTable headerTable )
{
this.headerTable = headerTable;
}
public Element getHeaderWrapper()
{
return headerWrapper;
}
public void setHeaderWrapper( Element headerWrapper )
{
this.headerWrapper = headerWrapper;
}
@Override
public void resizeColumn( int column, int columnWidth )
{
headerTable.getColumnFormatter().getElement( column )
.setAttribute( "width", columnWidth + "px" );
dataTable.getColumnFormatter().getElement( column ).setAttribute( "width", columnWidth + "px" );
}
@Override
public boolean hasToChangeCurser( TableCellElement tableCellElement, TableRowElement tr )
{
return tr == getTableHeadElement();
}
private TableRowElement getTableHeadElement()
{
return headerTable.getRowFormatter().getElement( 0 ).cast();
}
@Override
public boolean hasSelectedElement( TableRowElement tr )
{
return tr == null;
}
protected ResizeHandler getResizeHandler()
{
if ( resizeHandler == null )
{
resizeHandler = new ResizeHandler( this );
}
return this.resizeHandler;
}
}
Вот код для ResizeHandler:
public class ResizeHandler
{
private int mouseDownX;
private boolean mouseDown;
private int columnWidth;
private TableCellElement headerElem;
private int column;
private ResizeMode resizeMode;
private ResizeableTableInterface resizeableTable;
private Element checkElem;
/**
* @param resizeableTable
*/
public ResizeHandler( ResizeableTableInterface resizeableTable )
{
super();
this.resizeableTable = resizeableTable;
}
/**
* Hier wird versuch zu resizen
*
* @param event
* das Event
* @return true wenn die superMethode gerufen werden soll
*/
public boolean onBrowserEvent( Event event )
{
if ( event.getType().equals( "change" ) )
{
return true;
}
boolean eventMouseUp = event.getType().equals( "mouseup" );
boolean eventClick = event.getType().equals( "click" );
boolean eventMouseDown = event.getType().equals( "mousedown" );
boolean eventMouseMove = event.getType().equals( "mousemove" );
if ( checkElem != null )
{
if ( eventClick && event.getCurrentEventTarget().equals( checkElem ) )
{
return true;
}
}
if ( eventMouseUp )
{
mouseDownX = -1;
mouseDown = false;
}
if ( resizeMode == ResizeMode.RESIZING && eventClick )
{
resizeMode = ResizeMode.ENDING;
}
TableCellElement tableCellElement = findNearestParentCell( (Element) event.getEventTarget()
.cast() );
if ( tableCellElement == null )
{
return true;
}
Element trElem = tableCellElement.getParentElement();
if ( trElem == null )
{
return true;
}
TableRowElement tr = TableRowElement.as( trElem );
if ( resizeableTable.hasSelectedElement( tr ) )
{
return true;
}
if ( resizeableTable.hasToChangeCurser( tableCellElement, tr ) )
{
changeCurser( event, tableCellElement, eventMouseDown, eventMouseMove );
}
else
{
return true;
}
if ( headerElem != null && eventMouseMove && mouseDown )
{
int move = event.getClientX() - mouseDownX;
@SuppressWarnings ( "hiding")
int columnWidth = this.columnWidth + move;
if ( columnWidth > 24 )
{
resizeableTable.resizeColumn( column, columnWidth );
resizeMode = ResizeMode.RESIZING;
}
}
if ( resizeMode != ResizeMode.RESIZING && resizeMode != ResizeMode.ENDING && eventClick )
{
return true;
}
else if ( resizeMode == ResizeMode.ENDING )
{
resizeMode = ResizeMode.NO;
}
return false;
}
/**
* Verändert das Aussehen des Cursers
*/
protected void changeCurser( Event event, TableCellElement tableCellElement,
boolean eventMouseDown, boolean eventMouseMove )
{
int mouseX = event.getClientX();
int right = tableCellElement.getAbsoluteLeft() + tableCellElement.getOffsetWidth();
if ( !mouseDown && eventMouseDown )
{
if ( mouseX <= right && mouseX >= right - 10 )
{
headerElem = tableCellElement;
column = tableCellElement.getCellIndex();
mouseDownX = event.getClientX();
mouseDown = true;
columnWidth = headerElem.getOffsetWidth();
}
}
else if ( eventMouseMove )
{
if ( mouseDown || mouseX <= right && mouseX >= right - 10 )
{
tableCellElement.getStyle().setCursor( Cursor.COL_RESIZE );
}
else
{
tableCellElement.getStyle().setCursor( Cursor.AUTO );
}
}
}
/**
* Diese Methode ist 1 zu 1 aus der Oberklasse übernommen. Nicht ändern!!!
*/
private TableCellElement findNearestParentCell( Element elem )
{
while ( (elem != null) && (elem != resizeableTable.getElement()) )
{
String tagName = elem.getTagName();
if ( "td".equalsIgnoreCase( tagName ) || "th".equalsIgnoreCase( tagName ) )
{
return elem.cast();
}
elem = elem.getParentElement();
}
return null;
}
public Element getCheckElem()
{
return checkElem;
}
public void setCheckElem( Element checkElem )
{
this.checkElem = checkElem;
}
}
Код ResizeableTableInterface:
public interface ResizeableTableInterface
{
public com.google.gwt.user.client.Element getElement();
boolean hasToChangeCurser(TableCellElement tableCellElement, TableRowElement tr );
/**
* @param column
* @param columnWidth
*/
public void resizeColumn( int column, int columnWidth );
/**
* @param tr
* @return
*/
public boolean hasSelectedElement( TableRowElement tr );
}
ResizeMode:
public enum ResizeMode
{
NO,
RESIZING,
ENDING
}