Patent Publication Number: US-7584478-B1

Title: Framework for lengthy Java Swing interacting tasks

Description:
REFERENCE TO EARLIER-FILED APPLICATION 
     This application claims benefit of priority from U.S. Provisional Patent Application No. 60/582,871, filed Jun. 25, 2004, for SWINGWORKER FRAMEWORK FOR LENGTHY JAVA SWING/JFC INTERACTING TASKS, which is hereby incorporated by reference. 
     CROSS REFERENCE TO RELATED APPLICATIONS 
     This application relates to commonly assigned, U.S. Pat. No. 7,464,382, filed concurrently herewith, for UI AWARE METHOD INVOCATION TRANSFERRING JAVA EVENT DISPATCH THREAD, which is hereby incorporated by reference. 
    
    
     FIELD 
     The present invention relates to the implementing of lengthy user interface (UI) interacting tasks using a Java event dispatch thread. 
     BACKGROUND 
     The Java 2 Platform Standard Edition (J2SE) and the Java Development Kit (JDK) provide developers with access to a wide range of user interface (UI) and graphical user interface (GUI) components. The JDK provides flexibility and control over the appearance of UIs and GUIs. 
     Conventional graphics toolkits, such as the Abstract Windowing Toolkit (AWT), provide application programming interfaces (APIs) for applications. The Java Foundation Classes (JFC), also commonly referred to as “Swing” or the “Swing toolkit,” are a set of Java class libraries having components that build upon the AWT by providing additional UI and GUI components and services. The Swing toolkit incorporates the AWT and is included in the JDK and J2SE to provide a rich, extensible GUI component library. The Swing toolkit is implemented in the Java programming language, and enables building of applications with GUIs and graphics functionality that can run on any platform supporting the J2SE, such as Microsoft Windows, Linux, and Mac OS X. 
     The Swing toolkit includes categories of components: atomic controls, complex data components, text components, menu components, layout containers and top-level window components. Examples of Swing components include buttons, panels, listboxes and checkboxes. In addition to the new components, the Swing toolkit offers a customizable look and feel that allows the components to take on the appearance of various windowing systems, or their own unique look and feel. For instance, Swing allows applications to easily convert from a “Java look and feel” to a “Windows look and feel.” Developers have the ability to create their own look and feel for custom applications. Regardless of the desired look and feel, a consistent API can be maintained for the component. Thus, developers can code their application GUI once and run it in multiple look and feels. 
     Swing is not designed for multi-threading. Access to a Swing component or class has to occur from a single thread, specifically an event dispatch thread (EDT). Thus, once a Swing component has been realized (e.g., when the component&#39;s “paint” method has been called), all code that might affect or depend on the state of that component should be executed on the EDT. The EDT is responsible for processing all UI and GUI related events, such as user interactions (e.g., mouse clicks, key presses), notification of listeners of user input, and all painting and graphics including repainting dirty regions or updated areas. Essentially every instruction to change something or request something from the Swing component is executed as an event on the EDT. 
     The EDT handles many different events, as described above. At the EDT, all of the events or tasks are queued and processed sequentially. Problems can occur when too many events are queued. If one event takes a long time to process on the EDT, such as loading an HTML page, all of the other events in the queue will have to wait to be processed. This waiting or delay is undesirable. It is generally perceived as the entire UI and application itself being unresponsive, often referred to as “freezing” or “blocking.” 
     Conventional techniques for attempting to reduce freezing or blocking include two Swing utilities. These Swing utilities are java.awt.EventQueue.invokeLater, used for asynchronous method calls, and java.awt.EventQueue.invokeandWait for synchronous calls. However, the methods java.awt.EventQueue.invokeLater and java.awt.EventQueue.invokeandWait create runnable classes for every call to those methods. Each runnable class is executed as a separate event on the EDT. Creating new runnable classes for every call is computationally expensive, and often results in the same freezing or blocking problem described above when many runnable classes are passed to the EDT. 
     Lengthy tasks are computational operations requiring a long time, that is, more than a nominal amount of time, to process. As used herein, anything more than a fraction of a second generally constitutes a “long time.” Examples of lengthy tasks include various calculations, class loading, class initialization, blocking for data networks such as the Internet, disk access operations, and loading HTML documents from the Internet for display on a GUI. Because lengthy tasks are time-consuming, they are desirably processed as background processes separate and apart from the EDT. Otherwise, sending lengthy tasks to the EDT could result in unacceptable freezing situations. That is, all of the regular tasks to be scheduled on the EDT such as painting, responding to mouse movements, processing button events, and application resizing, would have to wait until the lengthy task was completed. 
     In some cases, lengthy tasks require interaction with Java Swing components. Handling of these lengthy tasks can be particularly troubling. On the one hand, it is desirable to process the lengthy task as a background process, because of its time-consuming nature. On the other hand, the general rule is that Swing components have to be accessed from the EDT only. 
     SwingWorker is an abstract class that can be subclassed to perform GUI-related work in a dedicated thread. The conventional SwingWorker class is implemented in SwingWorker.java, and is publicly available for download. SwingWorker provides the mechanism for implementing lengthy tasks as background processes, i.e., background threads. 
     To use the conventional SwingWorker class, a developer first creates a subclass of it. In the subclass, a construct( ) method is implemented so that the subclass contains the code to perform the lengthy task. When the SwingWorker subclass is instantiated, SwingWorker creates a thread but does not start it. The developer invokes start( ) on the SwingWorker object to start the thread, which then calls the construct( ) method. When the object returned by the construct( ) method is needed, the SwingWorker&#39;s get( ) method is called. The following is one example of using SwingWorker: 
     
       
         
           
               
               
             
               
                   
                   
               
             
            
               
                   
                 . . . //in the main method: 
               
               
                   
                   final SwingWorker worker = 
               
               
                   
                     new SwingWorker( ) { 
               
               
                   
                       public Object construct( ) { 
               
               
                   
                         return new 
               
               
                   
                           expensiveDialogComponent( ); 
               
               
                   
                       } 
               
               
                   
                   }; 
               
               
                   
                   worker.start( ); 
               
               
                   
                 . . . //in an action event handler: 
               
               
                   
                   JOptionPane.showMessageDialog 
               
               
                   
                       (f, worker.get( )); 
               
               
                   
                   
               
            
           
         
       
     
     When the program&#39;s main( ) method invokes the start( ) method, SwingWorker starts a new thread that instantiates ExpensiveDialogComponent. The main( ) method also constructs a GUI that consists of a window with a button. When the user clicks the button, the program blocks, if necessary, until the ExpensiveDialogComponent has been created. The program then shows a modal dialog containing the ExpensiveDialogComponent. You can find the entire program in MyApplication.java. 
     With conventional implementations of SwingWorker, it is generally only possible to deliver the final result or output of a lengthy task to the EDT. Intermediate results and state information, provided before the final result is provided, cannot be delivered. Thus, a user has to wait for the final result. For instance, when downloading a document, a user must wait for the entire document (final result) to be downloaded, even though certain data within the document such as images, text, and other objects (partial results) are downloaded in the interim. Waiting in this manner can be frustrating for the user who is more concerned with the partial results, i.e., parts of the final document, or at least some state information describing the progress or status of the document download. 
     Efficient techniques are needed for accessing Swing components from outside of the EDT, including calling methods requiring execution of events on the EDT from outside of the EDT, and executing lengthy tasks which need to interact with a UI using the EDT. 
     SUMMARY 
     Disclosed are methods and apparatus, including computer program products, implementing and using techniques for accessing Swing components from outside an event dispatch thread (EDT). Aspects of the present invention provide for efficient execution of events on the EDT responsive to method calls from outside of the EDT and, in some aspects, interaction with the EDT to execute lengthy tasks. 
     According to some aspects of the present invention, methods and apparatus provide improvements to SwingWorker and provide a framework to facilitate the development and implementation of many sorts of processes, including lengthy tasks, that interact with Java Swing/JFC components of a UI. In one implementation, the methods and apparatus described herein are provided in an abstract class to be extended by a developer. Such can ease the effort required to write a non-freezing UI. 
     According to some aspects of the present invention, methods and apparatus address the limitation that Swing access the Swing application programming interface (API) from the EDT only. In some embodiments, the disclosed methods and apparatus allow lengthy tasks executing outside the EDT to deliver state information and partial results to the EDT. Processing is minimized on the EDT by sending partial results and state information to the EDT. 
     According to some aspects of the present invention, methods and apparatus provide the capability of coalescing method calls, such as partial result publishing on the EDT. An example of coalescing is provided by the Consume method, in which arguments are combined when the same method is called for the same object. Calls coalescing improves application performance and the UI response time. 
     According to one aspect of the present invention, techniques are disclosed for sending method calls from a process to an EDT for output, wherein the EDT handles events related to a user interface. A process is provided, executing independent of the EDT. The process generates a first partial result and a second partial result during execution, and a final result. The first partial result has a first argument, and the second partial result has a second argument. During execution of the process, the first and second partial results are sent to a memory. The first and second partial results are coalesced to produce a combined partial result. The combined partial result is output to the EDT. The outputting is asynchronous with sending the first and second partial results to the memory. 
     All of the foregoing, along with other methods of aspects of the present invention, may be implemented in software, firmware, hardware and combinations thereof. For example, methods of aspects of the present invention may be implemented by computer programs embodied in machine-readable media and other products. These and other features and benefits of aspects of the invention will be described in more detail below with reference to the associated drawings. 
    
    
     
       BRIEF DESCRIPTION OF THE FIGURES 
         FIG. 1  is a block diagram showing an event dispatch thread, according to one embodiment of the present invention. 
         FIG. 2  is a class diagram for an application programming interface (API) that implements embodiments of methods and apparatus of the present invention. 
         FIG. 3  is a flow diagram showing a method for coalescing method calls, performed in accordance with one embodiment of the present invention. 
         FIG. 4  is a sequence diagram showing a method for transferring a method call to the EDT, performed in accordance with an embodiment of the present invention. 
         FIG. 5  is a block diagram showing a background process and an event dispatch thread, implementing embodiments of methods and apparatus of the present invention. 
         FIG. 6A  is a timing diagram showing operation of a Schedule method and a Consume method during processing of a background process and event dispatch thread, according to one embodiment of the present invention. 
         FIG. 6B  is a class diagram for an application programming interface (API) that implements a SwingWorker embodiment of methods and apparatus of the present invention. 
         FIG. 7  shows a graphical user interface updated using a method for sending method calls to an event dispatch thread, according to one embodiment of the present invention. 
         FIG. 8  is a block diagram of a computer system or data processing apparatus  700  used for performing methods in accordance with embodiments of the present invention. 
         FIG. 9  is a diagrammatic representation of a virtual machine suitable for implementing embodiments of methods and apparatus of the present invention. 
     
    
    
     In the Figs., like reference symbols in the various drawings indicate like elements. 
     DETAILED DESCRIPTION 
     Reference will now be made in detail to some specific embodiments of the invention including the best modes contemplated by the inventors for carrying out the invention. Examples of these specific embodiments are illustrated in the accompanying drawings. While the invention is described in conjunction with these specific embodiments, it will be understood that it is not intended to limit the invention to the described embodiments. On the contrary, it is intended to cover alternatives, modifications, and equivalents as may be included within the spirit and scope of the invention as defined by the appended claims. Moreover, numerous specific details are set forth below in order to provide a thorough understanding of the present invention. The present invention may be practiced without some or all of these specific details. In other instances, well known process operations have not been described in detail in order not to obscure the present invention. 
     Embodiments of the present invention provide methods and apparatus, including computer program products, implementing efficient techniques for accessing Swing components from outside an event dispatch thread (EDT). Embodiments of the methods and apparatus described herein provide efficient execution of events on the EDT responsive to method calls from outside of the EDT and, in some embodiments, interaction with the EDT to execute lengthy tasks. 
     Methods performed in accordance with embodiments of the invention provide efficient transfer of methods from one thread to another thread. Such transfer of executing code avoids the unnecessary queuing of events on the EDT, thus minimizing and often eliminating the freezing or blocking phenomenon. In some embodiments, the present invention provides scheduling and coalescing of method calls for execution on the EDT, preventing the EDT from being overwhelmed. 
     Embodiments of the methods and apparatus described herein provide improvements to SwingWorker and provide a framework to facilitate the development and implementation of many sorts of processes, including lengthy tasks, that interact with Java Swing/JFC components of a UI. In one embodiment, the methods and apparatus for interacting with Swing components implement novel techniques for transferring method calls from one thread to another, as described herein. In one embodiment, embodiments of the methods and apparatus described herein are provided in an abstract class to be extended by a developer. In this way, the methods and apparatus can ease the effort required to write a non-freezing UI. 
     Embodiments of the methods and apparatus described herein address the limitation that Swing access the Swing application programming interface (API) from the EDT only. In some embodiments, the disclosed methods and apparatus allow lengthy tasks executing outside the EDT to deliver state information and partial results to the EDT. Processing is minimized on the EDT by sending partial results and state information to the EDT. As used herein, “partial results” refers to method calls generated by a background process, such as a lengthy task, during execution of the process that is ready to be published or otherwise output on the EDT before the final result of the background process is available. “Final result” refers to the final output of the background process, generally when the background process completes execution. In some instances, the final result includes part or all of the partial results that may have been generated during execution. 
     The handling of partial results by embodiments of the present invention represents an improvement over conventional techniques in which only final results were delivered to the EDT. Embodiments of the present invention provide for partial results to be easily published. In many situations, the partial results (e.g., blocks of text or images contained in a single HTML document to be downloaded from the Internet) may be more important to the user to receive as soon as reasonably possible, rather than waiting for the final result (e.g., entire document). Using embodiments of methods and apparatus of the present invention, when a time consuming operation is being performed, such as downloading a document, the user can see parts of the document before the entire document has been received. 
     In addition, embodiments of methods and apparatus of the present invention provide the capability of coalescing method calls, such as partial result publishing on the EDT. “Coalescing” refers to merging two or more calls into one to be executed on the EDT. An example of coalescing is provided by the Consume method, described below, in which arguments are combined when the same method is called for the same object. Other types of coalescing are described below. Calls coalescing for the Consume method and the setProgress method, described below, improve application performance and the UI response time. 
     Embodiments of the methods and apparatus described herein provide the capability of controlling a background process executing separate and apart from the EDT. The process can be cancelled, it can receive a query for status, and it can receive a status change notification. 
       FIG. 1  shows a diagram of an event dispatch thread  105 , provided in accordance with one embodiment of the present invention. The EDT  105  has an associated event queue  110  implemented as a memory device or other suitable storage medium as will be understood by those skilled in the art. In one example, queue  110  is implemented in a cache memory of a computer system or other data processing apparatus. As described in greater detail below, method calls can be stored and retrieved in queue  110 . The EDT  105  retrieves method calls stored in one or more locations in the memory and executes them as events. 
     In  FIG. 1 , in one embodiment, the queue  110  includes memory cells  110   a - 110 N. Before method calls are executed on the EDT, they are stored in the cells  110   a - 110 N. Preferably, the queue is provided in a FIFO arrangement. Cell  110   a  represents the top of the queue  110  from which calls are retrieved and executed one-by-one as events on the EDT  105 . Generally the oldest call is situated at the top of queue  110  in cell  110   a . A new call, or most recent call, is sent to the bottom of queue  110 , in one example, cell  110 N. 
     Embodiments of methods and apparatus of the present invention provide for the efficient transfer of method calls to the EDT. In one embodiment, as shown in the class diagram of  FIG. 2 , the methods and apparatus are implemented as an API with two classes: 
     (1) public class Call&lt;V&gt;  120  which implements java.util.concurrent.Callable&lt;V&gt;  125 , and 
     (2) public class EDTExecutorService  130  which implements the executor service interface from the java.util.concurrent package, namely java.util.concurrent.ExecutorService  135 . 
     In  FIG. 2 , Call&lt;V&gt;  120  represents a method call to be executed on the EDT. When the method is to be called, the Call&lt;V&gt; object  120  is created. The Call&lt;V&gt; object encapsulates data describing the call. As shown in  FIG. 2 , the Call&lt;V&gt; object  120  encapsulates several methods, the operations of which are described below with respect to  FIG. 4 . These methods include coalesce(:Call&lt;V&gt;), callOnEDT( ), callOnEDTSync( ), and call( ). call( ) is used anytime it is desired to call a method. When it is desired to coalesce two calls, the coalesce (:Call&lt;V&gt;) method is used. Often, subsequent processing varies according to the desired implementation. 
     In one embodiment, the Call&lt;V&gt; constructor is: 
     Call(Object callee, Method method, CallProperty callProperty, Object . . . args); 
     where “callee” is the object to execute the method for, “method” is the method to call, “callProperty” is a coalescing indicator describing whether and how the call could be coalesced, that is, combined with another call, and “args” are parameters, also referred to herein as arguments, for the method invocation. Thus, the class Call&lt;V&gt; has a pointer to the object to call, a pointer to the method to invoke, and parameters to pass. 
     Embodiments of the present invention provide for a plurality of calls to be coalesced when the calls have the same callee and method. Embodiments of the present invention provide for the calls to be coalesced in several ways. In one embodiment, callProperty governs how the coalescing occurs. In this embodiment, callProperty has one of three values: plain, onlyLast, or coalescing. The value “plain” indicates that the Call cannot be coalesced; “onlyLast” indicates that the Call is to replace a previous call, e.g., for a progress bar or other progress notification for a component; and “coalescing” indicates that the arguments for the Call are to be appended to the arguments for a previous call. Thus, the method can be invoked with a single call, providing the combined set of arguments. The calls can only be coalesced when the calls are for the same callee and for the same method. 
     In  FIG. 2 , Call&lt;V&gt;  120  is extendible. The implementation above, using callee, method, and callProperty, is only one of many implementations. This implementation can be changed in many ways as desired. For example, if a particular method call for a certain object is undesirable, the call( ) method can be overridden, as can the coalesce(:Call&lt;V&gt;) method. Extending the Call&lt;V&gt;  120  class enables other operations to be carried out rather than calling the predefined method for the predefined object. In one embodiment, callProperty is used, while other embodiments provide coalescing using different techniques. Also, the Call&lt;V&gt; constructor can be customized as desired for a different implementation to execute code on the EDT. All such alterations and customizations are intended to fall within the spirit and scope of the present invention. 
     In  FIG. 2 , the method coalesce is responsible for merging two calls into one, using techniques described herein. When calls are coalesced, the coalesce method returns a value of true. Using the coalesce method, additional types of coalescing can be performed than the particular coalescing operations described herein, within the spirit and scope of the present invention. The coalesce ( ) method can be implemented in many ways, and can be customized as desired for the particular implementation. 
     In  FIG. 2 , the EDTExecutorService  130  is a class which submits a call for execution on the EDT. In addition, EDTExecutorService  130  can be used to submit runnables to the EDT. In one example, in which a call is submitted, the method is as follows: 
     EDTExecutorService.submit(Call call). 
     The EDTExecutorService class resolves coalescing and ensures that the EDT is not overwhelmed with incoming calls. In one embodiment, time slices are used to implement the EDTExecutorService. 
     In  FIG. 1 , when coalescing is performed on method calls in queue  110 , method calls in two or more of cells  110   a -N are combined.  FIG. 3  shows an example of one coalesce method  400 , performed in accordance with embodiments of the present invention. 
     In  FIG. 3 , the method  300  begins with calling the coalesce (:Call&lt;V&gt;) method invocation with another call as the argument, in step  145 . The supplied method call can be stored as a new call in one of the cells  110   a - 110 N. The coalesce method identifies one or more previous calls already stored in queue  110 . When the methods identified by the new call and the previous call(s) are the same, in step  150 , and the objects, i.e. callees identified by the object identifiers in the new call and the previous call(s) are the same, in step  155 , the arguments in the new call and previous call(s) are combined in step  160 . In steps  150  and  155 , when either the methods or the identified objects are not the same, the coalesce method returns a value of “False”. In step  160 , in this embodiment, the arguments are combined according to the callProperty value, as described above. Finally, in step  165 , the coalesce method  300  returns a value of “True,” as mentioned above. 
     In  FIG. 3 , in step  160 , when the callProperty value is “plain,” the new call is simply added to the bottom of queue  110 . When the callProperty value is “onlyLast,” the new call replaces a previous call. Or, when the callProperty value is “coalescing,” the arguments for the new call are appended to the arguments for the previous call so the coalesced call has the object identifier, method identifier, and combined arguments. 
       FIG. 4  shows a sequence diagram of a method  200  for transferring a method call to the EDT, performed in accordance with an embodiment of the present invention. Method  200  provides processing steps for the invoke thread putting a call on the queue  110  and, at some later time, the call being picked up on the EDT  105  and executed. In  FIG. 4 , the method  200  is divided into parts A, B and C. Part A demonstrates placing a call into the queue  110 . Part B demonstrates the invoking of calls on the EDT  105 , and Part C demonstrates the invocation of calls on the EDT  105  synchronously. 
     In  FIG. 4 , part A shows how calls are delivered to the EDT  105 . In part A, the method  200  begins with a user  205  identifying a method and an object to call on the EDT  105 . In step  210 , the callonEDT method constructs the Call&lt;V&gt; object  120  for this method and object. As mentioned above, the constructor for Call&lt;V&gt; indicates that the identified method is be called for the identified object (i.e., “callee”), indicates how the call can be coalesced (e.g., plain, onlyLast, or coalescing), and passes particular arguments for the method. In step  215 , the newly defined call is submitted to the EDTExecutorService  130  using the submit(self) method. The method  200  continues in step  220 , when the EDTExecutorService  130  accesses the queue  110 , also referred to herein as EDTExecutorService.callsQueue  110 , and attempts to coalesce the new call with any previous calls already in the queue  110 , using callProperty values as described above. For example, when the callProperty value is “onlyLast,” and a previous call is identified having the same method and same object, coalescing involves replacing the previous call with the new call. When the new call is coalesced with any previous calls, processing is complete for part A. When the new call cannot be coalesced, in step  225 , the new call is added to the end of queue  110 . 
     In  FIG. 4 , Part B of method  200  provides for the invoking of calls on the EDT  105 , and is initiated on EDT  105 . Part B of method  200  happens asynchronously with respect to part A of method  200 . A special task  230  is defined to run periodically, each time executing calls from the queue  110 . The frequency with which special task  230  runs is preferably often enough so that users do not have to wait for the execution of calls. In this way, freezing is avoided. In one example, 20 times per second is often sufficient, although other frequencies may be used depending on the desired implementation. In step  235 , every time the special task  230  runs, the EDT  105  runs an execute( ) method, and a timer is tolled. Responsive to the execute( ) method, in step  240 , the EDTExecutorService  130  accesses the queue  110  and gets, i.e., retrieves, calls one-by-one from the queue  110  for execution on the EDT  105 . In step  245 , retrieved calls are executed in sequence by EDTExecutorService  130  until the timer reaches a predetermined threshold, e.g., 0.045 seconds. When the threshold is exceeded, the execution of calls is postponed until the special task  230  runs again. Subsequent execution by EDTExecutorService  130  begins with the first call from the queue  110 . 
     In  FIG. 4 , in part B, step  250  involves calling method call on class Call  120 . That is, the identified method is called for the identified object passed in the constructor, and passes the arguments, as described above. Lastly, in Part B of method  200 , a notifyWaitforResult message is executed in which a notification message is sent to any listeners, indicating whether the new call was executed, in step  255 . 
     In  FIG. 4 , part C demonstrates the calling of methods synchronously, when it is desirable to wait for a result after calling a method. In part C, the method  200  begins in step  260  with running the method callOnEDTSync, that is, to call the method synchronously. Responsive to callonEDTSync, in step  265 , the method callOnEDT  210  is run, as described above in part A. Then, in step  270 , the waitForResult method waits for a result, that is, listens for the notification from step  255  of part B. Any result is provided when the call is executed on the EDT in part B. In step  275 , the method  200  proceeds with determining whether any exceptions were thrown when the method was called. When there are exceptions, they are thrown. When no exceptions were thrown, the result is returned to the user. 
     Many times a UI, including frames, buttons, and other graphical representations, is created on the main thread of an application. When these elements are visible, the properties of these elements cannot be changed from other threads than the EDT. Thus, when it is desirable to call a method which is not thread-safe, including the majority of Swing methods, from any other thread than the EDT, the methods and apparatus described above with respect to  FIGS. 1B-1D  can be used. 
       FIG. 5  is an illustration of a background process  295  and an EDT  105 , implementing embodiments of methods and apparatus of the present invention. The background process  295  represents any application, program, or thread that is executed separate and apart from the EDT  105 . In this way, the background process  295  generally does not affect the performance of a UI managed by EDT  105 . In  FIG. 5 , suitable background processes are those that perform time-consuming operations or can otherwise cause freezing, such as the lengthy tasks described above. Examples of background process  295  include user-initiated operations that are time-consuming, such as a program which makes a database request or loads a file in response to the user selecting a menu item. 
     Embodiments of methods and apparatus of the present invention are used for implementing a new SwingWorker which has several improvements over the original version. These improvements include delivering intermediate results by a Schedule and Consume method, described below, and sharing the state of a process using setProgress and firePropertyChange methods, and a propertyChangeListener method, also described below. In one implementation, these new methods are incorporated as additions to the SwingWorker abstract class, described above, from which a subclass can be defined by a developer to perform GUI-related work in a dedicated thread. 
       FIG. 5  demonstrates one context for the new SwingWorker methods and apparatus including Schedule, setProgress, and firePropertyChange, performed in accordance with embodiments of the present invention. In one embodiment, novel methods for transferring calls, described above with respect to  FIG. 4 , are used to provide a framework to implement the novel SwingWorker methods and apparatus. 
     In  FIG. 5 , background process  295  and EDT  105  execute independent of one another. That is, background process  295  executes regardless of what is happening on the EDT  105 , and is not dependent on any input or other interaction from EDT  105 . Similarly, EDT  105  executes regardless of what is happening on the background process  295 , and only receives indirect input from the background process  295  through queue  110 . At some point during execution of the background process, a Send data operation  145  is called. In one embodiment, the Send data operation  145  is carried out by part A of method  200  for transferring calls, described above with respect to  FIG. 4 . Examples of Send data operation  145  include the Schedule method, setProgress method, and firePropertyChange method described below. The Send data operation  145  causes method calls to be sent to queue  110  for later retrieval and execution on the EDT  105 . Because background process  295  and EDT  105  execute independent of one another, the method calls may be stored in queue  110  for some time until they are retrieved. Those skilled in the art will appreciate that Send data operation  145  may be called multiple times during execution of background process  295 . 
     In  FIG. 5 , independent of the storing of output method calls in queue  110 , at some point during processing on the EDT, a Handle data operation  150  is performed on the EDT. In one embodiment, the Handle data operation  150  is carried out by part B of method  200 , described above with respect to  FIG. 4 . The performing of Handle data operation  150  is controlled by the EDT  105 . The Handle data operation  150  retrieves method calls stored in queue  110 . The method calls can then be executed on the EDT  105 . In instances when the Send data operation  145  includes calling the Schedule method, the Handle data operation  150  includes calling the Consume method for outputting the method calls on the EDT  105 . Those skilled in the art will appreciate that Handle data operation  150  may be called multiple times during execution of EDT  105 . 
     In  FIG. 5 , the retrieving of method calls from queue  110  and outputting of method calls on the EDT  105  when Handle data operation  150  is called happens asynchronously with respect to the sending of method calls to queue  110  during Send data operation  145 . That is, there is no relationship between the Send data operation  145  and the Handle data operation  150 . The Send data operation  145  is performed according to the schedule determined by background process  295 , regardless of when Handle data operation  150  might be performed by EDT  105  or anything else happening on the EDT  105 , and is not dependent on any input or other interaction from EDT  105 . Similarly, the Handle data operation  150  is performed as determined by EDT  105 , regardless of when Send data operation  145  might be performed by background process  295  or anything else happening on the background process  295 . 
     In  FIG. 5 , in one embodiment, the Send data operation  145  can include any of several methods including a Schedule method, a setProgress method, and a firePropertyChange method. When the Send data operation  145  includes the Schedule method, the Handle data operation  150  generally includes a Consume method. The Schedule method is called on the background process or some thread other than the EDT, and Consume is called on the EDT  105 . The Schedule method and Consume method cooperate to prevent the EDT  105  from being overwhelmed by the queuing of method calls for execution, thus making the desired application more responsive. In one embodiment, as described above with respect to  FIG. 4 , the coalescing of events provides for performing the Handle data operation  150  periodically to retrieve method calls for output on the EDT  105  (e.g., every 50 milliseconds). 
     In  FIG. 5 , the Schedule method is called as needed on the background process  295 . The background process  295  can be tailored to invoke Schedule as desired to push partial results to the queue  110  for publication on EDT  105 . In one embodiment, the Schedule method calls the Consume method, using the above constructor. In  FIG. 5 , when Send data operation  145  includes calling the Schedule method, the Schedule method call is sent to queue  110  and generally stored in one address, also referred to herein as a cell, described above with respect to  FIG. 1 . 
     In  FIG. 5 , when the Handle data operation  150  is performed, one or more cells  110   a - 110 N starting from the top cell  110   a  of queue  110  are accessed and the method calls stored therein are retrieved. In one example, when the Handle data operation  150  is the Consume method, the following command is made by the Handle data operation  150 : 
     Consume.invoke(Callee, Args, CallProperty) 
     In another example, when Consume is an object of type Call&lt;V&gt;, then the arguments needed to execute the call are encapsulated into the object. Thus, the callee, method and arguments are known. In this example, the following command will be used: 
     Consume.callOnEDT( ) 
     In  FIG. 5 , the Consume method retrieves method calls from queue  110  and executes or otherwise outputs those method calls on the EDT  105 . One example of a scheme for implementing a Consume method is set forth below. In this example, a table.getModel ( ) method updates a table displayed on a GUI to include a row of data with the “item” argument. The method is as follows: 
     // Executed on EDT, receives the data from schedule( ) 
     protected void consume (Item . . . chunks) {
         for (Item item : chunks) {
           table.getModel( ).addRow(item);   
               

     } } 
     Those skilled in the art will appreciate that the table.getModel( ) method is generally available in Swing. 
     An additional enhancement of performance is calls “coalescing.” Coalescing allows for updating a GUI fewer times than the number of update requests. The combination of calls “scheduling” and “coalescing” improves performance dramatically. Scheduling ensures that the EDT has enough time to handle painting, key events, mouse events, and the like. Coalescing ensures that coalescable GUI updates are accumulated to save the GUI from more frequent updates than necessary. 
     Generally, coalescing is performed as described above in part A of  FIG. 4 . With embodiments of the present invention, the coalescing operation can be performed on method calls sent from the background process  295  for output to the EDT  105  at various stages, and by various threads and methods. In one embodiment, the background process  295  performs coalescing of method calls when Send data operation  145  is called. In another embodiment, the Send data operation  145  performs coalescing of method calls as they are stored in queue  110 . In another embodiment, a separate coalescing process performs coalescing of method calls before or after they are stored in queue  110 . In yet another embodiment, coalescing is performed by Handle data operation  150  when the method calls are retrieved from queue  110 . 
     In another coalescing example, when the Send data operation  145  is a setProgress method, described below, a plurality of cells of the queue  110  identify the setProgress method. In this case, only two cells are relevant: the cell having the most current state information, and the cell having the oldest state information. The difference represent the change in progress. These two cells are selected when the Handle data operation  150  is called, and any intermediate cells are discarded. The arguments in the two selected cells are then provided to the Handle data operation  150 . 
     In  FIG. 6A , a Schedule method is called at three different times during processing of the background process  295 . Each call results in a block  1 ,  2  and  3  being sent to queue  110  for storage. In this example, these blocks  1 ,  2  and  3  represent first, second and third partial results and/or the arguments of those results to be output on EDT  105  by the Consume method. But before being output, the coalescing function ensures that what can be coalesced is coalesced. In this example, the identified method and object in the blocks  1 ,  2  and  3  are all the same, so the three partial results are combined into a combined partial result with the object identifier, method identifier, and combined arguments. That is, arguments passed by multiple Schedule method calls can be executed on the EDT by a single Consume method call in which the arguments are combined, as shown in  FIG. 6A . In this example, the three schedule operations, Schedule( 1 ), Schedule( 2 ) and Schedule( 3 ) pass arguments  1 ,  2  and  3  which are coalesced and executed in a single consume operation, Consume( 1 , 2 , 3 ). Such coalescing improves computational efficiency, because updating a GUI is generally time consuming. With fewer Consume method calls, the fewer times the GUI needs to be updated, and time and computational resources are conserved. 
     State information can be updated on the EDT using two other methods when Send data operation  145  is called: firePropertyChange and setProgress. When state information is updated, propertyChange listeners are called on the EDT. 
     In  FIG. 5 , the firePropertyChange and setProgress methods have some similar functionality to the Schedule method. The setProgress method is a special case of firePropertyChange. The firePropertyChange method is called when the “bound” property changes for SwingWorker, as known to those skilled in the art and described in java beans documentation for java.beans.PropertyChangeEvent, which is hereby incorporated by reference. A “PropertyChange” event is delivered to the EDT whenever a bean changes a “bound” or “constrained” property. A PropertyChangeEvent object is sent as an argument to PropertyChangeListener and VetoableChangeListener methods. Normally, PropertyChangeEvents are accompanied by the name and the old and new value of the changed property. If the new value is a primitive type (such as int or boolean), the new value must be wrapped as the corresponding java.lang.* Object type (such as Integer or Boolean). 
     The setProgress method is a special case because it is known that calls can be coalesced for the progress. The setProgress and firePropertyChange methods call propertyChangeListeners with the PropertyChangeEvent object. 
     A process can have many ‘bounding’ properties. Progress is one of them. For example, when a lengthy task accesses a website, the bounding property might be the status of such connection. The firePropertyChange method would be called to update listeners on the property value. 
     In  FIG. 5 , when calling the Send data operation  145  includes calling of firePropertyChange or setProgress, an object, method identifier, and arguments are passed to the queue  110  and stored in a memory cell. In these situations, the method identified by the method identifier is either “firePropertyChange” or “setProgress.” The differences are that while the Schedule method passes partial results, the firePropertyChange and setProgress methods pass state information. The state information generally includes information representing the progress of one or more threads or processes. Another difference is that the schedule method essentially notifies the Consume method, while firePropertyChange and setProgress notify propertychange listeners. In addition, while the Consume method is essentially part of the EDT, listeners can be external to the process or invoked on the EDT as well. In one embodiment, calling of the firePropertyChange or setProgress method on the background process triggers propertyChange listeners invocation on the EDT. 
     In one example, a setProgress counter displayed on a GUI is incremented every time a new item is loaded and displayed. Listeners on the EDT are notified that the setProgress counter has changed. Other examples of how setProgress can be used include the progress bar  615  and the pie-shaped progress circle  620  in the GUI  600  of  FIG. 7 . 
     The Consume method and setProgress method both provide coalescing. In the Consume method, coalescing includes joining arguments, as described above. With the setProgress method, the oldest state and the current state are retrieved for an object indicating progress of some operation. In one example, a progress object has a value from 0 to 100 indicating an estimated percentage of completion of the operation. 0 indicates that no progress has been made, and 100 indicates that the operation has been completed. So, for example, when the current state is setProgress( 30 ), the user can receive this value and not have to bother with out-of-date state information such as setProgress( 20 ) or setProgress( 10 ). 
     FirePropertyChange is a method used for disclosing a property which a process in progress may have. A process can have many different properties, e.g., last username and password, how much memory used, internal cache state, etc. The properties are essentially anything internal to the background process. FirePropertyChange indicates that the property was changed. For instance, a button on the GUI can indicate status information (e.g., “connection open,” “connection closed,” “connection refused”). Partial results can also be handled by FirePropertyChange. 
       FIG. 6B  is a SwingWorker class diagram for an application programming interface (API) that implements embodiments of methods and apparatus of the present invention. In  FIG. 6B , SwingWorker&lt;T,V&gt;  505  is an abstract class for developers to extend. “T” represents the type of the final result of a lengthy task, and “V” represents a type of intermediate, i.e. partial result. The SwingWorker class  505  is a convenient framework for implementing lengthy UI interacting tasks. 
     In  FIG. 6B , SwingWorker&lt;T,V&gt;  505  implements java.util.concurrent.Future&lt;T&gt;  510  and, as such, could be controlled via a Future API, as described in java.util.concurrent.Future API, (http://iava.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Future.html), which is hereby incorporated by reference. A method summary for java.util.concurrent Interface Future&lt;V&gt; is as follows: 
     Boolean cancel (boolean mayInterruptIfRunning)
         Attempts to cancel execution of this task.       

     V get( ) 
     Waits if necessary for the computation to complete, and then retrieves its result. 
     V get(long timeout, TimeUnit unit) 
     Waits if necessary for at most the given time for the computation to complete, and then retrieves its result, if available. 
     boolean isCancelled( ) 
     Returns true if this task was cancelled before it completed normally. 
     boolean isDone( ) 
     Returns true if this task completed. 
     In one embodiment, SwingWorker&lt;T,V&gt;  505  implements Future&lt;T&gt; as follows: 
     { 
     //methods for the developer to implement 
     //----- 
     abstract T call( ); // this is what construct in older swingworker used to be 
     consume(V . . . chunks) 
     done(T res) 
     //----- 
     In one embodiment, a SwingWorker API for developers to use is as follows: 
     //SwingWorker API for developers to use 
     //----- 
     execute 
     schedule(V . . . chunks) 
     addPropertyChangeListener 
     firePropertyChange 
     setProgress 
     //all methods from Future&lt;T&gt; 
     //---- 
     } 
     In  FIG. 6B , preferably all time consuming actions are to take place in the SwingWorker&lt;T,V&gt;.call( ) method. Any results of such actions are to be returned from this method. The SwingWorker&lt;T,V&gt;.call( ) method is called on the background thread. SwingWorker&lt;T,V&gt;.done(T res) is called on the EDT with the result from the ‘call’ method. 
     In situations where there is a need to share the ‘bound’ property change, firePropertyChange is to be used. PropertyChange listeners will be invoked on the EDT thread. setProgress is a convenient method for notification regarding ‘progress’ change. 
     In  FIG. 6B , for handling intermediate results there is a Schedule(V . . . chunks)/Consume(V . . . chunks) methods pair. The Schedule method sends intermediate results to be handled on the EDT, and Consume is invoked on the EDT to handle such results. To improve performance, coalescing methods described herein are used for Schedule/Consume. The setProgress/notifying propertyChangeListeners methods are described herein. 
     SwingWorker can be started by a SwingWorker.execute method or by submitting SwingWorker to a special executorSerivice. SwingWorker is sent to be handled on the background thread. In one implementation, java.util.conncurrent.ThreadPoolExecutor is used). On that background thread, SwingWorker.call is invoked. 
     Below are several examples of using SwingWorker. The first example is as follows: 
     
       
         
           
               
               
             
               
                   
                   
               
             
            
               
                   
                 class LoadTableData extends SwingWorker&lt;Table, Row&gt; { 
               
               
                   
                   Table call( ) { 
               
               
                   
                     Table table; 
               
               
                   
                     while (there is a new row) { 
               
               
                   
                       add new row to the table; 
               
               
                   
                     } 
               
               
                   
                   } 
               
               
                   
                 } 
               
               
                   
                   
               
            
           
         
       
     
     In the above example, SwingWorker loads some table data. There is no interaction with a GUI. 
     In a second example, another method is added: 
     &lt;skip&gt; 
     done(Table table) {
         display table in JTable       

     } 
     &lt;skip&gt; 
     The method done is executed on the EDT. When the call method is finished it returns table as a result. This table is the argument of the done method. The table is displayed in JTable component. 
     A third example incorporates additional features described herein, namely the setProgress method: 
     
       
         
           
               
               
             
               
                   
                   
               
             
            
               
                   
                 Table call( ) { 
               
               
                   
                     Table table; 
               
               
                   
                     while (there is a new row) { 
               
               
                   
                       add new row to the table; 
               
               
                   
                       // 
               
               
                   
                       setProgress(++progress); 
               
               
                   
                       // 
               
               
                   
                     } 
               
               
                   
                 } 
               
               
                   
                   
               
            
           
         
       
     
     In the third example, propertyChange listeners of SwingWorker will be notified on the EDT as to the progress change. Progress can be visualized in a JProgress component, for example, as described herein. 
     A fourth example is provided for situations where it is desired to visualize new rows as soon as they are ready. 
     
       
         
           
               
               
             
               
                   
                   
               
             
            
               
                   
                  Table call( ) { 
               
               
                   
                     Table table; 
               
               
                   
                     while (there is a new row) { 
               
               
                   
                       add new row to the table; 
               
               
                   
                       // 
               
               
                   
                       schedule(row); 
               
               
                   
                       // 
               
               
                   
                       setProgress(++progress); 
               
               
                   
                       // 
               
               
                   
                     } 
               
               
                   
                 } 
               
               
                   
                 // 
               
               
                   
                 consume(Row. . chunks) { 
               
               
                   
                     add new rows to the table model; 
               
               
                   
                 } 
               
               
                   
                   
               
            
           
         
       
     
     In one example, as shown in the GUI of  FIG. 7 , an HTML page  600  is loaded for display by a browser. In a first portion  605  of the GUI, a table has rows or paragraphs displaying a plurality of items submitted for auction. Each item has an image, a title, a name, and detailed information, which are provided as partial results. In a second portion  610  of the screen, detailed information describing a particular item is shown when that item is selected. When the HTML page is loaded for display by the browser, the page is loaded paragraph-by-paragraph. Each paragraph can be pushed to the GUI to display, however, such pushing could cause too many events to be queued by the EDT, resulting in freeze. Instead, the Schedule and Consume methods are used, as described above, to provide the images, text and other individual data objects within each paragraph as partial results. The Consume method outputs the items on the EDT for display on the GUI as soon as reasonably possible, when Handle data operation  150  is called. 
     Also in  FIG. 7 , a setProgress method tracks the progress of the data loading and updates the GUI, in particular, a progress bar  615  shown at the bottom of the GUI. The progress bar  615  shows progress of the background process of loading the entire page from the Internet. The setProgress method updates the progress bar  615  every time a new item is received and displayed in the table shown in the first portion  605  of the GUI. A second setProgress method updates pie-shaped progress circle  620  indicating the progress of downloading all of the items in a particular row, in this case, associated with a particular auction item. The pie-shaped progress circle  620  serves as a “preloading” indicator for each auction item, indicating the status of the loading of data describing that item. 
     In  FIG. 7 , embodiments of methods and apparatus of the present invention provide increased responsiveness and a more real-time experience as opposed to conventional applications which wait until all items are loaded, and then show the entire GUI in one shot as a final result. By providing partial results and state information, the methods and apparatus described herein provide a more responsive GUI for the user. 
     In  FIG. 7 , in one embodiment, each of four rows of information in first portion  605  is passed as a separate argument of a respective Schedule method call. At some later time, the Consume method is called on the EDT. Using the coalescing techniques described above, the arguments are displayed on the GUI with a single call to the Consume method. 
     In  FIG. 7 , in a preferred embodiment, there are a plurality of SwingWorkers in operation. The SwingWorkers cooperate to split an otherwise complicated process into simpler and manageable pieces. One SwingWorker is responsible for loading tabular data for the items Table. The others are responsible for prefetching html documents for visible items in the table. When item becomes invisible, the prefetching process for this item is canceled. Thus, for example, the user might click on a visible item to get more details on it in html format. If this data is prefetched, the result will be instant. Thus, the user experience is improved. An otherwise time consuming operation becomes an almost instant result using SwingWorker. 
     Other applications in which embodiments of methods and apparatus of the present invention can be used include table display applications, such as financial applications. In one example, stock quotes and other partial results are loaded at regular intervals from the Internet, and the UI is responsive by updating a table in which the quotes are displayed. The table is updated so that the stock quotes are displayed shortly after being received. 
       FIG. 8  is a block diagram of a computer system  700 , also referred to herein as a data processing apparatus  700 , used for performing methods described herein. The computer system  700  includes a processor  730  for executing program instructions stored in a memory  725 . In some embodiments, processor  730  includes a single microprocessor, while in others, processor  730  includes a plurality of microprocessors to define a multi-processor system. The memory  725  stores instructions and data for execution by processor  730 , including instructions and data for performing the methods described above. Depending on the extent of software implementation in computer system  700 , the memory  725  stores executable code when in operation. The memory  725  includes, for example, banks of read-only memory (ROM), dynamic random access memory (DRAM) as well as high-speed cache memory. 
     In  FIG. 8 , within computer system  700 , an operating system comprises program instruction sequences. The operating system provides a software platform upon which application programs may execute, in a manner readily understood by those skilled in the art. The computer system  700  further comprises one or more applications having program instruction sequences for performing the methods described above. 
     In  FIG. 8 , the computer system  700  incorporates any combination of additional devices. These include, but are not limited to, a mass storage device  735 , one or more peripheral devices  740 , an audio means  750 , one or more input devices  755 , one or more portable storage medium drives  760 , a graphics subsystem  780 , a display  785 , and one or more output devices  745 . The various components are connected via an appropriate bus  790  as known by those skilled in the art. In alternative embodiments, the components are connected through other communications media known in the art. In one example, processor  730  and memory  725  are connected via a local microprocessor bus; while mass storage device  735 , peripheral devices  740 , portable storage medium drives  760 , and graphics subsystem  780  are connected via one or more input/output buses. 
     In  FIG. 8 , mass storage device  735  is implemented as fixed and/or removable media, for example, as a magnetic, optical, or magneto-optical disk drive. The drive is preferably a non-volatile storage device for storing data and instructions for use by processor  730 . In some embodiments, mass storage device  735  stores client and server information, code for carrying out methods in accordance with exemplary embodiments of the invention, and computer instructions for processor  730 . In other embodiments, computer instructions for performing methods in accordance with exemplary embodiments of the invention also are stored in processor  730 . The computer instructions are programmed in a suitable language such as Java or C++. 
     In  FIG. 8 , the portable storage medium drive  760 , in some embodiments, operates in conjunction with a portable non-volatile storage medium, such as a floppy disk, CD-ROM, or other computer-readable medium, to input and output data and code to and from the computer system  700 . In some embodiments, methods performed in accordance with exemplary embodiments of the invention are implemented using computer instructions that are stored on such a portable medium and input to the computer system  700  via portable storage medium drive  760 . 
     In  FIG. 8 , the peripheral devices  740  include any type of computer support device, such as an input/output (I/O) interface, to add functionality to computer system  700 . In one example, the peripheral devices include a network interface card for interfacing to a network, a modem, and the like. The peripheral devices also include input devices to provide a portion of a user interface and may include an alphanumeric keypad or a pointing device such as a mouse, a trackball, a stylus, or cursor direction keys. The I/O interface comprises conventional circuitry for controlling input devices and performing particular signal conversions upon I/O data. The I/O interface may include, for example, a keyboard controller, a serial port controller, and/or digital signal processing circuitry. 
     In  FIG. 8 , the graphics subsystem  780  and the display  785  provide output alternatives of the system. The graphics subsystem  780  and display  785  include conventional circuitry for operating upon and outputting data to be displayed, where such circuitry preferably includes a graphics processor, a frame buffer, and display driving circuitry. The display  785  may include a cathode ray tube (CRT) display, a liquid crystal display (LCD), or other suitable devices. The display  785  preferably can display at least 256 colors. The graphics subsystem  780  receives textual and graphical information and processes the information for output to the display  785 , often as a GUI. A video card in the computer system  700  also comprises a part of graphics subsystem  780  and also preferably supports at least 256 colors. For optimal results in viewing digital images, the user should use a video card and monitor that can display the True Color (24 bit color) setting. This setting enables the user to view digital images with photographic image quality. 
     In  FIG. 8 , audio means  750  preferably includes a sound card that receives audio signals from a peripheral microphone. In addition, audio means  750  may include a processor for processing sound. The signals can be processed by the processor in audio means  750  of computer system  700  and passed to other devices as, for example, streaming audio signals. In some embodiments, programs for performing methods in accordance with exemplary embodiments of the invention are embodied as computer program products. These generally include a storage medium or media having instructions stored thereon used to program a computer to perform the methods described above. Examples of suitable storage medium or media include any type of disk including floppy disks, optical disks, DVDs, CD ROMs, magnetic optical disks, RAMs, EPROMs, EEPROMs, magnetic or optical cards, hard disk, flash card, smart card, and other media. 
     Stored on one or more of the computer readable media, the program includes software for controlling both the hardware of a general purpose or specialized computer or microprocessor. This software also enables the computer or microprocessor to interact with a human or other mechanism utilizing the results of exemplary embodiments of the invention. Such software includes, but is not limited to, device drivers, operating systems and user applications. Preferably, such computer readable media further include software for performing the methods described above. 
     In certain other embodiments, a program for performing an exemplary method of the invention or an aspect thereof is situated on a carrier wave such as an electronic signal transferred over a data network, as one form of a computer program product. Suitable networks include the Internet, a frame relay network, an ATM network, a wide area network (WAN), or a local area network (LAN). Those skilled in the art will recognize that merely transferring the program over the network, rather than executing the program on a computer system or other device, does not avoid the scope of the invention. 
       FIG. 9  is a diagrammatic representation of a virtual machine suitable for implementing embodiments of methods and apparatus of the present invention. When a computer program, e.g., a computer program written in the Java™ programming language, is executed, source code  804  is provided to a compiler  806  within compile-time environment  805 . Compiler  806  translates source code  804  into bytecodes  808 . In general, source code  804  is translated into bytecodes  808  at the time source code  804  is created by a software developer. 
     In  FIG. 9 , bytecodes  808  may generally be reproduced, downloaded, or otherwise distributed through a network or stored on a storage device. In the described embodiment, bytecodes  808  are platform independent. That is, bytecodes  808  may be executed on substantially any computer system that is running on a suitable virtual machine  812 . Bytecodes  808  are provided to a runtime environment  810  which includes virtual machine  812 . Runtime environment  810  may generally be executed using a processor or processors. Virtual machine  812  includes a compiler  814 , an interpreter  816 , a runtime system  818 , and an operating system  820 . Bytecodes  808  may be provided either to compiler  814  or interpreter  816 . 
     In  FIG. 9 , when bytecodes  808  are provided to compiler  814 , methods contained in bytecodes  808  are compiled into machine instructions. In one embodiment, compiler  814  is a just-in-time compiler which delays the compilation of methods contained in bytecodes  808  until the methods are about to be executed. When bytecodes  808  are provided to interpreter  816 , bytecodes  808  are read into interpreter  816  one bytecode at a time. Interpreter  816  then performs the operation defined by each bytecode as each bytecode is read into interpreter  816 . That is, interpreter  816  “interprets” bytecodes  808 , as will be appreciated by those skilled in the art. In general, interpreter  816  processes bytecodes  808  and performs operations associated with bytecodes  808  substantially continuously. 
     In  FIG. 9 , when a method is invoked by another method, or is invoked from runtime environment  810 , if the method is interpreted, runtime system  818  may obtain the method from runtime environment  810  in the form of a sequence of bytecodes  808 , which may be directly executed by interpreter  816 . If, on the other hand, the method which is invoked is a compiled method which has not been compiled, runtime system  818  also obtains the method from runtime environment  810  in the form of a sequence of bytecodes  808 , then may go on to activate compiler  814 . Compiler  814  then generates machine instructions from bytecodes  808 , and the resulting machine-language instructions may be executed directly by one or more processors. In general, the machine-language instructions are discarded when virtual machine  812  terminates. The operation of virtual machines or, more particularly, Java™ virtual machines, is described in more detail in  The Java™ Virtual Machine Specification  by Tim Lindholm and Frank Yellin (ISBN 0-201-63452-X), which is incorporated herein by reference. 
     A number of implementations of the invention have been described. Nevertheless, it will be understood that various modifications may be made without departing from the spirit and scope of the invention. Accordingly, other embodiments are within the scope of the following claims.