Monday, February 13, 2012

Event delegation

It is important to consider how users interact with the user interface when designing a graphical user interface (GUI). The GUI may require users to click, resize, or drag and drop components of the interface, and input data using the keyboard. These actions will result to an event and you need to write a code to handle them.
Event handling code deals with events generated by GUI user interaction. The best practices for coding event handlers are outlined in the event delegation model.
The event delegation model comprises three elements:
  • Event source
  • Event listener
  • Adapter
Event source
An event source is a component, such as a GUI component, that generates an event. The event source can be generated by any type of user interaction. You can also combine a number of different types of events into one event object.

For example, if a user clicks and drags an icon, you can sum up the mouse-clicked event and the mouse-moved event into one event object.

In the event delegation model, a class represents each event type. Event objects are all defined in the java.util.EventObject subclasses.

A generated event object

  • provides the methods to add or remove the source event
  • manages the list of registered event listeners
  • provides the appropriate class type to the registered event listeners
Event listener
Event listeners are objects that receive notification of an event. Components define the events they fire by registering objects called listeners for those event types. When an event is fired, an event object is passed as an argument to the relevant listener object method. The listener object then handles the event.

To receive notification of an event, the object must be registered with the event source. To subscribe to the event source, you implement the appropriate listener interface.

All listeners are implementations of the EventListener interface or one of its subinterfaces. The Java API provides a predefined listener interface for each set of event types that a source can fire. For example, the MouseListener interface deals with mouse events, and the ActionListener interface deals with action events fired by buttons and other components.

Each listener interface provides at least one method for delivering the event object to the listener, in addition to any methods required for the action. All methods take one parameter and are part of the EventObject class.
Adapter
Adapters are abstract classes that implement listener interfaces using predefined methods. These are provided for convenience.

You can use an adapter to apply one listener's methods without having to implement all other methods. Adapters provide empty implementations for all interfaces' methods, so you only need to override the method you are interested in.
SwingWorker class is designed to be used for situations where you need to have a long running task run in a background thread and provide updates to the GUI either when done or while still in progress. Subclasses of SwingWorker must implement the doInBackground method to perform the background computation.
When using the SwingWorker class, you need to subclass SwingWorker and override the doInBackground method and done method. You can code a lengthy operation inside doInBackground and add another task into the done method before updating the Swing component from the event thread.
With the release of Java SE 6.0, additional features for sorting and filtering the JTable have been added. By filtering the contents of a JTable, only the rows that match the user specified constraints are displayed. Users can click on a specific column to be able to sort the contents accordingly.
Sorting is done by associating a JTable with a RowSorter class. RowSorter maintains two mappings. One maps rows in a JTable to the elements of the underlying model and the other let you go back again. Having two mappings allows you to do sorting and filtering. The class is generic enough to work with both TableModel and ListModel. TableRowSorter class is used to work with a JTable.
In the simplest case, you pass the TableModel to the TableRowSorter constructor and then pass the created RowSorter into the setRowSorter method of JTable.

The code shows an example:
           TableModel model = new DefaultTableModel(rows, columns) {
               public Class getColumnClass(int column) {
                   Class returnValue;
                   if ((column >= 0) && (column < getColumnCount())) {
                     returnValue = getValueAt(0, column).getClass();
                   } else {
                       returnValue = Object.class;
                   }
                   return returnValue;
             }
           };

           JTable table = new JTable(model);
           RowSorter<TableModel> sorter =new TableRowSorter<TableModel>(model);
           table.setRowSorter(sorter);
           JScrollPane pane = new JScrollPane(table);
           frame.add(pane, BorderLayout.CENTER);
           frame.setBounds(400, 350, 300, 225);
     frame.setResizable(false);   
           frame.setVisible(true);
       
     }
}
To perform filtering on a JTable, a RowFilter needs to be associated with the TableRowSorter and use it to filter the contents of a table using the include method.

The syntax for the include method is:
boolean include(RowFilter.Entry<? extends M,? extends I> entry)
For each entry in the model associated with the RowSorter, the method indicates whether the specified entry should be shown in the current view of the model. In many cases, you don't need to create your own RowFilter implementation.
In the given example, we use the regexFilter() method which uses a regular expression for filtering.
import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;
import java.util.regex.*;

   public class SampleFilterJTable {
     public static void main(String args[]) {
           JFrame frame = new JFrame("Sorting JTable");
           frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
           Object rows[][] = {
             {"CLSRE", "Callinsure", 388.44},
                    {"INTRSW", "Inter-Swift", 12.56},
                    {"BRCD", "Brocadero", 57.13},
                    {"MIMPS", "Med-Imps", 32.52},
                    {"CBCO", "Custom Boat Co.", 443.26},
                    {"SETLS",  "Sharp-End Tools", 12.90},
                     {"PHLX", "Phlogistix", 31.25},
               {"MTLD", "Mathemetric Ltd.", 45.89}
           };
           Object columns[] = {"Symbol", "Name", "Price"};
           TableModel model =
              new DefaultTableModel(rows, columns) {
             public Class getColumnClass(int column) {
               Class returnValue;
               if ((column >= 0) && (column < getColumnCount())) {

4 comments:

very good....very informative with simple and understandable language

Great article! Keep up the good work!!

Post a Comment