I'm learning to build gui applications. My current private project is working, the program is doing everything I want. But the implementation looks pretty bad and is not maintainable or extensible anymore. It is not really following MVC or other design pattern in the main parts. So I've started to rework it and would appreciate some advise.
The goal of the program:
It is a monitoring tool getting the data from an external source all the time as long as the application is running. The data is displayed (some labels, text areas, an OSM map) and updated permanently. Depending on the data a button to start the recording of the data (into a file) is enabled or not. When the recording is stopped by the user (same button) some post actions are executed.
Due to lack of knowledge I have implemented two separate SwingWorkers, one to display the current data and one for the recording, started when the button is pressed (is reading the date too!). This is my main pain point. Just one data-retrieving SwingWorker must be sufficent.
So I have started to rework it. I have a gui view class. Once the gui is initialized the SwingWorker (as a gui member variable) is executed and updates the view elements. Fine. Works. But is this a nice approach? The SwingWorker is the central object. From my feeling it should not belong to the view. Other objects should also observe and use its progress. Whenever new data came in gui elements or others should get notified. So I could add several observers to the SwingWorker and call notify(myData) within the doInBackground() method.
My second, bigger issue is concerning the start-stop button to record my data. What kind of implementation approach would you suggest? My idea was to implement a PropertyChangeListener to get the button clicked action. But how can this handle/record the data from the SwingWorker and interrupt on demand? It must get notified permanently too. Or is there some other, better pattern to pulling the data on demand? Is there a nice example with a single SwingWorker and multiple independent listeners/observers?
Thanks in advance,
Niels
I have a GUI and the GUI is starting another thread (Java). This thread is starting a class which is crawling many websites. Now I want to show in the GUI how many websites are crawled and how many are left.
I wonder what's the best solution for that.
First idea was to start a timer in the GUI and periodically ask the crawler how many is left. But I guess this is quite dirty...
Then one could pass the GUI to the crawler and it is calling a GUI method every time the count of ready websites changes. But I don't think that's much better?
What is the best way to do something like that?
It depends.
Ask the crawler how much work it is done isn't a bad idea. The benefit is you can actually control when an update occurs and can balance out the load.
The downside is that the information may go stale very quickly and you may never get accurate results, as by the time you've read the values, the crawler may have already changed them.
You could have the crawler provide a call back interface, which the GUI registers to and when the crawler updates it's states, calls back to the GUI.
The problem here is the UI may become swamped with results, causing to lag as it tries to keep up. Equally, while the crawler is firing these notifications, it isn't doing it's work...
(Assuming Swing)
In either case, you need to make sure that any ideas you make to the UI are made from within the Event Dispatching Thread. This means if you use the callback method, the updates coming back will come from the crawlers thread context. You will need to resync these with the EDT.
In this case you could simply use a SwingWorker which provides mechanisms for syncing updates back to the EDT for you.
Check out Concurrency in Swing for more details
register a callback function to your thread. when your data is dirty, invoke this callback function to notify GUI thread to update. don't forget to use synchronization.
Let me first sketch the concrete situation I find myself in, although my question is actually more general. I'm writing a component containing several sliders and I have listeners listening for events from these sliders. When one of these sliders changes I want my component to send an event to its own listeners to notify them that its state has changed. I would however like to limit the number of events that are sent, i.e. if there are several events waiting when my component notifies its listeners, I would like to collapse all these events into a single event.
My question is whether there are standard techniques for this. If so, any example would be welcome, because I couldn't find any. (Maybe collapsing is not the correct terminology?)
I believe collapsing is the correct term. An example class from the Java Core libraries that implements such behavior is RepaintManager. I would check out it's source code to see how it collapses multiple repaint requests.
Before you do any such thing you should make sure that it is really necessary.
I guess you would need to access the EventQueue from your listener. When an event triggers the callback method, this method should first look in the queue to see if there are more recent events of the relevant type and, if so, process the most recent event only and then remove all events of that type from the queue.
Since the callbacks are always on the Swing (awt) event thread, you don't need to worry about concurrency.
I'm new to advanced programming - but from what I've read, all my android programs are on one thread.
This means, only one line of code or method/function can be executed at a time before moving on to the next line (that's what I thought anyway).
However, I'm using a custom dialog to develop this application and yet, the program continues even after the dialog has ran. I'd like my program to wait for the dialog to close so that I can receive the input and manipulate it.
This seems fairly straightforward when programming in Java (e.g. the Scanner tool waits for the user input before proceeding as opposed to running the code following it while it waits for user input).
How can I do this?
Everything does happen on one thread unless you explicitly tell it not to. However, showing a Dialog happens asynchronously. Basically, when you ask the Dialog to show, it adds that information to a list of UI events that are waiting to happen, and it will happen at a later time.
This has the effect that the code after asking the Dialog to show will execute right away.
To have something execute after a Dialog choice is made, add an onDismissListener to the dialog and do whatever it is you want to do in onDismiss.
I'm developing a java swing application that will have several subsystems. For all intents and purposes, let's assume that I am making an internet chat program with a random additional piece of functionality. That functionality will be... a scheduler where you can set a time and get a reminder at that time, as well as notify everyone on your friend list that you got a reminder.
It makes sense to organize this functionality into three classes: a GUI, a ChatManager, and a Scheduler. These classes would do the following:
GUI - Define all of the swing components and events
ChatManager - Create a chat connection, send and receive messages, manage friend list
Scheduler - Monitor system time, send notifications, store a file to remember events between sessions
For the program to work, each of these classes must be capable of communicating with the other two. The GUI needs to tell the ChatManager when to send a message and tell the Scheduler when to start monitoring. The ChatManager needs to display messages on the GUI when they're received, and finally, the Scheduler needs to both notify the GUI when it's finished, and send a status update or whatever to the ChatManager.
Of course, the classes as described here are all pretty simple, and it might not be a bad idea to just let them communicate with each other directly. However, for the sake of this question, let's assume the interactions are much more complex.
For example, let's say we can register a particular event with the scheduler instead of a particular time. When sending a message, I went to send it to the user, store it in a log file, create an event object and pass it to the scheduler, and handle any exceptions that might be thrown along the way.
When communication becomes this complex, it becomes difficult to maintain your code if communication with these classes can be happening in many different places. If I were to refactor the ChatManager, for example, I might also need to make significant chaneges to both the GUI and Scheduler (and whatever else, if I introduce something new). This makes the code difficult to maintain and makes us sleep-deprived programmers more likely to introduce bugs when making changes.
The solution that initially seemed to make the most sense is to use the mediator design pattern. The idea is that none of these three main classes are directly aware of each other, and instead, each is aware of a mediator class. The mediator class, in turn, defines methods that handle communication between the three classes. So, for example, the GUI would call the sendMessage() method in the mediator class, and the mediator would handle everything that needed to happen. Ultimately, this decouples the three main classes, and any changes to one of them would likely only result in changes to the mediator.
However, this introduces two main problems, which ultimately resulted in me coming here to seek feedback. They are as follows:
Problems
Many tasks will need to update the GUI, but the Mediator isn't aware of the components. - Suppose the user starts the program and enters their username/password and clicks login to login to the chat server. While logging in, you want to report the login process by displaying text on the login screen, such as "Connecting...", "Logging in...", or "Error". If you define the login method in the Mediator class, the only way to display these notifications is to create a public method in the GUI class that updates the correct JLabel. Eventually, the GUI class would need a very large amount of methods for updating its components, such as displaying a message from a particular user, updating your friend list when a user logs on/off, and so on. Also, you'd have to expect that these GUI updates could randomly happen at any time. Is that okay?
The Swing Event Dispatch Thread. You'll mostly be calling mediator methods from component ActionListeners, which execute on the EDT. However, you don't want to send messages or read/write files on the EDT or your GUI will become unresponsive. Thus, would it be a good idea to have a SingleThreadExecutor available in the mediator object, with every method in the mediator object defining a new runnable that it can submit to the executor thread? Also, updating GUI components has to occur on the EDT, but that Executor thread will be calling the methods to update the GUI components. Ergo, every public method in the GUI class would have to submit itself to the EDT for execution. Is that necessary?
To me, it seems like a lot of work to have a method in the GUI class to update every component that somehow communicates with the outside, with each of those methods having the additional overheard of checking if it's on the EDT, and adding itself to the EDT otherwise. In addition, every public method in the Mediator class would have to do something similar, either adding Runnable code to the Mediator thread or launching a worker thread.
Overall, it seems like it is almost as much work to maintain the application with the Mediator pattern than to maintain the application without it. So, in this example, what would you do different, if anything?
Your GUI classes will end up with many methods to keep it up to date and that is fine. If it worries you there is always the option of breaking up the GUI into sub GUIs each with a different functionality or a small set of related functionality. The number of methods will obviously not change, but it will be more organised, coherent and decoupled.
Instead of having every method in your GUI create a Runnable and use SwingUtilities.invokeLater to put that update on the EDT I'd advise you to try out another solution. For my personal projects I use The Swing Application Framework (JSR296) which has some convenient Task classes for launching background jobs and then the succeed method is automatically on the EDT thread. If you cannot use this you should try and create your own similar framework for background jobs.
Here, a partial answer to you design questions...
It looks like you want to have loose coupling between your components.
In your case, I would use the mediator as a message dispatcher to the GUI.
The ChatManager and the Scheduler would generate UpdateUIMessage.
And I would write my GUI that way
public class MyView {
public void handleUpdateMessage(final UpdateUIMessage msg){
Runnable doRun = new Runnable(){
public void run(){
handleMessageOnEventDispatcherThread(msg);
}
};
if(SwingUtilities.isEventDispatcherThread()){
doRun.run();
} else {
SwingUtilities.invokeLater(doRun);
}
}
}
So you have only one public method on your GUI, which handles all the EdT stuff.
If you want to have a loose coupling between the GUI and the other components (meaning : you do not want the GUI to know all the API of the other components), the GuiController could also publish ActionMessage (on a specific Thread?), which would be dispatched by the mediator to the other components.
Hope it helps.
Well, I will change the world you are working with. You have 3 classes and each of them is just observer of the chat-world. The MVC is the way how to deal with your problem. You had to create Model for your world, in this case chat program. This model will store data, chat queue, friend list and keep eye on consistency and notify everybody interested about changes. Also, there will be several observers which are interested in state of world and are reflecting its state to user and server. The GUI is bringing visualization to friends-list and message queue and reacts on their changes. The Scheduler is looking about changes in scheduled tasks and update model with their results. The ChatManager will be better doing its job in several classes like SessionManager, MessageDispatcher, MessageAcceptor etc. You have 3 classes with empty center. Create center and connect them together using this center and Observer Pattern. Then each class will deal only with one class and only with interesting events. One GUI class is bad idea. Divide to more subclasses representing logical group (view of model). This is the way how to conquer your UI.
You might want to look at a project that originally started as a MVC framework for Flex development. PureMVC has been ported to many programming languages meanwhile, including Java. Though it is only in a alpha status as of writing this!