Domanda
Esiste un modo per avere un pannello "Ridimensionabile" in GWT.
Per ridimensionamento intendo che se trascini sul bordo del Pannello, puoi ridimensionarlo di conseguenza.
Soluzione
Capito da solo, ecco un esempio:
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;
}
}
Altri suggerimenti
Guarda qui: http://code.google.com/p/resizepanel/ C'è un esempio completamente funzionale per FF / IE / GChrome
Nei browser moderni, puoi risolverlo indipendentemente da GWT. Molto più semplice e pulito. Usa semplicemente la proprietà CSS3 resize
, e specifica un valore overflow
diverso da quello predefinito ( visibile
).
Nota che probabilmente vorrai sovrascrivere la proprietà resize
per gli elementi figlio in modo che non ereditino tutti i ridimensionamenti.
Nel mio caso, ho qualcosa di simile nel mio file .ui.xml
:
<g:HTMLPanel addStyleNames="myTableContainer">
<g:ScrollPanel>
<g:FlexTable ui:field="myTable"></g:FlexTable>
</g:ScrollPanel>
</g:HTMLPanel>
E qualcosa del genere nel mio foglio di stile (GWT aggiunge alcuni div extra, quindi potrebbe essere necessario regolare i selettori in modo che funzionino per il tuo caso):
.myTableContainer div {
resize: vertical;
overflow: auto;
}
.myTableContainer div div {
resize: none;
overflow: visible;
}
Questo dà al mio FlexTable
una maniglia di ridimensionamento nell'angolo in basso a destra, in questo modo:
Gli utenti possono trascinare la maniglia verso il basso per ridimensionare verticalmente il pannello contenente il mio FlexTable
. Ovviamente, invece di vertical
, puoi anche consentire il ridimensionamento in orizzontale
o entrambi
.
Se preferisci fare le cose in modo programmatico nel modo UiBinder, sono sicuro che puoi adattarlo semplicemente aggiungendo gli stili appropriati ai tuoi elementi nel codice.
I lati negativi? Non funziona in IE / Edge (ehi, ho detto browser moderni ... e CSS3 ), ma in molti altri .
Sembra che le estensioni del widget GWT-Ext contengano ciò che desideri its Pannello ridimensionabile
Per il codice sopra in onBrowserEvent (...) non dimenticare di inserire
event.preventDefault();
o avrai problemi con il trascinamento delle immagini di Firefox!