Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / GUI / August 2004

Tip: Looking for answers? Try searching our database.

How to do thread blocking as Dialog.show() does?

Thread view: 
johnson - 19 Nov 2003 20:36 GMT
Hi,

Here is my question: we need to do the same thing as
java.awt.Dialog.show() does. Basically, upon show() is called in a
Dialog, it blocks the current thread, but it still keeps the
eventDispatchThread responsive, so that the dialog still responds to
user input.

Checked the code in java.awt.Dialog.show(), here is a simplified
version:

// We have two mechanisms for blocking: 1. If we're on the
// EventDispatchThread, start a new event pump. 2. If we're
// on any other thread, call wait() on the treelock.

// keep the KeyEvents from being dispatched
// until the focus has been transfered
long time = Toolkit.getEventQueue().getMostRecentEventTime();
Component predictedFocusOwner = getMostRecentFocusOwner();
KeyboardFocusManager.getCurrentKeyboardFocusManager().
enqueueKeyEvents(time, predictedFocusOwner);

Runnable pumpEventsForHierarchy = new Runnable() {
public void run() {
EventDispatchThread dispatchThread =
 (EventDispatchThread)Thread.currentThread();
dispatchThread.pumpEventsForHierarchy(new Conditional() {
  public boolean evaluate() {
   return keepBlocking && windowClosingException == null;
  }
  }, Dialog.this);
 }
};

if (EventQueue.isDispatchThread()) {
/*
* dispose SequencedEvent we are dispatching on current
* AppContext, to prevent us from hang.
*/
SequencedEvent currentSequencedEvent = KeyboardFocusManager.
 getCurrentKeyboardFocusManager().getCurrentSequencedEvent();
if (currentSequencedEvent != null) {
 currentSequencedEvent.dispose();
}

pumpEventsForHierarchy.run();
} else {
 synchronized (getTreeLock()) {
 Toolkit.getEventQueue().
 postEvent(new PeerEvent(this,
  pumpEventsForHierarchy,
  PeerEvent.PRIORITY_EVENT));
  while (keepBlocking && windowClosingException == null) {
 try {
  getTreeLock().wait();
 } catch (InterruptedException e) {
  break;
}
}
}
}

however, there are many classes/methods that are not public
accessable,
therefore, I can not use the above piece of code in my class.
Does anyone have an idea on how to implement this?
Steve W. Jackson - 19 Nov 2003 21:05 GMT
>:Hi,
>:
[quoted text clipped - 62 lines]
>:therefore, I can not use the above piece of code in my class.
>:Does anyone have an idea on how to implement this?

When you call show(), it is by nature executed on the EDT, so the code
you're seeing starts a second EDT while that one's at work.  The first
question has to be whether that's what you need to do, or is it some
other thread you need to block?

In my environment, we take great care not to do any but the shortest of  
work on the EDT.  So when most of our EDT listeners pick up something,
they promptly hand it off to a separate thread and let the EDT go on its
way (thus remaining responsive).  Then, any work done in that separate
thread is not holding up the GUI.  If any code there needs to display a
modal dialog using show(), it's all taken care of.

= Steve =
Signature

Steve W. Jackson
Montgomery, Alabama

Harald Hein - 20 Nov 2003 06:06 GMT
>>:// We have two mechanisms for blocking: 1. If we're on the
>>:// EventDispatchThread, start a new event pump. 2. If we're
[quoted text clipped - 42 lines]
>>:  } catch (InterruptedException e) {
>>:   break;

> When you call show(), it is by nature executed on the EDT,

show() is one of the few methods that need not be called from the EDT.
In fact, when you first call it, you don't have an EDT, you call it
from the main thread.

> so the
> code you're seeing starts a second EDT while that one's at work.

You even have the code in front of you, and you claim this? There is no
new EDT started. The eventpump is replaced.
Harald Hein - 20 Nov 2003 05:56 GMT
> Here is my question: we need to do the same thing as
> java.awt.Dialog.show() does. Basically, upon show() is called in a
[quoted text clipped - 4 lines]
> Checked the code in java.awt.Dialog.show(), here is a simplified
> version:

You ignore all this implementation details, you simply use it. You
subclass your own Dialog class. Then you set your own Dialog to modal.
Because of this, all this existing code is run as if you have typed it
in yourself :-), and your own Dialog's show() blocks until you hide the
Dialog.
Rob - 30 Nov 2003 00:57 GMT
You might consider checking out Foxtrot, it does this
kind of thing: http://foxtrot.sourceforge.net

> Hi,
>
[quoted text clipped - 3 lines]
> eventDispatchThread responsive, so that the dialog still responds to
> user input.
lfleysher - 25 Aug 2004 11:55 GMT
Here are some code snipplets that can give a clue how to do event pumping
yourself while your dispatching thread is stuck waiting for some long
operation:
This function gives you the event despatching queue of the system:

private EventQueue getEventQueue()
   {
       return (EventQueue)AccessController.doPrivileged(new
PrivilegedAction()
       {
           public Object run()
           {
               return Toolkit.getDefaultToolkit().getSystemEventQueue();
           }
       });
   }

// This function pumps events on the queue until the receiverThread
returns
   private void pumpEvents(EventQueue queue, Thread receiverThread) {
        while (true) {
               if (receiverThread.isAlive() == false) {
                   break;
               }
               pumpEvent(queue);   // pump event (may be blocking but
receiverThread sends empty event when finished)
        }
   }
   
   
   private void pumpEvent(EventQueue queue) {
       try {
           AWTEvent event = queue.getNextEvent();  // may be blocking if
no events
           dispatchEvent(queue, event);
       } catch (InterruptedException e) {}
         catch (Throwable x) {
             handleThrowable(x);
       }
   }

/**
   * Copy/Paste of the Sun's JDK 1.3 implementation in
java.awt.EventQueue.dispatchEvent(AWTEvent)
   * @param queue The system EventQueue
   * @param event The event to dispatch
   */
   protected void dispatchEvent(EventQueue queue, AWTEvent event)
   {
       Object source = event.getSource();

       if (event instanceof ActiveEvent)
           ((ActiveEvent)event).dispatch();
       else if (source instanceof Component)
           ((Component)source).dispatchEvent(event);
       else if (source instanceof MenuComponent)
           ((MenuComponent)source).dispatchEvent(event);
       else
           System.err.println("[Communication] Unable to dispatch event "
+ event);
   }

   /**
   * Handle a RuntimeException or Error happened during event
dispatching.
   * If the system property <code>sun.awt.exception.handler</code> is
defined,
   * that handler will be used, otherwise it simply logs on
<code>System.err</code>.
   */
   protected void handleThrowable(Throwable x)
   {
       String handlerName = (String)AccessController.doPrivileged(new
PrivilegedAction()
       {
           public Object run()
           {
           return System.getProperty("sun.awt.exception.handler");
           }
       });

       if (handlerName != null)
       {
           try
           {
               Object handler =
Thread.currentThread().getContextClassLoader().loadClass(handlerName).newInstance();
               Method handle = handler.getClass().getMethod("handle", new
Class[]{Throwable.class});
               handle.invoke(handler, new Object[]{x});
               return;
           }
           catch (Throwable ignored)
           {
               System.err.println("[Communication] Exception occurred
while invoking AWT exception handler: " + ignored);
               // Fall through
           }
       }

       System.err.println("[JDK13QueueEventPump] Exception occurred
during event dispatching:");
       x.printStackTrace();
   }

to send empty event when receiver thread is finished use there:
           // send empty event to ensure that pumpEvent returns. sleep
added in order to give this thread time to exit
               javax.swing.SwingUtilities.invokeLater(new Runnable(){
                   public void run() {
                   }
               });
lfleysher - 25 Aug 2004 11:56 GMT
Here are some code snipplets that can give a clue how to do event pumping
yourself while your dispatching thread is stuck waiting for some long
operation:
This function gives you the event despatching queue of the system:

private EventQueue getEventQueue()
   {
       return (EventQueue)AccessController.doPrivileged(new
PrivilegedAction()
       {
           public Object run()
           {
               return Toolkit.getDefaultToolkit().getSystemEventQueue();
           }
       });
   }

// This function pumps events on the queue until the receiverThread
returns
   private void pumpEvents(EventQueue queue, Thread receiverThread) {
        while (true) {
               if (receiverThread.isAlive() == false) {
                   break;
               }
               pumpEvent(queue);   // pump event (may be blocking but
receiverThread sends empty event when finished)
        }
   }
   
   
   private void pumpEvent(EventQueue queue) {
       try {
           AWTEvent event = queue.getNextEvent();  // may be blocking if
no events
           dispatchEvent(queue, event);
       } catch (InterruptedException e) {}
         catch (Throwable x) {
             handleThrowable(x);
       }
   }

/**
   * Copy/Paste of the Sun's JDK 1.3 implementation in
java.awt.EventQueue.dispatchEvent(AWTEvent)
   * @param queue The system EventQueue
   * @param event The event to dispatch
   */
   protected void dispatchEvent(EventQueue queue, AWTEvent event)
   {
       Object source = event.getSource();

       if (event instanceof ActiveEvent)
           ((ActiveEvent)event).dispatch();
       else if (source instanceof Component)
           ((Component)source).dispatchEvent(event);
       else if (source instanceof MenuComponent)
           ((MenuComponent)source).dispatchEvent(event);
       else
           System.err.println("[Communication] Unable to dispatch event "
+ event);
   }

   /**
   * Handle a RuntimeException or Error happened during event
dispatching.
   * If the system property <code>sun.awt.exception.handler</code> is
defined,
   * that handler will be used, otherwise it simply logs on
<code>System.err</code>.
   */
   protected void handleThrowable(Throwable x)
   {
       String handlerName = (String)AccessController.doPrivileged(new
PrivilegedAction()
       {
           public Object run()
           {
           return System.getProperty("sun.awt.exception.handler");
           }
       });

       if (handlerName != null)
       {
           try
           {
               Object handler =
Thread.currentThread().getContextClassLoader().loadClass(handlerName).newInstance();
               Method handle = handler.getClass().getMethod("handle", new
Class[]{Throwable.class});
               handle.invoke(handler, new Object[]{x});
               return;
           }
           catch (Throwable ignored)
           {
               System.err.println("[Communication] Exception occurred
while invoking AWT exception handler: " + ignored);
               // Fall through
           }
       }

       System.err.println("[JDK13QueueEventPump] Exception occurred
during event dispatching:");
       x.printStackTrace();
   }

to send empty event when receiver thread is finished use there:
           // send empty event to ensure that pumpEvent returns. sleep
added in order to give this thread time to exit
               javax.swing.SwingUtilities.invokeLater(new Runnable(){
                   public void run() {
                   }
               });


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.