Pergunta
Existe alguma maneira de ter um painel 'Resizable' em GWT.
Por média redimensionável I que se arrasta na borda do painel pode ser redimensionada em conformidade.
Solução
Descobri-lo eu mesmo, aqui está um exemplo:
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;
}
}
Outras dicas
Basta olhar aqui: http://code.google.com/p/resizepanel/ Há um exemplo totalmente funcional para FF / IE / Gchrome
Em navegadores modernos, você pode resolver este independentemente do GWT. Muito mais fácil e mais limpo. Basta usar o CSS3 resize
propriedade, e especifique um overflow
valor diferente do padrão (visible
).
Note que você provavelmente vai querer substituir a propriedade resize
para elementos filho para que eles não todos herdar redimensionamento-alças.
No meu caso, eu tenho algo parecido com isso no meu arquivo .ui.xml
:
<g:HTMLPanel addStyleNames="myTableContainer">
<g:ScrollPanel>
<g:FlexTable ui:field="myTable"></g:FlexTable>
</g:ScrollPanel>
</g:HTMLPanel>
E algo como este em minha folha de estilo (GWT adiciona algumas divs extras, então você pode precisar de ajustar os seletores para trabalhar para o seu caso):
.myTableContainer div {
resize: vertical;
overflow: auto;
}
.myTableContainer div div {
resize: none;
overflow: visible;
}
Isto dá meu FlexTable
uma alça de redimensionamento no canto inferior direito, como esta:
Os usuários podem arrastar a alça para baixo para redimensionar verticalmente o painel contendo meu FlexTable
. É claro que, em vez de vertical
, você pode também permitir o redimensionamento para ser horizontal
ou both
.
Se você prefere fazer as coisas de forma programática para o caminho UiBinder, eu tenho certeza que você pode adaptá-lo simplesmente adicionando os estilos adequados aos seus elementos no código.
Desvantagens? Não funciona no IE / Edge (hey, eu disse modernos navegadores ... e CSS3 ), mas em a maioria dos outros .
Parece que o GWT-Ext Widget de extensões contém o que você quer em sua Painel Resizable
Para o código acima em onBrowserEvent (...) Não se esqueça de inserir
event.preventDefault();
ou você terá problemas com firefox imagem arrastando!