Question

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.

Was it helpful?

Solution

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;
    }
}

OTHER TIPS

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:

Resize handle

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.

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!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top