if i have a class gui and a class for the logic, is holding a reference in gui to logic and logic to gui very bad?
As a general rule it is bad to have the "logic" class having knowledge of the "gui" class. The idea behind the separation is the Model/View design pattern (or Model/View/Controller). The view will need a reference to the model. Look really closely at why the model needs a reference to the view. Usually when the model needs to send information to the view event listeners are used (see javax.swing table and list models for an example).
It should be avoided.
In your GUI, you can have a reference to your Domain Logic, but you should not have a reference to your GUI in your domain logic.
Why ?
Because otherwise, you have no advantage of splitting GUI & Domain logic up in separate files. When your Logic has a dependency to your GUI, then you cannot use your Logic with another GUI.
So, you should try to avoid this dependency from your logic to your gui, or, you should make abstraction of it.
I hope i'm making myself clear here. :)
If you can avoid it, you probably should. Otherwise you might get into a lot of problems with circular dependencies later.
Do they really have to know about each other, or could you have a third "control" concept referencing the two?
The GUI probably needs to expose some kind of interface to the logic class, to have the GUI update when the logic class changes something.
The logic should not have direct knowledge of the the GUI implementation, only its interface.
The Observer Pattern is sometimes used for this.
Related
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......
I am just about done with our exam project, and when looking back at what I coded, I feel I did quite alright. Though, stuff could obviously always be alot better. But maybe that's just me.
I was in charge of coding the GUI, and coupling it with the application logic. When making the GUI I made the decision that I would make a class file for every window (e.g. LoginWnd.java), and actually build the GUI in the constructor. I would initalize everything and set all data inside this constructor.
Then in order to navigate through the application, I would set actionlisteners on the jbutton. For example, in SearchWnd, hitting the "Search" jbutton would create a new object of ResultWnd with some specified parameters.
Now i'm kinda wondering: Was this design decision bad in any way? Are there any design paradigms that I should've been aware of?
Thanks.
Your approach sounds fine overall - as long as it works you've achieved the main goal! So my comments here are more about fine-tuning / broader design aspects.
There's nothing fundamentally wrong with doing GUI construction in the constructor providing that the GUI doesn't subsequently change during program execution. The rationale here is that constructors should be reserved for "one-off" construction activities. So it's probably fine for dialog boxes and suchlike that have a pre-determined layout.
If you have a more dynamic GUI where components are frequently being added and removed throughout program execution, then I'd strongly suggest moving this to a set of methods outside the constructor so that they can be called independently of object construction. The constructor itself can still call these methods if needed to do initial setup, but subsequently you have the ability to call these methods later to add new components, refresh the layout etc.
The good news is that this stuff isn't hard to refactor if you get it wrong - it's usually trivial to pull setup code out of a constructor into separate methods later if needed.
Another thing to be aware of is the oft-repeated mantra "prefer composition to inheritance". That is to say, if you can make your GUI work by assembling existing components rather than inheriting and overriding your design will probably be better/more easy to maintain in the long run. For example, I don't think I've ever subclassed JFrame - it's almost always cleaner to just add JPanels within it that contain all the application-specific components.
Finally, be cautious of coupling your GUI components too closely to your application logic. Swing actually does a pretty good job of encoraging you to separate out your data model from the presentation code (e.g. with ListModel and friends). It's worth studying and understanding that approach. The point is that you should usually build GUI components in a way that is fairly application-agnostic, but give them application specific behaviour by connecting them to the right data model and event handlers etc.
I also initialize my GUI in the constructor, so it can't be bad :) But when it gets too long I extract parts of the code into separate GUI components.
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.
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.
Hey all, I'm currently working on a Java Swing application and I was looking for some guidence. The application is fairly small, but I'm noticing that as the code base is growing larger, that I have an awful lot of coupling in my object graph. I'm relatively new to Swing, but I've been programming long enough to know where this is headed.
The biggest problem I'm having is setting up my event handling. How should my child windows and objects be communicating events to my higher level objects without having references to them? I've done a fair amount of MVC web coding. Does this pattern lend itself well to Swing? Should I be building my own controller? I guess I'm just fishing for patterns that people have found useful working with Swing.
Thanks in advance for your help.
The best way to reduce coupling in a GUI, I think, is to use an Event Bus.
There are several existing implementations out there, including some supporting Swing specifically.
Just google for swing event bus and you'll find.
If you use Guice in your GUI, you may also want to take a look at guts-events.
Yes. MVC is what you have to use. Here is a very good article about MVC and Swing:
http://java.sun.com/products/jfc/tsc/articles/architecture/
Another Pattern that might be interesting for you is the MVP (Model View Presenter)-Pattern. This is great for coupling views more loosely to the model. A good explanation by Todd Snyder can be found here.
As you already said your intent to use MVC , or you may be already using. Once you have seperated out data (I call it as data model layer). Now you need to apply OBSERVER pattern on these data model classes. All the views (your ui components) using this data model are observing this model objects for any change (Via observer pattern).
I hope this is what you are looking for.
MVC !!! Then you can use also a variant of Observer called Publish/Subscribe in order to implement the event flow inside your app.
I don't agree with the people who suggest to use Event bus, because
because of code like EventBus.subscribe(SymbolListChangeEvent.class, this); your whole code will depend on a single event bus instance which makes it very hard to test,
it is hard to find out where a specific event is used.
Instead I suggest to use interfaces to encapsulate external dependencies of a module. If you like, you can use them with the listener pattern, but generally are free to refactor everything if you like.
If you want to communicate with other GUI components in the hierarchy then you should consider something like singleton that mediates calls between branches. See :
http://blue-walrus.com/2013/06/mediator-pattern-in-swing/