SwingQueue.java :  » Scripting » oscript-2.10.4 » ti » swing » Java Open Source

Java Open Source » Scripting » oscript 2.10.4 
oscript 2.10.4 » ti » swing » SwingQueue.java
/*=============================================================================
 *     Copyright Texas Instruments 2002. All Rights Reserved.
 * 
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 * 
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 * 
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */


package ti.swing;


import ti.pub.WorkerThread;

import java.awt.*;
import java.util.LinkedList;


/**
 * A queue implementation with a {@link #enqueue} method and a blocking 
 * {@link #dequeue} method that is safe to call from the AWT event dispatch
 * thread.
 * 
 * @author Rob Clark
 * @version 0.1
 */
public class SwingQueue
{
  private Toolkit    toolkit;
  private LinkedList queue = new LinkedList();
  
  /**
   * Class Constructor.
   */
  public SwingQueue()
  {
    toolkit = Toolkit.getDefaultToolkit();
  }
    
  /**
   * Enqueue, potentially unblocking any threads that have called the
   * {@link #dequeue} method.
   * 
   * @param obj          the object to enqueue
   * @see #dequeue
   */
  public void enqueue( Object obj )
  {
    synchronized(queue)
    {
      queue.addFirst(obj);
      queue.notify();
      
      /* in case dequeuing thread is blocked in getNextEvent(): (this depends 
       * a bit too much on the implementation of EventQueue... but what else
       * can we do?)
       */
      EventQueue q = toolkit.getSystemEventQueue();
      synchronized(q)
      {
        q.notify();
      }
    }
  }
  
  private int swingTimerCnt = 0;
  private javax.swing.Timer swingTimer = 
    new javax.swing.Timer( 200, new java.awt.event.ActionListener() {
        
        public void actionPerformed( java.awt.event.ActionEvent evt ) { /* no-op */ }
        
      } );
  
  private synchronized void startTimer()
  {
    if( swingTimerCnt == 0 )
      swingTimer.start();
    swingTimerCnt++;
  }
  private synchronized void stopTimer()
  {
    swingTimerCnt--;
    if( swingTimerCnt == 0 )
      swingTimer.stop();
  }
  
  /**
   * Dequeue item from queue, blocking until object is enqueued if the queue 
   * is currently empty.  If multiple threads call this method it is not 
   * defined which one will dequeue an entry first.  It is guaranteed that
   * objects will be dequeued in the same order they are enqueued.
   * 
   * 
   * @return the dequeued object
   * @see #enqueue
   */
  public Object dequeue()
  {
    while(true)
    {
      synchronized(queue)
      {
        if( queue.size() > 0 )
          return queue.removeLast();
      }
      
      try
      {
        if( javax.swing.SwingUtilities.isEventDispatchThread() )
        {
          // there is a possibility for a race condition here, because we
          // can't synchronize this w.r.t. enqueue() without blocking the
          // enqueue() operation itself.  It isn't too bad because presumably
          // we will eventually get an event to dispatch, which will give us
          // another chance to check to see if there is anything queued.
          startTimer();
          AWTEvent event = toolkit.getSystemEventQueue().getNextEvent();
          stopTimer();
          Object   src   = event.getSource();
          // can't call theQueue.dispatchEvent, so I pasted its body here
          if( event instanceof ActiveEvent )
            ((ActiveEvent)event).dispatch();
          else if( src instanceof Component )
            ((Component)src).dispatchEvent(event);
          else if( src instanceof MenuComponent )
            ((MenuComponent)src).dispatchEvent(event);
          else
            System.err.println("unable to dispatch event: " + event);
        }
        else if( Thread.currentThread() instanceof WorkerThread )
        {
          ((WorkerThread)(Thread.currentThread())).runNext(100);
        }
        else
        {
          synchronized(queue)
          {
            if( queue.size() <= 0 )
              queue.wait();
          }
        }
      }
      catch(InterruptedException e)
      {
        Thread.interrupted();
      }
    }
  }
}



/*
 *   Local Variables:
 *   tab-width: 2
 *   indent-tabs-mode: nil
 *   mode: java
 *   c-indentation-style: java
 *   c-basic-offset: 2
 *   eval: (c-set-offset 'substatement-open '0)
 *   eval: (c-set-offset 'case-label '+)
 *   eval: (c-set-offset 'inclass '+)
 *   eval: (c-set-offset 'inline-open '0)
 *   End:
 */

java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.