Save This Page
Home » openjdk-7 » javax » swing » text » html » [javadoc | source]
    1   /*
    2    * Copyright 1998-2006 Sun Microsystems, Inc.  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.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   package javax.swing.text.html;
   26   
   27   import java.awt;
   28   import java.util;
   29   import java.net;
   30   import java.io;
   31   import javax.swing;
   32   import javax.swing.text;
   33   import javax.swing.event;
   34   
   35   import sun.swing.text.html.FrameEditorPaneTag;
   36   
   37   /**
   38    * Implements a FrameView, intended to support the HTML
   39    * <FRAME> tag.  Supports the frameborder, scrolling,
   40    * marginwidth and marginheight attributes.
   41    *
   42    * @author    Sunita Mani
   43    */
   44   
   45   class FrameView extends ComponentView implements HyperlinkListener {
   46   
   47   
   48       JEditorPane htmlPane;
   49       JScrollPane scroller;
   50       boolean editable;
   51       float width;
   52       float height;
   53       URL src;
   54       /** Set to true when the component has been created. */
   55       private boolean createdComponent;
   56   
   57       /**
   58        * Creates a new Frame.
   59        *
   60        * @param elem the element to represent.
   61        */
   62       public FrameView(Element elem) {
   63           super(elem);
   64       }
   65   
   66       protected Component createComponent() {
   67   
   68           Element elem = getElement();
   69           AttributeSet attributes = elem.getAttributes();
   70           String srcAtt = (String)attributes.getAttribute(HTML.Attribute.SRC);
   71   
   72           if ((srcAtt != null) && (!srcAtt.equals(""))) {
   73               try {
   74                   URL base = ((HTMLDocument)elem.getDocument()).getBase();
   75                   src = new URL(base, srcAtt);
   76                   htmlPane = new FrameEditorPane();
   77                   htmlPane.addHyperlinkListener(this);
   78                   JEditorPane host = getHostPane();
   79                   boolean isAutoFormSubmission = true;
   80                   if (host != null) {
   81                       htmlPane.setEditable(host.isEditable());
   82                       String charset = (String) host.getClientProperty("charset");
   83                       if (charset != null) {
   84                           htmlPane.putClientProperty("charset", charset);
   85                       }
   86                       HTMLEditorKit hostKit = (HTMLEditorKit)host.getEditorKit();
   87                       if (hostKit != null) {
   88                           isAutoFormSubmission = hostKit.isAutoFormSubmission();
   89                       }
   90                   }
   91                   htmlPane.setPage(src);
   92                   HTMLEditorKit kit = (HTMLEditorKit)htmlPane.getEditorKit();
   93                   if (kit != null) {
   94                       kit.setAutoFormSubmission(isAutoFormSubmission);
   95                   }
   96   
   97                   Document doc = htmlPane.getDocument();
   98                   if (doc instanceof HTMLDocument) {
   99                       ((HTMLDocument)doc).setFrameDocumentState(true);
  100                   }
  101                   setMargin();
  102                   createScrollPane();
  103                   setBorder();
  104               } catch (MalformedURLException e) {
  105                   e.printStackTrace();
  106               } catch (IOException e1) {
  107                   e1.printStackTrace();
  108               }
  109           }
  110           createdComponent = true;
  111           return scroller;
  112       }
  113   
  114       JEditorPane getHostPane() {
  115           Container c = getContainer();
  116           while ((c != null) && ! (c instanceof JEditorPane)) {
  117               c = c.getParent();
  118           }
  119           return (JEditorPane) c;
  120       }
  121   
  122   
  123       /**
  124        * Sets the parent view for the FrameView.
  125        * Also determines if the FrameView should be editable
  126        * or not based on whether the JTextComponent that
  127        * contains it is editable.
  128        *
  129        * @param parent View
  130        */
  131       public void setParent(View parent) {
  132           if (parent != null) {
  133               JTextComponent t = (JTextComponent)parent.getContainer();
  134               editable = t.isEditable();
  135           }
  136           super.setParent(parent);
  137       }
  138   
  139   
  140       /**
  141        * Also determines if the FrameView should be editable
  142        * or not based on whether the JTextComponent that
  143        * contains it is editable. And then proceeds to call
  144        * the superclass to do the paint().
  145        *
  146        * @param parent View
  147        * @see text.ComponentView#paint
  148        */
  149       public void paint(Graphics g, Shape allocation) {
  150   
  151           Container host = getContainer();
  152           if (host != null && htmlPane != null &&
  153               htmlPane.isEditable() != ((JTextComponent)host).isEditable()) {
  154               editable = ((JTextComponent)host).isEditable();
  155               htmlPane.setEditable(editable);
  156           }
  157           super.paint(g, allocation);
  158       }
  159   
  160   
  161       /**
  162        * If the marginwidth or marginheight attributes have been specified,
  163        * then the JEditorPane's margin's are set to the new values.
  164        */
  165       private void setMargin() {
  166           int margin = 0;
  167           Insets in = htmlPane.getMargin();
  168           Insets newInsets;
  169           boolean modified = false;
  170           AttributeSet attributes = getElement().getAttributes();
  171           String marginStr = (String)attributes.getAttribute(HTML.Attribute.MARGINWIDTH);
  172           if ( in != null) {
  173               newInsets = new Insets(in.top, in.left, in.right, in.bottom);
  174           } else {
  175               newInsets = new Insets(0,0,0,0);
  176           }
  177           if (marginStr != null) {
  178               margin = Integer.parseInt(marginStr);
  179               if (margin > 0) {
  180                   newInsets.left = margin;
  181                   newInsets.right = margin;
  182                   modified = true;
  183               }
  184           }
  185           marginStr = (String)attributes.getAttribute(HTML.Attribute.MARGINHEIGHT);
  186           if (marginStr != null) {
  187               margin = Integer.parseInt(marginStr);
  188               if (margin > 0) {
  189                   newInsets.top = margin;
  190                   newInsets.bottom = margin;
  191                   modified = true;
  192               }
  193           }
  194           if (modified) {
  195               htmlPane.setMargin(newInsets);
  196           }
  197       }
  198   
  199       /**
  200        * If the frameborder attribute has been specified, either in the frame,
  201        * or by the frames enclosing frameset, the JScrollPane's setBorder()
  202        * method is invoked to achieve the desired look.
  203        */
  204       private void setBorder() {
  205   
  206           AttributeSet attributes = getElement().getAttributes();
  207           String frameBorder = (String)attributes.getAttribute(HTML.Attribute.FRAMEBORDER);
  208           if ((frameBorder != null) &&
  209               (frameBorder.equals("no") || frameBorder.equals("0"))) {
  210               // make invisible borders.
  211               scroller.setBorder(null);
  212           }
  213       }
  214   
  215   
  216       /**
  217        * This method creates the JScrollPane.  The scrollbar policy is determined by
  218        * the scrolling attribute.  If not defined, the default is "auto" which
  219        * maps to the scrollbar's being displayed as needed.
  220        */
  221       private void createScrollPane() {
  222           AttributeSet attributes = getElement().getAttributes();
  223           String scrolling = (String)attributes.getAttribute(HTML.Attribute.SCROLLING);
  224           if (scrolling == null) {
  225               scrolling = "auto";
  226           }
  227   
  228           if (!scrolling.equals("no")) {
  229               if (scrolling.equals("yes")) {
  230                   scroller = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
  231                                              JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
  232               } else {
  233                   // scrollbars will be displayed if needed
  234                   //
  235                   scroller = new JScrollPane();
  236               }
  237           } else {
  238               scroller = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_NEVER,
  239                                          JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
  240           }
  241   
  242           JViewport vp = scroller.getViewport();
  243           vp.add(htmlPane);
  244           vp.setBackingStoreEnabled(true);
  245           scroller.setMinimumSize(new Dimension(5,5));
  246           scroller.setMaximumSize(new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE));
  247       }
  248   
  249   
  250       /**
  251        * Finds the outermost FrameSetView.  It then
  252        * returns that FrameSetView's container.
  253        */
  254       JEditorPane getOutermostJEditorPane() {
  255   
  256           View parent = getParent();
  257           FrameSetView frameSetView = null;
  258           while (parent != null) {
  259               if (parent instanceof FrameSetView) {
  260                   frameSetView = (FrameSetView)parent;
  261               }
  262               parent = parent.getParent();
  263           }
  264           if (frameSetView != null) {
  265               return (JEditorPane)frameSetView.getContainer();
  266           }
  267           return null;
  268       }
  269   
  270   
  271       /**
  272        * Returns true if this frame is contained within
  273        * a nested frameset.
  274        */
  275       private boolean inNestedFrameSet() {
  276           FrameSetView parent = (FrameSetView)getParent();
  277           return (parent.getParent() instanceof FrameSetView);
  278       }
  279   
  280   
  281       /**
  282        * Notification of a change relative to a
  283        * hyperlink. This method searches for the outermost
  284        * JEditorPane, and then fires an HTMLFrameHyperlinkEvent
  285        * to that frame.  In addition, if the target is _parent,
  286        * and there is not nested framesets then the target is
  287        * reset to _top.  If the target is _top, in addition to
  288        * firing the event to the outermost JEditorPane, this
  289        * method also invokes the setPage() method and explicitly
  290        * replaces the current document with the destination url.
  291        *
  292        * @param HyperlinkEvent
  293        */
  294       public void hyperlinkUpdate(HyperlinkEvent evt) {
  295   
  296           JEditorPane c = getOutermostJEditorPane();
  297           if (c == null) {
  298               return;
  299           }
  300   
  301           if (!(evt instanceof HTMLFrameHyperlinkEvent)) {
  302               c.fireHyperlinkUpdate(evt);
  303               return;
  304           }
  305   
  306           HTMLFrameHyperlinkEvent e = (HTMLFrameHyperlinkEvent)evt;
  307   
  308           if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
  309               String target = e.getTarget();
  310               String postTarget = target;
  311   
  312               if (target.equals("_parent") && !inNestedFrameSet()){
  313                   target = "_top";
  314               }
  315   
  316               if (evt instanceof FormSubmitEvent) {
  317                   HTMLEditorKit kit = (HTMLEditorKit)c.getEditorKit();
  318                   if (kit != null && kit.isAutoFormSubmission()) {
  319                       if (target.equals("_top")) {
  320                           try {
  321                               movePostData(c, postTarget);
  322                               c.setPage(e.getURL());
  323                           } catch (IOException ex) {
  324                               // Need a way to handle exceptions
  325                           }
  326                       } else {
  327                           HTMLDocument doc = (HTMLDocument)c.getDocument();
  328                           doc.processHTMLFrameHyperlinkEvent(e);
  329                       }
  330                   } else {
  331                       c.fireHyperlinkUpdate(evt);
  332                   }
  333                   return;
  334               }
  335   
  336               if (target.equals("_top")) {
  337                   try {
  338                       c.setPage(e.getURL());
  339                   } catch (IOException ex) {
  340                       // Need a way to handle exceptions
  341                       // ex.printStackTrace();
  342                   }
  343               }
  344               if (!c.isEditable()) {
  345                   c.fireHyperlinkUpdate(new HTMLFrameHyperlinkEvent(c,
  346                                                                     e.getEventType(),
  347                                                                     e.getURL(),
  348                                                                     e.getDescription(),
  349                                                                     getElement(),
  350                                                                     e.getInputEvent(),
  351                                                                     target));
  352               }
  353           }
  354       }
  355   
  356       /**
  357        * Gives notification from the document that attributes were changed
  358        * in a location that this view is responsible for.  Currently this view
  359        * handles changes to its SRC attribute.
  360        *
  361        * @param e the change information from the associated document
  362        * @param a the current allocation of the view
  363        * @param f the factory to use to rebuild if the view has children
  364        *
  365        */
  366       public void changedUpdate(DocumentEvent e, Shape a, ViewFactory f) {
  367   
  368           Element elem = getElement();
  369           AttributeSet attributes = elem.getAttributes();
  370   
  371           URL oldPage = src;
  372   
  373           String srcAtt = (String)attributes.getAttribute(HTML.Attribute.SRC);
  374           URL base = ((HTMLDocument)elem.getDocument()).getBase();
  375           try {
  376               if (!createdComponent) {
  377                   return;
  378               }
  379   
  380               Object postData = movePostData(htmlPane, null);
  381               src = new URL(base, srcAtt);
  382               if (oldPage.equals(src) && (src.getRef() == null) && (postData == null)) {
  383                   return;
  384               }
  385   
  386               htmlPane.setPage(src);
  387               Document newDoc = htmlPane.getDocument();
  388               if (newDoc instanceof HTMLDocument) {
  389                   ((HTMLDocument)newDoc).setFrameDocumentState(true);
  390               }
  391           } catch (MalformedURLException e1) {
  392               // Need a way to handle exceptions
  393               //e1.printStackTrace();
  394           } catch (IOException e2) {
  395               // Need a way to handle exceptions
  396               //e2.printStackTrace();
  397           }
  398       }
  399   
  400       /**
  401        * Move POST data from temporary storage into the target document property.
  402        *
  403        * @return the POST data or null if no data found
  404        */
  405       private Object movePostData(JEditorPane targetPane, String frameName) {
  406           Object postData = null;
  407           JEditorPane p = getOutermostJEditorPane();
  408           if (p != null) {
  409               if (frameName == null) {
  410                   frameName = (String) getElement().getAttributes().getAttribute(
  411                           HTML.Attribute.NAME);
  412               }
  413               if (frameName != null) {
  414                   String propName = FormView.PostDataProperty + "." + frameName;
  415                   Document d = p.getDocument();
  416                   postData = d.getProperty(propName);
  417                   if (postData != null) {
  418                       targetPane.getDocument().putProperty(
  419                               FormView.PostDataProperty, postData);
  420                       d.putProperty(propName, null);
  421                   }
  422               }
  423           }
  424   
  425           return postData;
  426       }
  427   
  428       /**
  429        * Determines the minimum span for this view along an
  430        * axis.
  431        *
  432        * @param axis may be either <code>View.X_AXIS</code> or
  433        *  <code>View.Y_AXIS</code>
  434        * @return the preferred span; given that we do not
  435        * support resizing of frames, the minimum span returned
  436        * is the same as the preferred span
  437        *
  438        */
  439       public float getMinimumSpan(int axis) {
  440         return 5;
  441       }
  442   
  443       /**
  444        * Determines the maximum span for this view along an
  445        * axis.
  446        *
  447        * @param axis may be either <code>View.X_AXIS</code> or
  448        *  <code>View.Y_AXIS</code>
  449        * @return the preferred span; given that we do not
  450        * support resizing of frames, the maximum span returned
  451        * is the same as the preferred span
  452        *
  453        */
  454       public float getMaximumSpan(int axis) {
  455           return Integer.MAX_VALUE;
  456       }
  457   
  458       /** Editor pane rendering frame of HTML document
  459        *  It uses the same editor kits classes as outermost JEditorPane
  460        */
  461       class FrameEditorPane extends JEditorPane implements FrameEditorPaneTag {
  462           public EditorKit getEditorKitForContentType(String type) {
  463               EditorKit editorKit = super.getEditorKitForContentType(type);
  464               JEditorPane outerMostJEditorPane = null;
  465               if ((outerMostJEditorPane = getOutermostJEditorPane()) != null) {
  466                   EditorKit inheritedEditorKit = outerMostJEditorPane.getEditorKitForContentType(type);
  467                   if (! editorKit.getClass().equals(inheritedEditorKit.getClass())) {
  468                       editorKit = (EditorKit) inheritedEditorKit.clone();
  469                       setEditorKitForContentType(type, editorKit);
  470                   }
  471               }
  472               return editorKit;
  473           }
  474   
  475           FrameView getFrameView() {
  476               return FrameView.this;
  477           }
  478       }
  479   }

Save This Page
Home » openjdk-7 » javax » swing » text » html » [javadoc | source]