Java Swing GUI User actions handling - java

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.

Related

One Listener instace for all components or an instance for each component

Short Question
I want to know if there is any good practice recommendation about write one listener instace for all components or an instance for each component.
Extended Question
I'm developing a java swing application.
In the same form i can have a dozen of components (with no relation between them) that use the same listener class. I write each of my listeners in their own class.
The listeners are used to make some validations over the data introduced on the component.
Should i create an instance of the listener class for each component, or should i use the same instance of the listener for all the components.
I can't find any good practice suggestion about this, except this comment, that does not point to any reference.
For the particular case of ActionListener, encapsulate the desired functionality using Action. The wide use of this class throughout Swing suggest its value. This simple example illustrates a few built-in text component actions; this more elaborate example shows how actions can be shared among menus and toolbars.
The alternative is an ever-growing and hard-to-maintain if-then-else ladder based on the event source.
Addendum: Ah, I misread your question. #Andrew's comment is about classes; your question asks about instances. For the former, a single listener tends to evolve toward a a known anti-pattern; earlier versions of the example cited illustrate the problem. For the latter, use only as many instances as required; I usually catch the most egregious violations in a trip through the profiler.
I think the best solution is the one that makes your code the cleanest possible.
Basically, if having one single instance doesn't complicate the code too much then you could create just one instance and share it across the components. Otherwise, you can have multiple instances.
You should choose one which keeps your code readable and maintainable.
If creating instances makes it simpler go ahead and do it but since the behavior remains the same; I believe single instance should work.
Your idea is really interesting........
Moveover if its Swing....then its already based on MVC architecture......
Model - Business Logic and Data
View - Representation of Output
Controller - On which the action is done.
Now i think its also better to have the Business Logic with its data together, so we can easily associate the logic and its corresponding data.
You can always have an a common listener for common EventSource, like JButton...
You can have 4 JButton, which do different works, now you can have a single ActionListener with switch statements..... quite easy to handle......

How to Use Java Observer's update(Observable, Object) Function?

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

How can I avoid passing around a single instance of a top level component to all my subclasses

So I've been trying to see how I could best structure my code, because I have an intuitive feel that there must be a better way to achieve what I want without passing around a single object to nearly every UI class in the project.
The project I'm working on has a class RhythmWheel that extends JRootPane. The constructor then goes on to create all the components that form a RhythmWheel. For example it creates an instance of ControlPanel (which extends JPanel) and adds it to itself.
However ControlsPanel needs to have a lot of knowelgde of things that are defined in RhythmWheels like the number of wheels that are currently selected. Currently the constructor for ControlsPanel takes a RhythmWheel as an argument, and then keeps a reference to it. It uses this for things ranging for component a JFileChooser should be parented to to, and as an argument to a function that writes the revelant state of the application to an XML file.
It seems wrong to me that I'm passing around a main component across so many classes. I thought about design patterns, and figured that a singleton might be a solution to this. However I have read numerous times that singletons are evil and are an anti-pattern. I guess the MVC pattern might help, but I'm not sure how I'd implement that in Swing. And most recently I came across Dependency Injection as a possible solution.
I'm a little lost as to what I should be doing, or if I should be doing aything at all. If you'd like to glance at the code I'm working on, you can see it at https://github.com/vamega/RhythmWheels so any advice on how to proceed would be great.
if everything needs a reference to RhythmWheel then it sounds like RhythmWheel is awfully complex. maybe you can break RhythmWheel into a collection of components that (hopefully, and likely, since GUI should reflect logical structure) correspond to particular parts of the GUI?
also, why do all the GUI components keep references to the RhythmWheel (or the appropriate sub-component, if you refactor as described above)? i haven't done much spring programming, but i thought the idea was to structure things round an observer pattern. in that case, the gui components should be registering themselves as observers on the wheel components, so that they can update when the wheel changes.
and yes, this is mvc. the wheel components form your model; the gui is your view. what is less clear is what the controller is. i suspect that it is the high-level wheel.
so, in summary:
the wheel is composed of sub-components
the wheel has high-level methods that reflect what you can "do" to it
the wheel's high-level methods are what are called by actions in the view
the wheel's high-level methods make changes to the wheel's sub-components
the wheel's sub-components, when they change, inform the model, which updates
only the input parts of the view need references to the wheel; the display parts are triggered via callbacks registered with the wheel sub-components.
(to answer the original question directly, i don't see anything so bad in passing around a wheel instance, but as i suggest above, it might be better for it to "fragment" into different components as it gets "lower" into the GUI).
I don't see what's wrong with using singletons. A control panel sounds like a prime candidate for a singleton. Why would have you more than one? Same goes for the others. Anything your currently accessing in ControlPanel from RhythmWheel can be exposed through getters and setters.
Unless there's a model/view separation that you would like to decouple or a view that needs to observe model updates, I wouldn't use MVC.

Java Swing GUI code structure

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.

GUI patterns in Java/GWT - general approach

I'm helping to build a GWT application for a client and rewrote most of the stuff to work better, shorter code, faster, etc. However in all the GUI application I've worked on (not so many really) there comes a flexing point where you just have to put a lot of rules and move logic from the listeners to some common mediator. Then some times this could get an ugly mess so you whatever small think you need to do in the listener.
Let's take an example:
form with 10-20 fields
two exclusive radio control about half of the state of the other fields (enabling, validation, input limits)
three exclusive radio controls control again almost the same fields, but in a different way (affecting calculations, enabling); they are also controlled by the above
4 or so number fields are validated on the fly depending on the previous selections and some real-time data object; they can have upper/lower limits, be enabled/disabled
one drop-down box controls the next 6 or so controls - displaying/hiding them, modifying validators
some checkboxes (shown by the above combo) activate some input fields and also determine their validation algorithm
While everything is up an running, without known bugs, there are a few coding gotchas that really bother me:
code is spread among listeners and some mediator methods.
loading the form with some preset values presents its own challenges: like data objects that might be available or not, data objects that might alter their state and subsequent field behaviour
some fields are having a default value set and this should not be overwritten by automatic filling, but if the data objects are not there (yet) then they will need to be filled eventually when the later become available
form cannot be submitted if any of the fields are not validated
My approach:
identify which fields share a common afair and move code into one place
each radio group shares a single listener implementation between its radios
default form filling is deferred until the live data is available (as much as possible) and as a result it gets called multiple times
each action has a call to a common validator method
the validator runs through all the fields in the form, calls their validators (which highlight all errors) and returns a single boolean
each relevant keypress or mouse action, data change it gets deferred to be called after 250ms from the last call; this means first call just places the validator as a delayed action, subsequent calls reset the timer
Ok, it doesn't make any sense to dwelve into more details but I'm more upset about the fact that there is no clear separation between visual actions (enabling), data actions (setting form field values), field listeners, retrieving form values and live data listeners.
What would be a good approach/pattern (next time maybe) to make sure that MVC get separated and lends itself better to maintenance? I know this is not a typical question but I've read every documentation I could get my hands on and still did not find some helpful answer.
I'd move closer towards MVP than MVC. It's clearly the way Google intends to go, so adopting it will probably mean that you're able to go with the flow rather than fight the current.
How does this affect you? Well, I believe you should accept that a tidier implementation may involve more code: not the 'shorter code' you were hoping for. But, if it's logically structured, efficient code the Google compiler should be able to trim lots out in the compiler optimisation phase.
So, move as much of the logic as you can into the model layer. Test this thoroughly, and verify that the correct level of page reset/tidying happens (all of this can be done with plain JUnit, without any UI). Next, use your Presenter (Activity) to tie the View to the Model: handling the interactions, populating the fields, etc.
you can divide a Huge class in different classes bu dividing the GUI in different JPanels. All the panels are implemented in different classes extending JPanel. Guess that would help you.

Categories