1 |
| |
2 |
| |
3 |
| |
4 |
| |
5 |
| |
6 |
| |
7 |
| |
8 |
| |
9 |
| |
10 |
| |
11 |
| |
12 |
| |
13 |
| |
14 |
| |
15 |
| package org.apache.tapestry.form; |
16 |
| |
17 |
| import java.util.ArrayList; |
18 |
| import java.util.Arrays; |
19 |
| import java.util.Collections; |
20 |
| import java.util.HashMap; |
21 |
| import java.util.HashSet; |
22 |
| import java.util.Iterator; |
23 |
| import java.util.List; |
24 |
| import java.util.Map; |
25 |
| import java.util.Set; |
26 |
| |
27 |
| import org.apache.hivemind.ApplicationRuntimeException; |
28 |
| import org.apache.hivemind.HiveMind; |
29 |
| import org.apache.hivemind.Location; |
30 |
| import org.apache.hivemind.Resource; |
31 |
| import org.apache.hivemind.util.ClasspathResource; |
32 |
| import org.apache.hivemind.util.Defense; |
33 |
| import org.apache.tapestry.IComponent; |
34 |
| import org.apache.tapestry.IForm; |
35 |
| import org.apache.tapestry.IMarkupWriter; |
36 |
| import org.apache.tapestry.IRender; |
37 |
| import org.apache.tapestry.IRequestCycle; |
38 |
| import org.apache.tapestry.NestedMarkupWriter; |
39 |
| import org.apache.tapestry.PageRenderSupport; |
40 |
| import org.apache.tapestry.StaleLinkException; |
41 |
| import org.apache.tapestry.Tapestry; |
42 |
| import org.apache.tapestry.TapestryUtils; |
43 |
| import org.apache.tapestry.engine.ILink; |
44 |
| import org.apache.tapestry.services.ServiceConstants; |
45 |
| import org.apache.tapestry.util.IdAllocator; |
46 |
| import org.apache.tapestry.valid.IValidationDelegate; |
47 |
| |
48 |
| |
49 |
| |
50 |
| |
51 |
| |
52 |
| |
53 |
| |
54 |
| public class FormSupportImpl implements FormSupport |
55 |
| { |
56 |
| |
57 |
| |
58 |
| |
59 |
| |
60 |
| |
61 |
| |
62 |
| public static final String FORM_IDS = "formids"; |
63 |
| |
64 |
| |
65 |
| |
66 |
| |
67 |
| |
68 |
| |
69 |
| |
70 |
| public static final String RESERVED_FORM_IDS = "reservedids"; |
71 |
| |
72 |
| |
73 |
| |
74 |
| |
75 |
| |
76 |
| |
77 |
| public static final String SUBMIT_MODE = "submitmode"; |
78 |
| |
79 |
| public static final String SCRIPT = "/org/apache/tapestry/form/Form.js"; |
80 |
| |
81 |
| private final static Set _standardReservedIds; |
82 |
| |
83 |
| |
84 |
| |
85 |
| |
86 |
| |
87 |
| |
88 |
| public static final String FIELD_FOCUS_ATTRIBUTE = "org.apache.tapestry.field-focused"; |
89 |
| |
90 |
| static |
91 |
| { |
92 |
1
| Set set = new HashSet();
|
93 |
| |
94 |
1
| set.addAll(Arrays.asList(ServiceConstants.RESERVED_IDS));
|
95 |
1
| set.add(FORM_IDS);
|
96 |
1
| set.add(RESERVED_FORM_IDS);
|
97 |
1
| set.add(SUBMIT_MODE);
|
98 |
| |
99 |
1
| _standardReservedIds = Collections.unmodifiableSet(set);
|
100 |
| } |
101 |
| |
102 |
| private final static Set _submitModes; |
103 |
| |
104 |
| static |
105 |
| { |
106 |
1
| Set set = new HashSet();
|
107 |
1
| set.add(FormConstants.SUBMIT_CANCEL);
|
108 |
1
| set.add(FormConstants.SUBMIT_NORMAL);
|
109 |
1
| set.add(FormConstants.SUBMIT_REFRESH);
|
110 |
| |
111 |
1
| _submitModes = Collections.unmodifiableSet(set);
|
112 |
| } |
113 |
| |
114 |
| |
115 |
| |
116 |
| |
117 |
| |
118 |
| |
119 |
| private int _allocatedIdIndex; |
120 |
| |
121 |
| |
122 |
| |
123 |
| |
124 |
| |
125 |
| |
126 |
| private final List _allocatedIds = new ArrayList(); |
127 |
| |
128 |
| private final IRequestCycle _cycle; |
129 |
| |
130 |
| private final IdAllocator _elementIdAllocator = new IdAllocator(); |
131 |
| |
132 |
| private String _encodingType; |
133 |
| |
134 |
| private final List _deferredRunnables = new ArrayList(); |
135 |
| |
136 |
| |
137 |
| |
138 |
| |
139 |
| |
140 |
| private final Map _prerenderMap = new HashMap(); |
141 |
| |
142 |
| |
143 |
| |
144 |
| |
145 |
| |
146 |
| |
147 |
| |
148 |
| private Map _events; |
149 |
| |
150 |
| private final IForm _form; |
151 |
| |
152 |
| private final List _hiddenValues = new ArrayList(); |
153 |
| |
154 |
| private final boolean _rewinding; |
155 |
| |
156 |
| private final IMarkupWriter _writer; |
157 |
| |
158 |
| private final Resource _script; |
159 |
| |
160 |
| private final IValidationDelegate _delegate; |
161 |
| |
162 |
| private final PageRenderSupport _pageRenderSupport; |
163 |
| |
164 |
93
| public FormSupportImpl(IMarkupWriter writer, IRequestCycle cycle, IForm form)
|
165 |
| { |
166 |
93
| Defense.notNull(writer, "writer");
|
167 |
93
| Defense.notNull(cycle, "cycle");
|
168 |
93
| Defense.notNull(form, "form");
|
169 |
| |
170 |
93
| _writer = writer;
|
171 |
93
| _cycle = cycle;
|
172 |
93
| _form = form;
|
173 |
93
| _delegate = form.getDelegate();
|
174 |
| |
175 |
93
| _rewinding = cycle.isRewound(form);
|
176 |
93
| _allocatedIdIndex = 0;
|
177 |
| |
178 |
93
| _script = new ClasspathResource(cycle.getEngine().getClassResolver(), SCRIPT);
|
179 |
| |
180 |
93
| _pageRenderSupport = TapestryUtils.getOptionalPageRenderSupport(cycle);
|
181 |
| } |
182 |
| |
183 |
| |
184 |
| |
185 |
| |
186 |
| |
187 |
6
| public void addEventHandler(FormEventType type, String functionName)
|
188 |
| { |
189 |
6
| if (_events == null)
|
190 |
3
| _events = new HashMap();
|
191 |
| |
192 |
6
| List functionList = (List) _events.get(type);
|
193 |
| |
194 |
| |
195 |
| |
196 |
| |
197 |
| |
198 |
6
| if (functionList == null)
|
199 |
| { |
200 |
3
| functionList = new ArrayList();
|
201 |
| |
202 |
3
| _events.put(type, functionList);
|
203 |
| } |
204 |
| |
205 |
6
| functionList.add(functionName);
|
206 |
| } |
207 |
| |
208 |
| |
209 |
| |
210 |
| |
211 |
| |
212 |
| |
213 |
| |
214 |
| |
215 |
| |
216 |
| |
217 |
58
| private void addHiddenFieldsForLinkParameters(ILink link)
|
218 |
| { |
219 |
58
| String[] names = link.getParameterNames();
|
220 |
58
| int count = Tapestry.size(names);
|
221 |
| |
222 |
58
| StringBuffer extraIds = new StringBuffer();
|
223 |
58
| String sep = "";
|
224 |
58
| boolean hasExtra = false;
|
225 |
| |
226 |
| |
227 |
| |
228 |
| |
229 |
| |
230 |
| |
231 |
58
| preallocateReservedIds();
|
232 |
| |
233 |
58
| for (int i = 0; i < count; i++)
|
234 |
| { |
235 |
293
| String name = names[i];
|
236 |
| |
237 |
| |
238 |
| |
239 |
293
| if (!_standardReservedIds.contains(name))
|
240 |
| { |
241 |
12
| _elementIdAllocator.allocateId(name);
|
242 |
| |
243 |
12
| extraIds.append(sep);
|
244 |
12
| extraIds.append(name);
|
245 |
| |
246 |
12
| sep = ",";
|
247 |
12
| hasExtra = true;
|
248 |
| } |
249 |
| |
250 |
293
| addHiddenFieldsForLinkParameter(link, name);
|
251 |
| } |
252 |
| |
253 |
58
| if (hasExtra)
|
254 |
12
| addHiddenValue(RESERVED_FORM_IDS, extraIds.toString());
|
255 |
| } |
256 |
| |
257 |
285
| public void addHiddenValue(String name, String value)
|
258 |
| { |
259 |
285
| _hiddenValues.add(new HiddenFieldData(name, value));
|
260 |
| } |
261 |
| |
262 |
5
| public void addHiddenValue(String name, String id, String value)
|
263 |
| { |
264 |
5
| _hiddenValues.add(new HiddenFieldData(name, id, value));
|
265 |
| } |
266 |
| |
267 |
| |
268 |
| |
269 |
| |
270 |
| |
271 |
| |
272 |
| |
273 |
53
| private String buildAllocatedIdList()
|
274 |
| { |
275 |
53
| StringBuffer buffer = new StringBuffer();
|
276 |
53
| int count = _allocatedIds.size();
|
277 |
| |
278 |
53
| for (int i = 0; i < count; i++)
|
279 |
| { |
280 |
61
| if (i > 0)
|
281 |
23
| buffer.append(',');
|
282 |
| |
283 |
61
| buffer.append(_allocatedIds.get(i));
|
284 |
| } |
285 |
| |
286 |
53
| return buffer.toString();
|
287 |
| } |
288 |
| |
289 |
53
| private void emitEventHandlers(String formId)
|
290 |
| { |
291 |
53
| if (_events == null || _events.isEmpty())
|
292 |
50
| return;
|
293 |
| |
294 |
3
| StringBuffer buffer = new StringBuffer();
|
295 |
| |
296 |
3
| Iterator i = _events.entrySet().iterator();
|
297 |
| |
298 |
3
| while (i.hasNext())
|
299 |
| { |
300 |
3
| Map.Entry entry = (Map.Entry) i.next();
|
301 |
3
| FormEventType type = (FormEventType) entry.getKey();
|
302 |
3
| Object value = entry.getValue();
|
303 |
| |
304 |
3
| buffer.append("Tapestry.");
|
305 |
3
| buffer.append(type.getAddHandlerFunctionName());
|
306 |
3
| buffer.append("('");
|
307 |
3
| buffer.append(formId);
|
308 |
3
| buffer.append("', function (event)\n{");
|
309 |
| |
310 |
3
| List l = (List) value;
|
311 |
3
| int count = l.size();
|
312 |
| |
313 |
3
| for (int j = 0; j < count; j++)
|
314 |
| { |
315 |
6
| String functionName = (String) l.get(j);
|
316 |
| |
317 |
6
| if (j > 0)
|
318 |
| { |
319 |
3
| buffer.append(";");
|
320 |
| } |
321 |
| |
322 |
6
| buffer.append("\n ");
|
323 |
6
| buffer.append(functionName);
|
324 |
| |
325 |
| |
326 |
| |
327 |
| |
328 |
6
| if (!functionName.endsWith(")"))
|
329 |
| { |
330 |
5
| buffer.append("()");
|
331 |
| } |
332 |
| } |
333 |
| |
334 |
3
| buffer.append(";\n});\n");
|
335 |
| } |
336 |
| |
337 |
| |
338 |
| |
339 |
3
| _pageRenderSupport.addInitializationScript(buffer.toString());
|
340 |
| } |
341 |
| |
342 |
| |
343 |
| |
344 |
| |
345 |
| |
346 |
| |
347 |
| |
348 |
| |
349 |
| |
350 |
| |
351 |
20
| public String getElementId(IFormComponent component)
|
352 |
| { |
353 |
20
| return getElementId(component, component.getId());
|
354 |
| } |
355 |
| |
356 |
| |
357 |
| |
358 |
| |
359 |
| |
360 |
| |
361 |
| |
362 |
| |
363 |
| |
364 |
| |
365 |
116
| public String getElementId(IFormComponent component, String baseId)
|
366 |
| { |
367 |
| |
368 |
| |
369 |
116
| String filteredId = TapestryUtils.convertTapestryIdToNMToken(baseId);
|
370 |
| |
371 |
116
| String result = _elementIdAllocator.allocateId(filteredId);
|
372 |
| |
373 |
116
| if (_rewinding)
|
374 |
| { |
375 |
53
| if (_allocatedIdIndex >= _allocatedIds.size())
|
376 |
| { |
377 |
1
| throw new StaleLinkException(FormMessages.formTooManyIds(_form, _allocatedIds
|
378 |
| .size(), component), component); |
379 |
| } |
380 |
| |
381 |
52
| String expected = (String) _allocatedIds.get(_allocatedIdIndex);
|
382 |
| |
383 |
52
| if (!result.equals(expected))
|
384 |
2
| throw new StaleLinkException(FormMessages.formIdMismatch(
|
385 |
| _form, |
386 |
| _allocatedIdIndex, |
387 |
| expected, |
388 |
| result, |
389 |
| component), component); |
390 |
| } |
391 |
| else |
392 |
| { |
393 |
63
| _allocatedIds.add(result);
|
394 |
| } |
395 |
| |
396 |
113
| _allocatedIdIndex++;
|
397 |
| |
398 |
113
| component.setName(result);
|
399 |
| |
400 |
113
| return result;
|
401 |
| } |
402 |
| |
403 |
154
| public boolean isRewinding()
|
404 |
| { |
405 |
154
| return _rewinding;
|
406 |
| } |
407 |
| |
408 |
92
| private void preallocateReservedIds()
|
409 |
| { |
410 |
92
| for (int i = 0; i < ServiceConstants.RESERVED_IDS.length; i++)
|
411 |
552
| _elementIdAllocator.allocateId(ServiceConstants.RESERVED_IDS[i]);
|
412 |
| } |
413 |
| |
414 |
| |
415 |
| |
416 |
| |
417 |
| |
418 |
| |
419 |
| |
420 |
| |
421 |
| |
422 |
| |
423 |
| |
424 |
34
| private void reinitializeIdAllocatorForRewind()
|
425 |
| { |
426 |
34
| String allocatedFormIds = _cycle.getParameter(FORM_IDS);
|
427 |
| |
428 |
34
| String[] ids = TapestryUtils.split(allocatedFormIds);
|
429 |
| |
430 |
34
| for (int i = 0; i < ids.length; i++)
|
431 |
57
| _allocatedIds.add(ids[i]);
|
432 |
| |
433 |
| |
434 |
| |
435 |
| |
436 |
34
| preallocateReservedIds();
|
437 |
| |
438 |
34
| String extraReservedIds = _cycle.getParameter(RESERVED_FORM_IDS);
|
439 |
| |
440 |
34
| ids = TapestryUtils.split(extraReservedIds);
|
441 |
| |
442 |
34
| for (int i = 0; i < ids.length; i++)
|
443 |
3
| _elementIdAllocator.allocateId(ids[i]);
|
444 |
| } |
445 |
| |
446 |
58
| public void render(String method, IRender informalParametersRenderer, ILink link, String scheme)
|
447 |
| { |
448 |
58
| String formId = _form.getName();
|
449 |
| |
450 |
58
| emitEventManagerInitialization(formId);
|
451 |
| |
452 |
| |
453 |
| |
454 |
| |
455 |
58
| addHiddenFieldsForLinkParameters(link);
|
456 |
| |
457 |
| |
458 |
| |
459 |
| |
460 |
58
| addHiddenValue(SUBMIT_MODE, null);
|
461 |
| |
462 |
58
| IMarkupWriter nested = _writer.getNestedWriter();
|
463 |
| |
464 |
58
| _form.renderBody(nested, _cycle);
|
465 |
| |
466 |
53
| runDeferredRunnables();
|
467 |
| |
468 |
53
| writeTag(_writer, method, link.getURL(scheme, null, 0, null, false));
|
469 |
| |
470 |
| |
471 |
53
| _writer.attribute("name", formId);
|
472 |
| |
473 |
| |
474 |
53
| _writer.attribute("id", formId);
|
475 |
| |
476 |
53
| if (_encodingType != null)
|
477 |
3
| _writer.attribute("enctype", _encodingType);
|
478 |
| |
479 |
| |
480 |
| |
481 |
53
| emitEventHandlers(formId);
|
482 |
| |
483 |
53
| informalParametersRenderer.render(_writer, _cycle);
|
484 |
| |
485 |
| |
486 |
| |
487 |
53
| _writer.println();
|
488 |
| |
489 |
53
| writeHiddenFields();
|
490 |
| |
491 |
| |
492 |
| |
493 |
53
| nested.close();
|
494 |
| |
495 |
| |
496 |
| |
497 |
53
| _writer.end();
|
498 |
| |
499 |
53
| String fieldId = _delegate.getFocusField();
|
500 |
| |
501 |
53
| if (fieldId == null || _pageRenderSupport == null)
|
502 |
42
| return;
|
503 |
| |
504 |
| |
505 |
| |
506 |
| |
507 |
11
| if (!_form.getFocus() || _cycle.getAttribute(FIELD_FOCUS_ATTRIBUTE) != null)
|
508 |
2
| return;
|
509 |
| |
510 |
9
| _pageRenderSupport.addInitializationScript("Tapestry.set_focus('" + fieldId + "');");
|
511 |
| |
512 |
9
| _cycle.setAttribute(FIELD_FOCUS_ATTRIBUTE, Boolean.TRUE);
|
513 |
| } |
514 |
| |
515 |
| |
516 |
| |
517 |
| |
518 |
| |
519 |
58
| protected void emitEventManagerInitialization(String formId)
|
520 |
| { |
521 |
58
| if (_pageRenderSupport == null)
|
522 |
8
| return;
|
523 |
| |
524 |
50
| _pageRenderSupport.addExternalScript(_script);
|
525 |
| |
526 |
50
| _pageRenderSupport.addInitializationScript("Tapestry.register_form('" + formId + "');");
|
527 |
| } |
528 |
| |
529 |
35
| public String rewind()
|
530 |
| { |
531 |
35
| _form.getDelegate().clear();
|
532 |
| |
533 |
35
| String mode = _cycle.getParameter(SUBMIT_MODE);
|
534 |
| |
535 |
| |
536 |
| |
537 |
35
| if (FormConstants.SUBMIT_CANCEL.equals(mode))
|
538 |
1
| return mode;
|
539 |
| |
540 |
34
| reinitializeIdAllocatorForRewind();
|
541 |
| |
542 |
34
| _form.renderBody(_writer, _cycle);
|
543 |
| |
544 |
30
| int expected = _allocatedIds.size();
|
545 |
| |
546 |
| |
547 |
| |
548 |
| |
549 |
| |
550 |
30
| if (_allocatedIdIndex < expected)
|
551 |
| { |
552 |
1
| String nextExpectedId = (String) _allocatedIds.get(_allocatedIdIndex);
|
553 |
| |
554 |
1
| throw new StaleLinkException(FormMessages.formTooFewIds(_form, expected
|
555 |
| - _allocatedIdIndex, nextExpectedId), _form); |
556 |
| } |
557 |
| |
558 |
29
| runDeferredRunnables();
|
559 |
| |
560 |
29
| if (_submitModes.contains(mode))
|
561 |
5
| return mode;
|
562 |
| |
563 |
| |
564 |
| |
565 |
| |
566 |
24
| return FormConstants.SUBMIT_NORMAL;
|
567 |
| |
568 |
| } |
569 |
| |
570 |
82
| private void runDeferredRunnables()
|
571 |
| { |
572 |
82
| Iterator i = _deferredRunnables.iterator();
|
573 |
82
| while (i.hasNext())
|
574 |
| { |
575 |
2
| Runnable r = (Runnable) i.next();
|
576 |
| |
577 |
2
| r.run();
|
578 |
| } |
579 |
| } |
580 |
| |
581 |
5
| public void setEncodingType(String encodingType)
|
582 |
| { |
583 |
| |
584 |
5
| if (_encodingType != null && !_encodingType.equals(encodingType))
|
585 |
1
| throw new ApplicationRuntimeException(FormMessages.encodingTypeContention(
|
586 |
| _form, |
587 |
| _encodingType, |
588 |
| encodingType), _form, null, null); |
589 |
| |
590 |
4
| _encodingType = encodingType;
|
591 |
| } |
592 |
| |
593 |
| |
594 |
| |
595 |
| |
596 |
285
| protected void writeHiddenField(IMarkupWriter writer, String name, String id, String value)
|
597 |
| { |
598 |
285
| writer.beginEmpty("input");
|
599 |
285
| writer.attribute("type", "hidden");
|
600 |
285
| writer.attribute("name", name);
|
601 |
| |
602 |
285
| if (HiveMind.isNonBlank(id))
|
603 |
2
| writer.attribute("id", id);
|
604 |
| |
605 |
285
| writer.attribute("value", value == null ? "" : value);
|
606 |
285
| writer.println();
|
607 |
| } |
608 |
| |
609 |
321
| private void writeHiddenField(String name, String id, String value)
|
610 |
| { |
611 |
321
| writeHiddenField(_writer, name, id, value);
|
612 |
| } |
613 |
| |
614 |
| |
615 |
| |
616 |
| |
617 |
| |
618 |
| |
619 |
| |
620 |
| |
621 |
47
| protected void writeHiddenFields()
|
622 |
| { |
623 |
47
| _writer.begin("div");
|
624 |
47
| _writer.attribute("style", "display:none;");
|
625 |
| |
626 |
47
| writeHiddenFieldList();
|
627 |
| |
628 |
47
| _writer.end();
|
629 |
| } |
630 |
| |
631 |
| |
632 |
| |
633 |
| |
634 |
| |
635 |
| |
636 |
53
| protected void writeHiddenFieldList()
|
637 |
| { |
638 |
53
| writeHiddenField(FORM_IDS, null, buildAllocatedIdList());
|
639 |
| |
640 |
53
| Iterator i = _hiddenValues.iterator();
|
641 |
53
| while (i.hasNext())
|
642 |
| { |
643 |
268
| HiddenFieldData data = (HiddenFieldData) i.next();
|
644 |
| |
645 |
268
| writeHiddenField(data.getName(), data.getId(), data.getValue());
|
646 |
| } |
647 |
| } |
648 |
| |
649 |
293
| private void addHiddenFieldsForLinkParameter(ILink link, String parameterName)
|
650 |
| { |
651 |
293
| String[] values = link.getParameterValues(parameterName);
|
652 |
| |
653 |
| |
654 |
| |
655 |
293
| if (values == null)
|
656 |
109
| return;
|
657 |
| |
658 |
184
| for (int i = 0; i < values.length; i++)
|
659 |
| { |
660 |
184
| addHiddenValue(parameterName, values[i]);
|
661 |
| } |
662 |
| } |
663 |
| |
664 |
47
| protected void writeTag(IMarkupWriter writer, String method, String url)
|
665 |
| { |
666 |
47
| writer.begin("form");
|
667 |
47
| writer.attribute("method", method);
|
668 |
47
| writer.attribute("action", url);
|
669 |
| } |
670 |
| |
671 |
0
| public void prerenderField(IMarkupWriter writer, IComponent field, Location location)
|
672 |
| { |
673 |
0
| Defense.notNull(writer, "writer");
|
674 |
0
| Defense.notNull(field, "field");
|
675 |
| |
676 |
0
| String key = field.getExtendedId();
|
677 |
| |
678 |
0
| if (_prerenderMap.containsKey(key))
|
679 |
0
| throw new ApplicationRuntimeException(FormMessages.fieldAlreadyPrerendered(field),
|
680 |
| location, null); |
681 |
| |
682 |
0
| NestedMarkupWriter nested = writer.getNestedWriter();
|
683 |
| |
684 |
0
| field.render(nested, _cycle);
|
685 |
| |
686 |
0
| _prerenderMap.put(key, nested.getBuffer());
|
687 |
| } |
688 |
| |
689 |
75
| public boolean wasPrerendered(IMarkupWriter writer, IComponent field)
|
690 |
| { |
691 |
75
| String key = field.getExtendedId();
|
692 |
| |
693 |
| |
694 |
| |
695 |
| |
696 |
75
| if (!_prerenderMap.containsKey(key))
|
697 |
75
| return false;
|
698 |
| |
699 |
0
| String buffer = (String) _prerenderMap.get(key);
|
700 |
| |
701 |
0
| writer.printRaw(buffer);
|
702 |
| |
703 |
0
| _prerenderMap.remove(key);
|
704 |
| |
705 |
0
| return true;
|
706 |
| } |
707 |
| |
708 |
2
| public void addDeferredRunnable(Runnable runnable)
|
709 |
| { |
710 |
2
| Defense.notNull(runnable, "runnable");
|
711 |
| |
712 |
2
| _deferredRunnables.add(runnable);
|
713 |
| } |
714 |
| |
715 |
0
| public void registerForFocus(IFormComponent field, int priority)
|
716 |
| { |
717 |
0
| _delegate.registerForFocus(field, priority);
|
718 |
| } |
719 |
| |
720 |
| } |