View Javadoc

1   /*
2    * $Id: FieldManager.java,v 1.12 2006/10/25 10:07:42 edankert Exp $
3    *
4    * The contents of this file are subject to the Mozilla Public License 
5    * Version 1.1 (the "License"); you may not use this file except in 
6    * compliance with the License. You may obtain a copy of the License at 
7    * http://www.mozilla.org/MPL/ 
8    *
9    * Software distributed under the License is distributed on an "AS IS" basis, 
10   * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
11   * for the specific language governing rights and limitations under the License.
12   *
13   * The Original Code is XML Hammer code. (org.xmlhammer.*)
14   *
15   * The Initial Developer of the Original Code is Edwin Dankert. Portions created 
16   * by the Initial Developer are Copyright (C) 2005 - 2006 the Initial Developer. 
17   * All Rights Reserved.
18   *
19   * Contributor(s): Edwin Dankert <edankert@gmail.com>
20   */
21  
22  package org.xmlhammer.gui;
23  
24  import java.awt.Component;
25  import java.awt.event.FocusEvent;
26  import java.awt.event.FocusListener;
27  import java.awt.event.ItemEvent;
28  import java.awt.event.ItemListener;
29  import java.util.ArrayList;
30  
31  import javax.swing.JComboBox;
32  import javax.swing.JComponent;
33  import javax.swing.JTextField;
34  import javax.swing.JToggleButton;
35  import javax.swing.event.ChangeEvent;
36  import javax.swing.event.ChangeListener;
37  import javax.swing.event.DocumentEvent;
38  import javax.swing.event.DocumentListener;
39  import javax.swing.event.EventListenerList;
40  
41  import org.apache.log4j.Logger;
42  
43  /***
44   * Manages the fields for a project, handling undo and focus ...
45   * 
46   * @version $Revision: 1.12 $, $Date: 2006/10/25 10:07:42 $
47   * @author Edwin Dankert <edankert@gmail.com>
48   */
49  
50  public class FieldManager implements FocusListener, ItemListener, DocumentListener {
51      protected EventListenerList listeners = new EventListenerList();
52  
53      private ArrayList<JComponent> fields = null;
54  	private ProjectView view = null;
55  	private JComponent lastFocusedComponent = null;
56      private boolean fieldsChanged = false;
57      private boolean propertiesChanged = false;
58      private boolean ignore = false;
59  
60  	/***
61  	 * @param view the view this field manager should manage.
62  	 */
63  	public FieldManager( ProjectView view) {
64  		fields = new ArrayList<JComponent>();
65  		this.view = view;
66  	}
67  	
68  	/***
69  	 * @param field the field to listen to changes on.
70  	 */
71  	public void addField( JComponent field) {
72  		fields.add( field);
73  		
74  		if ( field instanceof JToggleButton) {
75  			((JToggleButton)field).addItemListener( this);
76              field.addFocusListener( this);
77  		} else if ( field instanceof JComboBox) {
78              if ( ((JComboBox)field).isEditable()) {
79      			Component editor = ((JComboBox)field).getEditor().getEditorComponent();
80      			
81      			if ( editor instanceof JTextField) {
82      				fields.add( (JTextField)editor);
83      				((JTextField)editor).getDocument().addDocumentListener(this);
84      				((JTextField)editor).addFocusListener( this);
85      			}
86              } else {
87                  field.addFocusListener( this);
88                  ((JComboBox)field).addItemListener( this);
89              }
90  		} else if ( field instanceof JTextField) {
91  			((JTextField)field).getDocument().addDocumentListener( this);
92              field.addFocusListener( this);
93  		}
94  	}
95  	
96  	/***
97  	 * @param field the field to listen to changes for.
98  	 */
99  	public void removeField( JComponent field) {
100 		fields.remove( field);
101 		field.removeFocusListener( this);
102 
103 		if ( field instanceof JToggleButton) {
104 			((JToggleButton)field).removeItemListener( this);
105 		} else if ( field instanceof JComboBox) {
106 			Component editor = ((JComboBox)field).getEditor().getEditorComponent();
107 			if ( editor instanceof JTextField) {
108 				((JTextField)editor).getDocument().removeDocumentListener( this);
109 				((JTextField)editor).removeFocusListener( this);
110 			}
111 			((JComboBox)field).removeItemListener( this);
112 		} else if ( field instanceof JTextField) {
113 			((JTextField)field).getDocument().removeDocumentListener( this);
114 		}
115 	}
116 	
117 	/***
118 	 * @param event invoked when a field gained focus.
119 	 */
120 	public void focusGained( FocusEvent event) {
121 		lastFocusedComponent = (JComponent)event.getSource();
122 		view.setSelected( true);
123 	}
124 
125 	/***
126 	 * @param event invoked when a field lost focus.
127 	 */
128 	public void focusLost( FocusEvent event) {}
129 	
130 	/***
131 	 * @return the field which had focus last.
132 	 */
133 	public JComponent getLastFocusedField() {
134 		return lastFocusedComponent;
135 	}
136 	
137 	/***
138 	 * @return true when any of the fields have been changed by the user.
139 	 */
140 	public boolean isChanged() {
141 		return fieldsChanged || propertiesChanged;
142 	}
143 	
144 	/***
145 	 * @param changed overrides the changed state from the outside (view saved/initialised).
146 	 */
147 	public void setChanged( boolean changed) {
148 		setPropertiesChanged(changed);
149         setFieldsChanged(changed);
150 
151         notifyChange();
152 	}
153 	
154     /***
155      * @param changed overrides the changed state from the outside.
156      */
157     public void setFieldsChanged( boolean changed) {
158         this.fieldsChanged = changed;
159 
160         notifyChange();
161     }
162 
163     /***
164      * @param changed overrides the changed state from the outside.
165      */
166     public void setPropertiesChanged( boolean changed) {
167         this.propertiesChanged = changed;
168 
169         notifyChange();
170     }
171 
172 	/***
173 	 * @param e state has changed.
174 	 */
175 	public void itemStateChanged( ItemEvent e) {
176         if (!ignore) {
177             fieldsChanged = true;
178     		notifyChange(); 
179         }
180 	}
181 	
182     /***
183      * @param e state has changed.
184      */
185     public void setIgnoreChanges( boolean ignore) {
186         this.ignore = ignore;
187     }
188 
189     /***
190      * @param e state has changed.
191      */
192     public boolean isIgnoreChanges() {
193         return ignore;
194     }
195 
196     /***
197 	 * notifies user changes to the underlying project view.
198 	 *
199 	 */
200 	public void notifyChange() {
201    		view.setChanged( isChanged());
202 
203         Object[] list = listeners.getListenerList();
204         
205         // Process the listeners last to first, notifying
206         // those that are interested in this event
207         for ( int i = list.length-2; i >= 0; i -= 2) {
208             if ( list[i] == ChangeListener.class) {
209                 ((ChangeListener)list[i+1]).stateChanged( new ChangeEvent( this));
210             }
211         }
212 	}
213 
214     public void insertUpdate(DocumentEvent event) {
215         Logger.getLogger(this.getClass()).debug("insertUpdate( "+event+")");
216         
217         if (!ignore) {
218             for (JComponent component : fields) {
219                 if (component instanceof JTextField) {
220                     JTextField field = (JTextField)component;
221                     if (field.getDocument() == event.getDocument() && field.hasFocus()) {
222                         fieldsChanged = true;
223                         notifyChange();
224                         break;
225                     }
226                 }
227             }
228         }
229     }
230 
231     public void removeUpdate(DocumentEvent event) {
232         Logger.getLogger(this.getClass()).debug("removeUpdate( "+event+")");
233 
234         if (!ignore) {
235             for (JComponent component : fields) {
236                 if (component instanceof JTextField) {
237                     JTextField field = (JTextField)component;
238                     if (field.getDocument() == event.getDocument() && field.hasFocus()) {
239                         fieldsChanged = true;
240                         notifyChange();
241                         break;
242                     }
243                 }
244             }
245         }
246     }
247 
248     public void addChangeListener(ChangeListener l) {
249         listeners.add(ChangeListener.class, l);
250     }
251 
252     public void removeChangeListener(ChangeListener l) {
253         listeners.remove(ChangeListener.class, l);
254     }
255 
256     public void changedUpdate(DocumentEvent arg0) {}
257 }