1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
206
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 }