I am creating a custom JPanel element (a login form).
I want to allow people who use my panel to subscribe/listen to an event called "loginSuccessful".
What is the best way to implement this in my JPanel object?
UPDATE: oh and i also want to add that when that action is triggered, i also want to return a "User" object containing the person that was just logged in
I normally prefer EventBus for those kinds of Events.
Library and Examples can be found here
Moreover you should consider to keep businesslogic out of your viewclass (panel) and create some kind of LoginController for your loginbusinesslogic. There are plenty of good examples out there.
EDIT: You can send an UserObject within an EventBusEvent as well.
I would start by separating your code form widget code. Don't extend where you don't need to. Where classes are focussed on a particular job, everything becomes so much easier.
Related
been trying to solve this problem for over a day now, and throwing in the white flag now. Taking this class at UMUC, and it's pretty much a self-study curriculum without any help so I really appreciate being able to ask this question here.
Just going to ask this question conceptually, because I can't even get my head wrapped around the concept.
I have a GUI class (subclass of JPanel) that creates a button. In the GUI class, the button uses ActionListener to recognize when it is clicked and performs validation tests on a textfield. So far so good!
Now, after the validation tests -- which ensure the input in textfield is numeric, I want to use this input to add to a variable in a different class (called Account).
In the third class, which includes main method -- I have created two instances of Account class: checking and saving, as well as Frame and adding GUI to the frame.
Problem:
(1) How do I trigger the add method in account class when button in GUI class is clicked?
(2) How do I ensure it applies to the specific instance of the Account class, i.e, either checking or saving?
There are a number of ways you might be able to do this. One would be to provide a ActionListener property to your JPanel, which you would then trigger once you've validated the input from the button. This a basic observer pattern (and you're already using it on the JButton).
The problem is then how to get the information from the panel. You could provide getters on the panel, but this begins to tighten the coupling in your code.
A slightly better solution might be to provide your own listener/observer interface which you could then pass the information you want from the GUI to the listener, further de-coupling the API
I'd avoid passing the Account to the GUI if possible, unless it has some reason to actually use/modify the account, it's best to keep it decoupled of the responsibility, the GUI's responsibility is to get and validate the information as best as possible and pass the processing on to the observer/listener.
In this case, you just need to wrap the listener/observer around a particular instance of the account, so when it's triggered, it's operating on the correct account
I'm creating my first "bigger" application in Java. As MVC is only pattern I know, I decided to use it. But there's something wrong with this concept.
For example. I need an Action (or generally event) fired from 2 places (from Button in frame and MenuItem). It has to do changes in at least 2 places and in the model.
I've got some ideas, but they seem wrong:
Pass the controller object to every view element, so newly created actions could use controller's methods to modify rest of the application.
Make controller static (for same reasons)
Make controller only model listener
Please tell me how to build it. Or give me some links to some easy to analyse applications.
Source of my project is here, if anyone wants to have a look: https://github.com/Arrvi/ColorExtractor
You are correct to use Action to encapsulate functionality for use by disparate components such as menus and buttons. A spectrum of examples is cited here. As regards MVC, recall that Swing uses a separable model architecture, examined here. In effect, the user is the controller, and not every interaction needs to pass through your application's controller.
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 developing a project in a MVC architecture. It should be a simple application to manage some customers.
There are MainModel, MainView and MainController classes which make the main window to show the content of the customers tables and to let the user insert, remove or edit customers.
My problem is that the insert and edit buttons should show some dialog windows to let the user insert and edit some text values and I have some doubts.
I would like to ask you some questions:
Should I use the MVC architecture for each dialog window?
If yes, I have tried doing it but my dialog windows are modal, so my code runs the model, runs the view but it gets blocked in the view and it doesn't run the controller class. How could I solve it?
For example here it gets blocked in the "new InsertCustomerController..." instruction:
CustomerModel customerModel = new CustomerModel();
InsertCustomerView insertCustomerView = new insertCustomerView(customerModel);
new InsertCustomerController(insertCustomerView, customerModel);
Thank you very much.
Irrespective of modality, you can use the observer pattern to keep your dialogs synchronized with the application's model. This example uses a PropertyChangeListener; other approaches are mentioned here.
Although I can't fully tell from your post, I'm not sure you're thinking of MVC the right way. But let's say you have a Customer, CustomerView, and CustomerController class..
Customer could contain all of the business logic related to being a customer-- so it might have methods like setBalance(int newBalance), getBalance(), etc.
The CustomerView class could essentially be a subclass of JPanel or JFrame (since it looks like you're using Swing from your question's tags). This class would be representative of one Customer instance. Maybe you could have a private Customer class variable. This class's responsibilities should only consist of displaying the data to the user contained in its Customer instance as well as allowing them to modify it.
It would be tough to say what the CustomerController would do since I don't know anything about your application, but it could potentially contain ActionListeners and that sort of thing that help to route input and output to the different parts of your model and view.
I did some googling and found a pretty straightforward example you may want to check out: http://www.austintek.com/mvc/
Good luck. Hope this helps.
Im pretty new to gui programming so i've been reading through every post on this site about swing and design. Whats been answered over and over again is that one should have a multiton class for the actions. Like this: (GUI being some JFrame)
alt text http://img341.imageshack.us/img341/255/skjermdump.png
Now, this works great for one-way actions, like OpenDialog. But the actions for buttons in DialogA and B will have to have access to all the components (there will be many) in its dialog, and the controller. This is where im stuck.
The only sane way i can see is to put it in DialogA/B but i would then need to pass the controller all the way down, through classes that dont even need it, and it'll get all spaghetti. Really dont want that.
Someone must have encountered this problem before. So where should i put this Action? Or should i just drop the whole design?
Edit: got a good answer from elsewhere. Resolved.
In MVC the controller and the view access each other, the controller shields the view from the model. The best thing to do is to put your ActionHandler as anonymous class and have it simply call back to your view that in turn calls the controller.
If you really want you could have a Controller superclass that has generic messages to send a message and pass in a HashMap, that gives you good separation of code but, adds complexity and removes type checking.