In processing if you want to register a mouse event listener, you just need to define a function with the name "mousepressed", "mousereleased", etc. and they "magically" become event listeners. This also happens to the controlP5 library I'm using, where all the functions named after a control widget "magically" become its event handler. I'm wondering how does Java handle this kind of magic? Where can I see some source code or topic regarding this pattern. I would like to know its mechanism since I can't define the listeners in main applet.
Processing might use reflection for some stuff, but in the case of the mousePressed() functions, that's a simple matter of inheritance.
Processing contains a PApplet class, the source of which you can view here: https://github.com/processing/processing/blob/master/core/src/processing/core/PApplet.java
At the time of this answer, line 3087 of the PApplet class is the mousePressed(MouseEvent) function that is called via an Event handler, which you can read about here: http://docs.oracle.com/javase/tutorial/uiswing/events/
This mousePressed(MouseEvent) method calls the no-arg mousePressed() function, which is an empty function on line 3084.
When you write a Processing sketch, you're secretly extending PApplet. When you write a mousePressed() function in your sketch, you override the empty mousePressed() function of the PApplet class. Now when the PApplet class gets a MouseEvent from its MouseListener, it calls your mousePressed function. That's how inheritance works.
If you're asking a more specific question, please provide an MCVE that demonstrates exactly what you're talking about.
Related
Is there a way to call a method from another class to the class where the run method is present (without creating the object of the class with the run method)? I would like to know how the method addMouseListeners() call my mouseClicked() method located in the class where the run method is present. Please answer.
I think you're asking about the callback pattern. Wiki has some information and examples you might be interested in.
In general, the callback pattern involves passing off an instance of a class which will have various methods on it called in response to some event. Your mouse listener is a callback class instance, and the container you passed it to is generating mouse events and passing them to your mouse listener.
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.
When handling various events, my general policy has been to create a xxxHandler class like MouseHandler, WindowHandler, etc which extends its appropriate xxxAdapter class provided by Java.
I was just going over some other text about handling events and it says that whenever you extend any EventListener interface, say ActionListener, you must call the enableEvents(AWTEvent e) method in the constructor and call the super.processXXXEvent() whenever an event is generated.
I find this approach highly confusing. These methods have the access specifier as protected so I assume that these are for internal use only ?
What exactly are those methods for ?
Are they really needed for handling events ?
Do they offer any benefits over the usual actionPerformed(), mouseMoved(), etc where you add your code to handle the events in the method definition without calling any super methods?
Help needed. Simple words are highly appreciated rather than technical mumbo-jumbo.
What exactly are those methods for?
The processEvent() method filters the types of events that comes to it. The parameter to this method is of type AWTEvent type.
After filtering, this method calls the corresponding processXYZEvent() method which takes the corresponding event object.
For example, processMouseEvent(MouseEvent)
The processXYZEvent() method notifies the corresponding listeners about the event by passing the event object to the handler.
For example, processMouseEvent(MouseEvent) notifies the registered mouse listener(s).
The enableEvents() method decides what event(s) to give to the processEvent() method. This method cannot be overrided since it is final. However this can be accessed in the sub class of the Component class to decide what type of events that the component support.
Are they really needed for handling events ?
Their role is mentioned above. This means that they are needed for handling events because you can only handle an event when an event object is created and dispatched and those methods do this.
I have a class GuiApplication and a class ImageHandler. The GUI can work with the ImageHandler (and thus images) trough a class called Crawler which provides a façade for the methods the GUI can use.
There's a separate class called StartUp which has a main method and the only thing done there is create an instance of GuiApplication (so basically it starts the program).
In my GUI, there is a JTextPane which serves as a logger: certain actions and events will be shown there. With output that comes from elsewhere within my GUI, I can easily update its value. However, when there is output that comes from within my domain classes, e.g. ImageHandler, I can't do anything.
There is a Try-Catch block which prevents my program from crashing when an unexpected image URL passes trough my reader, and when it does I would like to show this in the textpane ("Error: File xxx could not be read").
However, I don't see an elegant way to communicate this to my GUI: I can't create an instance because that would create a new GUI and I don't think approaching my GUI trough the StartUp file is good practice either.
I was considering defining the variable in a different class that could be accessed troughout the entire project, but I wanted some opinions first.
The practical way is to throw a RuntimeException, which does not need to change the methods' signature. Catch it in the GUI and do a JOptionPane.showMessageDialog.
The other way is to extend the API of ImageHandler with an event handler, and install a message handler that calls in GuiApplication JOptionPane.showMessageDialog.
One option that comes to mind is a callback: pass an instance (it can be an anonymous class) of some interface to the method doing the work, which it calls when an error occurs.
I have a dialog, which have four buttons say New, Save, Delete, Cancel. Now each of these need to perform their action. So I have defined a separate class which implements an ActionListener. I have used this class to perform each of the button action.
public class MyClass implements ActionListener {
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand().toString() == "OK") {
// Code
} else if( .. ){
}
}
}
What I have done is, I defined an inner class which I used to do the same functionality. But what I was not getting is, is it best practice to write a separate class or is it best to use inner class. I was suggested to write in a public class so tomorrow some one can use this class to perform their action. So I have the following questions,
If the functionality is not called by any object (which I can't say) then I can write it in inner class? OR
Is it a good practice always to write inner class which performs the actions of that dialog?
There is no general answer to these questions. If the code in actionPerformed() is one line, writing a whole class file is usually overkill.
If the code is more complex, it might be suitable to reuse but as the code grows, it also gets more specific (so you can't reuse it anymore).
Try to follow this approach:
Build your application from simple blocks that are independent of each other.
Configure the application by writing code that connects the blocks.
So in your case, you could have helper methods which do the work. Wrap them in Swing Actions; this allows you to use them in all kinds of buttons and menus.
Try to move as much work as possible into the helpers so that the actions become really simple. If in doubt, ask yourself: Is this code part of the work? Does everyone need to do this?
If yes, then the code should go into a work/helper class.
If it's things like UI related checks (visible/enabled), conversion (string to number), validation, etc., it should go into the action.
When you talk about defining an inner class for a GUI listener, I think immediately of using anonymous classes to do the job:
newButton.addActionListener(
new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
// do the work for a button press
}
});
// similarly for save, cancel, delete buttons:
saveButton.addActionListener(
new ActionListener()
{
// ...
You'll often see this, and I often use this in my own code.
Which you use depends on the structure of your code, for instance:
how much work each listener needs to do
how much code is shared between the handlers
If each handler is short (e.g. just one method call, with all the real work handled within another class method), I'll use anonymous classes this way. But it does look goofy: unfortunately java requires us to define an object to employ a callback method.
It's also a matter of personal preference and coding style.
However, I'd rarely make a new top-level class for a GUI handler as in your example: even if I separate out the class so that I use the same class for each button, I'd define the class within the class file controlling the buttons, either as a non-public top-level class, or as an inner (non-anonymous) class. If the complexity of a GUI callback grows to the point that it deserves a separate class, I'd start looking for places to refactor.
proper way should be Swing Action(mentioned in comment by #Robin), for JButtons Components as most scalable choice, with implementations of interesting methods
most complex GUI is there way to add EventHandler, which fired event and could be compare in String value