View Javadoc

1   /*
2   Wotonomy: OpenStep design patterns for pure Java applications.
3   Copyright (C) 2000 Michael Powers
4   
5   This library is free software; you can redistribute it and/or
6   modify it under the terms of the GNU Lesser General Public
7   License as published by the Free Software Foundation; either
8   version 2.1 of the License, or (at your option) any later version.
9   
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  Lesser General Public License for more details.
14  
15  You should have received a copy of the GNU Lesser General Public
16  License along with this library; if not, see http://www.gnu.org
17  */
18  
19  package net.wotonomy.ui.swing;
20  
21  import java.awt.BorderLayout;
22  import java.awt.Insets;
23  import java.awt.event.ActionEvent;
24  import java.awt.event.ActionListener;
25  import java.awt.event.MouseEvent;
26  import java.awt.event.MouseListener;
27  import java.text.SimpleDateFormat;
28  import java.util.Date;
29  
30  import javax.swing.JFrame;
31  import javax.swing.JMenuItem;
32  import javax.swing.JPanel;
33  import javax.swing.JPopupMenu;
34  import javax.swing.JScrollPane;
35  import javax.swing.JTable;
36  import javax.swing.border.EmptyBorder;
37  import javax.swing.table.TableColumn;
38  
39  import net.wotonomy.foundation.NSMutableArray;
40  import net.wotonomy.foundation.NSNotification;
41  import net.wotonomy.foundation.NSNotificationCenter;
42  import net.wotonomy.foundation.NSSelector;
43  import net.wotonomy.ui.EOAssociation;
44  import net.wotonomy.ui.EODisplayGroup;
45  import net.wotonomy.ui.swing.components.FormattedCellRenderer;
46  import net.wotonomy.ui.swing.util.ObjectInspector;
47  import net.wotonomy.ui.swing.util.StackTraceInspector;
48  import net.wotonomy.ui.swing.util.WindowUtilities;
49  import net.wotonomy.control.internal.Surrogate;
50  
51  /***
52  * The NotificationInspector displays a JFrame that
53  * displays notifications as they occur.  <br><br>
54  *
55  * @author michael@mpowers.net
56  * @version $Revision: 904 $
57  */
58  
59  public class NotificationInspector
60      implements MouseListener, ActionListener
61  {
62      protected JTable table;
63      protected JPopupMenu popupMenu;
64      protected EODisplayGroup displayGroup;
65  
66      // key command to copy contents to clipboard
67      static public final String COPY = "COPY";
68  
69      protected static final String CLEAR_ALL = "Clear All";
70      protected static final String CLEAR_SELECTED = "Clear Selected";
71  
72  
73  /***
74  * Displays all notifications on the default notification center.
75  */
76      public NotificationInspector()
77      {
78          this( NSNotificationCenter.defaultCenter() );
79      }
80  
81  /***
82  * Displays all notifications from the specified notification center.
83  */
84      public NotificationInspector( NSNotificationCenter aCenter )
85      {
86          this( aCenter, null, null );
87      }
88  
89  /***
90  * Displays notifications from the default notification center
91  * using the specified name and object filters.
92  */
93      public NotificationInspector( String notificationName, Object anObject )
94      {
95          this( NSNotificationCenter.defaultCenter(),
96              notificationName, anObject );
97      }
98  
99  /***
100 * Displays notifications on the specified notification center
101 * using the specified name and object filters.
102 */
103     public NotificationInspector( NSNotificationCenter aCenter,
104         String notificationName, Object anObject )
105     {
106         // show stack traces
107         NSNotification.showStack = true;
108 
109         // register for notifications
110         NSSelector handleNotification =
111             new NSSelector( "handleNotification",
112                 new Class[] { NSNotification.class } );
113         aCenter.addObserver(
114             this, handleNotification, notificationName, anObject );
115 
116         table = new JTable();
117 
118         popupMenu = new JPopupMenu();
119         JMenuItem menuItem = popupMenu.add( CLEAR_SELECTED );
120         menuItem.addActionListener( this );
121         menuItem = popupMenu.add( CLEAR_ALL );
122         menuItem.addActionListener( this );
123 
124         displayGroup = new EODisplayGroup();
125 
126         TableColumn column;
127         TableColumnAssociation assoc;
128 
129         column = new TableColumn();
130         column.setHeaderValue( "Time" );
131         column.setCellRenderer( new FormattedCellRenderer( new SimpleDateFormat( "hh:mm:ss:SS" ) ) );
132         column.setPreferredWidth( 90 );
133         column.setMaxWidth( 90 );
134 
135         assoc = new TableColumnAssociation( column );
136         assoc.bindAspect( EOAssociation.ValueAspect, displayGroup, "time" );
137         assoc.setTable( table );
138         assoc.establishConnection();
139 
140         column = new TableColumn();
141         column.setHeaderValue( "Type" );
142 
143         assoc = new TableColumnAssociation( column );
144         assoc.bindAspect( EOAssociation.ValueAspect, displayGroup, "name" );
145         assoc.setTable( table );
146         assoc.establishConnection();
147 
148         column = new TableColumn();
149         column.setHeaderValue( "Object" );
150 
151         assoc = new TableColumnAssociation( column );
152         assoc.bindAspect( EOAssociation.ValueAspect, displayGroup, "objectString" );
153         assoc.setTable( table );
154         assoc.establishConnection();
155 
156         column = new TableColumn();
157         column.setHeaderValue( "Info" );
158 
159         assoc = new TableColumnAssociation( column );
160         assoc.bindAspect( EOAssociation.ValueAspect, displayGroup, "userInfoString" );
161         assoc.setTable( table );
162         assoc.establishConnection();
163 
164         initLayout();
165     }
166 
167     protected void initLayout()
168     {
169         table.addMouseListener( this ); // listen for double-clicks
170 
171         JPanel panel = new JPanel();
172         panel.setBorder( new EmptyBorder( new Insets( 10, 10, 10, 10 ) ) );
173         panel.setLayout( new BorderLayout( 10, 10 ) );
174 
175         JScrollPane scrollPane = new JScrollPane( table );
176         //scrollPane.setPreferredSize( new Dimension( 500, 250 ) );
177         panel.add( scrollPane, BorderLayout.CENTER );
178 
179         JFrame window = new JFrame();
180         window.setTitle( "Notification Inspector" );
181         window.getContentPane().add( panel );
182 
183         //window.pack();
184         window.setSize( 800, 400 );
185         WindowUtilities.cascade( window );
186 
187         // size the columns.
188 //        table.getColumnModel().getColumn( 0 ).setPreferredWidth( 100 );
189 
190         window.show();
191     }
192 
193 /***
194 * Handles the notification.
195 */
196     public void handleNotification( NSNotification aNotification )
197     {
198         Surrogate s = new Surrogate( new Object[] { aNotification } );
199         s.directPut( "time", new Date() );
200         s.directPut( "objectString", ""+aNotification.object() ); // snapshot of state
201         s.directPut( "userInfoString", ""+aNotification.userInfo() ); // snapshot of info
202         displayGroup.insertObjectAtIndex( s, 0 );
203     }
204 
205     // interface ActionListener
206 
207     /***
208      * Method used to listen for the action event from the popup menu items.
209      */
210     public void actionPerformed( ActionEvent e )
211     {
212         if ( CLEAR_SELECTED.equals( e.getActionCommand() ) )
213         {
214             NSMutableArray objects = new NSMutableArray( displayGroup.allObjects() );
215             objects.removeAll( displayGroup.selectedObjects() );
216             displayGroup.setObjectArray( objects );
217             displayGroup.updateDisplayedObjects();
218         }
219         else if ( CLEAR_ALL.equals( e.getActionCommand() ) )
220         {
221             displayGroup.setObjectArray( null );
222             displayGroup.updateDisplayedObjects();
223         }
224     }
225 
226     // interface MouseListener
227 
228     /***
229     * Double click to launch object inspector.
230     */
231 
232     public void mouseClicked(MouseEvent e)
233     {
234         if ( e.getSource() == table )
235         {
236             if ( e.getClickCount() > 1 )
237             {
238                 int row = table.rowAtPoint( e.getPoint() );
239                 int col = table.columnAtPoint( e.getPoint() );
240                 col = table.convertColumnIndexToModel( col );
241 
242                 if ( row == -1 ) return;
243 
244                 if ( col == 0 ) // time
245                 {
246                     new StackTraceInspector( ( (NSNotification) ( (Surrogate)
247                     displayGroup.displayedObjects().objectAtIndex( row ) ).getDelegate() ).stackTrace() );
248                 }
249                 else
250                 if ( col == 2 ) // object
251                 {
252                     new ObjectInspector( ( (NSNotification) ( (Surrogate)
253                     displayGroup.displayedObjects().objectAtIndex( row ) ).getDelegate() ).object() );
254                 }
255                 else
256                 if ( col == 3 ) // info
257                 {
258                     new ObjectInspector( ( (NSNotification) ( (Surrogate)
259                     displayGroup.displayedObjects().objectAtIndex( row ) ).getDelegate() ).userInfo() );
260                 }
261                 else
262                 {
263                     new ObjectInspector( ( (Surrogate)
264                         displayGroup.displayedObjects().objectAtIndex( row ) ).getDelegate() );
265                 }
266             }
267             else
268             {
269                 // Click count is 1 then, check for popup trigger.
270                 if ( e.isPopupTrigger() )
271                 {
272                     popupMenu.show( table, e.getX(), e.getY() );
273                 }
274             }
275         }
276     }
277 
278     public void mouseReleased(MouseEvent e)
279     {
280         if ( e.getSource() == table )
281         {
282             if ( e.isPopupTrigger() && ( e.getClickCount() == 1 ) )
283             {
284                 popupMenu.show( table, e.getX(), e.getY() );
285             }
286         }
287     }
288 
289     public void mousePressed(MouseEvent e)
290     {
291         if ( e.getSource() == table )
292         {
293             if ( e.isPopupTrigger() && ( e.getClickCount() == 1 ) )
294             {
295                 popupMenu.show( table, e.getX(), e.getY() );
296             }
297         }
298     }
299 
300     public void mouseEntered(MouseEvent e) {}
301     public void mouseExited(MouseEvent e) {}
302 
303 }
304 
305 /*
306  * $Log$
307  * Revision 1.2  2006/02/18 23:19:05  cgruber
308  * Update imports and maven dependencies.
309  *
310  * Revision 1.1  2006/02/16 13:22:23  cgruber
311  * Check in all sources in eclipse-friendly maven-enabled packages.
312  *
313  * Revision 1.6  2003/08/06 23:07:52  chochos
314  * general code cleanup (mostly, removing unused imports)
315  *
316  * Revision 1.5  2002/11/18 22:11:51  mpowers
317  * rglista's long-overdue enhancements: can now clear the display!
318  *
319  * Revision 1.4  2002/10/24 18:19:03  mpowers
320  * Now telling NSNotification to generate stack traces.
321  *
322  * Revision 1.3  2001/04/29 22:02:45  mpowers
323  * Work on id transposing between editing contexts.
324  *
325  * Revision 1.2  2001/04/09 21:40:25  mpowers
326  * Numerous usability enhancements.
327  *
328  * Revision 1.1  2001/04/08 20:58:45  mpowers
329  * Contributing notification inspector.
330  *
331  *
332  */
333