Here are the tasks you need to perform to create a new event set.
For example, you are developing a timer component and want to have timer events so you select "Timer" as the name for your event set.
For example, you might have timerTick, timerStart and timerStop methods.
For example, you might choose "TimerEvent."
Here are the tasks you must do to make your component capable of generating TimerEvents:
Component writers can create new program-generated events only. System- or user-generated events must be passed to the component by the AWT, and may optionally be passed on to other components via event source/listener connections.
These are the topics that explain in detail how to create custom event sets, how to add them to a source component, and how to make a component listen for the new events:
For example, the following is an event class for a timer event (a timer is a component that generates an event at specified intervals, like the ticking of a clock):
public class TimerEvent extends EventObject { protected int tickCount, tickInterval; TimerEvent(java.awt.Component source) { super(source); tickCount = 0; tickInterval = 100; } } public int getTickCount() { return tickCount; } public int getTickInterval() { return tickInterval; } public void setTickInterval(int milliseconds) { tickInterval = milliseconds; }Note that the tickCount and tickInterval fields do not have direct public access, but their values are retrieved through the public getTickCount() and getTickInterval() methods, and the tickInterval is set with the setTickInterval() method. Usually, event object states should not be changed, and using accessor methods helps accomplish this. When writing such a method, use the same conventions required for accessor methods for properties.
For example, this is a new event-listener interface for timer tick events:
public interface TimerListener extends EventListener { public void timerTick(TimerEvent event); public void timerStart(TimerEvent event); public void timerStop(TimerEvent event); }This sample interface declares three timer events: one that generates a "tick" event at a set interval, one that occurs when the timer starts "ticking," and another that occurs when the timer stops "ticking."
The components you want to listen to and respond to the new events must implement the new event-listener interface. For example,
public class SomeComponent implements TimerListener { public void timerTick(TimerEvent ev) { // code that does whatever you want to happen when this method is called } public void timerStart(TimerEvent ev) { // your code goes here } public void timerStop(TimerEvent ev) { // your code goes here }You can leave the bodies of the methods empty if you just want your listener component to be able to respond without any special processing. The user of your component will write the specific code that determines what happens when the event occurs.
See also:
Notifying a listening component
Listening for an event occurrence shows you how a listening component registers itself with the source component by calling the source component's add event-listener method. When the source component generates an event, it notifies all those components that are registered as listeners. Therefore, you must implement an add event-listener method for a source component, and you must provide a remove event-listener method. Once these are in place, listening components can register and unregister themselves with the list of components the source component notifies when it generates an event.
If a source component has only one listening component, the process of event handling looks something like the following diagram:
Unicast event handling
The source component creates an event object and passes it to the listening component. In the diagram, an event adapter class actually makes the proper method call, but adapter classes are optional. Whether or not adapter classes are used, the source component delegates the handling of the event to the listening component.
What if you want to have several components listening (and responding) to the same event? JavaBeans also have multicast events. Event delegation in multicast events look like this:
Multicast event handling
For component users, the difference between multicast and unicast events is invisible. Unicast events use a form of the add event-listener method that throws a TooManyListenersException if more than one component is registered as a listener. Because the registration method signature is the same for both multicast and unicast events, component users don't need to know whether an event is multicast or unicast. If a component is successfully registered as a listener, the component user can be sure the component receives the events.
AWT events and most programmer-defined events should be multicast, as they provide the greatest flexibility to your component users.
This is a timer component that has the registration methods for the new timer events:
import java.awt.*; public class MyTimer { private Vector listenerList = new Vector(); public synchronized void addTimerListener(TimerListener timerListener) { listenerList.addElement(timerListener); } public synchronized void removeTimerListener(TimerListener timerListener) { listenerList.removeElement(timerListener); }
public synchronized void add<event>Listener (<event>Listener <listener>);
The following describes the purpose of each element:
public synchronized void add<event>Listener(<event>Listener <listener>) throws TooMayListeners;
The following describes the purpose of each element:
sourceComponent.removeKeyListener (myComponent);
public synchronized void remove<event>Listener(<event>Listener <listener>);
The following describes the purpose of each element:
For example, the following code is added to the MyTimer class. When the program that uses this component calls any of the process methods, a TimerEvent object is created and sent to each listening component.
import java.awt.*; public class MyTimer { private Vector listenerList = new Vector(); public synchronized void addTimerListener(TimerListener timerListener) { listenerList.addElement(timerListener); } public synchronized void removeTimerListener(TimerListener timerListener) { listenerList.removeElement(timerListener); } protected void processTimerTick() { TimerEvent ev = new TimerEvent(this); // TimerEvent object instantiated for (int i = 0; i < listenerList.size(); i++) // for each component in the list ((TimerListener)listenerList.elementAt(i)).timerTick(ev); // call its timerTick() method, passing it the event object } protected void processStartTimer() { TimerEvent ev = new TimerEvent(this); // TimerEvent object instantiated for (int i = 0; i < listenerList.size(); i++) // for each component in the list ((TimerListener)listenerList.elementAt(i)).startTimer(ev); // call its startTimer() method, passing it the event object } protected void processStopTimer() { TimerEvent ev = new TimerEvent(this); // TimerEvent object instantiated for (int i = 0; i < listenerList.size(); i++) // for each component in the list ((TimerListener)listenerList.elementAt(i)).stopTimer(ev); // call its stopTimer() method, passing it the event object }The resulting MyTimer component can now generate the three timer events. When the MyTimer component is added to an application at design time, the event-listener interface methods (in this example the three methods of TimerListener) will appear on the Events page of the Component Inspector.
See also:
Understanding event adapter classes
Event adapters provide another advantage. If you have a component that listens to several other components that fire the same event type, but you want to treat the events differently, you can use one adapter for each source component. This way you have separate code being called for each event and you don't have to test the source components to know which one fired.
To use an event adapter in your application, instantiate it in your component and override the methods for the events you want to handle, calling the method in your component that contains the required behavior.
JBuilder uses event adapter classes when the component user links an event with a method. To see an event adapter class in action, follow these steps within JBuilder:
textAreaControl1.setText("Hello out there!");
In this example, the frame component listens for the button to generate a mouseClicked event. When the user clicks the button and the button generates a mouseClicked event, the text in the TextAreaControl is set.
When you double-clicked the mouseClicked event in the Component Inspector, JBuilder added a number of statements to your code. Examine the source code to find these statements.
In the jbinit() method for the frame, JBuilder added the addMouseListener() method call, which makes the frame a listener component for the a mouseClick event in the ButtonControl. This is the code JBuilder generated:
buttonControl1.addMouseListener(new Frame1_buttonControl1_MouseAdapter(this));Note that instead of Frame1 being passed to the addMouseListener() method, a Frame1_buttonControl_1MouseAdapter class is created and this new adapter class is passed to the addMouseListener() method, registering it as the listener. The this argument is passed to the constructor of the adapter class. this refers to the Frame1 component.
Near the bottom of the jbinit() method for the frame, JBuilder added a method in which you wrote your code:
void buttonControl1_mouseClicked(java.awt.event.MouseEvent e) { textAreaControl1.setText("Hello out there!"); // this is the code you added }The statement you wrote set the text property of the TextAreaControl. The connection between the two statements is in the adapter class itself. Finally, below the jbinit() method, is the definition of the adapter class:
class Frame1_ButtonControl1_MouseAdapter extends MouseAdapter { Frame1 adaptee; Frame1_buttonControl1_MouseAdapter(Frame1 adaptee) { this.adaptee = adaptee; } // override the method for the desired event, calling the method in Frame1 public void mouseClicked(java.awt.event.MouseEvent e) { adaptee.buttonControl1_mouseClicked(e); } }JBuilder creates the adapter class and overrides a single method. The method that handles the selected event calls the buttonControl1_mouseClicked() method in Frame1 to do the actual responding to the mouse click. The result is that the frame listens and responds to mouseClick events only and not mousePressed and mouseReleased events.
Your components are seldom listeners because JBuilder usually creates event listeners automatically in the container class where your components are used. If, however, you decide you want your component to be able to listen for particular events, you must implement the appropriate Listener interfaces for the event sets you choose.
For example, to make your component a key event listener, implement the KeyListener interface, an interface that extends the java.util.EventListener interface:
public class myComponent extends java.awt.Component implements KeyListener
public void keyTyped(KeyEvent event) { // your implementation goes here } public void keyPressed(KeyEvent event) { // your implementation goes here } public void keyReleased(KeyEvent event) { // your implementation goes here }
Within each of these methods, write the code to perform any special processing you want to occur. You can leave the body of the method empty, if you just want your component to be able to respond without any special processing. The user of your component can write the specific code that determines what happens when the event occurs.
Now your component is capable of listening for a event. The only question that remains is which source component is your component listening for key events in. To specify which source component your component listens to, some piece of code must call the add event-listener registration method of the source component passing your listening component as a parameter. The name of the registration method is the name of the event interface prefaced with the word add. For example, to register a component for notification of key events, call the addKeyListener() method. The addKeyListener() method adds your component to the list of components the source component notifies when it generates a key event.
The add-listener method could be called in several ways. It could be called by a source component when it creates various listening components, attaching them to itself. It could be called by a listening component that automatically attaches itself to some event source. But usually your component is only an event source JBuilder attaches action adapters as listeners to its events when the user uses the Events page of the Component Inspector. JBuilder generates action adapters and delegates the actual event handling to a method in the container class being designed.
To understand the need for this consider that when you are writing a component that a user will use to build applications, you don't know how the component will be used. Therefore, you really can't register your component at the time you create it. That is a task for the component user. When the component user selects an event for a control and double-clicks it on the Events page of the Component Inspector, JBuilder automatically adds the event listening (adapter class) code to the source file of the container class being designed. It also adds to the container class a call to the add event-listener method of your component. This registers the adapter as the listener, and the adapter acts as a connector, transfering the event from your component to some container method.
These event sets are defined in the dataset package.
These event sets are defined in the model package, and depend upon the specific model.
These event sets are defined in the view package.
See also:
Java AWT events