Tuesday, September 17, 2013

Rich editor in eclipse RCP (Part2)


A few month ago I built a rich editor for eclipse based on SWT browser.
I use this implementation from this time and now I want to integrate it in an EMF (EEF generated) GUI.
In this context this widget needs a focus managment but the SWT Browser does not manage those events (See Javadoc (event) ).
In my case I decide to rely on TyneMCE events managment (blur and focus), then react on those events invoking a BrowserFunction that allows javascript to java communication. In java side  the Browser fonction notify an internal listener.

Rely on tinyMce events



those event are identified bty name : blur and focus. To be able to react to those events, add to your tiny init (JS) :
setup : function(ed) {

   ...

   ed.onInit.add(function(ed) {

     if (tinymce.isIE) {

       tinymce.dom.Event.add(ed.getWin(), 'focus', function(e) {

           evt_focusGained();

       });

       tinymce.dom.Event.add(ed.getWin(), 'blur', function(e) {

           evt_focusLost();

       });

   } else {

       tinymce.dom.Event.add(ed.getDoc(), 'focus', function(e) {

           evt_focusGained();

       });

       tinymce.dom.Event.add(ed.getDOc(), 'blur', function(e) {

           evt_focusLost();

       });

   }

   });

  },

Usage of BrowserFuntion


Browser function allow communication from javascript to java. Excerpt : "Instances of this class represent java-side "functions" that are invokable from javascript. Browser clients define these functions by subclassing BrowserFunction and overriding its function(Object[]) method. This method will be invoked whenever javascript running in the Browser makes a call with the function's name."

So I add in the completed method of the SWT browser progressListener :

browser.addProgressListener(new ProgressListener() {

 public void changed(ProgressEvent event) {

 }

 public void completed(ProgressEvent event) {

  // used for setEditorText

  completed = true;

  loadEditorText((String) browser.getData("htmlcontent"));

  new BrowserFunction(browser, "evt_focusLost") {

   public Object function(Object[] arguments) {

    notifyListenersFocusLost();

    return null;

   }

  };

  new BrowserFunction(browser, "evt_focusGained") {

   public Object function(Object[] arguments) {

    notifyListenersFocusGained();

    return null;

   }

  };

 }

});

In this implementation, you could see notifyListenersFocusLost() and notifyListenersFocusGained(). Those two methods relate to two listeners similar implementation.

public interface TinyFocusLostListener {

 public abstract void focusLost();

}

private List listenersTinyFocusLost = new ArrayList();



public void addTinyFocusLostListener(TinyFocusLostListener listenerValue) {

 listenersTinyFocusLost.add(listenerValue);

}

// Warning UI action use asyncexec in eclipse

private void notifyListenersFocusLost() {

 Display.getCurrent().asyncExec(new Runnable() {

  public void run() {

   for (TinyFocusLostListener listener : listenersTinyFocusLost) {

    listener.focusLost();

   }

  }

 });

}

finally on Java side

myTinyIntegrationInstance.addTinyFocusLostListener(new TinyFocusLostListener() {

 @Override

 public void focusLost() {

  //Add your code here

  }

 }

});