Ratn Deo--Dev
Ratn Deo--Dev

Reputation: 1038

GWT resizable panel

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.

Upvotes: 8

Views: 13808

Answers (5)

Ratn Deo--Dev
Ratn Deo--Dev

Reputation: 1038

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

Upvotes: 7

Amos M. Carpenter
Amos M. Carpenter

Reputation: 4958

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.

Upvotes: 2

dmitrynikolaev
dmitrynikolaev

Reputation: 9132

For the code above in onBrowserEvent(...) dont forget inserting

 event.preventDefault();

or you will have troubles with firefox image dragging!

Upvotes: 0

berlindev
berlindev

Reputation: 1751

Just look here: http://code.google.com/p/resizepanel/ There is a fully functional example for FF/IE/GChrome

Upvotes: 2

Jarrod Dixon
Jarrod Dixon

Reputation: 15807

It looks like the GWT-Ext widget extensions contains what you want in its Resizable Panel

Upvotes: 0

Related Questions