Let's say I have a gui, and the gui is composed of two parts where each part has its own class.
So one class contains a JLabel.
And second class contains a text field with a submit button.
How would I go about making those two components talk to each other?
This is of course a simple example, but if I have two classes where I use one for submitting data, and one for showing the submitted data, then how do I make the two components communicate?
Some thoughts:
Don't add such bindings to the GUI classes, look for a pattern like MVC
Unidirectional change propagation (input -> output as in your example) is usually never problematic, but in many cases, full synchronization of editable component groups is required. So one may keep that in mind during development of the simple case for good reusability of any custom class or interface.
Avoid infinite circular updates with a flag, rather than with a comparison of component values.
Whatever you do, keep things separated and whatever pattern you use, don't add bidirectional references (e.g. among GUI class <-> controller)
Regardless of MVC, there could be a controller class, getting all necessary references to the UI objects (i.E. JPanels with nested JTextFields and JLabels, etc.) via constructor.
On construction, that controller can attach itself to those nested components.
The controller should preferably contain nested, inner or perhaps anonymous classes for implementing the listener interfaces, rather than adding the listener interface to the controller itself. First, to encapsulate these listeners and second, to avoid the event source distinction, if the same interface needs to be implemented for multiple components (sources). These listener implementations (perhaps pretty generic PropertyChangeListener's) could then act as, or use mediator objects (as mentioned), for updating other components.
If you have a submit button, you can add an action listener to it. When clicked you can call a method in your other class that will receive the string and then display it on your JLabel. However having multiple classes for different components isn't usually a good idea, and having a MVC like what Sam said is much better.
Class with JTextArea
//Have this object created
JLabelClass JLC = new JLabelClass();
//When submit button is clicked run this
JLC.displayText(JTextArea.getText());
Inside Class with JLabel
//add this method
public void displayText(String text){
JLabel.setText(text);
//Refresh Gui and display stuff....
}
Hope this helped... Sorry about the formatting I'm still new to StackOverflow
Related
I have tried to adhere to the mvc pattern in the java code that I have written. I want to keep the view and model independant of the controller and from each other. I am also trying my best to use interfaces to keep things modular.
My view has JButtons that I want to "bind" to specific methods in the model through the controller. I have tried two approaches to still keep the view independent of controller:
Registered the controller as an ActionListener to the view-object. Pros: The void addListener(ActionListener listener) abstract method encapsulates this behaviour in the view interface, so more buttons can be added without changing the interface. It also decouples the controller from the view, since it does not know anything about the actual buttons in the view. It is also easier to add more views or more controllers, so it follows the open-closed principle well. Con: For the controller to know the nature of the ActionEvent, I have only been able to come up with using the ActionEvent.getActionCommaned() in a switch statement, so mapping each case to its' corresponding method in the model. This seem unsafe and prone to cause irritation, since it seems like bad practice to match strings like this.
I also came up with adding public addActionListener(ActionListener) methods for each button in the view, like addGasButtonListener(ActionListener). Then doing something like view.addGasListener(e -> model.gasVehicles(view.getGasAmount())) in the controller. Pro: This seems like it reduces the uncertainty of matching strings. Cons: It means I have to add these new methods to the view interface, and each time a new button is added I have to do the same, making it difficult to add new views that does not have anything to do with some of the methods.
Main question:
I prefer the first method since it seems better to me, but I still would like to find a way to avoid matching strings, and find some nice way to do it (more similar to the rigidity of the second way of binding buttons to methdods). Is there?
Follow-up (less important) question:
I should also mention that my controller contains an inner class TimerListener implements ActionListener, that contains the loop of the app that acts on ActionEvents from the Timer. It also acts on ActionEvents from buttons if approach number one is used, which is why my follow-up question is: how would I seperate this main loop that only cares about the timer, from the switch statement used to act on button events. Since the ActionEvent.getActionCommand() is null almost all the time, it would be nice to seperate the two. Is there a approach that would let me do that?
I don't really see the value of working with ActionListener instances in the first place.
From your own example:
view.addGasListener(e -> model.gasVehicles(view.getGasAmount()))
You don't do anything with the actual event
In case you decide to use a different UI element in the future that doesn't fire ActionEvents, you will have to change the type of the listener.
I would rather expose a custom listener/callback that the controller (or model) can register on the view:
void onGasAmountChange(double gasAmount);
That being said, you might be focusing too hard on having a model, view and controller. If you look at more complicated Swing components (JList, JTable, ...), they have a view component and a model (ListModel and TableModel).
You could do something similar and create your own model for your view, and let the view call the necessary methods on the model directly (just like it happens for those Swing components).
That avoids having to write a bunch of one-liner listeners that basically delegate to the model.
I am trying to keep my Java Swing code clean. I figured one way to do this would be to attempt to isolate listener logic from the rest of the GUI.
What I'm trying to do at the moment is isolate all functionality regarding listeners into a single class/object that exists separately from the main JFrame of the GUI, so that it can be the central place that holds listeners and initiates the logic to assign these to components.
This way, the GUI can be separated into a dumb section (JFrame A contains/displays JPanel B, C, D etc) which holds no logic between how components interact when acted upon, and a smarter section that does hold logic.
Basically, I'm thinking of implementing the following:
The ListenerAssigner class contains all listeners used in the application as inner classes , instantiates them and hold this as an ArrayList internally. It holds a reference to the JFrame. It is not internal to the JFrame but external to it.
All listeners will contain an enum value on instantiation. This is will be used to compare itself against the enum value of the object needing a listener.
The ListenerAssigner calls a custom method on the JFrame (added through an interface) to pass the ArrayList of listeners to the objects that need listeners.
The JFrame in turn calls a custom method on its internal members to pass down the ArrayList to its internal objects, which in turn they repeat.
The objects holding the objects that need listeners will then call a findAndSetListener method on the objects, passing the ArrayList into them.
The objects implement findAndSetListener by iterating through the list of listeners, grabbing their enum values, comparing these against the enum value of the listener, and assigning that listener to itself should they match. We do this through an if statement in a for loop to avoid a very long switch statement.
This way listeners are assigned dynamically and are all contained in a single section instead of being all over different parts of the GUI.
Does this approach seem like a valid one? Would this abide by the SOLID principles and clean methods of coding, or should I just give up on trying to keep listener logic in one place?
I'm using MVC to organise an Maths Game application that has multiple classes that are the following:
MathsGame.java: Main class. Currently holds CardLayout which screen classes are contained in and runs the application along with other controller-like actions.
DiffScreen.java: Implements components and contains methods for use on the difficulty selection screen. Is extended from MigJPanel and is essentially a mix of a Model/View.
GameScreen.java: Implements components and contains methods for use on the game screen. Is extended from MigJPanel and is essentially a mix of a Model/View.
EndGameScreen.java: Implements components and contains methods for use on the end game screen. Is extended from MigJPanel and is essentially a mix of a Model/View.
MigJPanel.java: Extends JPanel and sets layout to MigLayout and adds a matte border.
ScreenInterface.java: Is implemented by DiffScreen, GameScreen, and EndGameScreen and contains final variables and an enum.
I've watched some tutorials and read up on MVC, but a lot of the resources I've found on it deal with very basic programs; having one model, one view, one controller, and a main class.
I have an idea of how I must go about refactoring my program to work with MVC, but I'm unsure about a couple of things.
Am I right in saying that from what classes I have above, I should split DiffScreen, GameScreen, and EndGameScreen into Model and View classes for each? Additionally, would it be better to create one Controller class or—as I've seen suggested—not bother and instead combine it with my Main MathsGame class? An approach I was suggested to use in a previous question here whereby I could implement a Controller interface seems useful too, but I'm not exactly sure if/how that would work with my new code.
Would it be helpful/needed for a project this small to split the Model, View, and Controller classes into their own sub-packages and keep MathsGame in the main package?
Further Clarification:
I'm essentially wondering if having these classes would be a good implementation of MVC:
MathsGame.java: As a main class, or possibly being my controller. Could also possibly implement a controller interface as suggested in the linked answer above.
These 3 possibly being inside their own sub-packages, let's say GamePackage.Views
DiffView.java
GameView.java
EndGameView.java
These 3 possibly being inside their own sub-packages, let's say GamePackage.Model
DiffModel.java
GameModel.java
EndGameModel.java
Controller.java: Won't be needed if MathsGame is both my main class and controller class. Could be in its own sub-package GamePackage.Controller if needed.
MigJPanel.java
ScreenInterface.java
Additional:
I've looked up on Model-View-Presenter. It looks to be similar and better suited to whole applications. It seems these questions are valid for that too. If this would be more fitted to what I want to do, I would be okay with that too.
I'm hope I've explained myself well enough. It is for a college project but I missed a lot last year due to illness so I'm a bit confused on these aspects. If I can clarify any part better, please leave a comment. Thanks in advance for any suggestions!
I'm answering based on the assumption that your user interfaces(GameView, EndGameView) contain Swing components such as JTextPane, JTextField, JTable etc..
Do you need a separate model?
The Swing components have their own models. For example a JTable has a TableModel and a JComboBox will have its own ComboBoxModel.
So I would say that having your own models that you synchronize with the UI changes are not the best way to handle things. For example if you have a list of numbers in a JList, and the sum in JTextField in your GameView, having a GameViewModel that has int sum and List<Integer> numbers will duplicate things since the JList and JTextField already have their own models.
But if you are saving this data to some persistent storage (the database maybe) and fetching the data back to show on the user interface, then having a GameData object that has int sum and List<Integer> numbers will be useful for that purpose. But synchronizing that object with the changes that happen in the UI is still not appropriate. This object should only be filled when the user saves the data(clicks on the save button).
Do you need a separate controller?
Swing already has ways to communicate between user interface components and its model via *Listeners(ActionListener,ItemListener etc..). So I don't think that you need a separate class to communicate between the user interface and the UI other than a Listener that comes with Swing.
Should you put models/views and controllers in different packages?
No. Why? Classes that communicate with each other should be in the same package. So if you have GameView, GameModel and GameController they should be in the same package. DiffView, DiffModel and DiffController should be in the same package etc.. You shouldn't put GameView and DiffView in the same package because they are both views and all models in another package etc... If you do that you will have to make most methods public in order for GameModel and GameView to communicate whereas if you had those in the same package, you could have given them default access. Why is this useful? Because the users of your classes(people who will make changes in the future) will know which methods are meant for use outside the package and which methods are not.
MathsGame.java = your most bottom layer
Views: DiffView.java, GameView.java, EndGameView.java
Model: DiffModel.java, GameModel.java, EndGameModel.java
Controller: Controller.java (must)
MigJPanel.java = layer on top of MathsGame.java
ScreenInterface.java = Interface to connect between your MigJPanel.java with your MVC presentation layer.
Please remember to implement Single-Responsibility pattern, in that one class serves only for one purpose only. You cannot mix your main code with controller code. Confusing and not recommended.
Thank you,
I was developing a swing application which calls multiple methods & initializes different classes.
Also I have multiple threads in which they process intermediate results. My requirement is to display that intermediate data on some labels and text boxes on the fly.
Please help me which of the below approach is best in terms of memory and performance.
I can have setter methods for all my labels and text boxes. So that I can call these methods using that swing class object but in that case I need to pass the swing class object to every class wherever I want to set the data to labels.
Another way is I can create public static object of my swing class and I would call it from any class whenever I need to set the label text.
First method creates more overhead as I need to pass the my Swing class object to other classes.
Second method is easiest way but creating static objects might create confusion as this application contains threads.
I just want to know which one to go for and why?
Otherwise if anybody have worked on some complex swing app development - how did you manage these kind of issues?
This example is typical of your first approach in a multi-threaded context. For expedience, the model and view are tightly coupled: each worker thread receives a reference to the label it should update. The alternative is loose coupling: each view registers to listen to the model, which notifies all registered listeners using the observer pattern.
This simpler example uses both approaches:
Tight coupling: The worker obtains a reference to its target label in an enclosing scope.
Loose coupling: The enclosing view registers a PropertyChangeListener, which the model uses to signal the view via setProgress().
You'll need to decide which is important in your application. I agree with #JB Nizet's comment about the second approach.
Why dont you use the 2nd method with Singleton principle, where you can use the same single instance of the swing class, so there will be no use of using static , and its sometime confusing cause we are uncertain of the order in which the JVM loads the static members...
Think of a GUI as a model with a view. The GUI components make up the view, while you create model classes that represent the model. Changes to the values in the model are reflected in the view. The rest of the application interacts with the model, and not the view.
Here's one example from a Java Spirograph GUI that I did.
i've started on some basic java coding with gwt, and im getting a bit concerned about the heft of my main class.
For instance - how does one compartmentalize the keyhandlers, since they trigger a number of changes to the UI, how could i move this into a separate .class file and still be able to access all the various widgets in the main class, without having to pass everything to the handler (ie. all the widgets i manipulate after the click event).
i've googled but didnt come across any particularly good examples - know of any readily legible code-bases i could read to see how it should be done? (gwt's own tuts are pretty basic, and just kitchen-sink every thing into a single file)
thanks!
I hate to say something so unimaginative, but MVC works--it's not the ultimate, but it can start getting you organized.
EDIT: While searching on a semi-related topic, I came across this which has similar ideas to mine but goes into more detail.
What that means in terms of GWT is that you should think of just laying out your GUI components in one class, put all your event handling in a second and put your object model objects separate from the other two.
One way to accomplish this is to make most or all the controls on your GUI public members. This sounds kind of lame, but their usage is encapsulated inside the controller so it's not like you have uncontrollable access--in fact your access is clearer/better defined than if all your members were private but your view code was combined with the controller.
Specific tricks:
Have listeners be their own class. You can often reuse them-- in other words, avoid anonymous inner classes. I sometimes create a listener class and instantiate a new instance for each button/control that needs to have a similar effect when pressed. If I need it to act slightly differently for a given button, I'll pass something into the constructor of the "special" handlers so that they know to act a little differently. You can also create different handler sub-classes if necessary--I'm just saying don't forget that event handlers are classes, you can use inheritance and everything if need be.
One Very Old GUI Trick I learned a long time ago, try not to have various mini-handlers modifying the GUI in different ways, instead have all the "active" buttons and controls set a state within your GUI and then call a single method that applies that state to ALL the controls on your GUI. When you get beyond a trivial GUI this can be a life-saver. If I'm not being clear, leave a comment and I'll leave an example for you.
Property sheets:
There is a special case for GUIs--the property sheet style GUI. I've done a LOT of these and they are irritating as HELL. They tend to have dozens or hundreds of controls on them, each GUI control tends to be tied to a specific field in your model and there are just hundreds of lines of copy and paste boilerplate code connecting them, each group copied and pasted with a few items changed--at minimum it's like 3 lines of code per control (Create control, copy value in and copy value out).
I always write these with a "Smart" controller--one that can intelligently bind the control to some data without any unique code. This can get tricky and if this is your problem let me know in the comments and I can give you some general advice as to some tricks you might try. I've gone from a minimal reflective solution to a full-on XML based solution. Were I to do it again, I might consider annotation-based.
Example of MVC:
Note, this is just an example, there are a MILLION ways to do MVC.
In your MAIN:
Instantiate MyView
Instantiate MyModel
Instantiate MyController(myView, myModel)
myView.setVisible(true)
in MyView
probably extends Frame
Most components are public final (public final Button b=new Button())
If public members make you nervous, use getters--same EXACT effect as public final members with a little extra syntax.
Remember that you can set final members in your constructor.
May have general methods such as reset(), but MyController may be a better place for this.
in MyController
saves references to myView and myModel
adds listeners to myView where necessary (see advice on listeners above)
configures myView based on state of myModel
when "done" button pressed, copies state from myView to myModel
notifies myModel that it's data has been updated and destroys itself.
in MyModel:
This would be a typical model class, it would contain your business logic (mostly not used as part of the GUI, that's more like GUI logic in MyController. The controller would tend to set values in your business logic then call some method like updated() to cause some business logic to take control. It should know nothing of a GUI--this is your "pure" business class.
Sometimes the GUI might call an update() or some other method to trigger some data change and then reload the GUI controls from the Model--this is a fairly good way to integrate your business logic with your GUI without your model knowing about the GUI...
Also, as I said above, I would put more work into MyController if I was working with property sheets just due to the sheer number of lines of boilerplate that you end up with if you aren't smart about it.
Note that View and Controller are nearly always paired. You can't just replace a Swing view with a web view and expect the controller to remain unmolested--but the model should not ever change for the view or controller.
You should take a look at the best practices for GWT applications first:
http://code.google.com/events/io/2009/sessions/GoogleWebToolkitBestPractices.html
One of the concepts they talk about is that of MVP (not MVC) to structure your application. There's a sample project on Google Code that you can look at to understand how to structure a GWT application in this way:
http://code.google.com/p/gwt-mvp/