|
Java example source code file (FormView.java)
The FormView.java Java example source code/* * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package javax.swing.text.html; import java.net.*; import java.io.*; import java.awt.*; import java.awt.event.*; import java.util.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.text.*; /** * Component decorator that implements the view interface * for form elements, <input>, <textarea>, * and <select>. The model for the component is stored * as an attribute of the the element (using StyleConstants.ModelAttribute), * and is used to build the component of the view. The type * of the model is assumed to of the type that would be set by * <code>HTMLDocument.HTMLReader.FormAction. If there are * multiple views mapped over the document, they will share the * embedded component models. * <p> * The following table shows what components get built * by this view. * <table summary="shows what components get built by this view"> * <tr> * <th>Element Type * <th>Component built * </tr> * <tr> * <td>input, type button |
* <td>JButton
* </tr>
* <tr>
* <td>input, type checkbox
* <td>JCheckBox
* </tr>
* <tr>
* <td>input, type image
* <td>JButton
* </tr>
* <tr>
* <td>input, type password
* <td>JPasswordField
* </tr>
* <tr>
* <td>input, type radio
* <td>JRadioButton
* </tr>
* <tr>
* <td>input, type reset
* <td>JButton
* </tr>
* <tr>
* <td>input, type submit
* <td>JButton
* </tr>
* <tr>
* <td>input, type text
* <td>JTextField
* </tr>
* <tr>
* <td>select, size > 1 or multiple attribute defined
* <td>JList in a JScrollPane
* </tr>
* <tr>
* <td>select, size unspecified or 1
* <td>JComboBox
* </tr>
* <tr>
* <td>textarea
* <td>JTextArea in a JScrollPane
* </tr>
* <tr>
* <td>input, type file
* <td>JTextField
* </tr>
* </table>
*
* @author Timothy Prinzing
* @author Sunita Mani
*/
public class FormView extends ComponentView implements ActionListener {
/**
* If a value attribute is not specified for a FORM input element
* of type "submit", then this default string is used.
*
* @deprecated As of 1.3, value now comes from UIManager property
* FormView.submitButtonText
*/
@Deprecated
public static final String SUBMIT = new String("Submit Query");
/**
* If a value attribute is not specified for a FORM input element
* of type "reset", then this default string is used.
*
* @deprecated As of 1.3, value comes from UIManager UIManager property
* FormView.resetButtonText
*/
@Deprecated
public static final String RESET = new String("Reset");
/**
* Document attribute name for storing POST data. JEditorPane.getPostData()
* uses the same name, should be kept in sync.
*/
final static String PostDataProperty = "javax.swing.JEditorPane.postdata";
/**
* Used to indicate if the maximum span should be the same as the
* preferred span. This is used so that the Component's size doesn't
* change if there is extra room on a line. The first bit is used for
* the X direction, and the second for the y direction.
*/
private short maxIsPreferred;
/**
* Creates a new FormView object.
*
* @param elem the element to decorate
*/
public FormView(Element elem) {
super(elem);
}
/**
* Create the component. This is basically a
* big switch statement based upon the tag type
* and html attributes of the associated element.
*/
protected Component createComponent() {
AttributeSet attr = getElement().getAttributes();
HTML.Tag t = (HTML.Tag)
attr.getAttribute(StyleConstants.NameAttribute);
JComponent c = null;
Object model = attr.getAttribute(StyleConstants.ModelAttribute);
// Remove listeners previously registered in shared model
// when a new UI component is replaced. See bug 7189299.
removeStaleListenerForModel(model);
if (t == HTML.Tag.INPUT) {
c = createInputComponent(attr, model);
} else if (t == HTML.Tag.SELECT) {
if (model instanceof OptionListModel) {
JList list = new JList((ListModel) model);
int size = HTML.getIntegerAttributeValue(attr,
HTML.Attribute.SIZE,
1);
list.setVisibleRowCount(size);
list.setSelectionModel((ListSelectionModel)model);
c = new JScrollPane(list);
} else {
c = new JComboBox((ComboBoxModel) model);
maxIsPreferred = 3;
}
} else if (t == HTML.Tag.TEXTAREA) {
JTextArea area = new JTextArea((Document) model);
int rows = HTML.getIntegerAttributeValue(attr,
HTML.Attribute.ROWS,
1);
area.setRows(rows);
int cols = HTML.getIntegerAttributeValue(attr,
HTML.Attribute.COLS,
20);
maxIsPreferred = 3;
area.setColumns(cols);
c = new JScrollPane(area,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
}
if (c != null) {
c.setAlignmentY(1.0f);
}
return c;
}
/**
* Creates a component for an <INPUT> element based on the
* value of the "type" attribute.
*
* @param set of attributes associated with the <INPUT> element.
* @param model the value of the StyleConstants.ModelAttribute
* @return the component.
*/
private JComponent createInputComponent(AttributeSet attr, Object model) {
JComponent c = null;
String type = (String) attr.getAttribute(HTML.Attribute.TYPE);
if (type.equals("submit") || type.equals("reset")) {
String value = (String)
attr.getAttribute(HTML.Attribute.VALUE);
if (value == null) {
if (type.equals("submit")) {
value = UIManager.getString("FormView.submitButtonText");
} else {
value = UIManager.getString("FormView.resetButtonText");
}
}
JButton button = new JButton(value);
if (model != null) {
button.setModel((ButtonModel)model);
button.addActionListener(this);
}
c = button;
maxIsPreferred = 3;
} else if (type.equals("image")) {
String srcAtt = (String) attr.getAttribute(HTML.Attribute.SRC);
JButton button;
try {
URL base = ((HTMLDocument)getElement().getDocument()).getBase();
URL srcURL = new URL(base, srcAtt);
Icon icon = new ImageIcon(srcURL);
button = new JButton(icon);
} catch (MalformedURLException e) {
button = new JButton(srcAtt);
}
if (model != null) {
button.setModel((ButtonModel)model);
button.addMouseListener(new MouseEventListener());
}
c = button;
maxIsPreferred = 3;
} else if (type.equals("checkbox")) {
c = new JCheckBox();
if (model != null) {
((JCheckBox)c).setModel((JToggleButton.ToggleButtonModel) model);
}
maxIsPreferred = 3;
} else if (type.equals("radio")) {
c = new JRadioButton();
if (model != null) {
((JRadioButton)c).setModel((JToggleButton.ToggleButtonModel)model);
}
maxIsPreferred = 3;
} else if (type.equals("text")) {
int size = HTML.getIntegerAttributeValue(attr,
HTML.Attribute.SIZE,
-1);
JTextField field;
if (size > 0) {
field = new JTextField();
field.setColumns(size);
}
else {
field = new JTextField();
field.setColumns(20);
}
c = field;
if (model != null) {
field.setDocument((Document) model);
}
field.addActionListener(this);
maxIsPreferred = 3;
} else if (type.equals("password")) {
JPasswordField field = new JPasswordField();
c = field;
if (model != null) {
field.setDocument((Document) model);
}
int size = HTML.getIntegerAttributeValue(attr,
HTML.Attribute.SIZE,
-1);
field.setColumns((size > 0) ? size : 20);
field.addActionListener(this);
maxIsPreferred = 3;
} else if (type.equals("file")) {
JTextField field = new JTextField();
if (model != null) {
field.setDocument((Document)model);
}
int size = HTML.getIntegerAttributeValue(attr, HTML.Attribute.SIZE,
-1);
field.setColumns((size > 0) ? size : 20);
JButton browseButton = new JButton(UIManager.getString
("FormView.browseFileButtonText"));
Box box = Box.createHorizontalBox();
box.add(field);
box.add(Box.createHorizontalStrut(5));
box.add(browseButton);
browseButton.addActionListener(new BrowseFileAction(
attr, (Document)model));
c = box;
maxIsPreferred = 3;
}
return c;
}
private void removeStaleListenerForModel(Object model) {
if (model instanceof DefaultButtonModel) {
// case of JButton whose model is DefaultButtonModel
// Need to remove stale ActionListener, ChangeListener and
// ItemListener that are instance of AbstractButton$Handler.
DefaultButtonModel buttonModel = (DefaultButtonModel) model;
String listenerClass = "javax.swing.AbstractButton$Handler";
for (ActionListener listener : buttonModel.getActionListeners()) {
if (listenerClass.equals(listener.getClass().getName())) {
buttonModel.removeActionListener(listener);
}
}
for (ChangeListener listener : buttonModel.getChangeListeners()) {
if (listenerClass.equals(listener.getClass().getName())) {
buttonModel.removeChangeListener(listener);
}
}
for (ItemListener listener : buttonModel.getItemListeners()) {
if (listenerClass.equals(listener.getClass().getName())) {
buttonModel.removeItemListener(listener);
}
}
} else if (model instanceof AbstractListModel) {
// case of JComboBox and JList
// For JList, the stale ListDataListener is instance
// BasicListUI$Handler.
// For JComboBox, there are 2 stale ListDataListeners, which are
// BasicListUI$Handler and BasicComboBoxUI$Handler.
AbstractListModel listModel = (AbstractListModel) model;
String listenerClass1 =
"javax.swing.plaf.basic.BasicListUI$Handler";
String listenerClass2 =
"javax.swing.plaf.basic.BasicComboBoxUI$Handler";
for (ListDataListener listener : listModel.getListDataListeners()) {
if (listenerClass1.equals(listener.getClass().getName())
|| listenerClass2.equals(listener.getClass().getName()))
{
listModel.removeListDataListener(listener);
}
}
} else if (model instanceof AbstractDocument) {
// case of JPasswordField, JTextField and JTextArea
// All have 2 stale DocumentListeners.
String listenerClass1 =
"javax.swing.plaf.basic.BasicTextUI$UpdateHandler";
String listenerClass2 =
"javax.swing.text.DefaultCaret$Handler";
AbstractDocument docModel = (AbstractDocument) model;
for (DocumentListener listener : docModel.getDocumentListeners()) {
if (listenerClass1.equals(listener.getClass().getName())
|| listenerClass2.equals(listener.getClass().getName()))
{
docModel.removeDocumentListener(listener);
}
}
}
}
/**
* Determines the maximum span for this view along an
* axis. For certain components, the maximum and preferred span are the
* same. For others this will return the value
* returned by Component.getMaximumSize along the
* axis of interest.
*
* @param axis may be either View.X_AXIS or View.Y_AXIS
* @return the span the view would like to be rendered into >= 0.
* Typically the view is told to render into the span
* that is returned, although there is no guarantee.
* The parent may choose to resize or break the view.
* @exception IllegalArgumentException for an invalid axis
*/
public float getMaximumSpan(int axis) {
switch (axis) {
case View.X_AXIS:
if ((maxIsPreferred & 1) == 1) {
super.getMaximumSpan(axis);
return getPreferredSpan(axis);
}
return super.getMaximumSpan(axis);
case View.Y_AXIS:
if ((maxIsPreferred & 2) == 2) {
super.getMaximumSpan(axis);
return getPreferredSpan(axis);
}
return super.getMaximumSpan(axis);
default:
break;
}
return super.getMaximumSpan(axis);
}
/**
* Responsible for processing the ActionEvent.
* If the element associated with the FormView,
* has a type of "submit", "reset", "text" or "password"
* then the action is processed. In the case of a "submit"
* the form is submitted. In the case of a "reset"
* the form is reset to its original state.
* In the case of "text" or "password", if the
* element is the last one of type "text" or "password",
* the form is submitted. Otherwise, focus is transferred
* to the next component in the form.
*
* @param evt the ActionEvent.
*/
public void actionPerformed(ActionEvent evt) {
Element element = getElement();
StringBuilder dataBuffer = new StringBuilder();
HTMLDocument doc = (HTMLDocument)getDocument();
AttributeSet attr = element.getAttributes();
String type = (String) attr.getAttribute(HTML.Attribute.TYPE);
if (type.equals("submit")) {
getFormData(dataBuffer);
submitData(dataBuffer.toString());
} else if (type.equals("reset")) {
resetForm();
} else if (type.equals("text") || type.equals("password")) {
if (isLastTextOrPasswordField()) {
getFormData(dataBuffer);
submitData(dataBuffer.toString());
} else {
getComponent().transferFocus();
}
}
}
/**
* This method is responsible for submitting the form data.
* A thread is forked to undertake the submission.
*/
protected void submitData(String data) {
Element form = getFormElement();
AttributeSet attrs = form.getAttributes();
HTMLDocument doc = (HTMLDocument) form.getDocument();
URL base = doc.getBase();
String target = (String) attrs.getAttribute(HTML.Attribute.TARGET);
if (target == null) {
target = "_self";
}
String method = (String) attrs.getAttribute(HTML.Attribute.METHOD);
if (method == null) {
method = "GET";
}
method = method.toLowerCase();
boolean isPostMethod = method.equals("post");
if (isPostMethod) {
storePostData(doc, target, data);
}
String action = (String) attrs.getAttribute(HTML.Attribute.ACTION);
URL actionURL;
try {
actionURL = (action == null)
? new URL(base.getProtocol(), base.getHost(),
base.getPort(), base.getFile())
: new URL(base, action);
if (!isPostMethod) {
String query = data.toString();
actionURL = new URL(actionURL + "?" + query);
}
} catch (MalformedURLException e) {
actionURL = null;
}
final JEditorPane c = (JEditorPane) getContainer();
HTMLEditorKit kit = (HTMLEditorKit) c.getEditorKit();
FormSubmitEvent formEvent = null;
if (!kit.isAutoFormSubmission() || doc.isFrameDocument()) {
FormSubmitEvent.MethodType methodType = isPostMethod
? FormSubmitEvent.MethodType.POST
: FormSubmitEvent.MethodType.GET;
formEvent = new FormSubmitEvent(
FormView.this, HyperlinkEvent.EventType.ACTIVATED,
actionURL, form, target, methodType, data);
}
// setPage() may take significant time so schedule it to run later.
final FormSubmitEvent fse = formEvent;
final URL url = actionURL;
SwingUtilities.invokeLater(new Runnable() {
public void run() {
if (fse != null) {
c.fireHyperlinkUpdate(fse);
} else {
try {
c.setPage(url);
} catch (IOException e) {
UIManager.getLookAndFeel().provideErrorFeedback(c);
}
}
}
});
}
private void storePostData(HTMLDocument doc, String target, String data) {
/* POST data is stored into the document property named by constant
* PostDataProperty from where it is later retrieved by method
* JEditorPane.getPostData(). If the current document is in a frame,
* the data is initially put into the toplevel (frameset) document
* property (named <PostDataProperty>.
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.