Let's say I have a class that builds a GUI and has a method updateMainUI(String text) that appends text to a JTextArea. Currently, I'm using abstract classes and methods to update the field from a different class, but I'm wondering if this is the 'right' way to do it?
I now have three abstract classes that have an protected abstract updateUI(String text) method that I override in my GUI class to update the field whenever I need to, but I'm doing the same thing in multiple classes and now I feel like I need another class that does the exact same thing.
Is there a better or more acceptable way of doing this?
From you question, it's difficult to be 100% sure, but, it is generally encouraged to use a Model–view–controller approach to these types of problems.
This is, the model defines the "virtual" state, the view represents this state to the user and the controller controls changes to the model initiated from the view...
The view is notified, by the model, when it changes, so it can update the state and the view notifies the controller when some part of its view/state has changed and may be reflected in the model.
To this end, I would encourage you to define some kind of model, which is normally described by a interface which can be used by the various aspects of your program. Updates to the model don't need to come from the user/UI, but you will need to ensure that you clearly document when notifications might come from a different thread other than the Event Dispatching Thread, so your UI code can take correct actions and synchronise the updates.
So, based on you example, your model might have a method call setText (or some such), which triggers some kind of event notification to registered listeners.
This instance of the model would be shared amongst the various classes of your application
You main UI would be one of these classes listening for a change in the models state, when it detected a change, it would update its state accordingly.
This is an example of the observer pattern and you see this in use all over Swing (via it's listener/event API)
Related
How should Listeners etc be managed? I've found only examples with one button etc.
I can think of following options:
Extra class for each - doesn't seem right, especially when items
can be created dynamically
Class for each group (such as form1,
form2, controlButtonsOnLeft, controButtonsOnRight, mainMenu,
userMenu, ...) where I'll check which button/component caused this
(via getSource method for example)
Some super (sized) controller,
which will accept all user actions
New anonymous class for each,
which will call controller's method with parameters specifying
details (probably enums)
And another question: I've found many examples for MVC, I was wondering what is better (or commonly used) for app. developed by 1 person (app will not be huge)?
A. Viewer sets listeners to controller (A1-3)
B. Controller calls viewer's methods, which accepts listener as parameter (methods addLoginSubmitListener, addControlBoldButtonListener etc)
All of above are possible to implement and so far I would choose B4.
Meaning in Control I would do something like this:
...
viewer.addLoginButtonListener(new Listener()
{
#Override
public void actionPerformed(ActionEvent e) {
...
someButtonsActionHandler(SomeButtonEnum, ActionEnum);
...
}
});
...
private void LoginActionHandler(LoginElementsEnum elem, ActionEnum action)
{
if (elem.equals(LOGINBUTTON)) {...}
...
}
...
This combines readable code (1 logic part at one place in code), doesnt create any unwanted redundant code, doesnt require any hardly-dynamic checks, is easily reusable and more.
Can you confirm/comment this solution?
To be honest the question comes down to a number of questions...
Do you want reusability?
Do you want configurability?
Are they self contained? That is, does it make sense for anybody else to listener to the component or need to modify the resulting action of the listener in the future?
Personally, I lean towards self containment. A single listener for a given action/task. This makes it easier to manage and change should I need to.
If I don't need reusability (of the listener) or configurability, then an anonymous inner class is generally a preferred choice. It hides the functionality and doesn't clutter the source code with small, once use classes. You should beware that it can make the source code difficult to read though. This of course assumes that the task is purpose built (its a single, isolated case). Normally, in these cases I will prefer to call other methods from the listener that actually do the work, this allows a certain amount of flexibility and extendability to the class. Too often you find yourself wanting to modify the behaviour of a component only to find that behaviour buried within an anonymous or private inner class...
If you want reusability and/or configurability - that is, the listener performs a common task which can be repeated throughout the program or over time via libraries, then you will need to provide dedicated classes for the task. Again, I'd favour a self contained solution, so any one listener does only one job, much easier to change a single listener then having to dig through a compound list of if-else statements :P
This could also be a series of abstract listeners, which can build functionality for like operations, deleting rows from a table for example...
You could considering something like the Action API (see How to Use Actions for more details), which are self contained units of work but which also carry configuration information with them. They are designed to work with buttons, such as JButtons and JMenuItems, but can also be used with key bindings, making them extremely versatile...
The second part of you question (about MVC) depends. I prefer to keep UI related functionality in the view and out of the controller as much as possible. Instead of allowing the controller to set listeners directly to components, I prefer to provide my own, dedicated, listener for the controller/view interaction, which notifies the controller of changes to the view that it might like to know about and visa versa.
Think about it this way. You might have a login controller and view, but the controller only cares about getting the credentials from the view and authenticating them when the view makes the request, it doesn't care how that request is made from the views perspective. This allows you to design different views for different circumstances, but so long as you maintain the contract between the view and the controller, it won't make any difference...But that's just me.
Originally I had the view holding commands for buttons, these buttons calculated this and output text onto JTextAreas after being pushed. What is produced is dependent on the value returned.
I am concerned I am not following standard MVC architecture by setting text like below inside my controller.
At the moment I changed my button commands into my controller as so
private class ReadActionListener implements ActionListener {
public void actionPerformed(ActionEvent l) {
/* there is other code in here, which results in setting text its not
just a set text button*/
/*interactions with model etc etc, outcome true? setText JTextArea like below*/
view.variable.setText("hi there");
}
}
Should I be setting text for the view inside the controller or is this breaking standard MVC architecture?
Thanks,
Jim
In MVC, you should not update the view from the controller. The controller is meant for event handling and altering the model according to these events. The model should then update its observers, ie. the view.
You can read up on the Observer design pattern here: http://javarevisited.blogspot.nl/2011/12/observer-design-pattern-java-example.html
There is a code example provided on that website as well.
In MVC, the model is a layer.
The model layer comprises of multiple objects: domain objects, services and mappers. You can read more in this post (although in PHP, the concepts still hold substance).
That being said, your controller handles the input from the user, sends this to the relevant object within the model layer, which then returns this data to the controller - and then your controller sends this to the view instance which handles the logic for displaying this to the user.
The observer pattern is really interesting and Koen's link above is a good one. I saved this snippet a while back from somewhere on SO:
Have state-setting operations on Subject call Notify after they change the
subject's state. The advantage of this approach is that clients don't have
to remember to call Notify on the subject. The disadvantage is that several
consecutive operations will cause several consecutive updates, which may be
inefficient.
Make clients responsible for calling Notify at the right time. The advantage
here is that the client can wait to trigger the update until after a series
of state changes has been made, thereby avoiding needless intermediate updates.
The disadvantage is that clients have an added responsibility to trigger the
update. That makes errors more likely, since clients might forget to call Notify.
This old but still valid example of the observer pattern may still be useful: http://javanook.tripod.com/patterns/observer.html
I'm building an application which contains a GUI and a Model. I'm using the Observer pattern (using java's built in interfaces) to update the GUI when fields in the model are changed.
This is generally working fine, but I have a situation in which a particular String variable in the model (specifically the url of a file) can be changed by two separate JTextFields (swing) the contents of which actually reflects the value of the model variable in question.
The issue I am having comes from the fact that an change in one of these JTextFields needs to cause an update to the state of the model, and the contents of the other JTextField. My Model ensures that notifications are sent to observers only in the case that the state of the model has changed. However, the process by which JTextFields are modified involves blanking it's text content then reseting it.
Without going into too much detail, the upshot of this is that the update / notification process gets stuck in an infinte loop. I have temporarily hacked around this by setting aside the observer pattern for this particular problem, but I was wondering if anyone could suggest a neat way of ensuring that a particular component is not "updated" by a change which originated from the same component.
Any help appreciated.
As discussed in Java SE Application Design With MVC, this is one of several Issues With Application Design. The suggested approach relies on a PropertyChangeListener, illustrated here. The PropertyChangeEvent includes both old & new values for reference.
This link which talks about a Bidirectional Observer may offer some help on this.
It does seem in your case that the Model and View are trying to update each other. The solution would lie in enforcing the direction of an update. For example Inner layer -> Model -> View and View -> Model -> Inner layer. So it wouldn't really be a true Observer Pattern.
The update(Observable o, Object arg) method of java.util.Observer does accept an Observable(Subject) object. This object can be used to provide a hint to the Model asking it to propagate the update inward rather than toward the View.
I gave it a quick try and found that setting up Bidirectional observer (using Java apis) is not as simple as I thought. But you could venture a try.
I have a basic MVC pattern created in Java that uses the Observable/Observer class/interface.
Observable Observer Observable/Observer
Model Controller View
View triggers an event to the Controller, when the user interacts with the GUI.
- E.g presses a button, fills in a field, etc.
Model triggers an event to the View when it updates its state.
- E.g when the a button was pressed and the Controller requests new results.
My question is about the Observer function
update(Observable obs, Object arg);
This is one function, but I have many different kinds of updating to do in my View for example. How do I elegantly distinguish between an update to, say, my search results or the displaying of additional information? These are two completely different updates that use different objects from the Model.
My first idea was to use the Object to pass a string which would describe what update is required.
"UpdateResults" "DisplayAdditionalInformation" "AddQuestions"
but that seems error-prone and ugly. My second instinct was to create an EventObject that would be passed as an Object, but then I have to keep asking what kind of EventObject I'm using:
if (arg instanceof ResultEventObject)
// Get results from model
else if (arg instanceof InformationEventObject)
// Get information from model
else if (arg instanceof QuestionsEventObject)
// get questions from model
My third idea is to simply update everything, but that seems pointlessly inefficient.
I am probably not understanding the Observable/Observer interface correctly or I'm not using update() as it was intended by it's authors. Therefore my question, how do I use the updatefunction properly when I have many different types of updates or events to process?
You can create your own Listener interfaces depending on what view/model you are listening to. This allows your view/model to pass exactly the information required to your controller and will make it easier to unit test the controller.
For listening to the model, updating everything is the simplest solution and you can do that unless performance proves to be an issue.
Yes, I think its better to use Listener Interface
check this note http://www.softcoded.com/web_design/java_listeners.php
I have a class which extends JFrame and forms the GUI of my program. I want to use the GUI for two main purposes:
I want the user to be able to input values to the program.
I want the GUI to display values created by my program.
Considering my class has a lot of GUI elements, the source file is already rather large and It does not seem like good practice to bundle all the program code in with the GUI code. I'm wondering what is the best way to structure my code? I believe there is an issue where requirement 1 creates a dependency from the GUI to the program code, and the second requirement does the opposite.
So, I want one class for my GUI which contains all my GUI related tasks. I then want another class for my program logic. I should then be able to call methods from the program logic class from the GUI and vice versa.
Sounds like you are looking for a textbook MVC (Model-View-Controller) design pattern. I recommend you google "MVC Design Pattern" for summaries and use cases. That being said, you might want to put your program logic into a "Singleton" class (again, google "Singleton Design Pattern"). A properly implemented Singleton should be accessible from any other class in your code.
Consider also a third middle class which acts solely for data storage, you put values into it for storage, and you fetch values from it for work. This now creates 3 clear segments for your code, the Data (the Model), the GUI (the View), and the logic (the Controller). Voila, you've just implemented the MVC (Model-View-Controller) design pattern...
The business logic should not depend on the GUI logic.
Have your GUI take inputs from the user. Call business logic methods with these inputs as method arguments, and use the values returned by the methods to display the result in the GUI. The GUI thus depends on the business logic, but the reverse is not true.
If the business logic must callback the GUI, it should do so via well-defined GUI-agnostic callback interfaces, or listeners. For example, you could register a ProgressListener on some business logic object, and this object would call back the progress listener. The GUI would have an implementation of the ProgressListener which would in fact update some progress bar or text area. But the business logic only depends on the interface, and not on the specific implementation.
I'm not sure there is one "best" way to structure GUI code. As a general rule though, you should follow MVC. Your program (Model) should never directly depend on your View code. What it's allowed to do is notify the controller that the model (or parts thereof) changed, and that whichever views are currently displaying said part of the model should be updated.
Swing already provides this abstraction layer for some of its types of component, most of the classes are (somewhat confusingly) suffixed with Model. A simple example you could look at would be BoundedRangeModel. There should be only one instance of such a Model for every "unit" of data your program manages, and different views displaying this data should share this instance. Your business code manages this object, and whenever this piece of data changes, the GUI is notified using it by firing off some event listeners.