Looking for a GUI design-pattern that fits this application - java

I'm developing a desktop app in java for a school project and I want to know how should I be designing the code of the GUI, specially because I will later have to run JUnit and functional tests on the app. I know it kinda sounds like an opinion-based question, but all I'm not asking for the "best" method, I just want to be pointed to a specific design pattern that can fit the need of my app.
To elaborate a little more on the type of application, it's "stage based", one button leads to a different section of the app. One main window, only error or warning popups (only one frame).
My current approach so far:
So far I've designed 3 different JPanel classes using eclipse's WindowBuilder (main menu, admin menu and user menu) and a AppGUI class that creates and empty frame with a CardLayout layout and fills it with one of the 3 panels (starts with main menu). Then the buttons on such panels point to the next panel. (Example, main menu -> user menu -> create profile)
The panels need to communicate with the AppGUI instance in order to execute the panel changes and later on, the functionality that the other options will have. To do this, I've been passing the AppGUI instance as a parameter to the panels on initialization and storing it inside each panel (I first thought of having a singleton AppGUI and have static reference to it, but I later on read that it's bad practice, specially for later mock testing).
Also I'd like to have the logic for the application on different classes other than the GUI classes and I'm not sure if passing the AppGUI as parameter to every method out there is good practice or not
In conclusion, it would be great if someone could point me to a specific design pattern for this kind of GUI, thanks in advance!

I would suggest the Model View Controller (MVC) pattern.
The idea of MVC is that the models (your app logic), the views (UI elements), and the controllers all work together. The models and the views are completely independent of each other i.e. you don't pass a model class object to a view class object or vice versa. The models and the views should talk to the controllers and the controllers makes all the decisions.
Controllers
They contain your app's UI logic, like how to layout the views. They are notified by the model once in a while (e.g. some data have changed!). They are also notified by the views (e.g. the user pressed a button!). And controllers need to respond to these notifications. For example, when the user pressed a button, the controller might tell another view to show, or tell the model to do some calculations or some other stuff. In your case, your controller is most likely to have all the ActionListener for the buttons and text boxes on the UI.
Models
They contain your app's logic. Try to design your model to be UI independent as much as possible. If designed correctly, your model should still work without the UI i.e. you should be able to make a command line version of your app without changing the model. For example, if you are making a calculator, the model should do the actual calculation.
Views
Most of the time, you don't need to worry about this part because swing already provides you with lots of view classes, such as JButton, JPanel, JTextArea etc. If you happen to be creating your own views, remember that it should not contain anything related to the model i.e. the view should work fine with a different model.
You can always search for more info on the web.

Related

How to handle form data while switching between multiple frames

I have created a swing application in Netbeans environment. This application consists of four frames. Now my requirement is, after filling A frame when user clicks "Next" button then A's data should be buffered somewhere and then go to second form and so on. Finally when user lands in the last form, at this point i want the total data of all forms should be stored in database.
I am not sure how to achieve this. Can anyone suggest some useful resource or idea?
Consider having one non-GUI model class, that can be passed into the view (GUI) classes, either via a constructor parameter, or a setter parameter, i.e., public void setModel(Model model). Then all views can have the same Model instance passed into them.
When the first window has its data "submitted", it submits it into the one shared model. If you're using a Model-View-Control structure, then this is usually done by the Control, but if your program is simple, a Model-View is probably all you need. The other windows can be notified by the Model of the changed data, and then change their displays accordingly.
But as an aside, also please ask yourself, how many professional applications do you use that jump from window to window? Not many because it is a very distracting and often unpleasant experience for the user. Most use a single main application window that swaps gui views within this window and with an occasional dialog window popping up when information is needed in a modal fashion. Please have a look at The Use of Multiple JFrames, Good/Bad Practice?

JAVA Swing MVC - Main Controller?

I'm having some troubles designing the architecture of an application I'm trying to develop. I'm working on JAVA, and I started working on this application because I want to deepen my overall knowledge of JAVA, architectures and patterns. I want to follow the guidelines to make a reusable, low coupled application, like it should be. The application has only one JFrame, but inside it there are several JPanels, each one representing a module of the application.
The question is: in JAVA Swing, how to implement an appropriate MVC pattern?
I struggle on how to understand the way it should be done.
Should I have a main Controller class, that holds references to all the other Controllers?
(I have an image to demonstrate this, here: https://docs.google.com/file/d/0B7tBdn5slIFeY2FoSmxESTREQ1k/edit?usp=sharing)
And in this case, should all the events that require changing the module that is being presented redirect to the main Controller?
Or should I just couple the JFrame with the Controllers of the application, and communicate directly with them?
Basically, I would like to know if i need to have a class that 'manages' all the others.
I have already read several explanations, and different opinions, but I believe this is a little more specific.
Hope I have made myself clear (and hope as well that my explanation is better than my drawing :)).
EDIT:
a sample of the application usage:
One (an only one) JFrame throughout all the lifecycle of the application;
the menu will be on the left side, as in BorderLayout.WEST;
the current module of the application will be in the center, as in BorderLayout.CENTER;
when the user presses one button of the menu, the corresponding module is loaded into the BorderLayout.CENTER;
Should the menu (View) have it's own Controller, and this Controller communicate with the JFrame? And the JFrame load the new module into it's Layout? Or should the JFrame have its own Controller (or Model, as Gilbert Le Blanc said)?
I know this may seem to specific, or easy to understand, but everytime I think of an desktop application, I struggle to understand this.
When you have an application with a GUI, the GUI model becomes the application view. The application interacts with the GUI through the GUI model.
Or should I just couple the JFrame with the Controllers of the application, and communicate directly with them?
This is what I've done. I've packaged the controller classes together, but I've never created one main controller class.
I keep the GUI controller classes in a separate package from any other application controller classes, like the data access objects.
I usually put each JPanel in its own class, but I wouldn't call that a requirement. The JFrame has its own class, although the instance of the JFrame and the instance of the GUI model are passed to almost all of the GUI components. This makes menu actions possible.
This Traffic Signal GUI article goes over the basics of how to code a very simple GUI.
Edited to respond to the changes in the question.
The GUI controller is separate from the GUI model. The GUI model contains all of the data elements that make up your GUI. Strings for JTextFields, DefaultTableModels for JTables.
Based on your application design, I'd recommend that you create a Java class for every JPanel that you want to put in the center of your application. Your JFrame will control which JPanel is displayed, based on the menu. I'd also suggest that you look at the JTabbedPane which uses a different user interface to accomplish the task of choosing which panel to work with.
Assuming you're going with the menu on the left, each menu option (toggling JButton?) will have it's own controller method or class. These controllers have to have an instance of the JFrame so the controller can call the method in the JFrame class that puts the appropriate panel in the center of the display. The controller decides which method to call, but the methods themselves are a part of the JFrame class.
I've been talking about JFrame and JPanel classes. It's important that you use composition rather than inheritance to build these classes. The JFrame class contains a JFrame. It does not extend JFrame. The only time you extend a Swing component is when you want to override a component method.
As discussed here, Swing components use a separable model architecture with the model and view loosely coupled using the observer pattern. Not every GUI control has to be part of your application's controller. Using an ActionListener, such as Action, is particularly convenient for encapsulating application functionality.
Addendum: I'd use CardLayout, illustrated here to switch panels. Note how the Action handlers can be used with buttons, menus, combos, toolbars, etc. Each card's content can have it's own implementation of the MVC pattern, separate from the others. Use a PropertyChangeEvent, seen here, for communication between components.
In general, Swing components, e.g. buttons and tables, already listen to their respective models, leaving you to focus on your application's data model and its listening views. Conveniently, a Swing model, e.g. ComboBoxModel or TableModel`, can have more than one listener.

Swing desktop app - how to organise my code

We are going to use Swing for our next project which will be a lightweight desktop app.
I've been reading the Swing tutorials on Oracle's website and have started to get the hang of it.
I was told that instead of switching JFrame I need to work within one JFrame and switch JPanels.
My questions to you would be the following.
Can I create the JPanel designs (or their templates) in design mode (WYSIWYG editor) and call jframe.setContentPane(nameOfJPanel) or do I do them programatically in code?
Secondly, how do I structure my code... If I dynamically add new JPanels and bind their events to an event handler.. all my logic and code will be in one HUGE class with tens of methods. I just don't know how to proceed and nowhere can I find an example with multiple (more than 6 let's say) panels on the internet.
To WYSIWYG or not WYSIWYG
This is a debatable question at the best of times.
I encourage all my junior developers to start out hand coding UIs as it teaches them important basics about how to use layout managers and how to handle compound layouts.
This tends to take longer as you need to verify the layout with each change.
I personally use the form editor in Netbeans for most of my general work, but will hand tweak UI's
Structure
Think about boundaries of responsibility, reuse and reduce strategies.
What you don't want is some huge master class that does EVERYTHING. It will be difficult to maintain and update (I live with this horror every day).
Instead, identify the distinct areas of responsibility and either use getters and setters or models to move the data around the application. The more you can decouple your code, the easier it will be to update and modify.
Identify like work and model it as interfaces and abstract classes where you can. Basically where ever you start thinking about coping code is probably a good indication that your design is off and you should consider implementing abstract classes to cover the overlap.
Take advantage of the Action API for replicating commonly used concepts (copy and paste is an example of this. You would want menu items, possible toolbar items and maybe even popup items, these can all be handled by the same Action class).
Separate the data from view. As I said before, take advantage of models. The data shouldn't care how it is collected or modified, only that it can be. Equally, the view shouldn't care about how the data is managed, only that it is.
If possible, define interfaces between the separate areas of your application. This way you can further decouple of the application and no one part becomes reliant on any one implementation (hello my world :P)
Don't be tempted to simply dig through a component hierarchy to gain access to that field, it will produce a nightmare if you need to change the code!!
The JFrame will be the main window of your app and the panels will be the brick composing it.
You should create each panel in its own class and you can arrange them by functionality in packages. You'll have panels for holding content of logical part of your application and panels that contains real stuff.
A logical panel could be the main view and the menu bar. An application panel would be a form, a menu, a canvas...
You'll have to put application panels inside logical panel and to change the content of the logical in response to users actions.
You should study how layouts work in order to compose the view inside the JFrame and to layout components inside panels.
For example the BorderLayout is a classic when defining the main area of an application:
- menu and toolbar on top
- browser on the left
- status bar at the bottom
- main panel on the center
You can use WYSIWYG editor, but avoid doing all design inside the same class. Else you'll have an horrible HUGE class. Create your panels in separate classes and compose them in your main view.
You can use empty panels as placeholder to help you create the structure of your application.
You'll have to bind your domain data to the view in order to not mix the two layer.
Bind means that you will write a way to go from a java bean to a form and the reverse.
Basic binding is handwritten, but some tools exists to do that.
If it is a small application, it is maybe better for you to handwrite everything.
Building a Swing application can be very tricky (you'll have to know about the event dispatch thread, layout management, event management, widgets (label are trivial, but JTable can be very complicated to handle);
I'll recommend to find a book about the topic, and to find some open source swing application in order to study how it structured, before you start your project.
This is how I organize my code:
class Panel1 extends JPanel{
//code for panel1 and its Components
}
class Panel2 extends JPanel{
//code for panel2 and its components
}
// and it follows.
class ApplicationFrame extends JFrame{
/// LOGIC to switch between panels
}
class Main{
//contains main() function
}
Any HAND-CRAFTED GUI code, is better than a COMPUTER GENERATED WYSIWYG -APP Code.

How to implement a Compound View/Presenter for a GWT DecoratedTabPanel?

I'm new to GWT, and I've been reviewing the MVP implementation which uses the rpcService and the eventBus. I was wondering how a tab panel can be implemented such that each tab has its own sub-view. I have been waffling between making a custom widget that derives from a panel, or to figuring out how to make a presenter use another presenter, or to make a compound presenter class which handles it all for me.
Does anyone have advice on how to separate the functionality for each tab as opposed to keeping the implementation within one view/presenter pair?
I was in the same situation, but decided to change my implementation to simulate a TabPanel. If your views and presenters don't need to interact with each other (e.g. dragging something from one tab to another) then I think it'll be easier to separate functionality by loading your View into a shared SimplePanel. You can simulate the tabbed portion of the TabPanel with a widget that listens for PlaceChangeEvents (to change the highlighted tab) and sends goTo commands to the PlaceController your app is using (to handle clicks on the different headers).
It took a couple of hours to implement this, and the resulting code is much cleaner. My initial attempt involved listening for PlaceChangeEvents and then calling the appropriate tabPanel.selectTab() function, but trying to figure out how to start and stop the presenters for the different tabs was too jumbled up - like you suggest, you'd have to implement your own compound view model.
I solved this without faking a main tab, but using the one provided with GWT's basic SDK. I did this by:
Add an ArrayList of Presenters to the MainTabPresenter
Constructed each tab's present plus view within the 'go' method of the MainTabPresenter
Called 'go(null)' on each of the tab presenters.
Handled the null situation on each.
Implemented a method in the MainTabView to add the tabs to the DecoratedTabPanel
It all works like a charm. The MainTabPresenter so very thin, and allows for complete implementations of View/Presenters to be written into their own files.

Designing mvc controller layer

I am trying to understand and practice the MVC-pattern to improve my development. So I started refactoring an application I once wrote and have progressed so far. It is completely clear how my model looks like and also the view is ready so far. But now I am searching for a good practice to design my controller layer.
I have created a view that's split up in different main components. Let me give you a short example:
There are 3 Panels that group specific components:
"FilePanel", holding a JTextField and two JButtons
"DataPanel", holding all components neccessary to display some data and some JButtons
"CalendarPanel", showing some calendar-sheets
These three Panels are each in a separate class and afterwards instantiated and arranged in a GUI-class.
No the actual question. As I separate the Panels, how should I build the controllers? Should each panel get its own controller class (FileController, DataController, CalendarController)? Or should there just be one controller class for the whole view?
If I create one controller class for each panel, how do can I achieve that the controllers communicate with each other? Example: If a button is clicked in "FilePanel", how do I notify "DataPanel" about this?
Could you give me some examples of best practice?
Are the Panels fundamentally separate?
NO: The set of panels is fundamentally one state. For example the panels represent a console showing different aspects of the same items under control. The user selects an item and all the other panels update to show views of the item. In this case one Controller is enough.
YES: That is can each of them move through various states independendently? This is the kind of realtionship you might have in a "Portal" style application. The user can work in each Panel pretty independently - extreme example, two separate side-by-side browser panes in one overall viewer. It's the kind of effect you get in Composite Applications where the user has windows open on different back-end systems. Sometimes user actions in one window cause things to happen in another window, but generally they run separately. In this case we have can have separate controllers each responsible for the state of a Panel. They can communicate with each other by event handling mechanisms. User clicks in File Panel, View contacts its controlled, which issues a "File Selected" event, whose payload is the id of the file. Note that the "click" event is translated into a non-ui specific event.
By having separate controllers we decouple the details of the current set of panels. Addind a new panel requires only that the new controller registers for events.

Categories

Resources