File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes NX: Using SwingUtilties.InvokeAndWait method in GUI Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "NX: Using SwingUtilties.InvokeAndWait method in GUI" Watch "NX: Using SwingUtilties.InvokeAndWait method in GUI" New topic
Author

NX: Using SwingUtilties.InvokeAndWait method in GUI

Xie Ruchang
Ranch Hand

Joined: Dec 25, 2003
Posts: 160
Hi,
Would like to find out whether anybody uses the above method in the Client GUI. The scenario is like when a user clicks on the [Business Function] button. The database is to be updated and a result is to be given back to the user.
Question A
Comment on whether a NEW THREAD is necessary within the ActionListener of the GUI for the wrapping the business method which ultimately uses the network and database resources to accomplish its aim.
You may answer just with a 'Yes' or 'No'.
Question B
Do you use the SwingUtilities.invokeAndWait(),
how do you handle the InterruptedException and InvocationTargetException if you use it?
You may also answer just with a 'Yes' or 'No'.
Question C
If your answer is YES to Question B, roughly how often it is used in the GUI code?
Thank you very much for your time.
Best Regards
George Marinkovich
Ranch Hand

Joined: Apr 15, 2003
Posts: 619
Hi Frankie,
A) Yes
B) No (but I use SwingUtilities.invokeLater instead)
C) I use invokeLater only once
For more details see: Topic: JFrame not repainting when overlayed JDialog is closed
Hope this helps,
George


Regards, George
SCJP, SCJD, SCWCD, SCBCD
Ken Krebs
Ranch Hand

Joined: Nov 27, 2002
Posts: 451
A. No
B. No
C. 0


kktec<br />SCJP, SCWCD, SCJD<br />"What we observe is not nature itself, but nature exposed to our method of questioning." - Werner Heisenberg
Xie Ruchang
Ranch Hand

Joined: Dec 25, 2003
Posts: 160
Thank you George and Ken!
Ken,
I would like to discuss this with you since you did not start a new thread in Question A. That means, correct me if I am wrong, you are using the GUI dispatch thread to do the job. The job here would be accessing the database over the network. Suppose the network hang or the there is an unexpected problem with the locking mechanism which caused a deadlock, you GUI will be hanged, unresponsive even for a System.exit(-1).
Alternatively, if a new thread is started, that thread got hanged and the user could do a File - Quit/Exit menu option to restart again without Ctrl+C. What are your consideration and view on this?
George,
Are you on the same line of thinking as me. Would appreciate your comments.
In summary, I feel that the GUI dispatch thread should be used for Swing activities and for executing business methods.
Best Regards.
Will the rest respond to my earlier survey, please, and join in the discussion.
Xie Ruchang
Ranch Hand

Joined: Dec 25, 2003
Posts: 160
In summary, I feel that the GUI dispatch thread should be used for Swing activities and NOT for executing business methods.

typos, corrections in bold.
Ken Krebs
Ranch Hand

Joined: Nov 27, 2002
Posts: 451
Frankie,
Your point is a very good one. I do agree with you that in a ***real*** app that it is best to spawn a separate thread to implement the business methods so that the user has a ***nice*** way out in case something goes wrong. It does add some extra complexity however as you then have to decide what the user will be allowed to do during this time and then take appropriate measures.
Since my instructions said:
The IT director does not anticipate much reuse of the first Java
technology system, but intends to use that system as a learning
exercise before going on to a web based system.

SUN brilliantly provides this magical statement which grants the implementor a great deal of freedom. It was my choice that it was not necessary to provide the extra thread to meet the stated requirements. In a ***real*** app that should indeed be extremely robust and user friendly, I would definitely address the issue you raise.
I think this reasoning was OK with the tester since my gui score was perfect but I am not 100% sure. It is possible that I got a small deduct in General Considerations. My score was 389/400 with all the deducts in General Considerations.
[ January 26, 2004: Message edited by: Ken Krebs ]
Xie Ruchang
Ranch Hand

Joined: Dec 25, 2003
Posts: 160
Thank you Ken,
That statement by Sun certainly gives us a lot of mileage!
Best Regards
George Marinkovich
Ranch Hand

Joined: Apr 15, 2003
Posts: 619
Hi Frankie,
I think you're headed in the right direction. I believe it is bad form to have the event-handling thread do something that is basically not Swing-related, such a business method that may take a fairly long time to complete.
As near as I can tell my GUI is sort of unique in that I have dialog that appears when a user attempts to book a locked record, that asks the question: Do you want to wait for the locked record to become available, or try again later?. My problem was that if the user said, yah sure go ahead and wait, then when I hid the dialog, the screen underneath the hidden dialog would not redraw because I had used the event handling thread to do my book business method. Part of my book business method would wait for the lock to become available and (like the specification for lock states) it would sit there and wait (consuming no CPU cycles). Since it was consuming no CPU cycles it never got around to redrawing the screen until after the lock on the requested record got realeased. Well, in the meantime it left a pretty horrible main window that looked like it had been infected with some weird GUI-eating bacteria. Mr. Friedman-Hill (over on the Swing/JFC/GUI forum) pointed me in the right direction (away from running a business method in the Swing event-handling thread). So, in my case, because of some GUI design decisions that I made (that I imagine most people had the good sense to avoid), I had to do the right thing (kick off a separate thread to do the book business method).
So, although that is the right way to go, I agree with Ken that it's not required and probably won't get you any additional GUI points. Also, my advice would be that if you're not seeing bad effects (remember that I was seeing very bad effects) by using the event-handling Swing thread to do your business method, then I wouldn't worry about it for the purpose of the assignment. However, it's nice to know about the proper way to do this for a future project.
Hope this helps,
George
Xie Ruchang
Ranch Hand

Joined: Dec 25, 2003
Posts: 160
Hi George,
Thank you for your reply! For the sake of discussion and not being argumentative or fault finding, or perhaps for my own better understanding. I see no need of you doing that in waiting for the lock to be released and informing the user at the GUI level. Here is my reasoning.
Reading records need no locking. When a record is locked, it is for the sole purpose of updating. When the update is done, the record is unlock. Now this whole process occur at split second. Even if ten threads are waiting for the same record, it will still happen at split second. Unless a deadlock due to application logic occurs which hold the record indefinitely, if and only if, then your situation will happen. If that is the case, it is to not avail because the lock will never be released.
The scenario will be like this when two clients booked record 17

From step 2 to 7 is only a few mini-seconds of wait and you like to show the user a dialog box for that? Maybe I have misunderstood the whole issue. If that is the case, could you please enlighten me.
Best Regards
George Marinkovich
Ranch Hand

Joined: Apr 15, 2003
Posts: 619
Hi Frankie,
Good arguments can definitely lead to better understanding. Argumentation has acquired a bad reputation, probably because there are more bad arguments going around than good ones. As for fault finding, a candidate should welcome it rather than resent it, since it can be very useful (at least up the point the project is submitted ). So for the sake of discussion, I'll share my reasoning on how I came to do what I did.
For background, I'll start with what happens when a user attempts to book a record. After having selected a row in the JTable, the user presses the Book button. The book method tests if the selected record is already locked (i.e., calls isLocked). If it isn't, then the book method attempts to acquire the lock on the selected record (i.e., calls lock). If it's already locked, then a dialog appears asking if the client wants to wait for the record to become available, or cancel the booking attempt and try again later. If the user chooses to wait, then lock is called and the user waits for the record to become available (i.e., be unlocked). How long can this wait be? I think the wait can be anywhere from a split-second to eternity. I have no idea how long it's going to take the current owner of the lock (lets call him Joe) to enter the customer ID in the book selected record dialog. I can imagine that Joe was just about to press OK, in which case it may only be a split second, or maybe Joe was in the middle of editing the customer ID, realized he was late for his plane, left the office, and spends the next two weeks having a relaxing vacation in Tahiti. The purpose of this absurd example is to illustrate that I have literally no idea how long it's going to take for the user to enter the customer ID. Furthermore, I have no guarantee that when the current user releases his lock on my selected record, that I will be the one to get the lock next or rather one of the other 20 users waiting for this same selected record. So it became clear to me (and perhaps only clear to me) that I really couldn't know how long a user could hold a lock.
What does it mean when a user attempts to book a selected record and finds that it's locked? Here's an illustration: user1 and user2 see that recNo=2 is currently unbooked (does not have a customer ID assigned as the owner of the record), user1 books the record first, so the next thing user1 sees is the book selected record dialog where he's asked to enter the customer id, user2 tries to book recNo=2 at this point and gets the "wait for lock now, or try again later" prompt. What is user2 thinking at this point? He went to book an unbooked record, but the next thing he sees is a dialog telling him the record is booked and asking if he wants to wait for the record to become available. So perhaps he thinks, darn someone beat me to recNo=2, why should I wait for this guy (user1) to finish (and unlock the record) as he's only likely to have booked the record for his client? I'm not willing to overwrite someone else's booking, so I'm just going to cancel my attempted booking and book the next best contractor for my client (before one of the other user's books him ahead of me). So there is some (theoretical) benefit to asking a user who has attempted to book a record, whether he really wants to wait for the record to become available (and no telling how long that will be, remember Joe sunning on a beach in Tahiti), or whether he simply wants to cancel the attempted booking and continue on with whatever he's doing.
So why did these bizarre scenarios occur to me? Probably it's an artifact of how I started testing server and client mode of my executable. I would start the server on one machine and start four network clients on the same machine, then I would start four network clients on a different machine (but still using the same server). I would lock recNo=2 in one of the clients (which would get the book selected record dialog), and then I would lock recNo=2 in all the other network clients (which would get the wait now or try again question). For a few of these network clients I would answer try again later, but for most of them I would answer wait now. So, I would have multiple clients waiting for the same record (recNo=2). I would enter different customer IDs in each of the book selected record dialogs, so I would see that a particular client always received the latest customer ID when he got his chance to see the book selected record dialog.
So, given this background, I'll respond to your statements and questions:

From step 2 to 7 is only a few mini-seconds of wait and you like to show the user a dialog box for that? Maybe I have misunderstood the whole issue. If that is the case, could you please enlighten me.
[/qb]<hr></blockquote>
According to my design (as part of step 5) a book selected record dialog is displayed and the user enters the customer ID as the new owner of the record. This takes a few seconds, maybe a minute or two, but maybe a lot longer. Maybe this is a new customer and the user doesn't have a customer ID yet so the user needs to use some other application to generate a new customer ID. If he does this while the book selected record dialog is displayed, then the record remains locked for as long as this takes.
Now, I did test my application in a multi-threaded test harness and basically what the special test book method did in this harness was: lock, read, increment customer ID, update, and unlock. So in that case, because there was no user interaction the locking duration was very quick (as you said only a few milliseconds).
But in my normal operating mode, I could not make the same assumption of a very short locking duration . It seemed to me that the user should be given the choice of waiting for the record to become available or canceling the book request (with the expectation that someone else was in the process of booking the record for a different customer). It seemed worthwhile to me at the time. Like a lot of things I did in my project if I had to do it over again I might not do it this way.
Another consideration I had in my design was to allow a user to overwrite a customer ID. I thought it's OK for a user to overwrite a customer ID as long as the user understands that he is in fact overwriting a customer ID. For example, user 1 books recNo=2 for customer ID=12345678. Customer ID=2222222 calls user 1 and tries to book the same record, but user1 tells him sorry it's already booked. Poor customer ID=12345678's house subsequently burns down, he calls user 1 and tells him: "I guess I won't be needing that painting contractor to come out on Thursday." User 1 remembers customer ID=2222222 was interested in the same contractor and calls him to make sure he's still interested. Customer ID=22222222 is still interested, so user 1 books recNo=2 again and overwrites the customer ID for that record indicating it is now booked for customer ID=222222222. So, in step 8 above, I would not prevent Client B from making a booking for his customer (note that in my design client B would know that the record had already been booked and would be making a conscious decision -- maybe good, maybe bad -- to overwrite the booking).
Thanks for asking such an interesting (at least to me) question. I hope this explanation helps,
George
P.S.
I think what I really wanted was a way for a user to abort waiting for a record lock, but I didn't see an easy way to do so, and so I settled for the design above. If anyone has implemented a way to cancel waiting for a lock I'd like to hear about it.
[ January 27, 2004: Message edited by: George Marinkovich ]
Javini Javono
Ranch Hand

Joined: Dec 03, 2003
Posts: 286
Hi,
Thanks very much for posting your detailed reasoning for others to learn by.
Keep in mind that I'm new to this exam (in that I keep discovering things that
I have to learn), and so my ideas may be off the mark; but, if I may, I'll state them.
Some of my comments may be vague or general or intuitive.

If it's already locked, then a dialog appears asking if the client wants to wait for the record to become available, or cancel the booking attempt and try again later.

Intuitively, this doesn't sound right. Waiting for a lock should not take overly long
(granted, "overly long" has not been defined).
First, before presenting my idea, let's consider an idea which may not be feasible:
in short: when a thread is sent to lock a record, it let's the system know who it
is and how long it has to do its job; if it has not reported back by that time
saying that it has got the lock, the Killer object interrupts the thread. This idea
is bad because if the thread is interrupted during an I/O operation, the DB file
could be corrupted and, the DB file may need to be re-opened.
However, this might be good idea, because you're only interested in catching a long
wait before the locking occurs. After the thread has the lock, it tells the Killer
object to disappear; thus, the Killer object can never kill the thread while it is
doing I/O.
Generally speaking, hopefully our systems are responsive enough so that we are
not waiting overly long for that lock.

How long can this wait be? I think the wait can be anywhere from a split-second to
eternity. I have no idea how long it's going to take the current owner of the lock
(lets call him Joe) to enter the customer ID in the book selected record dialog.

Intuitively, I don't think you should place your application in a position where it is
dependent upon the client entering data and pressing buttons. Now you have designed
in very long locks, which is, as I heard and read recently, not appropriate. Would it be worse
if the user booked a record and you simply came back saying that record has already
been booked? In general, locks are held for short amounts of time (in computer processing
speed standards, not human reaction time standards), or so I've read recently.
Actually, would it avoid the long, potential wait if the application would not accept
any action from the user requiring a lock until the user first entered his customer
ID?

Furthermore, I have no guarantee that when the current user releases his lock on my selected record, that I will be the one to get the lock next or rather one of the other 20 users waiting for this same selected record. So it became clear to me (and perhaps only clear to me) that I really couldn't know how long a user could hold a lock.

If the locking is always done for a short duration by any given thread, then it most
probably will not take an overly large amount of time, and thus you can know,
within reason, about how long it would take to get a lock if you know other
system information (how fast RMI is, how many clients there are, how many clients
are attempting to obtain a lock on the same record).
By the way, it just occurred to me that you may have already taken and passed
the exam. If so, I guess I sound foolish. But, assuming that you have not
already taken and passed the exam, then the above are my current opinions.

"wait for lock now, or try again later" prompt

I'd never issue this prompt, since the system should be designed so that the lock
will be had in a reasonable amount of time. However, an error message may
be appropriate, and I make one up: Unable to obtain record. Perhaps this would
be due to an I/O error, and hopefully not to a programming logic error.
Summary: It's quite possible that I don't fully understand the intricacies of your
detailed design, and in this light, my ideas may not make any sense; if so,
I apologize.
Thanks,
Javini Javono
[ January 27, 2004: Message edited by: Javini Javono ]
Javini Javono
Ranch Hand

Joined: Dec 03, 2003
Posts: 286
Hi,
As an aside, you mentioned the boolean isLocked(recordNumber) method.
Although I'm still learning and considering options, I have not yet found
any reason why my code needs to know whether a record is locked or not.
I figure that the reason Sun places this in as a requirement I have to implement
is that it requires another data structure/object to carry out this bookkeeping,
and that I also need to find a way to synchronize this bookkeeping object
such that I can modify one of its Mutex items without locking the complete
bookkeeping object.
But as far as actually needing isLocked(), I don't see why I would, since I am
assuming that any request to get a locked record will succeed (of course,
at some time when I have finished coding up this preliminary design idea,
then I might consider the exceptional cases).
One minor use of the isLocked method, a use I may or may not use, would
be if the server determines that there are no user's present, and it wants
to check itself to ensure that the file is consistent and that processing
was consistent. Thus, prior to shutting down, the server might take a trip
through the bookkeeping record to ensure that no records are locked;
if any are, then something went wrong somewhere.
Is it possible you are "forcing" the use of isLocked() in your design? Or
is your project sufficiently different from mine that you care whether
someone holds a "short" lock on the record?
I should also say that I am not informed as to the overall opinions on this
topic in this group. But I am assuming that I will implement isLocked()
to satisfy Sun, and primarily, will have no other use for it.
Thanks,
Javini Javono
[ January 27, 2004: Message edited by: Javini Javono ]
Xie Ruchang
Ranch Hand

Joined: Dec 25, 2003
Posts: 160
Hi George,
Thank you for your explanation, now I fully understand why you have to do that.
Let me share my approach. When the user clicks on the [Book] button, the GUI asks for the Customer ID, then the user clicks the [OK] button, THEN, the application proceed to lock, read, check, update and inform the user of the outcome. I delay the lock until the user says [OK], not at the [Book] button. That is the main difference between my approach and yours. The advantage is no indefinite waiting. Always have a outcome of success or not success.
Locking the record at that [Book] button causes resources to be held out too early. If the user cancel it, the lock is released. If the user doesn't cancel, the lock is forever held, like what you said, go for a holiday. Power failure or program crash at moment, deadlock at the server side. It is unwise to design a system like this.
The waiting part is a result of this design. If you take my approach, the waiting part automatically disappears.
Another thing you mentioned is regarding booking of an already booked record. I think the proper way to do it is to allow an [Unbook] function and then [Book] again. At least, the user knows what he is doing. If you allow a later booking to overwrite an early one, the first user who have no ideas that has happened, he may think that he made a mistake in entering the wrong customer id and may rebook the record with his first id. This would be disastrous.
In my design, I have the [Book] button and a textfield Customer already visible on the window. The user click on a record on the JTable, enters the customer id in the textfield and click the [Book] button. If the user didn't enter the id in the textfield, a dialog box will just pop up to remind him. When he clicks the [Book] button, the application lock, read, check, update and unlock. Then inform the user whether the booking is successful. If it is successful, the entered customer id will be refreshed on the JTable.
If another user concurrently book the same record and it is successful just before this one, then at the checking part, the application will detect that the field is not blank but has been taken by another customer, it will not overwrite the customer id, it then unlock the record and reports to the user that the record has already been booked by another customer. The Jtable now refreshes with the id of that customer.
To address the issue you have raised, my GUI has an [Unbook] button to cancel the booking, also based on the same locking principles.
So in my design, there will not a case of indefinite waiting.
Best Regards.
PS : By the way, this is also the approach taken by the web based (JSP/Servlet/EJB) applications as the Browser cannot have a lock on a record at the back end database or application server!
[ January 27, 2004: Message edited by: Frankie Cha ]
[ January 28, 2004: Message edited by: Frankie Cha ]
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: NX: Using SwingUtilties.InvokeAndWait method in GUI
 
Similar Threads
Locking
question about scjd
All of URLy Bird 1.1.3 how to use the same GUI and Data in alone or netword client
GUI display & booking questions
Newbie Question: Java EE vs Tomcat+Hibernate+Struts