changeset 7132:e0135f1a8627

8014519: scriptpad sample does not work with nashorn Reviewed-by: attila, jlaskey Contributed-by: rieberandreas@gmail.com
author sundar
date Tue, 14 May 2013 22:36:52 +0530
parents 5ea5f5dfb96a
children 790d292ee761 fdf082cddb69
files src/share/sample/scripting/scriptpad/src/com/sun/sample/scriptpad/Main.java src/share/sample/scripting/scriptpad/src/resources/Main.js src/share/sample/scripting/scriptpad/src/resources/conc.js src/share/sample/scripting/scriptpad/src/resources/gui.js src/share/sample/scripting/scriptpad/src/resources/mm.js src/share/sample/scripting/scriptpad/src/resources/scriptpad.js src/share/sample/scripting/scriptpad/src/scripts/browse.js src/share/sample/scripting/scriptpad/src/scripts/insertfile.js src/share/sample/scripting/scriptpad/src/scripts/linewrap.js src/share/sample/scripting/scriptpad/src/scripts/mail.js src/share/sample/scripting/scriptpad/src/scripts/memmonitor.js src/share/sample/scripting/scriptpad/src/scripts/memory.js src/share/sample/scripting/scriptpad/src/scripts/memory.sh src/share/sample/scripting/scriptpad/src/scripts/textcolor.js
diffstat 14 files changed, 744 insertions(+), 695 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/sample/scripting/scriptpad/src/com/sun/sample/scriptpad/Main.java	Tue May 14 20:16:21 2013 +0400
+++ b/src/share/sample/scripting/scriptpad/src/com/sun/sample/scriptpad/Main.java	Tue May 14 22:36:52 2013 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -75,7 +75,7 @@
          */
         InputStream is = Main.class.getResourceAsStream("/resources/" + name);
         // current script file name for better error messages
-        engine.put(ScriptEngine.NAME, name);
+        engine.put(ScriptEngine.FILENAME, name);
         // evaluate the script in the InputStream
         engine.eval(new InputStreamReader(is));
     }
--- a/src/share/sample/scripting/scriptpad/src/resources/Main.js	Tue May 14 20:16:21 2013 +0400
+++ b/src/share/sample/scripting/scriptpad/src/resources/Main.js	Tue May 14 22:36:52 2013 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,7 +37,6 @@
  * this sample code.
  */
 
-
 /*
  * This script can be loaded in jrunscript to start scriptpad.
  *
@@ -48,4 +47,3 @@
 load("gui.js");
 load("scriptpad.js");
 load("mm.js");
-
--- a/src/share/sample/scripting/scriptpad/src/resources/conc.js	Tue May 14 20:16:21 2013 +0400
+++ b/src/share/sample/scripting/scriptpad/src/resources/conc.js	Tue May 14 22:36:52 2013 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,15 +37,43 @@
  * this sample code.
  */
 
-
 /*
  * Concurrency utilities for JavaScript. These are based on
- * java.lang and java.util.concurrent API. The following functions 
+ * java.lang and java.util.concurrent API. The following functions
  * provide a simpler API for scripts. Instead of directly using java.lang
  * and java.util.concurrent classes, scripts can use functions and
- * objects exported from here. 
+ * objects exported from here.
  */
 
+// shortcut for j.u.c lock classes
+var Lock = java.util.concurrent.locks.ReentrantLock;
+var RWLock = java.util.concurrent.locks.ReentrantReadWriteLock;
+
+// check if there is a build in sync function, define one if missing
+if (typeof sync === "undefined") {
+    var sync = function(func, obj) {
+        if (arguments.length < 1 || arguments.length > 2 ) {
+            throw "sync(function [,object]) parameter count mismatch";
+        }
+
+        var syncobj = (arguments.length == 2 ? obj : this);
+
+        if (!syncobj._syncLock) {
+            syncobj._syncLock = new Lock();
+        }
+
+        return function() {
+            syncobj._syncLock.lock();
+            try {
+                func.apply(null, arguments);
+            } finally {
+                syncobj._syncLock.unlock();
+            }
+        };
+    };
+    sync.docString = "synchronize a function, optionally on an object";
+}
+
 /**
  * Wrapper for java.lang.Object.wait
  *
@@ -58,7 +86,6 @@
 }
 wait.docString = "convenient wrapper for java.lang.Object.wait method";
 
-
 /**
  * Wrapper for java.lang.Object.notify
  *
@@ -71,7 +98,6 @@
 }
 notify.docString = "convenient wrapper for java.lang.Object.notify method";
 
-
 /**
  * Wrapper for java.lang.Object.notifyAll
  *
@@ -84,7 +110,6 @@
 }
 notifyAll.docString = "convenient wrapper for java.lang.Object.notifyAll method";
 
-
 /**
  * Creates a java.lang.Runnable from a given script
  * function.
@@ -97,7 +122,7 @@
             func.apply(null, args);
         }
     }
-}
+};
 
 /**
  * Executes the function on a new Java Thread.
@@ -106,7 +131,7 @@
     var t = new java.lang.Thread(this.runnable.apply(this, arguments));
     t.start();
     return t;
-}
+};
 
 /**
  * Executes the function on a new Java daemon Thread.
@@ -116,7 +141,7 @@
     t.setDaemon(true);
     t.start();
     return t;
-}
+};
 
 /**
  * Creates a java.util.concurrent.Callable from a given script
@@ -128,7 +153,7 @@
     return new java.util.concurrent.Callable() {
           call: function() { return func.apply(null, args); }
     }
-}
+};
 
 /**
  * Registers the script function so that it will be called exit.
@@ -137,10 +162,10 @@
     var args = arguments;
     java.lang.Runtime.getRuntime().addShutdownHook(
          new java.lang.Thread(this.runnable.apply(this, args)));
-}
+};
 
 /**
- * Executes the function asynchronously.  
+ * Executes the function asynchronously.
  *
  * @return a java.util.concurrent.FutureTask
  */
@@ -152,13 +177,9 @@
     (function() { theExecutor.shutdown(); }).atexit();
     return function() {
         return theExecutor.submit(this.callable.apply(this, arguments));
-    }
+    };
 })();
 
-// shortcut for j.u.c lock classes
-var Lock = java.util.concurrent.locks.ReentrantLock;
-var RWLock = java.util.concurrent.locks.ReentrantReadWriteLock;
-
 /**
  * Executes a function after acquiring given lock. On return,
  * (normal or exceptional), lock is released.
@@ -179,7 +200,7 @@
     } finally {
         lock.unlock();
     }
-}
+};
 
 /**
  * Causes current thread to sleep for specified
@@ -193,15 +214,48 @@
 sleep.docString = "wrapper for java.lang.Thread.sleep method";
 
 /**
- * Schedules a task to be executed once in
- * every N milliseconds specified. 
+ * Schedules a task to be executed once in N milliseconds specified.
  *
  * @param callback function or expression to evaluate
  * @param interval in milliseconds to sleep
  * @return timeout ID (which is nothing but Thread instance)
  */
 function setTimeout(callback, interval) {
-    if (! (callback instanceof Function)) {
+    if (! (callback instanceof Function) && typeof callback !== "function") {
+        callback = new Function(callback);
+    }
+
+    // start a new thread that sleeps given time
+    // and calls callback in an infinite loop
+    return (function() {
+         try {
+             sleep(interval);
+         } catch (x) { }
+         callback();
+    }).daemon();
+}
+setTimeout.docString = "calls given callback once after specified interval";
+
+/**
+ * Cancels a timeout set earlier.
+ * @param tid timeout ID returned from setTimeout
+ */
+function clearTimeout(tid) {
+    // we just interrupt the timer thread
+    tid.interrupt();
+}
+clearTimeout.docString = "interrupt a setTimeout timer";
+
+/**
+ * Schedules a task to be executed once in
+ * every N milliseconds specified.
+ *
+ * @param callback function or expression to evaluate
+ * @param interval in milliseconds to sleep
+ * @return timeout ID (which is nothing but Thread instance)
+ */
+function setInterval(callback, interval) {
+    if (! (callback instanceof Function) && typeof callback !== "function") {
         callback = new Function(callback);
     }
 
@@ -209,38 +263,43 @@
     // and calls callback in an infinite loop
     return (function() {
          while (true) {
-             sleep(interval);
+             try {
+                 sleep(interval);
+             } catch (x) {
+                 break;
+             }
              callback();
          }
     }).daemon();
 }
-setTimeout.docString = "calls given callback once after specified interval"
+setInterval.docString = "calls given callback every specified interval";
 
-/** 
+/**
  * Cancels a timeout set earlier.
  * @param tid timeout ID returned from setTimeout
  */
-function clearTimeout(tid) {
+function clearInterval(tid) {
     // we just interrupt the timer thread
     tid.interrupt();
 }
+clearInterval.docString = "interrupt a setInterval timer";
 
 /**
- * Simple access to thread local storage. 
+ * Simple access to thread local storage.
  *
  * Script sample:
  *
  *  __thread.x = 44;
- *  function f() { 
- *      __thread.x = 'hello'; 
- *      print(__thread.x); 
+ *  function f() {
+ *      __thread.x = 'hello';
+ *      print(__thread.x);
  *  }
  *  f.thread();       // prints 'hello'
  * print(__thread.x); // prints 44 in main thread
  */
 var __thread = (function () {
     var map = new Object();
-    return new JSAdapter() {
+    return new JSAdapter({
         __has__: function(name) {
             return map[name] != undefined;
         },
@@ -263,8 +322,8 @@
         __delete__: function(name) {
             if (map[name] != undefined) {
                 map[name].set(null);
-            }            
+            }
         }
-    }
+    });
 })();
 
--- a/src/share/sample/scripting/scriptpad/src/resources/gui.js	Tue May 14 20:16:21 2013 +0400
+++ b/src/share/sample/scripting/scriptpad/src/resources/gui.js	Tue May 14 22:36:52 2013 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,16 +37,15 @@
  * this sample code.
  */
 
-
 /*
- * Few user interface utilities. 
+ * Few user interface utilities.
  */
 
 if (this.window === undefined) {
     this.window = null;
 }
 
-/** 
+/**
  * Swing invokeLater - invokes given function in AWT event thread
  */
 Function.prototype.invokeLater = function() {
@@ -54,13 +53,13 @@
     var func = this;
     var args = arguments;
     SwingUtilities.invokeLater(new java.lang.Runnable() {
-                       run: function() { 
+                       run: function() {
                            func.apply(func, args);
                        }
                   });
-}
+};
 
-/** 
+/**
  * Swing invokeAndWait - invokes given function in AWT event thread
  * and waits for it's completion
  */
@@ -69,11 +68,11 @@
     var func = this;
     var args = arguments;
     SwingUtilities.invokeAndWait(new java.lang.Runnable() {
-                       run: function() { 
+                       run: function() {
                            func.apply(func, args);
                        }
                   });
-}
+};
 
 /**
  * Am I running in AWT event dispatcher thread?
@@ -85,22 +84,24 @@
 isEventThread.docString = "returns whether the current thread is GUI thread";
 
 /**
- * Opens a file dialog box 
+ * Opens a file dialog box
  *
  * @param curDir current directory [optional]
  * @param save flag tells whether this is a save dialog or not
  * @return selected file or else null
  */
-function fileDialog(curDir, save) {   
+function fileDialog(curDir, save) {
     var result;
     function _fileDialog() {
         if (curDir == undefined) {
             curDir = new java.io.File(".");
         }
+
         var JFileChooser = javax.swing.JFileChooser;
-        var dialog = new JFileChooser(curDir);        
-        var res = save? dialog.showSaveDialog(window):
-                        dialog.showOpenDialog(window);
+        var dialog = new JFileChooser(curDir);
+        var res = save ? dialog.showSaveDialog(window):
+            dialog.showOpenDialog(window);
+
         if (res == JFileChooser.APPROVE_OPTION) {
            result = dialog.getSelectedFile();
         } else {
@@ -113,37 +114,41 @@
     } else {
         _fileDialog.invokeAndWait();
     }
+
     return result;
 }
 fileDialog.docString = "show a file dialog box";
 
 /**
- * Opens a color chooser dialog box 
+ * Opens a color chooser dialog box
  *
  * @param title of the dialog box [optional]
  * @param color default color [optional]
  * @return choosen color or default color
  */
-
 function colorDialog(title, color) {
     var result;
+
     function _colorDialog() {
         if (title == undefined) {
             title = "Choose Color";
         }
+
         if (color == undefined) {
             color = java.awt.Color.BLACK;
         }
+
         var chooser = new javax.swing.JColorChooser();
         var res = chooser.showDialog(window, title, color);
-        result = res? res : color;
-    }     
+        result = res ? res : color;
+    }
 
     if (isEventThread()) {
         _colorDialog();
     } else {
         _colorDialog.invokeAndWait();
     }
+
     return result;
 }
 colorDialog.docString = "shows a color chooser dialog box";
@@ -156,15 +161,15 @@
  * @param msgType type of message box [constants in JOptionPane]
  */
 function msgBox(msg, title, msgType) {
-   
-    function _msgBox() { 
+    function _msgBox() {
         var JOptionPane = javax.swing.JOptionPane;
         if (msg === undefined) msg = "undefined";
         if (msg === null) msg = "null";
         if (title == undefined) title = msg;
-        if (msgType == undefined) type = JOptionPane.INFORMATION_MESSAGE;
+        if (msgType == undefined) msgType = JOptionPane.INFORMATION_MESSAGE;
         JOptionPane.showMessageDialog(window, msg, title, msgType);
     }
+
     if (isEventThread()) {
         _msgBox();
     } else {
@@ -172,13 +177,13 @@
     }
 }
 msgBox.docString = "shows MessageBox to the user";
- 
+
 /**
  * Shows an information alert box
  *
  * @param msg message to be shown
  * @param title title of message box [optional]
- */   
+ */
 function alert(msg, title) {
     var JOptionPane = javax.swing.JOptionPane;
     msgBox(msg, title, JOptionPane.INFORMATION_MESSAGE);
@@ -197,7 +202,6 @@
 }
 error.docString = "shows an error message box to the user";
 
-
 /**
  * Shows a warning alert box
  *
@@ -210,7 +214,6 @@
 }
 warn.docString = "shows a warning message box to the user";
 
-
 /**
  * Shows a prompt dialog box
  *
@@ -225,11 +228,13 @@
         if (answer == undefined) answer = "";
         result = JOptionPane.showInputDialog(window, question, answer);
     }
+
     if (isEventThread()) {
         _prompt();
     } else {
         _prompt.invokeAndWait();
     }
+
     return result;
 }
 prompt.docString = "shows a prompt box to the user and returns the answer";
@@ -244,30 +249,33 @@
 function confirm(msg, title) {
     var result;
     var JOptionPane = javax.swing.JOptionPane;
+
     function _confirm() {
         if (title == undefined) title = msg;
         var optionType = JOptionPane.YES_NO_OPTION;
         result = JOptionPane.showConfirmDialog(window, msg, title, optionType);
     }
+
     if (isEventThread()) {
         _confirm();
     } else {
         _confirm.invokeAndWait();
-    }     
+    }
+
     return result == JOptionPane.YES_OPTION;
 }
 confirm.docString = "shows a confirmation message box to the user";
 
 /**
- * Exit the process after confirmation from user 
- * 
+ * Exit the process after confirmation from user
+ *
  * @param exitCode return code to OS [optional]
  */
 function exit(exitCode) {
     if (exitCode == undefined) exitCode = 0;
     if (confirm("Do you really want to exit?")) {
         java.lang.System.exit(exitCode);
-    } 
+    }
 }
 exit.docString = "exits jconsole";
 
--- a/src/share/sample/scripting/scriptpad/src/resources/mm.js	Tue May 14 20:16:21 2013 +0400
+++ b/src/share/sample/scripting/scriptpad/src/resources/mm.js	Tue May 14 22:36:52 2013 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,10 +37,9 @@
  * this sample code.
  */
 
-
 /*
  * This is a collection of utilities for Monitoring
- * and management API. 
+ * and management API.
  *
  * File dependency:
  *    conc.js -> for concurrency utilities
@@ -71,14 +70,14 @@
 }
 jmxConnect.docString = "connects to the given host, port (specified as name:port)";
 
-function mbeanConnection() {    
-    if (mmConnection == null) {        
+function mbeanConnection() {
+    if (mmConnection == null) {
         throw "Not connected to MBeanServer yet!";
     }
 
     return mmConnection;
 }
-mbeanConnection.docString = "returns the current MBeanServer connection"
+mbeanConnection.docString = "returns the current MBeanServer connection";
 
 /**
  * Returns a platform MXBean proxy for given MXBean name and interface class
@@ -102,7 +101,6 @@
 }
 objectName.docString = "creates JMX ObjectName for a given String";
 
-
 /**
  * Creates a new (M&M) Attribute object
  *
@@ -146,7 +144,6 @@
 }
 queryNames.docString = "returns QueryNames using given ObjectName and optional query";
 
-
 /**
  * Queries with given ObjectName and QueryExp.
  * QueryExp may be null.
@@ -220,7 +217,6 @@
 }
 getMBeanAttribute.docString = "returns a single Attribute of given ObjectName";
 
-
 // sets MBean attributes
 function setMBeanAttributes(objName, attrList) {
     objName = objectName(objName);
@@ -237,7 +233,6 @@
 }
 setMBeanAttribute.docString = "sets a single Attribute of given ObjectName";
 
-
 // invokes an operation on given MBean
 function invokeMBean(objName, operation, params, signature) {
     objName = objectName(objName);
@@ -260,16 +255,17 @@
  * will be of type FutureTask. When you need value, call 'get' on it.
  */
 function mbean(objName, async) {
+    var index;
     objName = objectName(objName);
-    var info = mbeanInfo(objName);    
+    var info = mbeanInfo(objName);
     var attrs = info.attributes;
     var attrMap = new Object;
-    for (var index in attrs) {
+    for (index in attrs) {
         attrMap[attrs[index].name] = attrs[index];
     }
     var opers = info.operations;
     var operMap = new Object;
-    for (var index in opers) {
+    for (index in opers) {
         operMap[opers[index].name] = opers[index];
     }
 
@@ -288,9 +284,9 @@
         __get__: function (name) {
             if (isAttribute(name)) {
                 if (async) {
-                    return getMBeanAttribute.future(objName, name); 
+                    return getMBeanAttribute.future(objName, name);
                 } else {
-                    return getMBeanAttribute(objName, name); 
+                    return getMBeanAttribute(objName, name);
                 }
             } else if (isOperation(name)) {
                 var oper = operMap[name];
@@ -302,12 +298,12 @@
                         sigNames[index] = sigs[index].getType();
                     }
                     if (async) {
-                        return invokeMBean.future(objName, name, 
+                        return invokeMBean.future(objName, name,
                                                   params, sigNames);
                     } else {
                         return invokeMBean(objName, name, params, sigNames);
                     }
-                }
+                };
             } else {
                 return undefined;
             }
@@ -327,9 +323,9 @@
 }
 mbean.docString = "returns a conveninent script wrapper for a MBean of given ObjectName";
 
-if (this.application != undefined) {    
-    this.application.addTool("JMX Connect", 
-        // connect to a JMX MBean Server 
+if (this.application != undefined) {
+    this.application.addTool("JMX Connect",
+        // connect to a JMX MBean Server
         function () {
             var url = prompt("Connect to JMX server (host:port)");
             if (url != null) {
--- a/src/share/sample/scripting/scriptpad/src/resources/scriptpad.js	Tue May 14 20:16:21 2013 +0400
+++ b/src/share/sample/scripting/scriptpad/src/resources/scriptpad.js	Tue May 14 22:36:52 2013 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,9 +37,8 @@
  * this sample code.
  */
 
-
 /*
- * This script creates a simple Notepad-like interface, which 
+ * This script creates a simple Notepad-like interface, which
  * serves as a simple script editor, runner.
  *
  * File dependency:
@@ -48,579 +47,583 @@
  */
 
 /*
+ * globalThis is used for actionHelpGlobals() and showFrame().
+ */
+var globalThis = this;
+
+/*
  * JavaImporter helps in avoiding pollution of JavaScript
  * global namespace. We can import multiple Java packages
  * with this and use the JavaImporter object with "with"
  * statement.
  */
 var guiPkgs = new JavaImporter(java.awt, java.awt.event,
-                         javax.swing, javax.swing.undo,
-                         javax.swing.event, javax.swing.text);
+                               javax.swing, javax.swing.undo,
+                               javax.swing.event, javax.swing.text);
 
-with (guiPkgs) {   
+// main entry point of the scriptpad application
+var main = function() {
+    function createEditor() {
+        var c = new guiPkgs.JTextArea();
+        c.setDragEnabled(true);
+        c.setFont(new guiPkgs.Font("monospaced", guiPkgs.Font.PLAIN, 12));
+        return c;
+    }
 
-     /*
-      * within this "with" statement all Java classes in
-      * packages defined in "guiPkgs" can be used as simple
-      * names instead of the fully qualified names.
-      */
+    /*const*/ var titleSuffix = "- Scriptpad";
+    /*const*/ var defaultTitle = "Untitled" + titleSuffix;
 
+    // Scriptpad's main frame
+    var frame;
+    // Scriptpad's main editor
+    var editor;
 
-     // main entry point of the scriptpad application
-     function main() {
-        function createEditor() {
-            var c = new JTextArea();
-            c.setDragEnabled(true);
-            c.setFont(new Font("monospaced", Font.PLAIN, 12));
-            return c;
-        }
+    // To track the current file name
+    var curFileName = null;
 
-        /*const*/ var titleSuffix = "- Scriptpad";
-        /*const*/ var defaultTitle = "Untitled" + titleSuffix;
+    // To track whether the current document
+    // has been modified or not
+    var docChanged = false;
 
-        // Scriptpad's main frame
-        var frame;
-        // Scriptpad's main editor
-        var editor;
-
-        // To track the current file name
-        var curFileName = null;
-
-        // To track whether the current document 
-        // has been modified or not
-        var docChanged = false;
-
-        // check and alert user for unsaved
-        // but modified document        
-        function checkDocChanged() {
-            if (docChanged) {
-                // ignore zero-content untitled document
-                if (curFileName == null &&
-                    editor.document.length == 0) {
-                    return;
-                }
-
-                if (confirm(
-                    "Do you want to save the changes?",
-                    "The document has changed")) {
-                    actionSave();
-                }
-            }
-        }
-
-        // set a document listener to track 
-        // whether that is modified or not
-        function setDocListener() {
-            var doc = editor.getDocument();
-            docChanged = false;
-            doc.addDocumentListener(new DocumentListener() {
-                    equals: function(o) { return this === o; },
-                    toString: function() { return "doc listener"; },
-                    changeUpdate: function() { docChanged = true; },
-                    insertUpdate: function() { docChanged = true; },
-                    removeUpdate: function() { docChanged = true; },
-                });
-        }
-
-        // menu action functions
-
-        // "File" menu 
-
-        // create a "new" document
-        function actionNew(){
-            checkDocChanged();
-            curFileName = null;
-            editor.setDocument(new PlainDocument());
-            setDocListener();
-            frame.setTitle(defaultTitle);
-            editor.revalidate();
-        }
-
-        // open an existing file
-        function actionOpen() {
-            checkDocChanged();
-            var f = fileDialog();
-            if (f == null) {
-                return;
-            }
-            if (f.isFile() && f.canRead()) {                
-                frame.setTitle(f.getName() + titleSuffix);
-                editor.setDocument(new PlainDocument());
-                var progress = new JProgressBar();
-                progress.setMinimum(0);
-                progress.setMaximum(f.length());
-                var doc = editor.getDocument();
-                var inp = new java.io.FileReader(f);
-                var buff = java.lang.reflect.Array.newInstance(
-                                java.lang.Character.TYPE, 4096);
-                var nch;
-                while ((nch = inp.read(buff, 0, buff.length)) != -1) {
-                    doc.insertString(doc.getLength(),
-                         new java.lang.String(buff, 0, nch), null);
-                    progress.setValue(progress.getValue() + nch);
-                }
-                inp.close();
-                curFileName = f.getAbsolutePath();
-                setDocListener();
-             } else {
-                error("Can not open file: " + f,
-                    "Error opening file: " + f);                    
-             }               
-        }
-
-        // open script from a URL
-        function actionOpenURL() {
-            checkDocChanged();
-            var url = prompt("Address:");
-            if (url == null) {
+    // check and alert user for unsaved
+    // but modified document
+    function checkDocChanged() {
+        if (docChanged) {
+            // ignore zero-content untitled document
+            if (curFileName == null &&
+                editor.document.length == 0) {
                 return;
             }
 
-            try {
-                var u = new java.net.URL(url); 
-                editor.setDocument(new PlainDocument());
-                frame.setTitle(url + titleSuffix);
-                var progress = new JProgressBar();
-                progress.setMinimum(0);
-                progress.setIndeterminate(true);
-                var doc = editor.getDocument();
-                var inp = new java.io.InputStreamReader(u.openStream());
-                var buff = java.lang.reflect.Array.newInstance(
-                                java.lang.Character.TYPE, 4096);
-                var nch;
-                while ((nch = inp.read(buff, 0, buff.length)) != -1) {
-                    doc.insertString(doc.getLength(), 
-                          new java.lang.String(buff, 0, nch), null);
-                    progress.setValue(progress.getValue() + nch);
-                }    
-                curFileName = null;
-                setDocListener();
-            } catch (e) {
-                error("Error opening URL: " + e,
-                      "Can not open URL: " + url);
-            }   
-        } 
+            if (confirm("Do you want to save the changes?",
+                        "The document has changed")) {
+                actionSave();
+            }
+        }
+    }
 
-        // factored out "save" function used by 
-        // save, save as menu actions
-        function save(file) {
-            var doc = editor.getDocument();
-            frame.setTitle(file.getName() + titleSuffix);
-            curFileName = file;
-            var progress = new JProgressBar();
-            progress.setMinimum(0);
-            progress.setMaximum(file.length());            
-            var out = new java.io.FileWriter(file);
-            var text = new Segment();
-            text.setPartialReturn(true);
-            var charsLeft = doc.getLength();
-            var offset = 0;
-            while (charsLeft > 0) {
-                doc.getText(offset, java.lang.Math.min(4096, charsLeft), text);
-                out.write(text.array, text.offset, text.count);
-                charsLeft -= text.count;
-                offset += text.count;
-                progress.setValue(offset);
-                java.lang.Thread.sleep(10);               
-            }
-            out.flush();
-            out.close();           
-            docChanged = false;           
+    // set a document listener to track
+    // whether that is modified or not
+    function setDocListener() {
+        var doc = editor.getDocument();
+        docChanged = false;
+        doc.addDocumentListener( new guiPkgs.DocumentListener() {
+                                     equals: function(o) {
+                                         return this === o; },
+                                     toString: function() {
+                                         return "doc listener"; },
+                                     changeUpdate: function() {
+                                         docChanged = true; },
+                                     insertUpdate: function() {
+                                         docChanged = true; },
+                                     removeUpdate: function() {
+                                         docChanged = true; }
+                                 });
+    }
+
+    // menu action functions
+
+    // "File" menu
+
+    // create a "new" document
+    function actionNew() {
+        checkDocChanged();
+        curFileName = null;
+        editor.setDocument(new guiPkgs.PlainDocument());
+        setDocListener();
+        frame.setTitle(defaultTitle);
+        editor.revalidate();
+    }
+
+    // open an existing file
+    function actionOpen() {
+        checkDocChanged();
+        var f = fileDialog();
+        if (f == null) {
+            return;
         }
 
-        // file-save as menu
-        function actionSaveAs() {
-            var ret = fileDialog(null, true);
-            if (ret == null) {
-                return;
+        if (f.isFile() && f.canRead()) {
+            frame.setTitle(f.getName() + titleSuffix);
+            editor.setDocument(new guiPkgs.PlainDocument());
+            var progress = new guiPkgs.JProgressBar();
+            progress.setMinimum(0);
+            progress.setMaximum(f.length());
+            var doc = editor.getDocument();
+            var inp = new java.io.FileReader(f);
+            var buff = java.lang.reflect.Array.newInstance(
+                java.lang.Character.TYPE, 4096);
+            var nch;
+            while ((nch = inp.read(buff, 0, buff.length)) != -1) {
+                doc.insertString(doc.getLength(),
+                                 new java.lang.String(buff, 0, nch), null);
+                progress.setValue(progress.getValue() + nch);
             }
-            save(ret);
+            inp.close();
+            curFileName = f.getAbsolutePath();
+            setDocListener();
+        } else {
+            error("Can not open file: " + f,
+                  "Error opening file: " + f);
+        }
+    }
+
+    // open script from a URL
+    function actionOpenURL() {
+        checkDocChanged();
+        var url = prompt("Address:");
+        if (url == null) {
+            return;
         }
 
-        // file-save menu
-        function actionSave() {            
-            if (curFileName) {
-                save(new java.io.File(curFileName));
-            } else {
-                actionSaveAs();
+        try {
+            var u = new java.net.URL(url);
+            editor.setDocument(new guiPkgs.PlainDocument());
+            frame.setTitle(url + titleSuffix);
+            var progress = new guiPkgs.JProgressBar();
+            progress.setMinimum(0);
+            progress.setIndeterminate(true);
+            var doc = editor.getDocument();
+            var inp = new java.io.InputStreamReader(u.openStream());
+            var buff = java.lang.reflect.Array.newInstance(
+                java.lang.Character.TYPE, 4096);
+            var nch;
+            while ((nch = inp.read(buff, 0, buff.length)) != -1) {
+                doc.insertString(doc.getLength(),
+                                 new java.lang.String(buff, 0, nch), null);
+                progress.setValue(progress.getValue() + nch);
+            }
+            curFileName = null;
+            setDocListener();
+        } catch (e) {
+            error("Error opening URL: " + e,
+                  "Can not open URL: " + url);
+        }
+    }
+
+    // factored out "save" function used by
+    // save, save as menu actions
+    function save(file) {
+        var doc = editor.getDocument();
+        frame.setTitle(file.getName() + titleSuffix);
+        curFileName = file;
+        var progress = new guiPkgs.JProgressBar();
+        progress.setMinimum(0);
+        progress.setMaximum(file.length());
+        var out = new java.io.FileWriter(file);
+        var text = new guiPkgs.Segment();
+        text.setPartialReturn(true);
+        var charsLeft = doc.getLength();
+        var offset = 0;
+        var min;
+
+        while (charsLeft > 0) {
+            doc.getText(offset, Math.min(4096, charsLeft), text);
+            out.write(text.array, text.offset, text.count);
+            charsLeft -= text.count;
+            offset += text.count;
+            progress.setValue(offset);
+            java.lang.Thread.sleep(10);
+        }
+
+        out.flush();
+        out.close();
+        docChanged = false;
+    }
+
+    // file-save as menu
+    function actionSaveAs() {
+        var ret = fileDialog(null, true);
+        if (ret == null) {
+            return;
+        }
+        save(ret);
+    }
+
+    // file-save menu
+    function actionSave() {
+        if (curFileName) {
+            save(new java.io.File(curFileName));
+        } else {
+            actionSaveAs();
+        }
+    }
+
+    // exit from scriptpad
+    function actionExit() {
+        checkDocChanged();
+        java.lang.System.exit(0);
+    }
+
+    // "Edit" menu
+
+    // cut the currently selected text
+    function actionCut() {
+        editor.cut();
+    }
+
+    // copy the currently selected text to clipboard
+    function actionCopy() {
+        editor.copy();
+    }
+
+    // paste clipboard content to document
+    function actionPaste() {
+        editor.paste();
+    }
+
+    // select all the text in editor
+    function actionSelectAll() {
+        editor.selectAll();
+    }
+
+    // "Tools" menu
+
+    // run the current document as JavaScript
+    function actionRun() {
+        var doc = editor.getDocument();
+        var script = doc.getText(0, doc.getLength());
+        var oldFile = engine.get(javax.script.ScriptEngine.FILENAME);
+        try {
+            if (engine == undefined) {
+                var m = new javax.script.ScriptEngineManager();
+                engine = m.getEngineByName("nashorn");
+            }
+            engine.put(javax.script.ScriptEngine.FILENAME, frame.title);
+            engine.eval(script, context);
+        } catch (e) {
+            error(e, "Script Error");
+            e.printStackTrace();
+        } finally {
+            engine.put(javax.script.ScriptEngine.FILENAME, oldFile);
+        }
+    }
+
+    // "Examples" menu
+
+    // show given script as new document
+    function showScript(title, str) {
+        actionNew();
+        frame.setTitle("Example - " + title + titleSuffix);
+        var doc = editor.document;
+        doc.insertString(0, str, null);
+    }
+
+    // "hello world"
+    function actionHello() {
+        showScript(actionEval.title,
+                   "alert('Hello, world');");
+    }
+    actionHello.title = "Hello, World";
+
+    // eval the "hello world"!
+    function actionEval() {
+        showScript(actionEval.title,
+                   "eval(\"alert('Hello, world')\");");
+    }
+    actionEval.title = "Eval";
+
+    // show how to access Java static methods
+    function actionJavaStatic() {
+        showScript(arguments.callee.title,
+                   "// Just use Java syntax\n" +
+                   "var props = java.lang.System.getProperties();\n" +
+                   "alert(props.get('os.name'));");
+    }
+    actionJavaStatic.title = "Java Static Calls";
+
+    // show how to access Java classes, methods
+    function actionJavaAccess() {
+        showScript(arguments.callee.title,
+                   "// just use new JavaClass();\n" +
+                   "var fr = new javax.swing.JFrame();\n" +
+                   "// call all public methods as in Java\n" +
+                   "fr.setTitle('hello');\n" +
+                   "fr.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);\n" +
+                   "fr.setSize(200, 200);\n" +
+                   "fr.setVisible(true);");
+    }
+    actionJavaAccess.title = "Java Object Access";
+
+    // show how to use Java bean conventions
+    function actionJavaBean() {
+        showScript(arguments.callee.title,
+                   "var fr = new javax.swing.JFrame();\n" +
+                   "fr.setSize(200, 200);\n" +
+                   "// access public get/set methods as fields\n" +
+                   "fr.defaultCloseOperation = javax.swing.WindowConstants.DISPOSE_ON_CLOSE;\n" +
+                   "fr.title = 'hello';\n" +
+                   "fr.visible = true;");
+    }
+    actionJavaBean.title = "Java Beans";
+
+    // show how to implement Java interface
+    function actionJavaInterface() {
+        showScript(arguments.callee.title,
+                   "// use Java anonymizer class-like syntax!\n" +
+                   "var r = new java.lang.Runnable() {\n" +
+                   "            run: function() {\n" +
+                   "                    alert('hello');\n" +
+                   "            }\n" +
+                   "    };\n" +
+                   "// use the above Runnable to create a Thread\n" +
+                   "new java.lang.Thread(r).start();\n" +
+                   "// For simple one method interfaces, just pass script function\n" +
+                   "new java.lang.Thread(function() { alert('world'); }).start();");
+    }
+    actionJavaInterface.title = "Java Interfaces";
+
+    // show how to import Java classes, packages
+    function actionJavaImport() {
+        showScript(arguments.callee.title,
+                   "// use Java-like import *...\n" +
+                   "//    importPackage(java.io);\n" +
+                   "// or import a specific class\n" +
+                   "//    importClass(java.io.File);\n" +
+                   "// or better - import just within a scope!\n" +
+                   "var ioPkgs = JavaImporter(java.io);\n" +
+                   "with (ioPkgs) { alert(new File('.').absolutePath); }");
+    }
+    actionJavaImport.title = "Java Import";
+
+    // "Help" menu
+
+    /*
+     * Shows a one liner help message for each
+     * global function. Note that this function
+     * depends on docString meta-data for each
+     * function.
+     */
+    function actionHelpGlobals() {
+        var names = new java.util.ArrayList();
+        for (var i in globalThis) {
+            var func = globalThis[i];
+            if (typeof(func) == "function" &&
+                ("docString" in func)) {
+                names.add(i);
             }
         }
+        java.util.Collections.sort(names);
+        var helpDoc = new java.lang.StringBuffer();
+        helpDoc.append("<table border='1'>");
+        var itr = names.iterator();
+        while (itr.hasNext()) {
+            var name = itr.next();
+            helpDoc.append("<tr><td>");
+            helpDoc.append(name);
+            helpDoc.append("</td><td>");
+            helpDoc.append(globalThis[name].docString);
+            helpDoc.append("</td></tr>");
+        }
+        helpDoc.append("</table>");
 
-        // exit from scriptpad
-        function actionExit() {
-            checkDocChanged();           
-            java.lang.System.exit(0);
+        var helpEditor = new guiPkgs.JEditorPane();
+        helpEditor.setContentType("text/html");
+        helpEditor.setEditable(false);
+        helpEditor.setText(helpDoc.toString());
+
+        var scroller = new guiPkgs.JScrollPane();
+        var port = scroller.getViewport();
+        port.add(helpEditor);
+
+        var helpFrame = new guiPkgs.JFrame("Help - Global Functions");
+        helpFrame.getContentPane().add("Center", scroller);
+        helpFrame.setDefaultCloseOperation(guiPkgs.WindowConstants.DISPOSE_ON_CLOSE);
+        helpFrame.pack();
+        helpFrame.setSize(500, 600);
+        helpFrame.setVisible(true);
+    }
+
+    // show a simple about message for scriptpad
+    function actionAbout() {
+        alert("Scriptpad\nVersion 1.1", "Scriptpad");
+    }
+
+    /*
+     * This data is used to construct menu bar.
+     * This way adding a menu is easier. Just add
+     * top level menu or add an item to an existing
+     * menu. "action" should be a function that is
+     * called back on clicking the correponding menu.
+     */
+    var menuData = [
+        {
+            menu: "File",
+            items: [
+                { name: "New",  action: actionNew , accel: guiPkgs.KeyEvent.VK_N },
+                { name: "Open...", action: actionOpen, accel: guiPkgs.KeyEvent.VK_O },
+                { name: "Open URL...", action: actionOpenURL, accel: guiPkgs.KeyEvent.VK_U },
+                { name: "Save", action: actionSave, accel: guiPkgs.KeyEvent.VK_S },
+                { name: "Save As...", action: actionSaveAs },
+                { name: "-" },
+                { name: "Exit", action: actionExit, accel: guiPkgs.KeyEvent.VK_Q }
+            ]
+        },
+
+        {
+            menu: "Edit",
+            items: [
+                { name: "Cut", action: actionCut, accel: guiPkgs.KeyEvent.VK_X },
+                { name: "Copy", action: actionCopy, accel: guiPkgs.KeyEvent.VK_C },
+                { name: "Paste", action: actionPaste, accel: guiPkgs.KeyEvent.VK_V },
+                { name: "-" },
+                { name: "Select All", action: actionSelectAll, accel: guiPkgs.KeyEvent.VK_A }
+            ]
+        },
+
+        {
+            menu: "Tools",
+            items: [
+                { name: "Run", action: actionRun, accel: guiPkgs.KeyEvent.VK_R }
+            ]
+        },
+
+        {
+            menu: "Examples",
+            items: [
+                { name: actionHello.title, action: actionHello },
+                { name: actionEval.title, action: actionEval },
+                { name: actionJavaStatic.title, action: actionJavaStatic },
+                { name: actionJavaAccess.title, action: actionJavaAccess },
+                { name: actionJavaBean.title, action: actionJavaBean },
+                { name: actionJavaInterface.title, action: actionJavaInterface },
+                { name: actionJavaImport.title, action: actionJavaImport }
+            ]
+        },
+
+        {
+            menu: "Help",
+            items: [
+                { name: "Global Functions", action: actionHelpGlobals },
+                { name: "-" },
+                { name: "About Scriptpad", action: actionAbout }
+            ]
+        }
+    ];
+
+    function setMenuAccelerator(mi, accel) {
+        var keyStroke = guiPkgs.KeyStroke.getKeyStroke(accel,
+                                                       guiPkgs.Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false);
+        mi.setAccelerator(keyStroke);
+    }
+
+    // create a menubar using the above menu data
+    function createMenubar() {
+        var mb = new guiPkgs.JMenuBar();
+        for (var m in menuData) {
+            var items = menuData[m].items;
+            var menu = new guiPkgs.JMenu(menuData[m].menu);
+
+            for (var i in items) {
+                if (items[i].name.equals("-")) {
+                    menu.addSeparator();
+                } else {
+                    var mi = new guiPkgs.JMenuItem(items[i].name);
+                    var action = items[i].action;
+                    mi.addActionListener(action);
+                    var accel = items[i].accel;
+                    if (accel) {
+                        setMenuAccelerator(mi, accel);
+                    }
+                    menu.add(mi);
+                }
+	        }
+
+	        mb.add(menu);
         }
 
-        // "Edit" menu 
+        return mb;
+    }
 
-        // cut the currently selected text
-        function actionCut() {
-            editor.cut();
+    // function to add a new menu item under "Tools" menu
+    function addTool(menuItem, action, accel) {
+        if (typeof(action) != "function") {
+            return;
         }
 
-        // copy the currently selected text to clipboard
-        function actionCopy() {
-            editor.copy();
-        }
-
-        // paste clipboard content to document
-        function actionPaste() {
-            editor.paste();
-        }
-
-        // select all the text in editor
-        function actionSelectAll() {
-            editor.selectAll();
-        }
-
-        // "Tools" menu 
-
-        // run the current document as JavaScript
-        function actionRun() {
-            var doc = editor.getDocument();
-            var script = doc.getText(0, doc.getLength());
-            var oldFile = engine.get(javax.script.ScriptEngine.FILENAME);
-            try {
-                if (this.engine == undefined) {
-                    var m = new javax.script.ScriptEngineManager();
-                    engine = m.getEngineByName("js");
-                }
-                engine.put(javax.script.ScriptEngine.FILENAME, frame.title);
-                engine.eval(script, context);
-            } catch (e) {  
-                error(e, "Script Error");
-                // e.rhinoException.printStackTrace();
-            } finally {
-                engine.put(javax.script.ScriptEngine.FILENAME, oldFile);
+        var toolsIndex = -1;
+        // find the index of the "Tools" menu
+        for (var i in menuData) {
+            if (menuData[i].menu.equals("Tools")) {
+                toolsIndex = i;
+                break;
             }
         }
+        if (toolsIndex == -1) {
+            return;
+        }
+        var toolsMenu = frame.getJMenuBar().getMenu(toolsIndex);
+        var mi = new guiPkgs.JMenuItem(menuItem);
+        mi.addActionListener(action);
+        if (accel) {
+            setMenuAccelerator(mi, accel);
+        }
+        toolsMenu.add(mi);
+    }
 
-        // "Examples" menu 
+    // create Scriptpad frame
+    function createFrame() {
+        frame = new guiPkgs.JFrame();
+        frame.setTitle(defaultTitle);
+        frame.setBackground(guiPkgs.Color.lightGray);
+        frame.getContentPane().setLayout(new guiPkgs.BorderLayout());
 
-        // show given script as new document
-        function showScript(title, str) { 
-            actionNew();
-            frame.setTitle("Example - " + title + titleSuffix);
-            var doc = editor.document;
-            doc.insertString(0, str, null);
-        }
+        // create notepad panel
+        var notepad = new guiPkgs.JPanel();
+        notepad.setBorder(guiPkgs.BorderFactory.createEtchedBorder());
+        notepad.setLayout(new guiPkgs.BorderLayout());
 
-        // "hello world"
-        function actionHello() {
-            showScript(arguments.callee.title,
-                "alert('Hello, world');");
-        }
-        actionHello.title = "Hello, World";
+        // create editor
+        editor = createEditor();
+        var scroller = new guiPkgs.JScrollPane();
+        var port = scroller.getViewport();
+        port.add(editor);
 
-        // eval the "hello world"!
-        function actionEval() {
-            showScript(actionEval.title,
-                "eval(\"alert('Hello, world')\");");
-        }
-        actionEval.title = "Eval";
+        // add editor to notepad panel
+        var panel = new guiPkgs.JPanel();
+        panel.setLayout(new guiPkgs.BorderLayout());
+        panel.add("Center", scroller);
+        notepad.add("Center", panel);
 
-        // show how to access Java static methods
-        function actionJavaStatic() {
-            showScript(arguments.callee.title,
-                "// Just use Java syntax\n" +
-                "var props = java.lang.System.getProperties();\n" +
-                "alert(props.get('os.name'));");
-        }
-        actionJavaStatic.title = "Java Static Calls";
+        // add notepad panel to frame
+        frame.getContentPane().add("Center", notepad);
 
-        // show how to access Java classes, methods
-        function actionJavaAccess() {
-            showScript(arguments.callee.title,
-                "// just use new JavaClass();\n" +
-                "var fr = new javax.swing.JFrame();\n" +
-                "// call all public methods as in Java\n" +
-                "fr.setTitle('hello');\n" +
-                "fr.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);\n" +
-                "fr.setSize(200, 200);\n" +
-                "fr.setVisible(true);");
-        }
-        actionJavaAccess.title = "Java Object Access";
+        // set menu bar to frame and show the frame
+        frame.setJMenuBar(createMenubar());
+        frame.setDefaultCloseOperation(guiPkgs.JFrame.EXIT_ON_CLOSE);
+        frame.pack();
+        frame.setSize(500, 600);
+    }
 
-        // show how to use Java bean conventions
-        function actionJavaBean() {
-            showScript(arguments.callee.title,
-                "var fr = new javax.swing.JFrame();\n" +
-                "fr.setSize(200, 200);\n" +
-                "// access public get/set methods as fields\n" +
-                "fr.defaultCloseOperation = javax.swing.WindowConstants.DISPOSE_ON_CLOSE;\n" +
-                "fr.title = 'hello';\n" +
-                "fr.visible = true;"); 
-        }
-        actionJavaBean.title = "Java Beans";
+    // show Scriptpad frame
+    function showFrame() {
+        // set global variable by the name "window"
+        globalThis.window = frame;
 
-        // show how to implement Java interface
-        function actionJavaInterface() {
-            showScript(arguments.callee.title,
-                "// use Java anonymizer class-like syntax!\n" +
-                "var r = new java.lang.Runnable() {\n" +
-                "            run: function() {\n" +
-                "                    alert('hello');\n" +
-                "            }\n" +
-                "    };\n" +
-                "// use the above Runnable to create a Thread\n" +
-                "java.lang.Thread(r).start();\n" +
-                "// For simple one method interfaces, just pass script function\n" +
-                "java.lang.Thread(function() { alert('world'); }).start();");
-        }
-        actionJavaInterface.title = "Java Interfaces";
+        // open new document
+        actionNew();
 
-        // show how to import Java classes, packages
-        function actionJavaImport() {
-            showScript(arguments.callee.title,
-                "// use Java-like import *...\n" +
-                "//    importPackage(java.io);\n" +
-                "// or import a specific class\n" +
-                "//    importClass(java.io.File);\n" +
-                "// or better - import just within a scope!\n" +
-                "var ioPkgs = JavaImporter(java.io);\n" +
-                "with (ioPkgs) { alert(new File('.').absolutePath); }");
-        }
-        actionJavaImport.title = "Java Import";
+        frame.setVisible(true);
+    }
 
-        // "Help" menu 
+    // create and show Scriptpad frame
+    createFrame();
+    showFrame();
 
-	/*
-         * Shows a one liner help message for each 
-         * global function. Note that this function 
-         * depends on docString meta-data for each 
-         * function.
-         */
-        function actionHelpGlobals() {
-            var names = new java.util.ArrayList();
-            for (var i in this) {
-                var func = this[i];
-                if (typeof(func) == "function" &&
-                   ("docString" in func)) {
-                    names.add(i);
-                }
-            }
-            java.util.Collections.sort(names);
-            var helpDoc = new java.lang.StringBuffer();
-            helpDoc.append("<table border='1'>");
-            var itr = names.iterator();
-            while (itr.hasNext()) {
-                var name = itr.next();
-                helpDoc.append("<tr><td>");
-                helpDoc.append(name);
-                helpDoc.append("</td><td>");
-                helpDoc.append(this[name].docString);
-                helpDoc.append("</td></tr>");                
-            }
-            helpDoc.append("</table>");
-
-            var helpEditor = new JEditorPane();
-            helpEditor.setContentType("text/html");            
-            helpEditor.setEditable(false);
-            helpEditor.setText(helpDoc.toString());
-
-            var scroller = new JScrollPane();
-            var port = scroller.getViewport();
-            port.add(helpEditor);
-
-            var helpFrame = new JFrame("Help - Global Functions");
-            helpFrame.getContentPane().add("Center", scroller);
-            helpFrame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
-            helpFrame.pack();
-            helpFrame.setSize(500, 600); 
-            helpFrame.setVisible(true);
-        }
-
-        // show a simple about message for scriptpad
-        function actionAbout() {
-            alert("Scriptpad\nVersion 1.0", "Scriptpad");
-        }
-
-        /*
-         * This data is used to construct menu bar.
-         * This way adding a menu is easier. Just add
-         * top level menu or add an item to an existing 
-         * menu. "action" should be a function that is
-         * called back on clicking the correponding menu.
-         */
-        var menuData = [
-            {
-              menu: "File",
-              items: [ 
-                  { name: "New",  action: actionNew , accel: KeyEvent.VK_N },
-                  { name: "Open...", action: actionOpen, accel: KeyEvent.VK_O },                         
-                  { name: "Open URL...", action: actionOpenURL, accel: KeyEvent.VK_U },
-                  { name: "Save", action: actionSave, accel: KeyEvent.VK_S },
-                  { name: "Save As...", action: actionSaveAs },
-                  { name: "-" },
-                  { name: "Exit", action: actionExit }
-                ]
-            },
-
-            {
-              menu: "Edit", 
-              items: [ 
-                  { name: "Cut", action: actionCut, accel: KeyEvent.VK_X },
-                  { name: "Copy", action: actionCopy, accel: KeyEvent.VK_C },                        
-                  { name: "Paste", action: actionPaste, accel: KeyEvent.VK_V },
-                  { name: "-" },
-                  { name: "Select All", action: actionSelectAll, accel: KeyEvent.VK_A }
-                ]
-            },
-           
-            { 
-              menu: "Tools", 
-              items: [                 
-                  { name: "Run", action: actionRun, accel: KeyEvent.VK_R },
-                ]
-            },
-
-            { 
-              menu: "Examples", 
-              items: [                 
-                  { name: actionHello.title, action: actionHello },
-                  { name: actionEval.title, action: actionEval },
-                  { name: actionJavaStatic.title, action: actionJavaStatic },
-                  { name: actionJavaAccess.title, action: actionJavaAccess },
-                  { name: actionJavaBean.title, action: actionJavaBean },
-                  { name: actionJavaInterface.title, action: actionJavaInterface },
-                  { name: actionJavaImport.title, action: actionJavaImport },
-               ]
-            },
-
-            { 
-              menu: "Help",  
-              items: [ 
-                  { name: "Global Functions", action: actionHelpGlobals },
-                  { name: "-" },
-                  { name: "About Scriptpad", action: actionAbout },
-                ]
-            }
-        ];
-
-
-        function setMenuAccelerator(mi, accel) {
-            var keyStroke = KeyStroke.getKeyStroke(accel,
-                Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false);
-            mi.setAccelerator(keyStroke);
-        }
-        
-        // create a menubar using the above menu data
-        function createMenubar() {
-            var mb = new JMenuBar();
-            for (var m in menuData) {
-                var items = menuData[m].items;
-                var menu = new JMenu(menuData[m].menu);                
-                for (var i in items) {
-                    if (items[i].name.equals("-")) {
-                        menu.addSeparator();
-                    } else {
-                        var mi = new JMenuItem(items[i].name);
-                        var action = items[i].action;
-                        mi.addActionListener(action);
-                        var accel = items[i].accel;
-                        if (accel) {
-                            setMenuAccelerator(mi, accel);
-                        }
-                        menu.add(mi);
-                    }
-	        }                    
-	        mb.add(menu);
-            }
-            return mb;
-        }
-
-        // function to add a new menu item under "Tools" menu
-        function addTool(menuItem, action, accel) {
-            if (typeof(action) != "function") {
-                return;
-            }
-
-            var toolsIndex = -1;
-            // find the index of the "Tools" menu
-            for (var i in menuData) {
-                if (menuData[i].menu.equals("Tools")) {
-                    toolsIndex = i;
-                    break;
-                }
-            }
-            if (toolsIndex == -1) {
-                return;
-            }
-            var toolsMenu = frame.getJMenuBar().getMenu(toolsIndex);
-            var mi = new JMenuItem(menuItem);
-            mi.addActionListener(action);
-            if (accel) {
-                setMenuAccelerator(mi, accel);
-            }
-            toolsMenu.add(mi);
-        }
-
-
-        // create Scriptpad frame
-        function createFrame() {
-            frame = new JFrame();
-            frame.setTitle(defaultTitle);
-            frame.setBackground(Color.lightGray);
-            frame.getContentPane().setLayout(new BorderLayout());
-
-            // create notepad panel
-            var notepad = new JPanel();
-            notepad.setBorder(BorderFactory.createEtchedBorder());
-            notepad.setLayout(new BorderLayout());
-
-            // create editor
-            editor = createEditor();
-            var scroller = new JScrollPane();
-            var port = scroller.getViewport();
-            port.add(editor);
-
-            // add editor to notepad panel
-            var panel = new JPanel(); 
-            panel.setLayout(new BorderLayout());        
-            panel.add("Center", scroller);
-            notepad.add("Center", panel);
-
-            // add notepad panel to frame
-            frame.getContentPane().add("Center", notepad);
-
-            // set menu bar to frame and show the frame   
-            frame.setJMenuBar(createMenubar());
-            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
-            frame.pack();
-            frame.setSize(500, 600);
-        }
-
-        // show Scriptpad frame
-        function showFrame() {
-            // set global variable by the name "window"
-            this.window = frame;     
-
-            // open new document
-            actionNew();
-
-            frame.setVisible(true);
-        }
-
-        // create and show Scriptpad frame
-        createFrame();
-        showFrame();
-
-        /*
-         * Application object has two fields "frame", "editor"
-         * which are current JFrame and editor and a method
-         * called "addTool" to add new menu item to "Tools" menu.
-         */
-        return {
-            frame: frame,
-            editor: editor,
-            addTool: addTool
-        };
-    }
-}
+    /*
+     * Application object has two fields "frame", "editor"
+     * which are current JFrame and editor and a method
+     * called "addTool" to add new menu item to "Tools" menu.
+     */
+    return {
+        frame: frame,
+        editor: editor,
+        addTool: addTool
+    };
+};
 
 /*
- * Call the main and store Application object 
+ * Call the main and store Application object
  * in a global variable named "application".
  */
 var application = main();
@@ -657,4 +660,3 @@
 }
 
 loadUserInit();
-
--- a/src/share/sample/scripting/scriptpad/src/scripts/browse.js	Tue May 14 20:16:21 2013 +0400
+++ b/src/share/sample/scripting/scriptpad/src/scripts/browse.js	Tue May 14 22:36:52 2013 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,33 +37,30 @@
  * this sample code.
  */
 
-
 /*
  * This function uses new Swing Desktop API in JDK 6.
  * To use this with scriptpad, open this in scriptpad
  * and use "Tools->Run Script" menu.
  */
 function browse() {
-    with (guiPkgs) {
-        var desktop = null;
-        // Before more Desktop API is used, first check 
-        // whether the API is supported by this particular 
-        // virtual machine (VM) on this particular host.
-        if (Desktop.isDesktopSupported()) {
-            desktop = Desktop.getDesktop();
-        } else {
-            alert("no desktop support");
-            return;
+    var desktop = null;
+    // Before more Desktop API is used, first check
+    // whether the API is supported by this particular
+    // virtual machine (VM) on this particular host.
+    if (java.awt.Desktop.isDesktopSupported()) {
+        desktop = java.awt.Desktop.getDesktop();
+    } else {
+        alert("no desktop support");
+        return;
+    }
+
+    if (desktop.isSupported(java.awt.Desktop.Action.BROWSE)) {
+        var url = prompt("Address:");
+        if (url != null) {
+            desktop.browse(new java.net.URI(url));
         }
-
-        if (desktop.isSupported(Desktop.Action.BROWSE)) {
-            var url = prompt("Address:");
-            if (url != null) {
-                desktop.browse(new java.net.URI(url));
-            }
-        } else {
-            alert("no browser support");
-        }
+    } else {
+        alert("no browser support");
     }
 }
 
@@ -71,4 +68,3 @@
     // add "Browse" menu item under "Tools" menu
     this.application.addTool("Browse", browse);
 }
-
--- a/src/share/sample/scripting/scriptpad/src/scripts/insertfile.js	Tue May 14 20:16:21 2013 +0400
+++ b/src/share/sample/scripting/scriptpad/src/scripts/insertfile.js	Tue May 14 22:36:52 2013 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,7 +37,6 @@
  * this sample code.
  */
 
-
 /*
  * This script adds "Insert File" mode menu item to "Tools" menu.
  * When selected, this menu shows a file dialog box and inserts
@@ -48,18 +47,22 @@
     application.addTool("Insert File...",
         function() {
             var file = fileDialog();
-            if (file) {               
+
+            if (file) {
                 var reader = new java.io.FileReader(file);
                 var arr = java.lang.reflect.Array.newInstance(
                       java.lang.Character.TYPE, 8*1024); // 8K at a time
                 var buf = new java.lang.StringBuffer();
                 var numChars;
+
                 while ((numChars = reader.read(arr, 0, arr.length)) > 0) {
                     buf.append(arr, 0, numChars);
                 }
+
                 var pos = application.editor.caretPosition;
                 var doc = application.editor.document;
+
                 doc.insertString(pos, buf.toString(), null);
            }
-        })
+        });
 }
--- a/src/share/sample/scripting/scriptpad/src/scripts/linewrap.js	Tue May 14 20:16:21 2013 +0400
+++ b/src/share/sample/scripting/scriptpad/src/scripts/linewrap.js	Tue May 14 22:36:52 2013 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,19 +37,15 @@
  * this sample code.
  */
 
-
 /*
  * This script adds "Line Wrap" mode menu item to "Tools" menu.
  * When selected, this menu toggles the current word wrap mode
  * of the editor.
  */
-with (guiPkgs) {
 
-    function toggleLineWrap() {
-        var wrap = application.editor.lineWrap;
-        application.editor.lineWrap = !wrap;
-    }
-
-    application.addTool("Line Wrap",  toggleLineWrap);
+function toggleLineWrap() {
+    var wrap = application.editor.lineWrap;
+    application.editor.lineWrap = !wrap;
 }
 
+application.addTool("Line Wrap",  toggleLineWrap);
--- a/src/share/sample/scripting/scriptpad/src/scripts/mail.js	Tue May 14 20:16:21 2013 +0400
+++ b/src/share/sample/scripting/scriptpad/src/scripts/mail.js	Tue May 14 22:36:52 2013 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,30 +37,27 @@
  * this sample code.
  */
 
-
 /*
  * This function uses new Swing Desktop API in JDK 6.
  * To use this with scriptpad, open this in scriptpad
  * and use "Tools->Run Script" menu.
  */
 function mail() {
-    with (guiPkgs) {
-        var desktop = null;
-        // Before more Desktop API is used, first check 
-        // whether the API is supported by this particular 
-        // virtual machine (VM) on this particular host.
-        if (Desktop.isDesktopSupported()) {
-            desktop = Desktop.getDesktop();
-        } else {
-            alert("no desktop support");
-            return;
-        }
+    var desktop = null;
+    // Before more Desktop API is used, first check
+    // whether the API is supported by this particular
+    // virtual machine (VM) on this particular host.
+    if (java.awt.Desktop.isDesktopSupported()) {
+        desktop = java.awt.Desktop.getDesktop();
+    } else {
+        alert("no desktop support");
+        return;
+    }
 
-        if (desktop.isSupported(Desktop.Action.MAIL)) {
-            var mailTo = prompt("Mail To:");
-            if (mailTo != null) {
-                desktop.mail(new java.net.URI("mailto", mailTo, null));
-            }
+    if (desktop.isSupported(java.awt.Desktop.Action.MAIL)) {
+        var mailTo = prompt("Mail To:");
+        if (mailTo != null) {
+            desktop.mail(new java.net.URI("mailto", mailTo, null));
         }
     }
 }
--- a/src/share/sample/scripting/scriptpad/src/scripts/memmonitor.js	Tue May 14 20:16:21 2013 +0400
+++ b/src/share/sample/scripting/scriptpad/src/scripts/memmonitor.js	Tue May 14 22:36:52 2013 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,36 +37,37 @@
  * this sample code.
  */
 
-
 // this checker function runs asynchronously
 function memoryChecker(memoryBean, threshold, interval) {
     while (true) {
         var memUsage = memoryBean.HeapMemoryUsage;
         var usage = memUsage.get("used") / (1024 * 1024);
-        println(usage);
+
+        println("usage: " + usage);
+
         if (usage > threshold) {
             alert("Hey! heap usage threshold exceeded!");
             // after first alert just return.
             return;
         }
-        java.lang.Thread.currentThread().sleep(interval);
+
+        java.lang.Thread.sleep(interval);
     }
 }
 
-
 // add "Tools->Memory Monitor" menu item
 if (this.application != undefined) {
-    this.application.addTool("Memory Monitor", 
+    this.application.addTool("Memory Monitor",
         function () {
             // show threshold box with default of 50 MB
             var threshold = prompt("Threshold (mb)", 50);
+
             // show interval box with default of 1000 millisec.
             var interval = prompt("Sample Interval (ms):", 1000);
             var memoryBean = mbean("java.lang:type=Memory");
 
-            // ".future" makes the function to be called 
+            // ".future" makes the function to be called
             // asynchronously in a separate thread.
             memoryChecker.future(memoryBean, threshold, interval);
         });
 }
-
--- a/src/share/sample/scripting/scriptpad/src/scripts/memory.js	Tue May 14 20:16:21 2013 +0400
+++ b/src/share/sample/scripting/scriptpad/src/scripts/memory.js	Tue May 14 22:36:52 2013 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,7 +37,6 @@
  * this sample code.
  */
 
-
 /*
  * This script serves as a simple "monitored application".
  * Start this script using memory.bat or memory.sh in the
@@ -45,12 +44,11 @@
  */
 
 java.lang.System.out.print("Enter a number and press enter:");
-java.lang.System["in"].read();        
+var input = java.lang.System["in"].read();
 
 // allocate an integer array of "big enough" size!
 var a = java.lang.reflect.Array.newInstance(
-            java.lang.Integer.TYPE, 1024*1024);  
+    java.lang.Integer.TYPE, input * 1024 * 1024);
 
-// loop forever!
-while (true);
-
+// sleep some time...
+java.lang.Thread.sleep(10*60*1000);
--- a/src/share/sample/scripting/scriptpad/src/scripts/memory.sh	Tue May 14 20:16:21 2013 +0400
+++ b/src/share/sample/scripting/scriptpad/src/scripts/memory.sh	Tue May 14 22:36:52 2013 +0530
@@ -30,7 +30,3 @@
 #
 
 jrunscript -J-Dcom.sun.management.jmxremote.port=1090 -J-Dcom.sun.management.jmxremote.ssl=false -J-Dcom.sun.management.jmxremote.authenticate=false memory.js
-
-
-
-
--- a/src/share/sample/scripting/scriptpad/src/scripts/textcolor.js	Tue May 14 20:16:21 2013 +0400
+++ b/src/share/sample/scripting/scriptpad/src/scripts/textcolor.js	Tue May 14 22:36:52 2013 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,14 +37,13 @@
  * this sample code.
  */
 
-
 /*
  * This script adds "Selected Text Color" menu item to "Tools" menu.
  * When selected, this menu changes the "selected text" color.
  */
 if (this.application) {
     application.addTool("Selected Text Color...",
-        function() {          
+        function() {
             var color = application.editor.selectedTextColor;
             color = colorDialog("Selected Text Color", color);
             application.editor.selectedTextColor = color;