Is there any way to have a \'Resizable\' panel in GWT.
By resizable I mean that if you you drag on the edge of Panel it can be resized accordingly.
It looks like the GWT-Ext widget extensions contains what you want in its Resizable Panel
For the code above in onBrowserEvent(...) dont forget inserting
event.preventDefault();
or you will have troubles with firefox image dragging!
Just look here: http://code.google.com/p/resizepanel/ There is a fully functional example for FF/IE/GChrome
In modern browsers, you can solve this independently of GWT. Much easier and cleaner. Just use the CSS3 resize property, and specify an overflow value other than the default (visible
).
Note that you'll probably want to override the resize
property for child elements so they don't all inherit resize-handles.
In my case, I have something like this in my .ui.xml
file:
<g:HTMLPanel addStyleNames="myTableContainer">
<g:ScrollPanel>
<g:FlexTable ui:field="myTable"></g:FlexTable>
</g:ScrollPanel>
</g:HTMLPanel>
And something like this in my stylesheet (GWT adds some extra divs, so you may need to adjust selectors to work for your case):
.myTableContainer div {
resize: vertical;
overflow: auto;
}
.myTableContainer div div {
resize: none;
overflow: visible;
}
This gives my FlexTable
a resize handle in the bottom-right corner, like this:
Users can drag the handle down to vertically resize the panel containing my FlexTable
. Of course, instead of vertical
, you can also allow resizing to be horizontal
or both
.
If you prefer doing things programmatically to the UiBinder way, I'm sure you can adapt it by simply adding the appropriate styles to your elements in the code.
Downsides? Doesn't work in IE/Edge (hey, I said modern browsers... and CSS3), but in most others.
Figured it out myself, here is an example:
public class DraggablePanel extends VerticalPanel {
private boolean isBeingDragged = false;
private boolean isBeingMoved = false;
private Element movingPanelElement;
public void setMovingPanelElement(Element movingPanelElement) {
this.movingPanelElement = movingPanelElement;
}
public DraggablePanel() {
super();
DOM.sinkEvents(getElement(), Event.ONMOUSEDOWN | Event.ONMOUSEMOVE
| Event.ONMOUSEUP | Event.ONMOUSEOVER);
}
@Override
public void onBrowserEvent(Event event) {
final int eventType = DOM.eventGetType(event);
if (Event.ONMOUSEOVER == eventType) {
if (isCursorResize(event)) {
getElement().getStyle().setProperty("cursor", "s-resize");
} else if (isCursorMove(event)) {
getElement().getStyle().setProperty("cursor", "move");
} else {
getElement().getStyle().setProperty("cursor", "default");
}
}
if (Event.ONMOUSEDOWN == eventType) {
if (isCursorResize(event)) {
if (!isBeingDragged) {
isBeingDragged = true;
DOM.setCapture(getElement());
}
} else if (isCursorMove(event)) {
DOM.setCapture(getElement());
isBeingMoved = true;
}
} else if (Event.ONMOUSEMOVE == eventType) {
if (!isCursorResize(event) && !isCursorMove(event)) {
getElement().getStyle().setProperty("cursor", "default");
}
if (isBeingDragged) {
int currentY = event.getClientY();
int originalY = getElement().getAbsoluteTop();
if (currentY > originalY) {
Integer height = currentY - originalY;
this.setHeight(height + "px");
}
} else if (isBeingMoved) {
RootPanel.get().setWidgetPosition(this,
event.getClientX(), event.getClientY());
}
} else if (Event.ONMOUSEUP == eventType) {
if (isBeingMoved) {
isBeingMoved = false;
DOM.releaseCapture(getElement());
}
if (isBeingDragged) {
isBeingDragged = false;
DOM.releaseCapture(getElement());
}
}
}
protected boolean isCursorResize(Event event) {
int cursor = event.getClientY();
int initial = getAbsoluteTop();
int height = getOffsetHeight();
return initial + height - 20 < cursor && cursor <= initial + height;
}
protected boolean isCursorMove(Event event) {
int cursor = event.getClientY();
int initial = movingPanelElement.getAbsoluteTop();
int height = movingPanelElement.getOffsetHeight();
return initial <= cursor && cursor <= initial + height;
}
}