looking for simple example applet/javascript communication

406 ogledov
Preskoči na prvo neprebrano sporočilo

Stephen Bannasch

neprebran,
21. feb. 2012, 17:27:2321. 2. 12
do netlog...@googlegroups.com
I'm looking for any simple examples of communication between A NetLogo applet and JavaScript running in a browser.

Examples of what I'd like to see (in order of presumed complexity):

Initiated from JavaScript:

1) read value from JavaScript of NetLogo global variable
2) click button in NetLogo from JavaScript
3) set value of slider in NetLogo from JavaScript

Initiated from NetLogo:

1) update a JavaScript variable when a NetLogo variable is changed
2) update a JavaScript array when a new value is added to a NetLogo list

I suspect that communication initiated in NetLogo and sending data to JavaScript may not be possible now.

What I'd like to be able to do is take data being displayed in a NetLogo grapher and display it in a JavaScript grapher.

Here's are a couple of example of html5 based grapher that I'd like to adapt for this purpose:

http://bl.ocks.org/1182434
http://lab.dev.concord.org/examples/surface-temperature/surface-temperature.html

I'd also like to be able to reset, start, and stop the model from JavaScript.

Corey Brady

neprebran,
21. feb. 2012, 19:50:3421. 2. 12
do Stephen Bannasch, netlogo-devel
Hi Stephen

The way that I've done this is to create a class that extends JApplet,

have it embed an org.nlogo.lite.AppletPanel, and mimic the startup stuff that the org.nlogo.lite.Applet does

Have this class expose some public methods that give pass-through access to AppletPanel's
report() and command()
functions

through liveconnect, this will give you 1 and 3, and could give you the EFFECT of 2, though not for a 'forever' button.


i haven't needed the other direction yet myself, but i think that it could work to create a kind of listener construct in your Applet, and then pass on events that you can get by implementing org.nlogo.api.NetLogoListener and registering for events.

i can send you code for the javascript-to-java direction, but it's all been rather sketchy experimental stuff and i'm not sure it is robust.

best,
--c

Stephen Bannasch

neprebran,
21. feb. 2012, 20:27:5521. 2. 12
do Corey Brady, netlogo-devel
At 6:50 PM -0600 2/21/12, Corey Brady wrote:
>Hi Stephen
>
>The way that I've done this is to create a class that extends JApplet,
>
>have it embed an org.nlogo.lite.AppletPanel, and mimic the startup stuff that the org.nlogo.lite.Applet does
>
>Have this class expose some public methods that give pass-through access to AppletPanel's
>report() and command()
>functions
>
>through liveconnect, this will give you 1 and 3, and could give you the EFFECT of 2, though not for a 'forever' button.
>
>
>i haven't needed the other direction yet myself, but i think that it could work to create a kind of listener construct in your Applet, and then pass on events that you can get by implementing org.nlogo.api.NetLogoListener and registering for events.
>
>i can send you code for the javascript-to-java direction, but it's all been rather sketchy experimental stuff and i'm not sure it is robust.

Corey,

I thought I might be able to read the value of a NetLogo global variable just using liveconnect -- but haven't tried yet.

I would love to look at your code if it's available under an open source license.

Corey Brady

neprebran,
21. feb. 2012, 22:06:2721. 2. 12
do Stephen Bannasch, netlogo-devel
hi stephen

i will make a github project and let you know when it's set up

btw -- i made this sketch in the course of thinking about how to make a WISE4 "step" based on a netlogo applet. i know you and others at concord have done a bunch of work with WISE so maybe there's some possible teaming up there...

in that context, i wanted some scriptable interactions, but also wanted to be able to save the state ( so, you'll see a sketch of doing export-world to a string that will then be read by javascript...

more soon,
-c

Seth Tisue

neprebran,
22. feb. 2012, 08:11:1722. 2. 12
do netlog...@googlegroups.com
>>>>> "Stephen" == Stephen Bannasch <stephen....@deanbrook.org> writes:

Stephen> Initiated from NetLogo:
Stephen> 1) update a JavaScript variable when a NetLogo variable is
Stephen> changed 2) update a JavaScript array when a new value is added
Stephen> to a NetLogo list
Stephen> I suspect that communication initiated in NetLogo and sending
Stephen> data to JavaScript may not be possible now.

The solution plan Corey describes seems to me like it would work.

Another approach would be to make an extension. The disadvantage is
that code in the model would have to explicitly call the extension
primitives, rather than communication being automatically triggered by
button presses and variable changes and so forth. But it might be
easier to get this way up and running since it wouldn't require making a
custom NetLogo jar, just an ordinary extension.

--
Seth Tisue | Northwestern University | http://tisue.net
lead developer, NetLogo: http://ccl.northwestern.edu/netlogo/

Stephen Bannasch

neprebran,
23. feb. 2012, 12:21:0123. 2. 12
do Seth Tisue, netlog...@googlegroups.com
At 8:11 AM -0500 2/22/12, Seth Tisue wrote:
> >>>>> "Stephen" == Stephen Bannasch <stephen....@deanbrook.org>writes:
>
> Stephen> Initiated from NetLogo:
> Stephen> 1) update a JavaScript variable when a NetLogo variable is
> Stephen> changed 2) update a JavaScript array when a new value is added
> Stephen> to a NetLogo list
> Stephen> I suspect that communication initiated in NetLogo and sending
> Stephen> data to JavaScript may not be possible now.
>
>The solution plan Corey describes seems to me like it would work.
>
>Another approach would be to make an extension. The disadvantage is
>that code in the model would have to explicitly call the extension
>primitives, rather than communication being automatically triggered by
>button presses and variable changes and so forth. But it might be
>easier to get this way up and running since it wouldn't require making a
>custom NetLogo jar, just an ordinary extension.

I'm looking at this code at the beginning of org.nlogo.lite.Applet and wondering if I can get access to the panel property and from this get access to global variables in the workspace?

I presume the answer is no (otherwise you and Corey might have mentioned it).

In OTrunk we embed an nlogo.lite.interface.component which gives us much more access to the internals.

public class Applet extends JApplet
implements Events.CompiledEvent.Handler, ScalaObject
{
private AppletPanel panel;

public void init()
{
VMCheck.detectBadJVMs();
EventQueue..MODULE$.invokeLater(new Runnable() {
public void run() { Applet.this.init2(); null; Applet.this.go(null); }
});
}

public void destroy() {
RuntimeErrorDialog.deactivate();
}
public AppletPanel panel() {
return this.panel; }
public void panel_$eq(AppletPanel paramAppletPanel) { this.panel = paramAppletPanel; }

Corey Brady

neprebran,
23. feb. 2012, 13:17:3923. 2. 12
do Stephen Bannasch, Seth Tisue, netlog...@googlegroups.com
hi - -

if memory serves me right, my original reason for re-producing the Applet's structure in my JApplet was that I thought that the panel member variable was not visible to me as a subclass.

HOWEVER, i think that either this has changed since then (maybe even, been converted to scala?) or i didn't understand how scala worked.

TODAY when i make a subclass of Applet against the 5.0 jar, eclipse tells me that panel is not visible, BUT if i do

this.panel(),

i do get an instance of AppletPanel, as i'd hoped.

this doesn't completely solve the problem, as i can't call all of the methods on this AppletPanel that i think i should be able to.

that is, even though i am able to call report()
https://github.com/NetLogo/NetLogo/blob/master/src/main/org/nlogo/lite/AppletPanel.scala#L178

on this instance, i cannot call

command()
https://github.com/NetLogo/NetLogo/blob/master/src/main/org/nlogo/lite/AppletPanel.scala#L143

or
commandLater()
https://github.com/NetLogo/NetLogo/blob/master/src/main/org/nlogo/lite/AppletPanel.scala#L159

Seth --- can you illuminate?

Thanks!
-c

--c

Seth Tisue

neprebran,
23. feb. 2012, 13:18:2923. 2. 12
do netlog...@googlegroups.com
>>>>> "Stephen" == Stephen Bannasch <stephen....@deanbrook.org> writes:

Stephen> I'm looking at this code at the beginning of
Stephen> org.nlogo.lite.Applet and wondering if I can get access to the
Stephen> panel property and from this get access to global variables in
Stephen> the workspace?

It looks you have an old version. In 5.0 it's public. In the Scala
code we have:

class Applet extends JApplet ... {
var panel: AppletPanel ...

public is the default access level in Scala.

And, javap shows:

% javap -classpath /Applications/NetLogo\ 5.0/NetLogo.jar org.nlogo.lite.Applet | grep -w panel
public org.nlogo.lite.AppletPanel panel();

Seth Tisue

neprebran,
23. feb. 2012, 13:31:4223. 2. 12
do netlog...@googlegroups.com
>>>>> "Corey" == Corey Brady <cbr...@inquirelearning.com> writes:

Corey> TODAY when i make a subclass of Applet against the 5.0 jar,
Corey> eclipse tells me that panel is not visible, BUT if i do
Corey> this.panel(),

The field itself is private, the getter method is public. So you need
the parens. (The Scala compiler only ever generates private fields.)

Corey> this doesn't completely solve the problem, as i can't call all
Corey> of the methods on this AppletPanel that i think i should be able
Corey> to.

Corey> that is, even though i am able to call report()
Corey> https://github.com/NetLogo/NetLogo/blob/master/src/main/org/nlogo/lite/AppletPanel.scala#L178
Corey> on this instance, i cannot call
Corey> command()
Corey> https://github.com/NetLogo/NetLogo/blob/master/src/main/org/nlogo/lite/AppletPanel.scala#L143
Corey> or commandLater()
Corey> https://github.com/NetLogo/NetLogo/blob/master/src/main/org/nlogo/lite/AppletPanel.scala#L159
Corey> Seth --- can you illuminate?

Sorry, not sure what's going on here. Maybe you could show your code
and the error message you're getting? Maybe try compiling the code
from the command line instead of through Eclipse?

The methods certainly exist:

% javap -classpath /Applications/NetLogo\ 5.0/NetLogo.jar org.nlogo.lite.AppletPanel | grep report
public java.lang.Object report(java.lang.String) throws org.nlogo.api.CompilerException;

% javap -classpath /Applications/NetLogo\ 5.0/NetLogo.jar org.nlogo.lite.AppletPanel | grep command
public void command(java.lang.String) throws org.nlogo.api.CompilerException;
public void commandLater(java.lang.String) throws org.nlogo.api.CompilerException;

Corey Brady

neprebran,
23. feb. 2012, 13:38:3123. 2. 12
do Seth Tisue, Stephen Bannasch, netlog...@googlegroups.com
the code is pretty simple:


import org.nlogo.api.CompilerException;
import org.nlogo.lite.Applet;

public class TestApplet extends Applet {

public void command( String cmd )
{
try {
Object o = panel().report(cmd);
panel().command( cmd );
panel().commandLater( cmd );
} catch (CompilerException e) {
e.printStackTrace();
}
}
}



Eclipse says that "the method command(String) is undefined for the type AppletPanel"  [same for commandLater(String)]

Is this what you're seeing, too, Stephen?

I have a meeting now, but I will try compiling from the command line this afternoon.

Best,
-C

Stephen Bannasch

neprebran,
23. feb. 2012, 14:17:1623. 2. 12
do Seth Tisue, netlog...@googlegroups.com
At 1:18 PM -0500 2/23/12, Seth Tisue wrote:
>>>>> "Stephen" == Stephen Bannasch <stephen....@deanbrook.org>writes:

 Stephen> I'm looking at this code at the beginning of
 Stephen> org.nlogo.lite.Applet and wondering if I can get access to the
 Stephen> panel property and from this get access to global variables in
 Stephen> the workspace?

It looks you have an old version.

I was looking directly at the code using the JD-GUI Java decompiler in this jar distributed with NetLogo 5.0:

$ ls -l /Users/stephen/Applications/NetLogo\ 5.0/NetLogoLite.jar

3592038 Feb 16 13:41 /Users/stephen/Applications/NetLogo 5.0/NetLogoLite.jar

P6811AE42.png

Seth Tisue

neprebran,
23. feb. 2012, 15:42:4323. 2. 12
do netlog...@googlegroups.com
>>>>> "Stephen" == Stephen Bannasch <stephen....@deanbrook.org> writes:

Stephen> I was looking directly at the code using the JD-GUI Java
Stephen> decompiler in this jar distributed with NetLogo 5.0:

It just dawned on me what's going on here.

You and Corey are looking at NetLogoLite.jar, I (as the transcripts I
posted show) am looking at NetLogo.jar.

NetLogoLite.jar has been through ProGuard to make it smaller. All sorts
of stuff gets stripped out when that happens. ProGuard doesn't just
remove whole unused classes, it removes individual unused methods, too.

While you're just trying to get something up and running, I'd suggest
you just use NetLogo.jar. It always includes everything.

Later, if you need to actually ship your thing to lots of users and you
care about jar size in that context, well, one of us could update the
ProGuard config so that it produces a NetLogoLite.jar that has the
particular thing you need. That config is in
https://github.com/NetLogo/NetLogo/blob/master/project/build/proguard/lite.txt

Hope that clears this up,

Corey Brady

neprebran,
23. feb. 2012, 15:49:2823. 2. 12
do netlogo-devel
AH. ok. so, switching to NetLogo.jar rather than Lite.jar does in fact clear up the compile errors for me.

NOW --> Stephen, your idea (extending org.nlogo.lite.Applet) is much better than what I had done before.
So I'm going to switch over to doing that.
That will take out most of my code, actually :) but if there's anything interesting left, I'll still start a github repo for it.

Best,
-c

Corey Brady

neprebran,
23. feb. 2012, 18:49:5823. 2. 12
do netlogo-devel
Stephen --

There's not much of interest here, but I've created a repo:

g...@github.com:cbradyatinquire/NetLogoAppletLiveConnect.git

The simple subclass of org.nlogo.lite.Applet is there, along with an HTML page that uses it.
(possibly most valuable for a copy-pasteable list of the .jars that NetLogo.jar references -- some of these are surely omissible but i just referenced them all :) )

-C

Stephen Bannasch

neprebran,
23. feb. 2012, 22:36:0323. 2. 12
do netlogo-devel
At 5:49 PM -0600 2/23/12, Corey Brady wrote:
>Stephen --
>
>There's not much of interest here, but I've created a repo:
>
>g...@github.com:cbradyatinquire/NetLogoAppletLiveConnect.git
>
>The simple subclass of org.nlogo.lite.Applet is there, along with an HTML page that uses it.
>(possibly most valuable for a copy-pasteable list of the .jars that NetLogo.jar references -- s

Cool, I got it working locally.

I added a shell script to build the wisenetlogo.jar, simplified the applet jar requirements to run (only the NetLogo jar isrequired).

I added the NetLogo and scala-library jars to the repo. This is annoying because they are large but this also makes this repo self-contained. The compilation and testing the example can now all be done with the resources in the repo.

I only needed to specify a class path to the NetLogo jar to compile -- but without the scala-library jar also available there were compilation errors.

These changes are available in a pull request.

Stephen Bannasch

neprebran,
23. feb. 2012, 22:56:1523. 2. 12
do netlogo-devel
Turns out the scala-library jar appears to be required at applet runtime also.

Combined the NetLogo and scala-library jars are over 14MB uncompressed. This is way too big to deploy to classrooms in any
scale.

Corey Brady

neprebran,
23. feb. 2012, 23:16:1823. 2. 12
do Stephen Bannasch, netlogo-devel
agreed - i am assuming seth meant for deployment scale to be approximately 1 before fixing the NetLogoLite.jar problem :)
-c

Stephen Bannasch

neprebran,
2. mar. 2012, 12:13:302. 3. 12
do Corey Brady, netlogo-devel
At 10:16 PM -0600 2/23/12, Corey Brady wrote:
>agreed - i am assuming seth meant for deployment scale to be approximately 1 before fixing the NetLogoLite.jar problem :)
>-c

Hi Seth,

Is there a way I can make a new version of the netlog lite jar that I can use practically as when running netlogo as an applet?

Or is that something I need to rely on you doing sometime in the future? If this is the case do any of your funded projectshavethis as a goal? And if this is also true do you have any sense of a timeline?

Seth Tisue

neprebran,
2. mar. 2012, 18:08:032. 3. 12
do netlogo-devel
On Fri, Mar 2, 2012 at 12:13 PM, Stephen Bannasch
<stephen....@deanbrook.org> wrote:
> Is there a way I can make a new version of the netlog lite jar that I can use practically as when running netlogo as an applet?

Yes. Assuming you can build NetLogo, then:

emacs project/build/proguard/lite.txt
# make your edits, forcing whatever methods you want kept to be kept
rm NetLogoLite.jar
make NetLogoLite.jar

This will re-run ProGuard with your new config.

Optional final step: send pull request.

> do any of your funded projectshavethis as a goal? And if this is also true do you have any sense of a timeline?

Yes, if you do nothing it will probably happen here anyway eventually.
No, not one I'd want you counting on.

Stephen Bannasch

neprebran,
5. mar. 2012, 00:45:335. 3. 12
do netlogo-devel
Corey and Seth,

Here's an example where I am saving and restoring model state from an applet running using JUST an un-modified NetLogoLite.jar.

https://github.com/stepheneb/netlogo-gcc

I'm using one of Bob's latest Global Climate change models.

See: https://github.com/stepheneb/netlogo-gcc/blob/master/netlogo.html#L46-70

Actually ... saving the state works ... but restoring the state doesn't yet. it's probably just errors in my use of Java,
which I'm not completely familiar with.

I'm trying to access the world.importWorld() function with this signature:

public strictfp void importWorld(Importer.ErrorHandler paramErrorHandler,
ImporterUser paramImporterUser, Importer.StringReader paramStringReader,
BufferedReader paramBufferedReader)

I'm getting these errors:

Uncaught Error: java.lang.IllegalArgumentException: No method found
matching name importWorld and arguments
[com.sun.java.browser.plugin2.liveconnect.v1.JavaNameSpace,
com.sun.java.browser.plugin2.liveconnect.v1.JavaNameSpace, java.io.StringReader,
com.sun.java.browser.plugin2.liveconnect.v1.JavaNameSpace]
Uncaught Error: Error calling method on NPObject.

Once we get saving and restoring the state working properly I'd like to know how to click buttons and set the slider from
JavaScript.

Then I'd like to know how to read a NetLogo variable from JavaScript.

Stephen Bannasch

neprebran,
5. mar. 2012, 00:58:455. 3. 12
do netlogo-devel
At 12:45 AM -0500 3/5/12, Stephen Bannasch wrote:
>Corey and Seth,
>
>Here's an example where I am saving and restoring model state from an applet running using JUST an un-modified NetLogoLite.jar.
>
> https://github.com/stepheneb/netlogo-gcc

...

>Once we get saving and restoring the state working properly I'd like to know how to click buttons and set the slider from JavaScript.
>
>Then I'd like to know how to read a NetLogo variable from JavaScript.


For example when I get the state of the World there are a series of GLOBALS:

min-pxcor -24
max-pxcor 24
min-pycor -15
max-pycor 15
perspective 0
subject nobody
nextIndex 57
directed-links ""NEITHER""
ticks 0
albedo 0.4
earth-top -7
model_speed 17
num-clouds 0
num-co2 0
sky-top 10
starter 0
sun-brightness 1.2
temperature 12"

I can read world.maxPxcor():

$ world = applet.panel().workspace().org$nlogo$lite$LiteWorkspace$$world;
$ world.maxPxcor()
=> 24

But that's using a method.

How can I for example read the value of "temperature" or "albedo"?

Seth Tisue

neprebran,
5. mar. 2012, 09:04:535. 3. 12
do netlogo-devel
>>>>> "Stephen" == Stephen Bannasch <stephen....@deanbrook.org> writes:

>> Here's an example where I am saving and restoring model state from
>> an applet running using JUST an un-modified NetLogoLite.jar.

Note that for this to work on a server, you'll need
NetLogoLite.jar.pack.gz as well. As a bonus, this will greatly speed
loading. See <https://github.com/NetLogo/NetLogo/issues/95>

Stephen> For example when I get the state of the World there are a
Stephen> series of GLOBALS: [...]
Stephen> How can I for example read the value of "temperature" or
Stephen> "albedo"?

Here's a Scala REPL session demonstrating the needed calls:

% cd /Applications/NetLogo\ 5.0
% scala -Yrepl-sync -Djava.awt.headless=true -classpath NetLogo.jar
Welcome to Scala version 2.9.1.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_29).

scala> import org.nlogo.headless.HeadlessWorkspace
import org.nlogo.headless.HeadlessWorkspace

scala> val ws = HeadlessWorkspace.newInstance
ws: org.nlogo.headless.HeadlessWorkspace = org.nlogo.headless.HeadlessWorkspace@3522971b

scala> ws.open("models/Sample Models/Earth Science/Climate Change.nlogo")

scala> val globals = ws.world.program.globals
globals: java.util.List[String] = [SUN-BRIGHTNESS, ALBEDO, SKY-TOP, EARTH-TOP, TEMPERATURE]

scala> ws.command("setup")

scala> ws.world.observer.getVariable(globals.indexOf("ALBEDO"))
res8: java.lang.Object = 0.6

scala> ws.world.observer.getVariable(globals.indexOf("TEMPERATURE"))
res9: java.lang.Object = 12.0

scala> ws.world.observer.variables
res4: Array[java.lang.Object] = Array(1.0, 0.6, 17.0, 0.0, 12.0)

Seth Tisue

neprebran,
5. mar. 2012, 09:59:235. 3. 12
do netlogo-devel
>>>>> "Stephen" == Stephen Bannasch <stephen....@deanbrook.org> writes:

Stephen> I'm trying to access the world.importWorld() function with
Stephen> this signature:

Stephen> public strictfp void importWorld(Importer.ErrorHandler
Stephen> paramErrorHandler, ImporterUser paramImporterUser,
Stephen> Importer.StringReader paramStringReader, BufferedReader
Stephen> paramBufferedReader)

It's a lot easier to use the importWorld method on Workspace, which
takes many fewer parameters. There's one version that reads from
the filesystem, which you don't want; instead, use:

void importWorld(java.io.Reader reader)
throws java.io.IOException;

It should work to stuff your string into a java.io.StringReader which
you then pass in.

Stephen> Once we get saving and restoring the state working properly
Stephen> I'd like to know how to click buttons and set the slider from
Stephen> JavaScript.

Setting the variable associated with a slider will move the slider.

Do you actually need to press a button, so the user will see it being
pressed, or do you just need to run the same code that a button press
would run? The latter is easy, just run e.g. commands("setup") on the
workspace. If you need the actual button to go down, that's also
possible; let me know.

Corey Brady

neprebran,
5. mar. 2012, 10:21:535. 3. 12
do Seth Tisue, netlogo-devel
Hi Stephen
That applet subclass that I set up the github report for does export and import world as well as command and report. If u discover better ways I'd be very interested. Best --C
--
Sent from my Android phone with K-9 Mail. Please excuse my brevity.

Stephen Bannasch

neprebran,
6. mar. 2012, 01:17:116. 3. 12
do Seth Tisue, netlogo-devel
Thanks, I'm now able to read the values of global variables.


Still need to get Restore State, Start and Stop, and Rest model working.

P59A4AF0C.png

Stephen Bannasch

neprebran,
6. mar. 2012, 14:49:576. 3. 12
do Seth Tisue, netlogo-devel
Lots of updates to the code: https://github.com/stepheneb/netlogo-gcc

I created a gh-pages branch so you can also run the demo here: http://stepheneb.github.com/netlogo-gcc/

At 9:59 AM -0500 3/5/12, Seth Tisue wrote:
>>>>> "Stephen" == Stephen Bannasch <stephen....@deanbrook.org>writes:

 Stephen> I'm trying to access the world.importWorld() function with
 Stephen> this signature:

 Stephen>   public strictfp void importWorld(Importer.ErrorHandler
 Stephen> paramErrorHandler, ImporterUser paramImporterUser,
 Stephen> Importer.StringReader paramStringReader, BufferedReader
 Stephen> paramBufferedReader)

It's a lot easier to use the importWorld method on Workspace, which
takes many fewer parameters.  There's one version that reads from
the filesystem, which you don't want; instead, use:

  void importWorld(java.io.Reader reader)
      throws java.io.IOException;

It should work to stuff your string into a java.io.StringReader which
you then pass in.

That's not yet working for me ... perhaps because the standard NetLogoLite jar doesn't include that method signature??

I've put a breakpoint just before trying to run: nl_world.importWorld(sr) -- I then execute it in the console and get an error that usually indicates that the method signature isn't available (but the error info passed back to JS isn't all that informative).


When I examine the methods in the org.nlogo.agent.World class in the NetLogoLite jar directly using JD_GUI I only see this method signature for importWorld:

public strictfp void importWorld(Importer.ErrorHandler paramErrorHandler, ImporterUser paramImporterUser, Importer.StringReaderparamStringReader, BufferedReader paramBufferedReader)
    throws IOException
  {
    new Importer(paramErrorHandler, this, paramImporterUser, paramStringReader).importWorld(paramBufferedReader);
  }
Which is why I was trying to use this more complex form ... but I'm pretty sure that errorHandler, importerUser, and bufferedReader are supposed to be instances of those classes, not the classes themselves. I'm not certain how to make them.

  var errorHandler = applet.Packages.org.nlogo.api.ImportErrorHandler;
  var importerUser = applet.Packages.org.nlogo.api.ImporterUser;
  var bufferedReader = applet.Packages.java.io.BufferedReader;
  var sr = new applet.Packages.java.io.StringReader(nl_state);
  nl_world.importWorld(errorHandler, importerUser, sr, bufferedReader);
P09EBEE4F 1.png

Stephen Bannasch

neprebran,
6. mar. 2012, 15:04:146. 3. 12
do Seth Tisue, netlogo-devel
At 9:04 AM -0500 3/5/12, Seth Tisue wrote:
>scala> val globals = ws.world.program.globals
>globals: java.util.List[String] = [SUN-BRIGHTNESS, ALBEDO, SKY-TOP, EARTH-TOP, TEMPERATURE]

I have a LiteWorkspace object in JavaScript and can get globals with it by going through it's world property:

nl_world = nl_workspace.org$nlogo$lite$LiteWorkspace$$world;
nl_observer = nl_world.observer();

nl_globals.get(3)
=> "TEMPERATURE"

nl_observer.getVariable(3)
=> 12

>scala> ws.command("setup")

But my LiteWorkspace object has no method "command":

nl_workspace.command("setup")
=> TypeError: Object org.nlogo.lite.LiteWorkspace@7bceb175 has no method 'command'

Corey Brady

neprebran,
6. mar. 2012, 15:18:396. 3. 12
do Stephen Bannasch, netlogo-devel
hi stephen --
isn't this the same issue, involving ProGuard and the exposure (or stripping out) of methods and properties from the Lite jar?
i am hoping to get time to try editing the ProGuard/Lite.txt according to Seth's prior note, but i haven't yet
have you tried that and been unable to change availability of the command() method?
-corey

Stephen Bannasch

neprebran,
6. mar. 2012, 15:24:286. 3. 12
do Corey Brady, netlogo-devel
At 2:18 PM -0600 3/6/12, Corey Brady wrote:
>hi stephen --
>isn't this the same issue, involving ProGuard and the exposure (or stripping out) of methods and properties from the Lite jar?
>i am hoping to get time to try editing the ProGuard/Lite.txt according to Seth's prior note, but i haven't yet
>have you tried that and been unable to change availability of the command() method?

I was going to try that soon -- am first seeing just how far I can get without doing that.

I've been able to get much more working with the existing NetLogoLite jar than I thought at first. If I don't have to update itthen deploying externally would be much easier.

But it may well be that I've hit a hard limit now enforced by the Proguard stripping patterns.

Seth Tisue

neprebran,
6. mar. 2012, 16:00:216. 3. 12
do netlogo-devel
>>>>> "Stephen" == Stephen Bannasch <stephen....@deanbrook.org> writes:

Stephen> I've been able to get much more working with the existing
Stephen> NetLogoLite jar than I thought at first. If I don't have to
Stephen> update itthen deploying externally would be much easier.

In the short term, yes. In the longer term, we'd include your ProGuard
config changes in the official jar in some 5.0.x release so you wouldn't
need to go on using a custom jar.

Seth Tisue

neprebran,
6. mar. 2012, 16:04:056. 3. 12
do netlogo-devel
>>>>> "Stephen" == Stephen Bannasch <stephen....@deanbrook.org> writes:

Stephen> Which is why I was trying to use this more complex form
Stephen> ... but I'm pretty sure that errorHandler, importerUser, and
Stephen> bufferedReader are supposed to be instances of those classes,
Stephen> not the classes themselves. I'm not certain how to make them.

Stephen> var errorHandler =
Stephen> applet.Packages.org.nlogo.api.ImportErrorHandler; var
Stephen> importerUser = applet.Packages.org.nlogo.api.ImporterUser; var
Stephen> bufferedReader = applet.Packages.java.io.BufferedReader; var
Stephen> sr = new applet.Packages.java.io.StringReader(nl_state);
Stephen> nl_world.importWorld(errorHandler, importerUser, sr,
Stephen> bufferedReader);

This path you're trying to go down is a difficult one, and unnecessary.
There is no straightforward way to fill in all these arguments yourself.
It would be a lot easier to just edit the ProGuard config and build a
new lite jar that includes the methods you need.

Stephen Bannasch

neprebran,
6. mar. 2012, 17:55:076. 3. 12
do netlogo-devel
Things are working even better now.

I modified the proguard file and now I've got restoring state and command communication working.

Two problems:

1) When I restore state I haven't been able to get the applet to repaint itself.

If I load the page and run the applet for 10s and stop it; save that state; click the applet "Reset" button, and restore the state there is no immediate visible change in the applet.

If however I then click the applet "Run" button the applet appears to start from the restored state.

2) Clicking the JavaScript "Run" button only runs the applet one model tick forward.

When I examined the "Run" button in the NetLogo application environment it was running the command "execute"-- which is what my JS "Run" button does.

How can I achieve the same effect as the "Run" button in the applet itself?

- start the applet model running
- stop a running applet

Of course stepping forward just ONE step is a useful function also.


*** NOTE:
1) If you have tried earlier versions of this example you might need to erase your Java cache -- on the Mac I had to open Java Preferences and erase the Java cache to get this to work.

Here are the changes I made in the proguard file -- it may be more than is necessary.



2) Testing:

Mac OS X 10.6.8:

Working: Chrome 17.0.963.46, Safari 5.1.2

Not working: FF

It works on Chrome and Safari on my Mac. The applet fails to load/display properly on FF.

Windows 7: running the example from Chrome told me the Java Plugin was blocked because it was out-of-date. I clicked the link: "Update plugin ..." which downloaded an initial updater.exe which download the update proper to upgrade Java JRE to 1.6.0_31.

Works: Chrome 17.0.963.66 m, Safari 5.1.2,

Not working: FF 10.0.2

This is what the applet looks like FF on both Mac OS X and Windows 7:


There is nothing in the Java plugin console other than the initial plugin info.

Not Working IE9

The applet worked but the page layout and the JS <=> Java comms aren't working.
P1101778B.png

Corey Brady

neprebran,
6. mar. 2012, 18:09:296. 3. 12
do Stephen Bannasch, netlogo-devel
hi 

i had the repaint problem as well.
what i did was to run the command "display"

so 

workspace.command( "display" );

this is like a "netlogo repaint"

-c



<P1101778B.png>

Stephen Bannasch

neprebran,
6. mar. 2012, 18:59:246. 3. 12
do Corey Brady, netlogo-devel
At 5:09 PM -0600 3/6/12, Corey Brady wrote:
>hi
>
>i had the repaint problem as well.
>what i did was to run the command "display"
>
>so
>
>workspace.command( "display" );
>
>this is like a "netlogo repaint"

That worked!

I tried this as a command to start the model running -- but it basically locks up the applet (and the browser somehwat):

nl_panel.command("loop [ execute]");

The model starts running but I can't stop it.

I have a similar problem if I add the following to the model:

to start-running
loop [ execute ]
end

If I call that from JavaScript I both don't get control back in the browser AND the model doesn't start.

If I execute: start-running in the NetLogop application command center the model starts running but them I can't stop it.

--------

Separately an error is generated if a model is running and I try and restore the state ... so I'd like to be able to tell if a model is running and stop it if it is.

Here are some basic commands/operations I'd like to know how to do.

- Is the model running?
- Is the model stopped?
- Start the model running continuously.

Stephen Bannasch

neprebran,
6. mar. 2012, 20:32:026. 3. 12
do netlogo-devel
At 6:59 PM -0500 3/6/12, Stephen Bannasch wrote:
>I tried this as a command to start the model running -- but it basically locks up the applet (and the browser somehwat):
>
> nl_panel.command("loop [ execute]");
>
>The model starts running but I can't stop it.
>
>I have a similar problem if I add the following to the model:
>
> to start-running
> loop [ execute ]
> end
>
>If I call that from JavaScript I both don't get control back in the browser AND the model doesn't start.
>
>If I execute: start-running in the NetLogop application command center the model starts running butthem I can't stop it.

I found this variety of suggestions for how to make a model keep runnning but none of them seem to apply:

http://groups.yahoo.com/group/netlogo-users/message/3638

Seth Tisue

neprebran,
6. mar. 2012, 21:33:156. 3. 12
do netlogo-devel
>>>>> "Stephen" == Stephen Bannasch <stephen....@deanbrook.org> writes:

Stephen> Here are some basic commands/operations I'd like to know how
Stephen> to do.
Stephen> - Is the model running? - Is the model stopped? - Start the
Stephen> model running continuously.

Stephen> I tried this as a command to start the model running -- but it
Stephen> basically locks up the applet (and the browser somehwat):
Stephen> nl_panel.command("loop [ execute]");
Stephen> The model starts running but I can't stop it.

Sounds like you want the commandLater() method instead of command().
commandLater "runs NetLogo commands in the background. Returns
immediately, without waiting for the commands to finish."

If you add a global variable to your model named "done?", then you could
do something like:

nl_panel.commandLater(
"set done? false while [not done?] [ execute ]")

Then if you want it stop after the current time through the loop
finishes, nl_panel.command/commandLater("set done? true").

There's also a "halt" method on workspace, but you usually won't want to
use that because it stops running code in its tracks, rather than waiting
for the current iteration to finish.

To answer "Is the model stopped?", you could use the anyPrimaryJobs
method on JobManager; a jobManager field is public in AbstractWorkspace.
"Primary" jobs are pieces of running NetLogo code not associated with
monitors (monitor jobs are "secondary" and remain active as long as
the monitor exists).

Anyway, all of the above is the approach I'd suggest if you *don't* plan
to make the "setup" and "go" buttons in the actual model visible to the
user, because you want to control the model entirely from JavaScript.
Is that the path you're on...?

You may be able to borrow previously used solutions from Concord's
previous work with embedding InterfaceComponent within OTrunk. Applet
and InterfaceComponent both inherit from AppletPanel, so many of the
available methods are the same.

Unfortunately some methods exist only in InterfaceComponent even though,
there's no good reason they aren't on AppletPanel instead. For example,
another solution plan would be to leave the "setup" and "go" buttons in
the model interface, and then arrange to actually click on buttons from
JavaScript, just as if the user had pressed them herself.
InterfaceComponent has a pressButton() method for this; you just pass it
the button name, which should be unique. But you're not using
InterfaceComponent, you're using Applet/AppletPanel. So to get the
pressButton method, you have some choices:

1) Move it from InterfaceComponent to AppletPanel yourself and make yourself a
new jar.
2) Ask us to move it, and as many other methods as we can, to
AppletPanel, and make a new jar for you.

If you find InterfaceComponent has methods AppletPanel lacks, feel free
to fool around with (1) in the short term -- it will probably actually
be easy in most cases -- but if you run into any trouble, (2) is
probably something that should happen anyway and we may need it
ourselves on our ABM+ grant, so that's better in the long run.

Seth Tisue

neprebran,
6. mar. 2012, 22:07:166. 3. 12
do netlogo-devel
>>>>> "Stephen" == Stephen Bannasch <stephen....@deanbrook.org> writes:

Stephen> 2) Testing:
Stephen> Mac OS X 10.6.8:
Stephen> It works on Chrome and Safari on my Mac. The applet fails to
Stephen> load/display properly on FF.
Stephen> This is what the applet looks like FF on both Mac OS X and
Stephen> Windows 7: [...]

In the past, a display like this where nothing shows but the sideways
NetLogo banner has sometimes indicated that the applet just needs to be
made a little larger.

However, given that you're on Mac OS X 10.6, that might not be the
problem here. Are you familiar with "Plugin 1" and "Plugin 2" on Mac OS
X? If I recall the history correctly, Firefox switched to "Plugin 2"
before the other browsers did, and before the new plugin was good enough
quality to run NetLogo applets. Apple continued to improve Plugin 2 on
Mac OS X 10.7, but 10.6 remained stuck with an old, substandard version.
My guess is that if you try it on Firefox on a Mac OS X 10.7 system that
is up-to-date with Software Update, you'll find that it works. Firefox
on 10.6 might be a lost cause.

I'm not entirely surely I'm remembering this history exactly right, but
if you're having trouble, it's a line of inquiry to pursue, anyway.

Nathan Kimball might know more about the browser differences; see e.g.
<http://groups.yahoo.com/group/netlogo-users/message/13402>

Stephen Bannasch

neprebran,
6. mar. 2012, 23:12:496. 3. 12
do Seth Tisue, netlogo-devel
At 10:07 PM -0500 3/6/12, Seth Tisue wrote:
> >>>>> "Stephen" == Stephen Bannasch <stephen....@deanbrook.org>writes:
>
> Stephen> 2) Testing:
> Stephen> Mac OS X 10.6.8:
> Stephen> It works on Chrome and Safari on my Mac. The applet fails to
> Stephen> load/display properly on FF.
> Stephen> This is what the applet looks like FF on both Mac OS X and
> Stephen> Windows 7: [...]
>
>In the past, a display like this where nothing shows but the sideways
>NetLogo banner has sometimes indicated that the applet just needs to be
>made a little larger.

Thanks for that suggestion. I just got the JS buttons working so when I removed the buttons in the model and tightened up the layout I saw this happening when I made the width and height properties on the applet element too small.

Now the example works in FF!

http://stepheneb.github.com/netlogo-gcc/index.html


At 9:33 PM -0500 3/6/12, Seth Tisue wrote:
>Anyway, all of the above is the approach I'd suggest if you *don't* plan
>to make the "setup" and "go" buttons in the actual model visible to the
>user, because you want to control the model entirely from JavaScript.
>Is that the path you're on...?

Yes.

Next I'm going to wire the Temperature Global variable in the NL model to the grapher.

Besides having the ability to style and layout the buttons nicely one of the other reason for being able to control the NL model from the browser is that there are many cases where the action of STARTING a model has important secondary effects.

For example for VISUAL I'm going to graph the temperature data from this model in the JS grapher. But we also want studentsto be able to collect multiple model runs. If a student has just collected 20s of a model run and then pressed the "Reset" button the browser needs to know this in order to save (or give the user the option of saving) the data that was justcollected.

NetLogo is not currently written to be able to notify JavaScript functions in the browser when events like this happen in the Java applet context.

And ... while we've solved these problems with the sensor applet -- it was difficult and fraught -- and my judgement is that this area of communication is fragile. Sometimes things get broken with browser updates because it's not used widely or tested well.

Of course polling the Temperature Global variable from JavaScript is also not very reliable. It's not that the code won't work -- it's that I'll need to set an interval timer in JS to start polling when the model starts. This does not have much to do with the speed of the model.

What I actually need are the array of Temperatures generated during the run of the model.

So after I get the first implementation using interval polling of the single Temperature datum, I'll modify the model code to also save an list of the temperatures.

Then I'll need to figure out how to efficiently get data in an NL list into and array in JS.

Stephen Bannasch

neprebran,
6. mar. 2012, 23:31:576. 3. 12
do Seth Tisue, netlogo-devel
At 11:12 PM -0500 3/6/12, Stephen Bannasch wrote:
>At 10:07 PM -0500 3/6/12, Seth Tisue wrote:
>> >>>>> "Stephen" == Stephen Bannasch <stephen....@deanbrook.org>writes:
>>
>> Stephen> 2) Testing:
>> Stephen> Mac OS X 10.6.8:
>> Stephen> It works on Chrome and Safari on my Mac. The applet fails to
>> Stephen> load/display properly on FF.
>> Stephen> This is what the applet looks like FF on both Mac OS X and
>> Stephen> Windows 7: [...]
>>
>>In the past, a display like this where nothing shows but the sideways
>>NetLogo banner has sometimes indicated that the applet just needs to be
>>made a little larger.
>
>Thanks for that suggestion. I just got the JS buttons working so when I removed the buttons in the model and tightened up the layout I saw this happening when I made the width and height properties on the applet element too small.
>
>Now the example works in FF!
>
> http://stepheneb.github.com/netlogo-gcc/index.html
>
>
>At 9:33 PM -0500 3/6/12, Seth Tisue wrote:
>>Anyway, all of the above is the approach I'd suggest if you *don't* plan
>>to make the "setup" and "go" buttons in the actual model visible to the
>>user, because you want to control the model entirely from JavaScript.
>>Is that the path you're on...?
>
>Yes.
>
>Next I'm going to wire the Temperature Global variable in the NL model to the grapher.
>
>Besides having the ability to style and layout the buttons nicely one of the other reason for beingable to control the NL modelfrom the browser is that there are many cases where the action of STARTING a model has important secondary effects.

I forgot to describe the most immediate and obvious need ...

Clicking the JavaScript start button not only starts the NL model (which the NL button already did) the event will also start the JS interval timer that collects data from the NL applet.

Clicking the "Stop" button will stop the NL model and stop the JS interval timer and complete the transfer of anydatain the NL model to the grapher.

Seth Tisue

neprebran,
7. mar. 2012, 09:28:237. 3. 12
do netlogo-devel
>>>>> "Stephen" == Stephen Bannasch <stephen....@deanbrook.org> writes:

Stephen> If a student has just collected 20s of a model run and then
Stephen> pressed the "Reset" button the browser needs to know this in
Stephen> order to save (or give the user the option of saving) the data
Stephen> that was justcollected.

Stephen> NetLogo is not currently written to be able to notify
Stephen> JavaScript functions in the browser when events like this
Stephen> happen in the Java applet context.

Couldn't you just attach a NetLogoListener (in org.nlogo.api) for
this...? AppletPanel has a listenerManager method, which returns a
NetLogoListenerManager object, which has an addListener method.

Are you thinking of our log4j-based logging stuff? That stuff isn't
available in NetLogo applets (so far, just because there hasn't been a
customer), but NetLogoListener should work.

Stephen> And ... while we've solved these problems with the sensor
Stephen> applet -- it was difficult and fraught -- and my judgement is
Stephen> that this area of communication is fragile. Sometimes things
Stephen> get broken with browser updates because it's not used widely
Stephen> or tested well.

Yeah, it's hard to know how far to trust LiveConnect.

Stephen> Of course polling the Temperature Global variable from
Stephen> JavaScript is also not very reliable. It's not that the code
Stephen> won't work -- it's that I'll need to set an interval timer in
Stephen> JS to start polling when the model starts. This does not have
Stephen> much to do with the speed of the model.

Indeed, I would not suggest polling.

Stephen> Then I'll need to figure out how to efficiently get data in an
Stephen> NL list into and array in JS.

If it helps, LogoList implements java.util.AbstractSequentialList, which
has a toArray method.

Stephen Bannasch

neprebran,
7. mar. 2012, 10:40:257. 3. 12
do Seth Tisue, netlogo-devel
At 9:28 AM -0500 3/7/12, Seth Tisue wrote:
> >>>>> "Stephen" == Stephen Bannasch <stephen....@deanbrook.org>writes:
>
> Stephen> If a student has just collected 20s of a model run and then
> Stephen> pressed the "Reset" button the browser needs to know this in
> Stephen> order to save (or give the user the option of saving) the data
> Stephen> that was justcollected.
>
> Stephen> NetLogo is not currently written to be able to notify
> Stephen> JavaScript functions in the browser when events like this
> Stephen> happen in the Java applet context.
>
>Couldn't you just attach a NetLogoListener (in org.nlogo.api) for
>this...? AppletPanel has a listenerManager method, which returns a
>NetLogoListenerManager object, which has an addListener method.

I'm not sure what I could do

Here's what we did in our sensor-applets work:

The html sets an applet param with the name of a JavaScript function that acts as a listener for events from the applet (which is an instance of an OTSensorApplet):

<param name="listenerPath" value="jsListener"/>
https://github.com/concord-consortium/sensor-applets/blob/master/example.html#L54

The initDataProxy() method in the OTSensorApplet class:

https://github.com/concord-consortium/sensor-applets/blob/master/src/main/java/org/concord/sensor/applet/OTSensorApplet.java#L168

Creating a JavascriptDataBridge object which ties the applet and the JS context and the listenerPath property together:

https://github.com/concord-consortium/sensor-applets/blob/master/src/main/java/org/concord/sensor/applet/JavascriptDataBridge.java

When the JavascriptDataBridge object is initialized it create a window object which is used to communicate to the JS context:

window = JSObject.getWindow(applet)

The handleEvent() method of the JavascriptDataBridge instance:

https://github.com/concord-consortium/sensor-applets/blob/master/src/main/java/org/concord/sensor/applet/JavascriptDataBridge.java#L30

puts together data being generated in the applet into a string which is then evaled in the JS context.

The method getJsEventCall() constructs the string to be evaluated in the JS context.

https://github.com/concord-consortium/sensor-applets/blob/master/src/main/java/org/concord/sensor/applet/JavascriptDataBridge.java#L40

Which might look something like this: "jsListener.dataReceived(<type>,<count>,<data>);"

I think something similar would need to be added to NetLogo in order to get communication working from the NetLogo Java applet ==> a function in the JavaScript browser context.


>Are you thinking of our log4j-based logging stuff? That stuff isn't
>available in NetLogo applets (so far, just because there hasn't been a
>customer), but NetLogoListener should work.

I hadn't consider this -- not sure if it would help or not.

> Stephen> And ... while we've solved these problems with the sensor
> Stephen> applet -- it was difficult and fraught -- and my judgement is
> Stephen> that this area of communication is fragile. Sometimes things
> Stephen> get broken with browser updates because it's not used widely
> Stephen> or tested well.
>
>Yeah, it's hard to know how far to trust LiveConnect.

Yeah ... the problem right now in IE9 is that this statement fails:

sw = new applet.Packages.java.io.StringWriter();

With this error:

java.lang.IllegalArgumentException: No method found matching name java.io.StringWriter
and arguments [sun.plugin2.main.client.MessagePassingJSObject]

Which is pretty confusing since it works everywhere else

> Stephen> Of course polling the Temperature Global variable from
> Stephen> JavaScript is also not very reliable. It's not that the code
> Stephen> won't work -- it's that I'll need to set an interval timer in
> Stephen> JS to start polling when the model starts. This does not have
> Stephen> much to do with the speed of the model.
>
>Indeed, I would not suggest polling.

I've got stupid polling working well now.

> Stephen> Then I'll need to figure out how to efficiently get data in an
> Stephen> NL list into and array in JS.
>
>If it helps, LogoList implements java.util.AbstractSequentialList, which
>has a toArray method.

Great -- this will allow much smarter polling.

I'll poll at whatever interval I like and either just copy the entire array of data to the JS context -- or if I end up needingto ask for just the new elements in the array I haven't yet received.

Odgovori vsem
Odgovori avtorju
Posreduj
0 novih sporočil