From: jprocter Date: Mon, 17 Jan 2011 13:59:00 +0000 (+0000) Subject: refactored javascript callback to parent class. X-Git-Tag: Release_2_7~299 X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=b97119fa4abbda0ef3d8e6e36f4634a06d79d411;p=jalview.git refactored javascript callback to parent class. --- diff --git a/src/jalview/javascript/JSFunctionExec.java b/src/jalview/javascript/JSFunctionExec.java new file mode 100644 index 0000000..9674926 --- /dev/null +++ b/src/jalview/javascript/JSFunctionExec.java @@ -0,0 +1,217 @@ +package jalview.javascript; + +import java.net.URL; +import java.util.Vector; + +import netscape.javascript.JSException; +import netscape.javascript.JSObject; +import jalview.bin.JalviewLite; + +public class JSFunctionExec implements Runnable +{ + JalviewLite jvlite; + + public JSFunctionExec(JalviewLite applet) + { + jvlite = applet; + } + + private static Vector jsExecQueue; + + private static Thread executor = null; + + public static void stopQueue() + { + if (jsExecQueue != null) + { + Vector q = jsExecQueue; + jsExecQueue = null; + q.removeAllElements(); + executor.notify(); + executor = null; + } + } + + public void run() + { + while (jsExecQueue != null) + { + if (jsExecQueue.size() > 0) + { + Runnable r = (Runnable) jsExecQueue.elementAt(0); + jsExecQueue.removeElementAt(0); + try + { + r.run(); + } catch (Exception ex) + { + ex.printStackTrace(); + } catch (Error ex) + { + ex.printStackTrace(); + } + } + else + { + try + { + synchronized (jsExecQueue) + { + jsExecQueue.wait(1000); + } + } catch (Exception ex) + { + } + ; + } + } + + } + + /** + * execute a javascript callback asynchronously + * + * @param _listener + * @param objects + * @throws Exception + */ + public void executeJavascriptFunction(final String _listener, + final Object[] objects) throws Exception + { + executeJavascriptFunction(false, _listener, objects); + } + + /** + * execute a javascript callback synchronously or asynchronously + * + * @param async + * - true to execute asynchronously (do this for gui events) + * @param _listener + * - javascript function + * @param objects + * - arguments + * @throws Exception + * - only if call is synchronous + */ + public void executeJavascriptFunction(final boolean async, + final String _listener, Object[] arguments) throws Exception + { + final Object[] objects = new Object[arguments != null ? arguments.length + : 0]; + if (arguments != null) + { + System.arraycopy(arguments, 0, objects, 0, arguments.length); + } + final Exception[] jsex = new Exception[1]; + Runnable exec = new Runnable() + { + public void run() + { + try + { + JSObject scriptObject = null; + try + { + scriptObject = JSObject.getWindow(jvlite.applet); + } catch (Exception ex) + { + } + ; + if (scriptObject != null) + { + scriptObject.call(_listener, objects); + } + } catch (Exception jex) + { + // squash any malformedURLExceptions thrown by windows/safari + if (!(jex instanceof java.net.MalformedURLException)) + { + if (jvlite.debug) + { + System.err.println(jex); + } + if (jex instanceof netscape.javascript.JSException) + { + jsex[0] = (netscape.javascript.JSException) jex; + if (jvlite.debug) + { + System.err.println("Falling back to javascript: url call"); + } + StringBuffer sb = new StringBuffer("javascript:" + _listener + + "("); + for (int i = 0; objects != null && i < objects.length; i++) + { + if (i > 0) + { + sb.append(","); + } + sb.append("\""); + // strip out nulls and complex objects that we can't pass this + // way. + if (objects[i] != null + && !(objects[i].getClass().getPackage().getName() + .indexOf("jalview") == 0)) + { + sb.append(objects[i].toString()); + } + sb.append("\""); + } + sb.append(")"); + if (jvlite.debug) + { + System.err.println(sb.toString()); + } + // alternate + URL url = null; + try + { + url = new URL(sb.toString()); + jvlite.getAppletContext().showDocument(url); + jex = null; + } catch (Exception uex) + { + jex = uex; + } + } + if (jex != null) + { + if (async) + { + jex.printStackTrace(); + } + else + { + jsex[0] = new Exception(jex); + } + } + ; + } + + } + } + }; + if (async) + { + if (JSFunctionExec.executor == null) + { + JSFunctionExec.jsExecQueue = new Vector(); + JSFunctionExec.executor = new Thread(new JSFunctionExec(jvlite)); + executor.start(); + } + synchronized (jsExecQueue) + { + jsExecQueue.addElement(exec); + jsExecQueue.notify(); + } + } + else + { + exec.run(); + if (jsex[0] != null) + { + throw (jsex[0]); + } + } + } + +} diff --git a/src/jalview/javascript/JsSelectionSender.java b/src/jalview/javascript/JsSelectionSender.java index 8b2ba2c..d948363 100644 --- a/src/jalview/javascript/JsSelectionSender.java +++ b/src/jalview/javascript/JsSelectionSender.java @@ -1,8 +1,6 @@ package jalview.javascript; -import java.util.ArrayList; -import java.util.Enumeration; - +import java.net.URL; import jalview.appletgui.AlignFrame; import jalview.appletgui.AlignViewport; import jalview.bin.JalviewLite; @@ -11,10 +9,9 @@ import jalview.datamodel.SequenceGroup; import jalview.structure.SelectionSource; import netscape.javascript.JSObject; -public class JsSelectionSender implements +public class JsSelectionSender extends JSFunctionExec implements jalview.structure.SelectionListener, JsCallBack { - JalviewLite jvlite; AlignFrame _af; @@ -23,7 +20,7 @@ public class JsSelectionSender implements public JsSelectionSender(JalviewLite jvlite, AlignFrame af, String listener) { - this.jvlite = jvlite; + super(jvlite); _af = af; _listener = listener; } @@ -52,6 +49,8 @@ public class JsSelectionSender implements .getSequenceSetId()); for (int a = 0; a < aps.length; a++) { + System.out.println("Selection: testing source alignPanel : " + + aps[a].getName()); if (aps[a].av == source) { src = aps[a].alignFrame; @@ -64,12 +63,12 @@ public class JsSelectionSender implements System.err.println("Unhandled selection source !"); return; } - JSObject jsoWindow = JSObject.getWindow(jvlite); String[] seqs = new String[] {}; String[] cols = new String[] {}; - int strt = 0, end = src.alignPanel.av.getAlignment().getWidth(); + int strt = 0, end = (src == null) ? -1 : src.alignPanel.av + .getAlignment().getWidth(); if (seqsel != null && seqsel.getSize() > 0) { seqs = new String[seqsel.getSize()]; @@ -81,18 +80,24 @@ public class JsSelectionSender implements { strt = seqsel.getStartRes(); } - if (end > seqsel.getEndRes()) + if (end==-1 || end > seqsel.getEndRes()) { end = seqsel.getEndRes(); } } if (colsel != null && colsel.size() > 0) { + if (end == -1) + { + end = colsel.getMax() + 1; + } cols = new String[colsel.getSelected().size()]; int d = 0, r = -1; for (int i = 0; i < cols.length; i++) { - cols[i] = ""+(1+((Integer)colsel.getSelected().elementAt(i)).intValue()); + cols[i] = "" + + (1 + ((Integer) colsel.getSelected().elementAt(i)) + .intValue()); } } else @@ -107,26 +112,27 @@ public class JsSelectionSender implements } System.err.println("Relaying selection to jsfunction:" + _listener); - jsoWindow.call( - _listener, - new Object[] - { src, setid, jvlite.arrayToSeparatorList(seqs), - jvlite.arrayToSeparatorList(cols) }); + executeJavascriptFunction( _listener, + new Object[] + { src, setid, jvlite.arrayToSeparatorList(seqs), + jvlite.arrayToSeparatorList(cols) }); } catch (Exception ex) { System.err .println("Jalview Javascript exec error: Couldn't send selection message using function '" + _listener + "'"); + ex.printStackTrace(); if (ex instanceof netscape.javascript.JSException) { - System.err.println("Javascript Exception: "+((netscape.javascript.JSException)ex).getMessage()); + System.err.println("Javascript Exception: " + + ((netscape.javascript.JSException) ex).getCause() + .toString()); } - else { - ex.printStackTrace(); - }; + } } + @Override public AlignFrame getAlignFrame() { diff --git a/src/jalview/javascript/MouseOverListener.java b/src/jalview/javascript/MouseOverListener.java index 462092e..c2ae6ef 100644 --- a/src/jalview/javascript/MouseOverListener.java +++ b/src/jalview/javascript/MouseOverListener.java @@ -6,9 +6,8 @@ import jalview.datamodel.SequenceI; import jalview.structure.VamsasListener; import netscape.javascript.JSObject; -public class MouseOverListener implements VamsasListener,JsCallBack +public class MouseOverListener extends JSFunctionExec implements VamsasListener,JsCallBack { - JalviewLite jvlite; AlignFrame _af; String _listener; SequenceI last = null; @@ -25,8 +24,7 @@ public class MouseOverListener implements VamsasListener,JsCallBack last = seq; i = index; try { - JSObject js = JSObject.getWindow(jvlite); - js.call(_listener, new Object[] { _af, seq.getDisplayId(false), ""+(1+i)}); + executeJavascriptFunction(_listener, new Object[] { _af, seq.getDisplayId(false), ""+(1+i)}); } catch (Exception ex) { @@ -35,16 +33,14 @@ public class MouseOverListener implements VamsasListener,JsCallBack { System.err.println("Javascript Exception: "+((netscape.javascript.JSException)ex).getMessage()); } - else { - ex.printStackTrace(); - }; + ex.printStackTrace(); } } } public MouseOverListener(JalviewLite applet, AlignFrame af, String listener) { - this.jvlite = applet; + super(applet); _af = af; _listener = listener; }