package fr.lteconsulting.hexa.client.ui.miracle; import java.util.HashMap; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.NativeEvent; import com.google.gwt.dom.client.Node; import com.google.gwt.event.dom.client.MouseDownEvent; import com.google.gwt.event.dom.client.MouseDownHandler; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.FlexTable; import com.google.gwt.user.client.ui.Widget; public class MiracleTable extends FlexTable { Element thead = null; HashMap<Element, Widget> hdrWidgets = new HashMap<Element, Widget>(); public MiracleTable() { super(); } public HandlerRegistration addMouseDownHandler( MouseDownHandler handler ) { sinkEvents( Event.ONMOUSEDOWN ); return addDomHandler( handler, MouseDownEvent.getType() ); } @SuppressWarnings( "deprecation" ) @Override public com.google.gwt.user.client.Element getBodyElement() { int nbc = getElement().getChildCount(); for( int c = 0; c < nbc; c++ ) { Node node = getElement().getChild( c ); if( node.getNodeName().equalsIgnoreCase( "tbody" ) ) return node.<com.google.gwt.user.client.Element>cast(); } return null; } public Element getHeaderElement() { int nbc = getElement().getChildCount(); for( int c = 0; c < nbc; c++ ) { Node node = getElement().getChild( c ); if( node.getNodeName().equalsIgnoreCase( "thead" ) ) return (com.google.gwt.dom.client.Element.as( node )); } return null; } public HdrInFlexTablePrinter getHdrPrinter( int column ) { ensureHeaderCell( column ); return new HdrInFlexTablePrinter( this, column ); } public void setHdrText( int col, String text ) { ensureHeaderCell( col ); Element th = Element.as( thead.getChild( col ) ); clearTH( th, false ); th.setInnerText( text ); } public void setHdrHTML( int col, String html ) { ensureHeaderCell( col ); Element th = Element.as( thead.getChild( col ) ); clearTH( th, false ); th.setInnerHTML( html ); } public void setHdrWidget( int col, Widget widget ) { ensureHeaderCell( col ); Element th = Element.as( thead.getChild( col ) ); clearTH( th, true ); if( widget != null ) { widget.removeFromParent(); // Logical attach. hdrWidgets.put( th, widget ); // Physical attach. DOM.appendChild( th, widget.getElement() ); adopt( widget ); } } private void clearTH( Element th, boolean fClearHTML ) { Widget w = hdrWidgets.remove( th ); if( w != null ) { remove( w ); } else { if( fClearHTML ) th.setInnerHTML( "" ); } } public int getHeaderForEvent( NativeEvent event ) { Element th = getEventTargetHeader( Event.as( event ) ); if( th == null ) return -1; return DOM.getChildIndex( DOM.getParent( th ), th ); } public Element getElementTargetHeader( Element th ) { Element headElem = getHeaderElement(); for( ; th != null; th = DOM.getParent( th ) ) { if( th.getTagName().equalsIgnoreCase( "th" ) ) { Element head = DOM.getParent( th ); if( head == headElem ) { return th; } } // If we run into this table's head, we're out of options. if( th == headElem ) { return null; } } return null; } public Element getEventTargetHeader( Event event ) { return getElementTargetHeader( DOM.eventGetTarget( event ) ); } public Element getRowElement( int row ) { return getRowFormatter().getElement( row ); } private void ensureHeader() { if( thead != null ) return; thead = DOM.createTHead(); getElement().insertBefore( thead, getBodyElement() ); } private void ensureHeaderCell( int col ) { ensureHeader(); while( thead.getChildCount() <= col ) thead.appendChild( DOM.createTH() ); } public static class HdrInFlexTablePrinter implements Printer { final MiracleTable table; final int col; HdrInFlexTablePrinter( MiracleTable table, int col ) { this.table = table; this.col = col; } @Override public void setHTML( String html ) { table.setHdrHTML( col, html ); } @Override public void setText( String text ) { table.setHdrText( col, text ); } @Override public void setWidget( Widget widget ) { table.setHdrWidget( col, widget ); } } }