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.awt.event;
   29   import java.io;
   30   import java.net.MalformedURLException;
   31   import java.net.URL;
   32   import javax.swing.text;
   33   import javax.swing;
   34   import javax.swing.border;
   35   import javax.swing.event;
   36   import java.util;
   37   
   38   /**
   39    * HiddenTagView subclasses EditableView to contain a JTextField showing
   40    * the element name. When the textfield is edited the element name is
   41    * reset. As this inherits from EditableView if the JTextComponent is
   42    * not editable, the textfield will not be visible.
   43    *
   44    * @author  Scott Violet
   45    */
   46   class HiddenTagView extends EditableView implements DocumentListener {
   47       HiddenTagView(Element e) {
   48           super(e);
   49           yAlign = 1;
   50       }
   51   
   52       protected Component createComponent() {
   53           JTextField tf = new JTextField(getElement().getName());
   54           Document doc = getDocument();
   55           Font font;
   56           if (doc instanceof StyledDocument) {
   57               font = ((StyledDocument)doc).getFont(getAttributes());
   58               tf.setFont(font);
   59           }
   60           else {
   61               font = tf.getFont();
   62           }
   63           tf.getDocument().addDocumentListener(this);
   64           updateYAlign(font);
   65   
   66           // Create a panel to wrap the textfield so that the textfields
   67           // laf border shows through.
   68           JPanel panel = new JPanel(new BorderLayout());
   69           panel.setBackground(null);
   70           if (isEndTag()) {
   71               panel.setBorder(EndBorder);
   72           }
   73           else {
   74               panel.setBorder(StartBorder);
   75           }
   76           panel.add(tf);
   77           return panel;
   78       }
   79   
   80       public float getAlignment(int axis) {
   81           if (axis == View.Y_AXIS) {
   82               return yAlign;
   83           }
   84           return 0.5f;
   85       }
   86   
   87       public float getMinimumSpan(int axis) {
   88           if (axis == View.X_AXIS && isVisible()) {
   89               // Default to preferred.
   90               return Math.max(30, super.getPreferredSpan(axis));
   91           }
   92           return super.getMinimumSpan(axis);
   93       }
   94   
   95       public float getPreferredSpan(int axis) {
   96           if (axis == View.X_AXIS && isVisible()) {
   97               return Math.max(30, super.getPreferredSpan(axis));
   98           }
   99           return super.getPreferredSpan(axis);
  100       }
  101   
  102       public float getMaximumSpan(int axis) {
  103           if (axis == View.X_AXIS && isVisible()) {
  104               // Default to preferred.
  105               return Math.max(30, super.getMaximumSpan(axis));
  106           }
  107           return super.getMaximumSpan(axis);
  108       }
  109   
  110       // DocumentListener methods
  111       public void insertUpdate(DocumentEvent e) {
  112           updateModelFromText();
  113       }
  114   
  115       public void removeUpdate(DocumentEvent e) {
  116           updateModelFromText();
  117       }
  118   
  119       public void changedUpdate(DocumentEvent e) {
  120           updateModelFromText();
  121       }
  122   
  123       // View method
  124       public void changedUpdate(DocumentEvent e, Shape a, ViewFactory f) {
  125           if (!isSettingAttributes) {
  126               setTextFromModel();
  127           }
  128       }
  129   
  130       // local methods
  131   
  132       void updateYAlign(Font font) {
  133           Container c = getContainer();
  134           FontMetrics fm = (c != null) ? c.getFontMetrics(font) :
  135               Toolkit.getDefaultToolkit().getFontMetrics(font);
  136           float h = fm.getHeight();
  137           float d = fm.getDescent();
  138           yAlign = (h > 0) ? (h - d) / h : 0;
  139       }
  140   
  141       void resetBorder() {
  142           Component comp = getComponent();
  143   
  144           if (comp != null) {
  145               if (isEndTag()) {
  146                   ((JPanel)comp).setBorder(EndBorder);
  147               }
  148               else {
  149                   ((JPanel)comp).setBorder(StartBorder);
  150               }
  151           }
  152       }
  153   
  154       /**
  155        * This resets the text on the text component we created to match
  156        * that of the AttributeSet for the Element we represent.
  157        * <p>If this is invoked on the event dispatching thread, this
  158        * directly invokes <code>_setTextFromModel</code>, otherwise
  159        * <code>SwingUtilities.invokeLater</code> is used to schedule execution
  160        * of <code>_setTextFromModel</code>.
  161        */
  162       void setTextFromModel() {
  163           if (SwingUtilities.isEventDispatchThread()) {
  164               _setTextFromModel();
  165           }
  166           else {
  167               SwingUtilities.invokeLater(new Runnable() {
  168                   public void run() {
  169                       _setTextFromModel();
  170                   }
  171               });
  172           }
  173       }
  174   
  175       /**
  176        * This resets the text on the text component we created to match
  177        * that of the AttributeSet for the Element we represent.
  178        */
  179       void _setTextFromModel() {
  180           Document doc = getDocument();
  181           try {
  182               isSettingAttributes = true;
  183               if (doc instanceof AbstractDocument) {
  184                   ((AbstractDocument)doc).readLock();
  185               }
  186               JTextComponent text = getTextComponent();
  187               if (text != null) {
  188                   text.setText(getRepresentedText());
  189                   resetBorder();
  190                   Container host = getContainer();
  191                   if (host != null) {
  192                       preferenceChanged(this, true, true);
  193                       host.repaint();
  194                   }
  195               }
  196           }
  197           finally {
  198               isSettingAttributes = false;
  199               if (doc instanceof AbstractDocument) {
  200                   ((AbstractDocument)doc).readUnlock();
  201               }
  202           }
  203       }
  204   
  205       /**
  206        * This copies the text from the text component we've created
  207        * to the Element's AttributeSet we represent.
  208        * <p>If this is invoked on the event dispatching thread, this
  209        * directly invokes <code>_updateModelFromText</code>, otherwise
  210        * <code>SwingUtilities.invokeLater</code> is used to schedule execution
  211        * of <code>_updateModelFromText</code>.
  212        */
  213       void updateModelFromText() {
  214           if (!isSettingAttributes) {
  215               if (SwingUtilities.isEventDispatchThread()) {
  216                   _updateModelFromText();
  217               }
  218               else {
  219                   SwingUtilities.invokeLater(new Runnable() {
  220                       public void run() {
  221                           _updateModelFromText();
  222                       }
  223                   });
  224               }
  225           }
  226       }
  227   
  228       /**
  229        * This copies the text from the text component we've created
  230        * to the Element's AttributeSet we represent.
  231        */
  232       void _updateModelFromText() {
  233           Document doc = getDocument();
  234           Object name = getElement().getAttributes().getAttribute
  235               (StyleConstants.NameAttribute);
  236           if ((name instanceof HTML.UnknownTag) &&
  237               (doc instanceof StyledDocument)) {
  238               SimpleAttributeSet sas = new SimpleAttributeSet();
  239               JTextComponent textComponent = getTextComponent();
  240               if (textComponent != null) {
  241                   String text = textComponent.getText();
  242                   isSettingAttributes = true;
  243                   try {
  244                       sas.addAttribute(StyleConstants.NameAttribute,
  245                                        new HTML.UnknownTag(text));
  246                       ((StyledDocument)doc).setCharacterAttributes
  247                           (getStartOffset(), getEndOffset() -
  248                            getStartOffset(), sas, false);
  249                   }
  250                   finally {
  251                       isSettingAttributes = false;
  252                   }
  253               }
  254           }
  255       }
  256   
  257       JTextComponent getTextComponent() {
  258           Component comp = getComponent();
  259   
  260           return (comp == null) ? null : (JTextComponent)((Container)comp).
  261                                          getComponent(0);
  262       }
  263   
  264       String getRepresentedText() {
  265           String retValue = getElement().getName();
  266           return (retValue == null) ? "" : retValue;
  267       }
  268   
  269       boolean isEndTag() {
  270           AttributeSet as = getElement().getAttributes();
  271           if (as != null) {
  272               Object end = as.getAttribute(HTML.Attribute.ENDTAG);
  273               if (end != null && (end instanceof String) &&
  274                   ((String)end).equals("true")) {
  275                   return true;
  276               }
  277           }
  278           return false;
  279       }
  280   
  281       /** Alignment along the y axis, based on the font of the textfield. */
  282       float yAlign;
  283       /** Set to true when setting attributes. */
  284       boolean isSettingAttributes;
  285   
  286   
  287       // Following are for Borders that used for Unknown tags and comments.
  288       //
  289       // Border defines
  290       static final int circleR = 3;
  291       static final int circleD = circleR * 2;
  292       static final int tagSize = 6;
  293       static final int padding = 3;
  294       static final Color UnknownTagBorderColor = Color.black;
  295       static final Border StartBorder = new StartTagBorder();
  296       static final Border EndBorder = new EndTagBorder();
  297   
  298   
  299       static class StartTagBorder implements Border, Serializable {
  300           public void paintBorder(Component c, Graphics g, int x, int y,
  301                                   int width, int height) {
  302               g.setColor(UnknownTagBorderColor);
  303               x += padding;
  304               width -= (padding * 2);
  305               g.drawLine(x, y + circleR,
  306                          x, y + height - circleR);
  307               g.drawArc(x, y + height - circleD - 1,
  308                         circleD, circleD, 180, 90);
  309               g.drawArc(x, y, circleD, circleD, 90, 90);
  310               g.drawLine(x + circleR, y, x + width - tagSize, y);
  311               g.drawLine(x + circleR, y + height - 1,
  312                          x + width - tagSize, y + height - 1);
  313   
  314               g.drawLine(x + width - tagSize, y,
  315                          x + width - 1, y + height / 2);
  316               g.drawLine(x + width - tagSize, y + height,
  317                          x + width - 1, y + height / 2);
  318           }
  319   
  320           public Insets getBorderInsets(Component c) {
  321               return new Insets(2, 2 + padding, 2, tagSize + 2 + padding);
  322           }
  323   
  324           public boolean isBorderOpaque() {
  325               return false;
  326           }
  327       } // End of class HiddenTagView.StartTagBorder
  328   
  329   
  330       static class EndTagBorder implements Border, Serializable {
  331           public void paintBorder(Component c, Graphics g, int x, int y,
  332                                   int width, int height) {
  333               g.setColor(UnknownTagBorderColor);
  334               x += padding;
  335               width -= (padding * 2);
  336               g.drawLine(x + width - 1, y + circleR,
  337                          x + width - 1, y + height - circleR);
  338               g.drawArc(x + width - circleD - 1, y + height - circleD - 1,
  339                         circleD, circleD, 270, 90);
  340               g.drawArc(x + width - circleD - 1, y, circleD, circleD, 0, 90);
  341               g.drawLine(x + tagSize, y, x + width - circleR, y);
  342               g.drawLine(x + tagSize, y + height - 1,
  343                          x + width - circleR, y + height - 1);
  344   
  345               g.drawLine(x + tagSize, y,
  346                          x, y + height / 2);
  347               g.drawLine(x + tagSize, y + height,
  348                          x, y + height / 2);
  349           }
  350   
  351           public Insets getBorderInsets(Component c) {
  352               return new Insets(2, tagSize + 2 + padding, 2, 2 + padding);
  353           }
  354   
  355           public boolean isBorderOpaque() {
  356               return false;
  357           }
  358       } // End of class HiddenTagView.EndTagBorder
  359   
  360   
  361   } // End of HiddenTagView

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