History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/javax/swing/text/html/FormView.java (1 of 18352 files). Show all

Unified · Split

java/pkg/javax/swing/text/html/FormView.java+909−0
@@ -0,0 +1,909 @@
1/*
2 * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25package javax.swing.text.html;
26
27import java.net.*;
28import java.io.*;
29import java.awt.*;
30import java.awt.event.*;
31import java.util.*;
32import javax.swing.*;
33import javax.swing.event.*;
34import javax.swing.text.*;
35
36/**
37 * Component decorator that implements the view interface
38 * for form elements, <input>, <textarea>,
39 * and <select>. The model for the component is stored
40 * as an attribute of the the element (using StyleConstants.ModelAttribute),
41 * and is used to build the component of the view. The type
42 * of the model is assumed to of the type that would be set by
43 * <code>HTMLDocument.HTMLReader.FormAction</code>. If there are
44 * multiple views mapped over the document, they will share the
45 * embedded component models.
46 * <p>
47 * The following table shows what components get built
48 * by this view.
49 * <table summary="shows what components get built by this view">
50 * <tr>
51 * <th>Element Type</th>
52 * <th>Component built</th>
53 * </tr>
54 * <tr>
55 * <td>input, type button</td>
56 * <td>JButton</td>
57 * </tr>
58 * <tr>
59 * <td>input, type checkbox</td>
60 * <td>JCheckBox</td>
61 * </tr>
62 * <tr>
63 * <td>input, type image</td>
64 * <td>JButton</td>
65 * </tr>
66 * <tr>
67 * <td>input, type password</td>
68 * <td>JPasswordField</td>
69 * </tr>
70 * <tr>
71 * <td>input, type radio</td>
72 * <td>JRadioButton</td>
73 * </tr>
74 * <tr>
75 * <td>input, type reset</td>
76 * <td>JButton</td>
77 * </tr>
78 * <tr>
79 * <td>input, type submit</td>
80 * <td>JButton</td>
81 * </tr>
82 * <tr>
83 * <td>input, type text</td>
84 * <td>JTextField</td>
85 * </tr>
86 * <tr>
87 * <td>select, size &gt; 1 or multiple attribute defined</td>
88 * <td>JList in a JScrollPane</td>
89 * </tr>
90 * <tr>
91 * <td>select, size unspecified or 1</td>
92 * <td>JComboBox</td>
93 * </tr>
94 * <tr>
95 * <td>textarea</td>
96 * <td>JTextArea in a JScrollPane</td>
97 * </tr>
98 * <tr>
99 * <td>input, type file</td>
100 * <td>JTextField</td>
101 * </tr>
102 * </table>
103 *
104 * @author Timothy Prinzing
105 * @author Sunita Mani
106 */
107public class FormView extends ComponentView implements ActionListener {
108
109 /**
110 * If a value attribute is not specified for a FORM input element
111 * of type "submit", then this default string is used.
112 *
113 * @deprecated As of 1.3, value now comes from UIManager property
114 * FormView.submitButtonText
115 */
116 @Deprecated
117 public static final String SUBMIT = new String("Submit Query");
118 /**
119 * If a value attribute is not specified for a FORM input element
120 * of type "reset", then this default string is used.
121 *
122 * @deprecated As of 1.3, value comes from UIManager UIManager property
123 * FormView.resetButtonText
124 */
125 @Deprecated
126 public static final String RESET = new String("Reset");
127
128 /**
129 * Document attribute name for storing POST data. JEditorPane.getPostData()
130 * uses the same name, should be kept in sync.
131 */
132 final static String PostDataProperty = "javax.swing.JEditorPane.postdata";
133
134 /**
135 * Used to indicate if the maximum span should be the same as the
136 * preferred span. This is used so that the Component's size doesn't
137 * change if there is extra room on a line. The first bit is used for
138 * the X direction, and the second for the y direction.
139 */
140 private short maxIsPreferred;
141
142 /**
143 * Creates a new FormView object.
144 *
145 * @param elem the element to decorate
146 */
147 public FormView(Element elem) {
148 super(elem);
149 }
150
151 /**
152 * Create the component. This is basically a
153 * big switch statement based upon the tag type
154 * and html attributes of the associated element.
155 */
156 protected Component createComponent() {
157 AttributeSet attr = getElement().getAttributes();
158 HTML.Tag t = (HTML.Tag)
159 attr.getAttribute(StyleConstants.NameAttribute);
160 JComponent c = null;
161 Object model = attr.getAttribute(StyleConstants.ModelAttribute);
162 if (t == HTML.Tag.INPUT) {
163 c = createInputComponent(attr, model);
164 } else if (t == HTML.Tag.SELECT) {
165
166 if (model instanceof OptionListModel) {
167
168 JList list = new JList((ListModel) model);
169 int size = HTML.getIntegerAttributeValue(attr,
170 HTML.Attribute.SIZE,
171 1);
172 list.setVisibleRowCount(size);
173 list.setSelectionModel((ListSelectionModel)model);
174 c = new JScrollPane(list);
175 } else {
176 c = new JComboBox((ComboBoxModel) model);
177 maxIsPreferred = 3;
178 }
179 } else if (t == HTML.Tag.TEXTAREA) {
180 JTextArea area = new JTextArea((Document) model);
181 int rows = HTML.getIntegerAttributeValue(attr,
182 HTML.Attribute.ROWS,
183 1);
184 area.setRows(rows);
185 int cols = HTML.getIntegerAttributeValue(attr,
186 HTML.Attribute.COLS,
187 20);
188 maxIsPreferred = 3;
189 area.setColumns(cols);
190 c = new JScrollPane(area,
191 JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
192 JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
193 }
194
195 if (c != null) {
196 c.setAlignmentY(1.0f);
197 }
198 return c;
199 }
200
201
202 /**
203 * Creates a component for an &lt;INPUT&gt; element based on the
204 * value of the "type" attribute.
205 *
206 * @param set of attributes associated with the &lt;INPUT&gt; element.
207 * @param model the value of the StyleConstants.ModelAttribute
208 * @return the component.
209 */
210 private JComponent createInputComponent(AttributeSet attr, Object model) {
211 JComponent c = null;
212 String type = (String) attr.getAttribute(HTML.Attribute.TYPE);
213
214 if (type.equals("submit") || type.equals("reset")) {
215 String value = (String)
216 attr.getAttribute(HTML.Attribute.VALUE);
217 if (value == null) {
218 if (type.equals("submit")) {
219 value = UIManager.getString("FormView.submitButtonText");
220 } else {
221 value = UIManager.getString("FormView.resetButtonText");
222 }
223 }
224 JButton button = new JButton(value);
225 if (model != null) {
226 button.setModel((ButtonModel)model);
227 button.addActionListener(this);
228 }
229 c = button;
230 maxIsPreferred = 3;
231 } else if (type.equals("image")) {
232 String srcAtt = (String) attr.getAttribute(HTML.Attribute.SRC);
233 JButton button;
234 try {
235 URL base = ((HTMLDocument)getElement().getDocument()).getBase();
236 URL srcURL = new URL(base, srcAtt);
237 Icon icon = new ImageIcon(srcURL);
238 button = new JButton(icon);
239 } catch (MalformedURLException e) {
240 button = new JButton(srcAtt);
241 }
242 if (model != null) {
243 button.setModel((ButtonModel)model);
244 button.addMouseListener(new MouseEventListener());
245 }
246 c = button;
247 maxIsPreferred = 3;
248 } else if (type.equals("checkbox")) {
249 c = new JCheckBox();
250 if (model != null) {
251 ((JCheckBox)c).setModel((JToggleButton.ToggleButtonModel) model);
252 }
253 maxIsPreferred = 3;
254 } else if (type.equals("radio")) {
255 c = new JRadioButton();
256 if (model != null) {
257 ((JRadioButton)c).setModel((JToggleButton.ToggleButtonModel)model);
258 }
259 maxIsPreferred = 3;
260 } else if (type.equals("text")) {
261 int size = HTML.getIntegerAttributeValue(attr,
262 HTML.Attribute.SIZE,
263 -1);
264 JTextField field;
265 if (size > 0) {
266 field = new JTextField();
267 field.setColumns(size);
268 }
269 else {
270 field = new JTextField();
271 field.setColumns(20);
272 }
273 c = field;
274 if (model != null) {
275 field.setDocument((Document) model);
276 }
277 field.addActionListener(this);
278 maxIsPreferred = 3;
279 } else if (type.equals("password")) {
280 JPasswordField field = new JPasswordField();
281 c = field;
282 if (model != null) {
283 field.setDocument((Document) model);
284 }
285 int size = HTML.getIntegerAttributeValue(attr,
286 HTML.Attribute.SIZE,
287 -1);
288 field.setColumns((size > 0) ? size : 20);
289 field.addActionListener(this);
290 maxIsPreferred = 3;
291 } else if (type.equals("file")) {
292 JTextField field = new JTextField();
293 if (model != null) {
294 field.setDocument((Document)model);
295 }
296 int size = HTML.getIntegerAttributeValue(attr, HTML.Attribute.SIZE,
297 -1);
298 field.setColumns((size > 0) ? size : 20);
299 JButton browseButton = new JButton(UIManager.getString
300 ("FormView.browseFileButtonText"));
301 Box box = Box.createHorizontalBox();
302 box.add(field);
303 box.add(Box.createHorizontalStrut(5));
304 box.add(browseButton);
305 browseButton.addActionListener(new BrowseFileAction(
306 attr, (Document)model));
307 c = box;
308 maxIsPreferred = 3;
309 }
310 return c;
311 }
312
313
314 /**
315 * Determines the maximum span for this view along an
316 * axis. For certain components, the maximum and preferred span are the
317 * same. For others this will return the value
318 * returned by Component.getMaximumSize along the
319 * axis of interest.
320 *
321 * @param axis may be either View.X_AXIS or View.Y_AXIS
322 * @return the span the view would like to be rendered into >= 0.
323 * Typically the view is told to render into the span
324 * that is returned, although there is no guarantee.
325 * The parent may choose to resize or break the view.
326 * @exception IllegalArgumentException for an invalid axis
327 */
328 public float getMaximumSpan(int axis) {
329 switch (axis) {
330 case View.X_AXIS:
331 if ((maxIsPreferred & 1) == 1) {
332 super.getMaximumSpan(axis);
333 return getPreferredSpan(axis);
334 }
335 return super.getMaximumSpan(axis);
336 case View.Y_AXIS:
337 if ((maxIsPreferred & 2) == 2) {
338 super.getMaximumSpan(axis);
339 return getPreferredSpan(axis);
340 }
341 return super.getMaximumSpan(axis);
342 default:
343 break;
344 }
345 return super.getMaximumSpan(axis);
346 }
347
348
349 /**
350 * Responsible for processeing the ActionEvent.
351 * If the element associated with the FormView,
352 * has a type of "submit", "reset", "text" or "password"
353 * then the action is processed. In the case of a "submit"
354 * the form is submitted. In the case of a "reset"
355 * the form is reset to its original state.
356 * In the case of "text" or "password", if the
357 * element is the last one of type "text" or "password",
358 * the form is submitted. Otherwise, focus is transferred
359 * to the next component in the form.
360 *
361 * @param evt the ActionEvent.
362 */
363 public void actionPerformed(ActionEvent evt) {
364 Element element = getElement();
365 StringBuilder dataBuffer = new StringBuilder();
366 HTMLDocument doc = (HTMLDocument)getDocument();
367 AttributeSet attr = element.getAttributes();
368
369 String type = (String) attr.getAttribute(HTML.Attribute.TYPE);
370
371 if (type.equals("submit")) {
372 getFormData(dataBuffer);
373 submitData(dataBuffer.toString());
374 } else if (type.equals("reset")) {
375 resetForm();
376 } else if (type.equals("text") || type.equals("password")) {
377 if (isLastTextOrPasswordField()) {
378 getFormData(dataBuffer);
379 submitData(dataBuffer.toString());
380 } else {
381 getComponent().transferFocus();
382 }
383 }
384 }
385
386
387 /**
388 * This method is responsible for submitting the form data.
389 * A thread is forked to undertake the submission.
390 */
391 protected void submitData(String data) {
392 Element form = getFormElement();
393 AttributeSet attrs = form.getAttributes();
394 HTMLDocument doc = (HTMLDocument) form.getDocument();
395 URL base = doc.getBase();
396
397 String target = (String) attrs.getAttribute(HTML.Attribute.TARGET);
398 if (target == null) {
399 target = "_self";
400 }
401
402 String method = (String) attrs.getAttribute(HTML.Attribute.METHOD);
403 if (method == null) {
404 method = "GET";
405 }
406 method = method.toLowerCase();
407 boolean isPostMethod = method.equals("post");
408 if (isPostMethod) {
409 storePostData(doc, target, data);
410 }
411
412 String action = (String) attrs.getAttribute(HTML.Attribute.ACTION);
413 URL actionURL;
414 try {
415 actionURL = (action == null)
416 ? new URL(base.getProtocol(), base.getHost(),
417 base.getPort(), base.getFile())
418 : new URL(base, action);
419 if (!isPostMethod) {
420 String query = data.toString();
421 actionURL = new URL(actionURL + "?" + query);
422 }
423 } catch (MalformedURLException e) {
424 actionURL = null;
425 }
426 final JEditorPane c = (JEditorPane) getContainer();
427 HTMLEditorKit kit = (HTMLEditorKit) c.getEditorKit();
428
429 FormSubmitEvent formEvent = null;
430 if (!kit.isAutoFormSubmission() || doc.isFrameDocument()) {
431 FormSubmitEvent.MethodType methodType = isPostMethod
432 ? FormSubmitEvent.MethodType.POST
433 : FormSubmitEvent.MethodType.GET;
434 formEvent = new FormSubmitEvent(
435 FormView.this, HyperlinkEvent.EventType.ACTIVATED,
436 actionURL, form, target, methodType, data);
437
438 }
439 // setPage() may take significant time so schedule it to run later.
440 final FormSubmitEvent fse = formEvent;
441 final URL url = actionURL;
442 SwingUtilities.invokeLater(new Runnable() {
443 public void run() {
444 if (fse != null) {
445 c.fireHyperlinkUpdate(fse);
446 } else {
447 try {
448 c.setPage(url);
449 } catch (IOException e) {
450 UIManager.getLookAndFeel().provideErrorFeedback(c);
451 }
452 }
453 }
454 });
455 }
456
457 private void storePostData(HTMLDocument doc, String target, String data) {
458
459 /* POST data is stored into the document property named by constant
460 * PostDataProperty from where it is later retrieved by method
461 * JEditorPane.getPostData(). If the current document is in a frame,
462 * the data is initially put into the toplevel (frameset) document
463 * property (named <PostDataProperty>.<Target frame name>). It is the
464 * responsibility of FrameView which updates the target frame
465 * to move data from the frameset document property into the frame
466 * document property.
467 */
468
469 Document propDoc = doc;
470 String propName = PostDataProperty;
471
472 if (doc.isFrameDocument()) {
473 // find the top-most JEditorPane holding the frameset view.
474 FrameView.FrameEditorPane p =
475 (FrameView.FrameEditorPane) getContainer();
476 FrameView v = p.getFrameView();
477 JEditorPane c = v.getOutermostJEditorPane();
478 if (c != null) {
479 propDoc = c.getDocument();
480 propName += ("." + target);
481 }
482 }
483
484 propDoc.putProperty(propName, data);
485 }
486
487 /**
488 * MouseEventListener class to handle form submissions when
489 * an input with type equal to image is clicked on.
490 * A MouseListener is necessary since along with the image
491 * data the coordinates associated with the mouse click
492 * need to be submitted.
493 */
494 protected class MouseEventListener extends MouseAdapter {
495
496 public void mouseReleased(MouseEvent evt) {
497 String imageData = getImageData(evt.getPoint());
498 imageSubmit(imageData);
499 }
500 }
501
502 /**
503 * This method is called to submit a form in response
504 * to a click on an image -- an &lt;INPUT&gt; form
505 * element of type "image".
506 *
507 * @param imageData the mouse click coordinates.
508 */
509 protected void imageSubmit(String imageData) {
510
511 StringBuilder dataBuffer = new StringBuilder();
512 Element elem = getElement();
513 HTMLDocument hdoc = (HTMLDocument)elem.getDocument();
514 getFormData(dataBuffer);
515 if (dataBuffer.length() > 0) {
516 dataBuffer.append('&');
517 }
518 dataBuffer.append(imageData);
519 submitData(dataBuffer.toString());
520 return;
521 }
522
523 /**
524 * Extracts the value of the name attribute
525 * associated with the input element of type
526 * image. If name is defined it is encoded using
527 * the URLEncoder.encode() method and the
528 * image data is returned in the following format:
529 * name + ".x" +"="+ x +"&"+ name +".y"+"="+ y
530 * otherwise,
531 * "x="+ x +"&y="+ y
532 *
533 * @param point associated with the mouse click.
534 * @return the image data.
535 */
536 private String getImageData(Point point) {
537
538 String mouseCoords = point.x + ":" + point.y;
539 int sep = mouseCoords.indexOf(':');
540 String x = mouseCoords.substring(0, sep);
541 String y = mouseCoords.substring(++sep);
542 String name = (String) getElement().getAttributes().getAttribute(HTML.Attribute.NAME);
543
544 String data;
545 if (name == null || name.equals("")) {
546 data = "x="+ x +"&y="+ y;
547 } else {
548 name = URLEncoder.encode(name);
549 data = name + ".x" +"="+ x +"&"+ name +".y"+"="+ y;
550 }
551 return data;
552 }
553
554
555 /**
556 * The following methods provide functionality required to
557 * iterate over a the elements of the form and in the case
558 * of a form submission, extract the data from each model
559 * that is associated with each form element, and in the
560 * case of reset, reinitialize the each model to its
561 * initial state.
562 */
563
564
565 /**
566 * Returns the Element representing the <code>FORM</code>.
567 */
568 private Element getFormElement() {
569 Element elem = getElement();
570 while (elem != null) {
571 if (elem.getAttributes().getAttribute
572 (StyleConstants.NameAttribute) == HTML.Tag.FORM) {
573 return elem;
574 }
575 elem = elem.getParentElement();
576 }
577 return null;
578 }
579
580 /**
581 * Iterates over the
582 * element hierarchy, extracting data from the
583 * models associated with the relevant form elements.
584 * "Relevant" means the form elements that are part
585 * of the same form whose element triggered the submit
586 * action.
587 *
588 * @param buffer the buffer that contains that data to submit
589 * @param targetElement the element that triggered the
590 * form submission
591 */
592 private void getFormData(StringBuilder buffer) {
593 Element formE = getFormElement();
594 if (formE != null) {
595 ElementIterator it = new ElementIterator(formE);
596 Element next;
597
598 while ((next = it.next()) != null) {
599 if (isControl(next)) {
600 String type = (String)next.getAttributes().getAttribute
601 (HTML.Attribute.TYPE);
602
603 if (type != null && type.equals("submit") &&
604 next != getElement()) {
605 // do nothing - this submit isnt the trigger
606 } else if (type == null || !type.equals("image")) {
607 // images only result in data if they triggered
608 // the submit and they require that the mouse click
609 // coords be appended to the data. Hence its
610 // processing is handled by the view.
611 loadElementDataIntoBuffer(next, buffer);
612 }
613 }
614 }
615 }
616 }
617
618 /**
619 * Loads the data
620 * associated with the element into the buffer.
621 * The format in which data is appended depends
622 * on the type of the form element. Essentially
623 * data is loaded in name/value pairs.
624 *
625 */
626 private void loadElementDataIntoBuffer(Element elem, StringBuilder buffer) {
627
628 AttributeSet attr = elem.getAttributes();
629 String name = (String)attr.getAttribute(HTML.Attribute.NAME);
630 if (name == null) {
631 return;
632 }
633 String value = null;
634 HTML.Tag tag = (HTML.Tag)elem.getAttributes().getAttribute
635 (StyleConstants.NameAttribute);
636
637 if (tag == HTML.Tag.INPUT) {
638 value = getInputElementData(attr);
639 } else if (tag == HTML.Tag.TEXTAREA) {
640 value = getTextAreaData(attr);
641 } else if (tag == HTML.Tag.SELECT) {
642 loadSelectData(attr, buffer);
643 }
644
645 if (name != null && value != null) {
646 appendBuffer(buffer, name, value);
647 }
648 }
649
650
651 /**
652 * Returns the data associated with an &lt;INPUT&gt; form
653 * element. The value of "type" attributes is
654 * used to determine the type of the model associated
655 * with the element and then the relevant data is
656 * extracted.
657 */
658 private String getInputElementData(AttributeSet attr) {
659
660 Object model = attr.getAttribute(StyleConstants.ModelAttribute);
661 String type = (String) attr.getAttribute(HTML.Attribute.TYPE);
662 String value = null;
663
664 if (type.equals("text") || type.equals("password")) {
665 Document doc = (Document)model;
666 try {
667 value = doc.getText(0, doc.getLength());
668 } catch (BadLocationException e) {
669 value = null;
670 }
671 } else if (type.equals("submit") || type.equals("hidden")) {
672 value = (String) attr.getAttribute(HTML.Attribute.VALUE);
673 if (value == null) {
674 value = "";
675 }
676 } else if (type.equals("radio") || type.equals("checkbox")) {
677 ButtonModel m = (ButtonModel)model;
678 if (m.isSelected()) {
679 value = (String) attr.getAttribute(HTML.Attribute.VALUE);
680 if (value == null) {
681 value = "on";
682 }
683 }
684 } else if (type.equals("file")) {
685 Document doc = (Document)model;
686 String path;
687
688 try {
689 path = doc.getText(0, doc.getLength());
690 } catch (BadLocationException e) {
691 path = null;
692 }
693 if (path != null && path.length() > 0) {
694 value = path;
695 }
696 }
697 return value;
698 }
699
700 /**
701 * Returns the data associated with the &lt;TEXTAREA&gt; form
702 * element. This is done by getting the text stored in the
703 * Document model.
704 */
705 private String getTextAreaData(AttributeSet attr) {
706 Document doc = (Document)attr.getAttribute(StyleConstants.ModelAttribute);
707 try {
708 return doc.getText(0, doc.getLength());
709 } catch (BadLocationException e) {
710 return null;
711 }
712 }
713
714
715 /**
716 * Loads the buffer with the data associated with the Select
717 * form element. Basically, only items that are selected
718 * and have their name attribute set are added to the buffer.
719 */
720 private void loadSelectData(AttributeSet attr, StringBuilder buffer) {
721
722 String name = (String)attr.getAttribute(HTML.Attribute.NAME);
723 if (name == null) {
724 return;
725 }
726 Object m = attr.getAttribute(StyleConstants.ModelAttribute);
727 if (m instanceof OptionListModel) {
728 OptionListModel model = (OptionListModel)m;
729
730 for (int i = 0; i < model.getSize(); i++) {
731 if (model.isSelectedIndex(i)) {
732 Option option = (Option) model.getElementAt(i);
733 appendBuffer(buffer, name, option.getValue());
734 }
735 }
736 } else if (m instanceof ComboBoxModel) {
737 ComboBoxModel model = (ComboBoxModel)m;
738 Option option = (Option)model.getSelectedItem();
739 if (option != null) {
740 appendBuffer(buffer, name, option.getValue());
741 }
742 }
743 }
744
745 /**
746 * Appends name / value pairs into the
747 * buffer. Both names and values are encoded using the
748 * URLEncoder.encode() method before being added to the
749 * buffer.
750 */
751 private void appendBuffer(StringBuilder buffer, String name, String value) {
752 if (buffer.length() > 0) {
753 buffer.append('&');
754 }
755 String encodedName = URLEncoder.encode(name);
756 buffer.append(encodedName);
757 buffer.append('=');
758 String encodedValue = URLEncoder.encode(value);
759 buffer.append(encodedValue);
760 }
761
762 /**
763 * Returns true if the Element <code>elem</code> represents a control.
764 */
765 private boolean isControl(Element elem) {
766 return elem.isLeaf();
767 }
768
769 /**
770 * Iterates over the element hierarchy to determine if
771 * the element parameter, which is assumed to be an
772 * &lt;INPUT&gt; element of type password or text, is the last
773 * one of either kind, in the form to which it belongs.
774 */
775 boolean isLastTextOrPasswordField() {
776 Element parent = getFormElement();
777 Element elem = getElement();
778
779 if (parent != null) {
780 ElementIterator it = new ElementIterator(parent);
781 Element next;
782 boolean found = false;
783
784 while ((next = it.next()) != null) {
785 if (next == elem) {
786 found = true;
787 }
788 else if (found && isControl(next)) {
789 AttributeSet elemAttr = next.getAttributes();
790
791 if (HTMLDocument.matchNameAttribute
792 (elemAttr, HTML.Tag.INPUT)) {
793 String type = (String)elemAttr.getAttribute
794 (HTML.Attribute.TYPE);
795
796 if ("text".equals(type) || "password".equals(type)) {
797 return false;
798 }
799 }
800 }
801 }
802 }
803 return true;
804 }
805
806 /**
807 * Resets the form
808 * to its initial state by reinitializing the models
809 * associated with each form element to their initial
810 * values.
811 *
812 * param elem the element that triggered the reset
813 */
814 void resetForm() {
815 Element parent = getFormElement();
816
817 if (parent != null) {
818 ElementIterator it = new ElementIterator(parent);
819 Element next;
820
821 while((next = it.next()) != null) {
822 if (isControl(next)) {
823 AttributeSet elemAttr = next.getAttributes();
824 Object m = elemAttr.getAttribute(StyleConstants.
825 ModelAttribute);
826 if (m instanceof TextAreaDocument) {
827 TextAreaDocument doc = (TextAreaDocument)m;
828 doc.reset();
829 } else if (m instanceof PlainDocument) {
830 try {
831 PlainDocument doc = (PlainDocument)m;
832 doc.remove(0, doc.getLength());
833 if (HTMLDocument.matchNameAttribute
834 (elemAttr, HTML.Tag.INPUT)) {
835 String value = (String)elemAttr.
836 getAttribute(HTML.Attribute.VALUE);
837 if (value != null) {
838 doc.insertString(0, value, null);
839 }
840 }
841 } catch (BadLocationException e) {
842 }
843 } else if (m instanceof OptionListModel) {
844 OptionListModel model = (OptionListModel) m;
845 int size = model.getSize();
846 for (int i = 0; i < size; i++) {
847 model.removeIndexInterval(i, i);
848 }
849 BitSet selectionRange = model.getInitialSelection();
850 for (int i = 0; i < selectionRange.size(); i++) {
851 if (selectionRange.get(i)) {
852 model.addSelectionInterval(i, i);
853 }
854 }
855 } else if (m instanceof OptionComboBoxModel) {
856 OptionComboBoxModel model = (OptionComboBoxModel) m;
857 Option option = model.getInitialSelection();
858 if (option != null) {
859 model.setSelectedItem(option);
860 }
861 } else if (m instanceof JToggleButton.ToggleButtonModel) {
862 boolean checked = ((String)elemAttr.getAttribute
863 (HTML.Attribute.CHECKED) != null);
864 JToggleButton.ToggleButtonModel model =
865 (JToggleButton.ToggleButtonModel)m;
866 model.setSelected(checked);
867 }
868 }
869 }
870 }
871 }
872
873
874 /**
875 * BrowseFileAction is used for input type == file. When the user
876 * clicks the button a JFileChooser is brought up allowing the user
877 * to select a file in the file system. The resulting path to the selected
878 * file is set in the text field (actually an instance of Document).
879 */
880 private class BrowseFileAction implements ActionListener {
881 private AttributeSet attrs;
882 private Document model;
883
884 BrowseFileAction(AttributeSet attrs, Document model) {
885 this.attrs = attrs;
886 this.model = model;
887 }
888
889 public void actionPerformed(ActionEvent ae) {
890 // PENDING: When mime support is added to JFileChooser use the
891 // accept value of attrs.
892 JFileChooser fc = new JFileChooser();
893 fc.setMultiSelectionEnabled(false);
894 if (fc.showOpenDialog(getContainer()) ==
895 JFileChooser.APPROVE_OPTION) {
896 File selected = fc.getSelectedFile();
897
898 if (selected != null) {
899 try {
900 if (model.getLength() > 0) {
901 model.remove(0, model.getLength());
902 }
903 model.insertString(0, selected.getPath(), null);
904 } catch (BadLocationException ble) {}
905 }
906 }
907 }
908 }
909}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t