This week's book giveaway is in the OCPJP forum. We're giving away four copies of OCA/OCP Java SE 7 Programmer I & II Study Guide and have Kathy Sierra & Bert Bates on-line! See this thread for details.
Hi, We have a client-server based architecture. In the client side, we are trying to separate the GUI module and the backend module. The backends are written as different libraries which will interact with the server and maintain an updated data repository. The GUI module calls APIs in the library and takes the data from the library as required. The libraries and the GUI run as a single java application. I have the following doubts regharding this subject: - Should the GUI module maintain duplicate copies of the data it takes from the library or should we enforce that the GUI module always takes data (when it requires) from the data repository in the library? - If we allow GUI module to maintain duplicate data, there is an extra overhead to keep that data in an updated manner. This method also increases the memory overhead - If we design in such a way that the GUI module will not hold data and will take data as it requires from the library, we run into certain repaint exceptions because the library updates the data when the GUI is being painted. - Should we take a model approach when we expose the library data to the GUI module or allow the GUI module to use the exact data structures used in the library. The later method will mean that the library cannot have the independence of changing its data structures without a correponding change in the application.
Can any of you please clarify the general design guidelines used in such situations?
Thanks in anticipation of a fast response. Karthik
It sounds like you may have some conflicting or challenging requirements. Making a copy of the data runs the risk of being stale, but getting data straight from the model runs the risk of some other thread updating the model as you go.
What is the alternative to the GUI having some kind of copy? If the GUI works directly on the "golden" version of the model data, does the model have to validate every keystroke? What if the user changes the city in an address but never changes the zip ... can we allow the model to stay in that bad state?
I started to write up some suggestions but stopped because we just don't know enough yet. Can you lay out your concurrency requirements a bit more? Do multiple users or threads or whatever share object instances in the model? Are there multiple instances of the whole application working on a shared database? What should a user experience if another user updates something he is looking at? What if he tries to save changes?
A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
Joined: Jan 08, 2007
Hi James, Thanks for the response. Actually, for the problem being discussed, the GUI module will treat the data in an absolutely read-only manner. There is no interface for
the user to change anything on the data directly. The user might trigger an action, but the trigger goes to the server, the server does the
action, the change is notified to the Backend module in the client and then the Backend module updates its data structures accordingly.
One problem that we have been facing here is as follows: - There is a JTable component using a TableModel which takes data from the Backend module - On trigger of a table repaint, the JTable component starts querying the model for data. Starts with getRowCount(). Assume that there are 10
rows in the Backend module at that point in time, the model replies 10. Accoringly, the JTable starts querying the model for getValueAt(x,y)
with y ranging from 0 to 9. - While it is querying data for the 4th row, the java Event dispatch thread gets suspended in the java JVM and another thread gets into
action - This thread might receive a packet from the server and update the Backend data that is currently being drawn by the JTable. Assume it
removes two rows in that data. This thread gets suspended at some point and the Java event dispatch thread resumes again. This thread
faithfully continues from row 4 and continues to query till row 9. But when it places a query for getValueAt(x,8), the corresponding data is
not available in the Backend module at this time, so the model returns null and the JTable throws an exception - To solve this problem, we started ensuring that any data update in the backend module is put under SwingUtilities.invokeLater() so that all
pending event dispatch thread activities are completed and then the data gets updated - But the problem with this approach is that it takes care of only the GUI thread. What if another thread is doing something which depends on
the Backend module data? What is a clean way of communicating such changes to the threads that use the data? A simple observer will not help
because the thread might have already started reading part of the data (such as getRowCount() and getValueAt()), may get suspended and will
continue the activity when it is scheduled later by the JVM.
This particular problem is different from what I asked in the initial post. As you asked some questions related to concurrency, I though I
will get this point clarified from you before bombarding you with other issues.
Anticipating an early (if possible earlier!!) response again. Thanks & Regards Karthik
Joined: Jan 29, 2003
Can you simply synchronize the methods that fetch and update data?
Calling the model once for rowCount() and again for each row sounds pretty dangerous. Can you try to make rowCount() unnecessary and get all the rows at once?
Joined: Jan 08, 2007
Thats the way the java Table works. A repaint on any JTable will first call the getRowCount() on the model and then a set of getValueAt(x,y). Is it possible to change the default behaviour of JTable? Even if thats possible to change JTable behaviour, I would be in terested in a generic solution (if any). The locking mechanism you have given will work only if the complete data is fetched at one shot.
Joined: Jan 29, 2003
Ah, you're talking abou the internal model inside Swing. I was talking about a business domain layer model. I don't do much Swing, but I'd probably consider the Swing model a copy of the business model and synchronize updates and repaints. Collisions should be rare.