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+ */
25+package javax.swing.text.html;
26+
27+import java.net.*;
28+import java.io.*;
29+import java.awt.*;
30+import java.awt.event.*;
31+import java.util.*;
32+import javax.swing.*;
33+import javax.swing.event.*;
34+import 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+ */
107+public 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