2010-03-11 8 views
0

J'implémente un aperçu/une info-bulle personnalisée pour un plug-in Eclipse. Il l'a fait en utilisant un Shell dans SWT, en enlevant toutes ses garnitures et en plaçant une boîte de texte à l'intérieur. Cela semble très bien. Cependant maintenant j'ai besoin de disposer du shell quand le curseur sort de la fenêtre shell et j'ai rencontré quelques problèmes:Élimination du shell SWT lorsque le curseur en sort

Est-il logique d'attacher un mousemoveListener au shell? D'abord je faisais cela mais ensuite je me suis rendu compte que cet écouteur ne capture que les mouvements de souris qui se produisent dans le shell. Comment vais-je capturer la souris qui sort de la coquille pour pouvoir en disposer?

Merci et salutations, Krt_Malta

Répondre

2

Joindre un MouseTrackListener avec MouseTrackAdapter en tant qu'auditeur et remplacez la méthode mouseExit().

+0

Merci, c'était génial, ça a fait l'affaire! Maintenant, une technicité: à proprement parler je joins l'écouteur à la zone de texte à l'intérieur du shell et non le shell car je ne reçois pas d'événements générés pour le shell pour une raison que je ne connais pas. Par conséquent, lorsque je passe à la barre de défilement à droite de la zone de texte, le shell est placé depuis que la souris est sortie de la zone de texte. Comment puis-je attacher l'auditeur à la coquille s'il vous plaît? Merci et salutations, Krt_Malta –

+0

Vous pouvez l'attacher directement au shell, shell est aussi un widget. – pajton

0

Comme une autre option, vous pouvez utiliser AbstractHoverInformationControlManager de org.eclipse.jface.text, qui gère tous les détails désagréables (par exemple, lorsque vous Alt + Tab hors de l'application, votre info-bulle disparaît?). Le traitement des événements est pris en charge et vous pouvez vous concentrer sur les choses intéressantes. Un exemple:

import org.eclipse.jface.text.AbstractHoverInformationControlManager; 
import org.eclipse.jface.text.AbstractReusableInformationControlCreator; 
import org.eclipse.jface.text.DefaultInformationControl; 
import org.eclipse.jface.text.IInformationControl; 
import org.eclipse.swt.events.DisposeEvent; 
import org.eclipse.swt.events.DisposeListener; 
import org.eclipse.swt.events.MouseEvent; 
import org.eclipse.swt.graphics.Rectangle; 
import org.eclipse.swt.layout.FillLayout; 
import org.eclipse.swt.widgets.Display; 
import org.eclipse.swt.widgets.Shell; 

public class Example { 
    public static void main(String[] args) { 
     final Display display = new Display(); 
     final Shell shell = new Shell(display); 
     shell.setLayout(new FillLayout()); 
     shell.setSize(200, 200); 

     final ExampleHoverInformationControlManager controlManager = new ExampleHoverInformationControlManager(); 
     // This must be done for the control for which you want the mouse 
     // tracking to be enabled and you possibly want to show hovers. 
     controlManager.install(shell); 

     shell.addDisposeListener(new DisposeListener() { 
      public void widgetDisposed(DisposeEvent e) { 
       controlManager.dispose(); 
      } 
     }); 

     shell.open(); 
     while (!shell.isDisposed()) { 
      if (!display.readAndDispatch()) 
       display.sleep(); 
     } 
     display.dispose(); 
    } 

    private static class ExampleHoverInformationControlCreator extends 
      AbstractReusableInformationControlCreator { 
     @Override 
     protected IInformationControl doCreateInformationControl(Shell parent) { 
      return new DefaultInformationControl(parent); 
     } 
    } 

    private static class ExampleHoverInformationControlManager extends 
      AbstractHoverInformationControlManager { 

     protected ExampleHoverInformationControlManager() { 
      super(new ExampleHoverInformationControlCreator()); 
     } 

     @Override 
     protected void computeInformation() { 
      MouseEvent e = getHoverEvent(); 

      // Just a static example area for simplicity 
      if (e.x >= 0 && e.x < 100 && e.y >= 0 && e.y < 20) { 
       Rectangle area = new Rectangle(0, 0, 100, 20); 
       setInformation(
         "This can be a string or something else, you control it", area); //$NON-NLS-1$ 
       return; 
      } 

      // computeInformation must setInformation in all cases 
      setInformation(null, null); 
     } 
    } 
} 
0

Je viens de découvrir une bien meilleure solution. Cela fonctionne comme ça.

      Shell coverup = new Shell(SWT.NO_TRIM) ; 
      coverup.setBounds(parentComposite.getShell().getBounds()); 

      coverup.moveAbove(Display.getCurrent().getActiveShell()); 
      coverup.setAlpha(13); 
      coverup.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); 




      popupShell = new Shell(coverup, SWT.NO_TRIM); 


      coverup.addMouseMoveListener(new MouseMoveListener() { 
       @Override 
       public void mouseMove(MouseEvent mouseEvent) 
        { 
         System.out.println("coverup - mouse moves"); 
         coverup.close() ; 
        } 
      }); 

Ce qui est en anglais:

Créer une coquille invisible la même taille que la coquille application/parent.

Couvrir la coque parent avec la coque invisible.

Fixation d'une souris Entrez l'écouteur sur la coque de couverture.

Créer le menu contextuel en tant qu'enfant de la coque de couverture Lorsque la souris entre dans le menu contextuel, activez le camouflage. Cela signifie que, peu importe où la souris se trouve après avoir été dans le popup, elle entre dans le shell coverup - et l'événement coverup mouse enter dispose tout.

Nous ne détectons pas lorsque nous quittons la fenêtre contextuelle - nous détectons lorsque la souris pénètre dans les environs.

Bonus supplémentaire: le réglage de l'arrière-plan du coverup à un gris clair, et un faible Alpha, rend l'application entière grisée subtilement - de sorte que l'utilisateur est conscient est désactivé. Petit gotcha: si le shell contextuel n'est pas entièrement contenu dans l'appwindow, où le shell popup sort de l'appwindow, la souris peut s'échapper sans déclencher le shell coverup.

Autre que cela - cela fonctionne très bien!