I have not yet seen a good way to CLEANLY have a class send notifications about its progress. (For example, when using a JProgressBar) I find I have to litter the code with calls to "notify()" throughout its processing methods in order to update something like a progress bar.
Is there a better way to do this? Some way for a separate object to "register" with the JVM or something to keep figuring out where some object is in it's method calls? There just has to be something better.
For example, if I have an object with a method like:
If I wanted to update a progress bar as it does the above, I'd have to do something along the lines of:
Basically, I'm littering my code with other code that technically has NOTHING to do with it - BAD practice. But as far as I can see, there's no other way to do it. UNLESS, there's some way to "register" with the JVM or class loader to be notified of certain method calls, or something like that. Anyone know of something?
(Granted, you could use AOP or BCEL, but then you're still littering the code with stuff that technically doesn't belong there. Just that as a developer, you wouldn't see it prior to compiling) [ January 21, 2005: Message edited by: Dan Bizman ]
I've run into this same problem and haven't found a solution I'm really happy with. If the task shouldn't take more than 5-15 seconds I set the progress bar to indeterminate and don't worry about it. I don't think a timer would work unless there is some way to know ahead of time just how long it will take, very unlikely.
Joined: Feb 25, 2003
Thanks for the suggestions, but steven bell is right. Those solutions don't fix the problem. With both solutions there's still a few problems:
1. I never know how long the task will take. It involves contacting a server, so sometimes it's 2 seconds and sometimes it's 15 seconds.
I DO, however, know how MANY tasks will need to be completed. I just don't want to clutter up the thing that has to execute each of these will calls to letting people know about it.
2. The Task framework is back to the same thing. I'm still relying on the object to know and notify, because it must implement the Task interface (or extend it) and fill out that info to let the observer know the progress. In fact, it's pretty much what I'm doing already.
Create an abstract class (AbstractTask) that all tasks will extend. AbstractTask registers listeners that want to monitor the task. Every time a new event is fired in AbstractTask, AbstractTask passes the right command to all its listeners.
That's just my object kicking off events - in other words, cluttering it again. Still not quite what I'm looking for.
Let's see if I can explain that a bit better. Imagine that I have an object which handles contacting a server and sending it a file. In the process of doing this it encrypts the file, creates an "envelope", adds the file and then contacts the server, identifies itself and sends it. To me, THAT is all the object should ever do. But the current event-listener model requires that my object take on two roles: file-sender and mediator or event-notifier (whatever you want to call it).
I know this is accepted practice, but I don't like it - it's messy. And if I ever want to change what events it notifies, or where it notifies about events, I have to go back in to all that code and re-write the FileSender class. Again, I don't like that. I feel like it should be abstracted. And AOP is not abstracting it (nor is BCEL). It's abstracting the process of adding the code, but that's it. Plus, what if a method has to do two things in one method (neither of which calls any other methods from that object but from JRE classes) and they each can hang a tad so you want to notify about the success of each? BCEL can deal with this (it's messy), but AOP is stuck at the method level.
Is there a solution? I don't know. [ January 21, 2005: Message edited by: Dan Bizman ]
You can pull all the event notifier code out of the task if that's what's bothering you. It's still responsible for sending messages, but not for implementing any observable code. I made a Publisher class that handles subscribe and unsubscribe in a base class and publish in a custom method.
The GoF on Observer / Publish Subscribe calls this an intermediary, I think, in an optional variation on the normal observable. It allows any number of publishers to publish exactly the same message, or for publishers to come in and out of existence over time which may or may not be useful.
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