2014-06-19 14 views
5

Sto cercando di aggiungere alcuni ascoltatori del mouse ai sottomenu/menu a cascata del MenuBar di GWT. Purtroppo non riesco ad accedere direttamente al sottomenu popuppanel: il metodo per farlo (getPopup()) è privato. E non puoi accedervi tramite la riflessione a causa del modo in cui compila GWT.Come posso accedere a un pannello popup/sottomenu della barra dei menu di GWT?

L'aggiunta di un listener del mouse alla barra del menu principale (per rilevare quando il mouse si trova all'interno dei limiti della barra dei menu) è stata semplice e intuitiva. Ma non riesco a capire un modo per aggiungere un listener del mouse per dire quando il mouse si trova in uno dei sottomenu a cascata.

Quello che sto facendo è questo:

com.google.gwt.user.client.ui.MenuBar myMainBar = new MenuBar(); 
myMainBar.addDomHandler(menuHoverOutHandler, MouseOutEvent.getType()); 
myMainBar.addDomHandler(menuHoverOverHandler, MouseOverEvent.getType()); 

Questa grande opera per l'attuale GWT MenuBar. Quando topo, il mouseOverEvent si innesca. Quando topo il mouse, si avvia il mouse su EventEut.

Il problema è che se apro un sottomenu dalla barra dei menu principale, il mouse in quel menu attiverà anche MouseOutEvent. Ho bisogno che non lo faccia.

Quando dico sottomenu voglio dire qualcosa di simile a quelli visti qui:

http://www.gwtproject.org/javadoc/latest/com/google/gwt/user/client/ui/MenuBar.html

Quindi, fintanto che io sono nel bar 'principale' che elenca Stile, frutta, e Termine, il mouse gli eventi lo riconoscono.

Ma se si scende al sottomenu che dice Grassetto, Corsivo, Altro, gli eventi del mouse credono che abbia lasciato completamente la barra dei menu. Ho bisogno di un modo per determinare se il mouse si trova all'interno di uno di questi sottomenu. (O che un sottomenu di questa barra del menu principale è aperto da qualche parte)

Non si può semplicemente fare

myMainBar.getPopup() 

e aggiungere gli ascoltatori alla conseguente PopupPanel come getPopup è privato. Sto cercando un altro modo per arrivare a MenuBar.popup

Sembra che non ci sia alcun metodo per sapere se uno dei sottomenu è aperto, il che è un po 'imbarazzante per me. Sembra esserci una frustrante mancanza di capacità di interagire con questi sottomenu, e mi chiedo se mi manca qualcosa.

+1

come posso accedere al codice? :) Per favore puoi condividere qualche pezzo di codice che ti dice cosa stai facendo? – Braj

+0

Ho aggiunto del codice che mostra quello che sto facendo e qualche spiegazione aggiuntiva. Grazie per aver dato un occhiata! – user2197116

+0

Sei riuscito a risolvere questo? Sto affrontando esattamente questo problema al momento ... – Sleeper9

risposta

4

Se si aggiunge uno MouseOverHandler e MouseOutHandler a ciascuno dei sottomenu, diversamente dalla barra dei menu principale, dovrebbe fare ciò che si desidera.

Ad esempio:

MenuBar subMenu = new MenuBar(true); 
subMenu.addItem("Item1", new Command() { 
    @Override 
    public void execute() { 
     Window.alert("Item1 clicked"); 
    } 
}); 

subMenu.addDomHandler(new MouseOverHandler() { 
    @Override 
    public void onMouseOver(MouseOverEvent arg0) { 
     Window.alert("SubMenu over!"); 
    } 
}, MouseOverEvent.getType()); 

subMenu.addDomHandler(new MouseOutHandler() { 
    @Override 
    public void onMouseOut(MouseOutEvent arg0) { 
     Window.alert("SubMenu out!"); 
    } 
}, MouseOutEvent.getType()); 

MenuBar mainMenu = new MenuBar(); 
mainMenu.addItem("SubMenu", subMenu); 

RootPanel.get().add(mainMenu); 
+1

OP potrebbe usare questo per impostare un flag e fare in modo che ignori MouseOutEvent nella barra dei menu principale se il tuo sottomenu è 'saltato fuori'. – Brian

2

Il tuo problema è legato alla logica degli eventi è di per sé: si vorrebbe avere un nuovo tipo di evento che attiva solo quando il mouse si sposta fuori del menu e non lo fa se si sposta tra i menu.

Per fare ciò è possibile aggiungere il codice che ascolta sia il mouse che il mouse e compilare le informazioni disponibili per capire cosa sta succedendo.

Si può essere certi di eseguire un codice dopo tutti gli eventi passati utilizzando un frammento Scheduler

Scheduler.get().scheduleDeferred(new Command() { 
    public void execute() { 
     //check all what happened in a static shared variable, there was a mouse out, was there a mouse over after it? if yes then stay calm; If there wasn't, then trigger a MouseOutOfAllMenus event 
    } 
    }); 

questo codice dovrebbe essere messo all'interno della onMouseOut(), e un altro codice che aggiorna solo lo stato dell'istanza classe statica deve essere inserito nello onMouseOver(). Puoi essere certo che il codice nel Scheduler.execute() verrà eseguito dopo l'esecuzione dello onMouseOver() grazie al meccanismo di rinvio pianificato. Quindi quando verrai a controllare lo stato, sarà dopo che il mouse è entrato in un altro menu (o non lo ha fatto); quindi puoi sapere se l'utente ha davvero lasciato le voci del menu o se è entrato in un sottomenu.

Ultima raccomandazione: eseguire questo codice in una classe separata in modo da poter disporre di questo menu arricchito come componente per un utilizzo futuro. Inoltre, tieni presente che mantenendo le cose separate puoi testare ed eseguire scenari di test automatizzati molto più facilmente.

Spero che hai capito tutto quello che ho cercato di spiegare, se non, sentitevi liberi di commentare, farò del mio meglio per rispondergli

migliori saluti,

ps: quando dico un'istanza statica stato, è solo per la facilità di comprensione. Si raccomanda naturalmente di evitare l'uso statico per poter avere più di un menu nella stessa applicazione. Per statico intendo: un'istanza accessibile a tutti i componenti

Problemi correlati