I am looking for advice in structure rather than particular coding.
My program has a Main class that initializes a GUI and then, after puting the name of the files that are going to be read, I click one button. I attached a listener with the respective mouseClicked event handler and I do all my routines INSIDE the handler.
This doesn't seem a good approach, is it? Is it usual to do things this way? All my program inside an event handler?
Is it usual to do things this way?
UI programming is event-based in Swing. Twisting it into any other style will not make it easier for you. What you might mean is that you should minimize the code in that UI part.
This means that you shouldn't tie the UI to the logic, therefore creating dense coupling. In this example, the file-reading code should be moved into another method, ideally in another class.
All my program inside an event handler?
To answer this specific question: No, that'd be terrible! It's okay to invoke your program from there, but don't write the code in the event-handler!
This doesn't seem a good approach, is it? Is it usual to do things this way? All my program inside an event handler?
You are right, this isn't a good approach. Instead look into implementing a Model-View-Control (MVC) type structure or one of its variants.
The Model: this is the brains of your program, the one that holds the program state. This should contain no GUI code, no listener code, just the data and the logic that goes with the data. The model should not implement a handler interface
The View: this is the GUI, here your Swing components and related code. The view should not implement a handler interface.
The Control: this is the connecting code between the two above, the code that handles user interactions, asks the model to change state. This may implement a handler interface, or have inner classes that do, or be composed of objects that do. Your control for instance could read in the file (in a background thread), supply the text to the model, and then the model could notify the view (or the control -- there are many variants of this) that its state has changed.
As an aside: don't give a JButton a MouseListener. Use an ActionListener instead.
There is no rules but only good practices.
And from Good Practice ethics, it is always advised to divide your code into small chunks, each one responsible for some stuff.
So you would better move your code outside the event handler and delegate the job to some method called readFiles() and call the later within your handler.
And even if this method can be cut into pieces you can do the same, e.g. it can only iterate over the files to be read and call a readFile() method for each one:
private void readFiles(Files[] files)
{
for(File file : files)
{
readFile(file);
}
}
Just a simple snippet and all should be updated to follow your model.
Firstly instead of providing a path to the file you can use
JFileChooser to do file selection operations. Especially since you
are using Swing.
Secondly one should attempt to modularize the code to an extent it
makes code looks simpler a d understandable. So you can create a
separate method that handles your file operations. The you can call
this function from any event handler. Be it mouse or keyboard. This
will avoid code duplication and will enable module reude.
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.
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.
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.
UPDATE: I'm using Netbeans and Matise and it's possible that it could be Matise causing the problems I describe below.
UPDATE 2: Thanks to those who offered constructive suggestions. After rewriting the code without Matise's help, the answer offered by ignis worked as he described. I'm still not sure how the code the Netbeans code generator interfered.
Though I've been programming in Java for awhile I've never done any GUI programming until now. I would like to control a certain part of my program externally (updating a jTextArea field with output from an external source) without requiring any user action to trigger the display of this output in the jTextArea.
Specifically, I want this output to begin displaying on startup and to start and stop depending on external conditions that have nothing to do with the GUI or what the user is doing. From what I understand so far you can trigger such events through action listeners, but these action listeners assume they are listening for user activity. If I must use action listeners, is there a way to trick the GUI into thinking user interaction has happened or is there a more straightforward way to achieve what I want to do?
Also, I'd really like to know more about best practices for separating GUI code from the application logic. From the docs I've come across, it seems that GUI development demands more of a messy integration of logic and user interface than, say, a web application where one can achieve complete separation. I'd be very interested in any leads in this area.
There is no need to use listeners. GUI objects are just like any other objects in the program, so actually
you can use the listener pattern in any part of the program, even if it is unrelated to the GUI
you can invoke methods of objects of the GUI whenever you want during the program execution, even if you do not attach any listeners to the objects in the GUI.
The main "rule" you must follow is that every method invocation performed on objects of the GUI must be run on the AWT Event Dispatch Thread (yes, that's true for Swing also).
http://download.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html
So you must wrap code accessing the GUI objects, into either
javax.swing.SwingUtilities.invokeLater( new Runnable() { ... } )
or
javax.swing.SwingUtilities.invokeAndWait( new Runnable() { ... } )
http://download.oracle.com/javase/6/docs/api/javax/swing/SwingUtilities.html
About "separating GUI code from the application logic": google "MVC" or "model view controller". This is the "standard" way of separating these things. It consists in making the GUI code (the "view") just a "facade" for the contents (the "model"). Another part of the application (the "controller") creates and invokes the model and the view as needed (it "controls" program execution, or it should do that, so it is named "controller"), and connects them with each other.
http://download.oracle.com/javase/tutorial/uiswing/components/model.html
For example, a JFoo class in the javax.swing package, that defines a Swing component, acts as the view for one or more FooModel class or interface defined either under javax.swing or one of its subpackages. You program will be the "controller" which instantiates the view and an implementation of the model properly (which may be one of the default implementations found under those packages I mentioned, or a custom implementation defined among your custom packages in the program).
http://download.oracle.com/javase/1.4.2/docs/api/javax/swing/package-summary.html
That's a really good question, IMHO... one I asked a couple of years ago on Sun's Java Forums (now basically defunct, thanx to Oracle, the half-witted pack of febrile fiscal fascists).
On the front of bringing order to kaos that is your typical "first cut" of an GUI, Google for Swing MVC. The first article I read on the topic was JavaWorld's "MVC meets Swing". I got lucky, because it explains the PROBLEMS as well as proposes sane solutions (with examples). Read through it, and google yourself for "extended reading" and hit us with any specific questions arrising from that.
On the "simulated user activity" front you've got nothing to worry about really... you need only observe your external conditions, say you detect that a local-file has been updated (for instance) and in turn "raise" a notification to registered listener(s)... the only difference being that in this case you're implementing both the "talker" and the "listener". Swings Listener interface may be re-used for the messaging (or not, at your distretion). Nothing tricky here.
"Raising" an "event" is totally straight forward. Basically you'd just invoke the "EventHappened" method on each of the listeners which is currently registered. The only tricky bit is dealing with "multithreaded-ness" innate to all non-trivial Swing apps... otherwise they'd run like three-legged-dogs, coz the EDT (google it) is constantly off doing everything, instead of just painting and message brokering (i.e. what it was designed for). (As said earlier by Ignis) The SwingUtilies class exposes a couple of handy invoke methods for "raising events" on the EDT.
There's nothing really special about Swing apps... Swing just has a pretty steep learning curve, that's all, especially multithreading... a topic which I had previously avoided like the plague, as "too complicated for a humble brain like mine". Needless to say that turned out to be a baseless fear. Even an old idiot like myself can understand it... it just takes longer, that's all.
Cheers. Keith.
This doesn't exactly answer your question, but you might be interested in using Netbeans for Java GUI development. You can use GUI in Netbeans to do Java GUI development.
Here's a good place to get started -
http://netbeans.org/kb/trails/matisse.html
So for my current project, there are basically three main Java classes:
GUI
Instant Messaging
Computation
Essentially, there needs to be full communication, so we've decided to use the mediator approach rather than than allow the GUI to run the entire project.
Basically, the mediator is going to encapsulate the communication. The problem we've run into is how to allow the GUI components to update without building a ton of methods for the mediator to call anytime something completes.
Ex. Say the GUI wants to log in the user, it goes through the mediator to create a thread and log in, but then the mediator has to relay the success/failure back to GUI as well as update a status message.
The other issue is things that need to update the GUI but do not need the moderator. Is it practical to just allow the GUI to create an instance of that class and run it or should everything go through the mediator?
Our original design just had the GUI managing everything, but it really killed reusability. Is there a better design method to use in this case?
If you're finding Observer to bring too much overhead, Mediator may be the best way to go. I definitely think that you shouldn't have the GUI run the show. If you're going to use the Mediator pattern, the mediator itself should be in charge. Something you might consider is a variant of the Command pattern. If you were using Ruby, I might recommend passing function callbacks around as a means of avoiding having the mediator contact the GUI for every little thing. But since it's Java, some form of encapsulating an action in Command pattern style may help.
If you don't want the callback/notification to be triggerd by the mediator, you can inject the callback into the login function and have login call it when it finishes.
I don't know how you would go about injecting the callback in Java, though. In a language where functions are first class citizens, you could just pass the function, but you're in Java so I guess you will have to use the command pattern as kmorris suggested.
You might also try having the GUI give the mediator a callback object that handles retrieving return values or setting whatever values you need (a version of the Command pattern). There would then be one per call from the GUI to the mediator.
Another thought is to group the methods the mediator calls into semantically related chunks. In particular if the mediator has sections where it tends to call several GUI methods in a row:
gui.a()
gui.b()
gui.c()
you can create a single method that handles the result of calling all three. The advantage of semantically grouped methods (i.e. setFileInformation over setFileMenu, setTab, etc.) is also then if you need to change the GUI, the contents of the methods might change, but the call the mediator makes may not.