< prev index next >

src/java.desktop/share/classes/javax/swing/text/StyleContext.java

Print this page


   1 /*
   2  * Copyright (c) 1997, 2014, 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


 462 
 463     // --- local methods -----------------------------------------------
 464 
 465     /**
 466      * Returns the maximum number of key/value pairs to try and
 467      * compress into unique/immutable sets.  Any sets above this
 468      * limit will use hashtables and be a MutableAttributeSet.
 469      *
 470      * @return the threshold
 471      */
 472     protected int getCompressionThreshold() {
 473         return THRESHOLD;
 474     }
 475 
 476     /**
 477      * Create a compact set of attributes that might be shared.
 478      * This is a hook for subclasses that want to alter the
 479      * behavior of SmallAttributeSet.  This can be reimplemented
 480      * to return an AttributeSet that provides some sort of
 481      * attribute conversion.
 482      *
 483      * @param a The set of attributes to be represented in the
 484      *  the compact form.

 485      */
 486     protected SmallAttributeSet createSmallAttributeSet(AttributeSet a) {
 487         return new SmallAttributeSet(a);
 488     }
 489 
 490     /**
 491      * Create a large set of attributes that should trade off
 492      * space for time.  This set will not be shared.  This is
 493      * a hook for subclasses that want to alter the behavior
 494      * of the larger attribute storage format (which is
 495      * SimpleAttributeSet by default).   This can be reimplemented
 496      * to return a MutableAttributeSet that provides some sort of
 497      * attribute conversion.
 498      *
 499      * @param a The set of attributes to be represented in the
 500      *  the larger form.


 501      */
 502     protected MutableAttributeSet createLargeAttributeSet(AttributeSet a) {
 503         return new SimpleAttributeSet(a);
 504     }
 505 
 506     /**
 507      * Clean the unused immutable sets out of the hashtable.
 508      */
 509     synchronized void removeUnusedSets() {
 510         attributesPool.size(); // force WeakHashMap to expunge stale entries
 511     }
 512 
 513     /**
 514      * Search for an existing attribute set using the current search
 515      * parameters.  If a matching set is found, return it.  If a match
 516      * is not found, we create a new set and add it to the pool.
 517      */
 518     AttributeSet getImmutableUniqueSet() {
 519         // PENDING(prinz) should consider finding a alternative to
 520         // generating extra garbage on search key.


 541     }
 542 
 543     /**
 544      * Converts a StyleContext to a String.
 545      *
 546      * @return the string
 547      */
 548     public String toString() {
 549         removeUnusedSets();
 550         String s = "";
 551         for (SmallAttributeSet set : attributesPool.keySet()) {
 552             s = s + set + "\n";
 553         }
 554         return s;
 555     }
 556 
 557     // --- serialization ---------------------------------------------
 558 
 559     /**
 560      * Context-specific handling of writing out attributes



 561      */
 562     public void writeAttributes(ObjectOutputStream out,
 563                                   AttributeSet a) throws IOException {
 564         writeAttributeSet(out, a);
 565     }
 566 
 567     /**
 568      * Context-specific handling of reading in attributes







 569      */
 570     public void readAttributes(ObjectInputStream in,
 571                                MutableAttributeSet a) throws ClassNotFoundException, IOException {
 572         readAttributeSet(in, a);
 573     }
 574 
 575     /**
 576      * Writes a set of attributes to the given object stream
 577      * for the purpose of serialization.  This will take
 578      * special care to deal with static attribute keys that
 579      * have been registered wit the
 580      * <code>registerStaticAttributeKey</code> method.
 581      * Any attribute key not registered as a static key
 582      * will be serialized directly.  All values are expected
 583      * to be serializable.
 584      *
 585      * @param out the output stream
 586      * @param a the attribute set
 587      * @exception IOException on any I/O error
 588      */


 668      * by toString should not have the class reference
 669      * in it (ie it should be reimplemented from the
 670      * definition in Object) in order to be the same when
 671      * recomputed later.
 672      *
 673      * @param key the non-null object key
 674      */
 675     public static void registerStaticAttributeKey(Object key) {
 676         String ioFmt = key.getClass().getName() + "." + key.toString();
 677         if (freezeKeyMap == null) {
 678             freezeKeyMap = new Hashtable<Object, String>();
 679             thawKeyMap = new Hashtable<String, Object>();
 680         }
 681         freezeKeyMap.put(key, ioFmt);
 682         thawKeyMap.put(ioFmt, key);
 683     }
 684 
 685     /**
 686      * Returns the object previously registered with
 687      * <code>registerStaticAttributeKey</code>.



 688      */
 689     public static Object getStaticAttribute(Object key) {
 690         if (thawKeyMap == null || key == null) {
 691             return null;
 692         }
 693         return thawKeyMap.get(key);
 694     }
 695 
 696     /**
 697      * Returns the String that <code>key</code> will be registered with
 698      * @see #getStaticAttribute
 699      * @see #registerStaticAttributeKey


 700      */
 701     public static Object getStaticAttributeKey(Object key) {
 702         return key.getClass().getName() + "." + key.toString();
 703     }
 704 
 705     private void writeObject(java.io.ObjectOutputStream s)
 706         throws IOException
 707     {
 708         // clean out unused sets before saving
 709         removeUnusedSets();
 710 
 711         s.defaultWriteObject();
 712     }
 713 
 714     private void readObject(ObjectInputStream s)
 715       throws ClassNotFoundException, IOException
 716     {
 717         fontSearch = new FontKey(null, 0, 0);
 718         fontTable = new Hashtable<>();
 719         search = new SimpleAttributeSet();


 755      * to be cleaned out of the hashtable they are stored
 756      * in.
 757      */
 758     private int unusedSets;
 759 
 760     /**
 761      * The threshold for no longer sharing the set of attributes
 762      * in an immutable table.
 763      */
 764     static final int THRESHOLD = 9;
 765 
 766     /**
 767      * This class holds a small number of attributes in an array.
 768      * The storage format is key, value, key, value, etc.  The size
 769      * of the set is the length of the array divided by two.  By
 770      * default, this is the class that will be used to store attributes
 771      * when held in the compact sharable form.
 772      */
 773     public class SmallAttributeSet implements AttributeSet {
 774 




 775         public SmallAttributeSet(Object[] attributes) {
 776             this.attributes = attributes;
 777             updateResolveParent();
 778         }
 779 




 780         public SmallAttributeSet(AttributeSet attrs) {
 781             int n = attrs.getAttributeCount();
 782             Object[] tbl = new Object[2 * n];
 783             Enumeration<?> names = attrs.getAttributeNames();
 784             int i = 0;
 785             while (names.hasMoreElements()) {
 786                 tbl[i] = names.nextElement();
 787                 tbl[i+1] = attrs.getAttribute(tbl[i]);
 788                 i += 2;
 789             }
 790             attributes = tbl;
 791             updateResolveParent();
 792         }
 793 
 794         private void updateResolveParent() {
 795             resolveParent = null;
 796             Object[] tbl = attributes;
 797             for (int i = 0; i < tbl.length; i += 2) {
 798                 if (tbl[i] == StyleConstants.ResolveAttribute) {
 799                     resolveParent = (AttributeSet)tbl[i + 1];


 801                 }
 802             }
 803         }
 804 
 805         Object getLocalAttribute(Object nm) {
 806             if (nm == StyleConstants.ResolveAttribute) {
 807                 return resolveParent;
 808             }
 809             Object[] tbl = attributes;
 810             for (int i = 0; i < tbl.length; i += 2) {
 811                 if (nm.equals(tbl[i])) {
 812                     return tbl[i+1];
 813                 }
 814             }
 815             return null;
 816         }
 817 
 818         // --- Object methods -------------------------
 819 
 820         /**
 821          * Returns a string showing the key/value pairs

 822          */
 823         public String toString() {
 824             String s = "{";
 825             Object[] tbl = attributes;
 826             for (int i = 0; i < tbl.length; i += 2) {
 827                 if (tbl[i+1] instanceof AttributeSet) {
 828                     // don't recurse
 829                     s = s + tbl[i] + "=" + "AttributeSet" + ",";
 830                 } else {
 831                     s = s + tbl[i] + "=" + tbl[i+1] + ",";
 832                 }
 833             }
 834             s = s + "}";
 835             return s;
 836         }
 837 
 838         /**
 839          * Returns a hashcode for this set of attributes.
 840          * @return     a hashcode value for this set of attributes.
 841          */


1365          * @see EventListenerList
1366          */
1367         protected void fireStateChanged() {
1368             // Guaranteed to return a non-null array
1369             Object[] listeners = listenerList.getListenerList();
1370             // Process the listeners last to first, notifying
1371             // those that are interested in this event
1372             for (int i = listeners.length-2; i>=0; i-=2) {
1373                 if (listeners[i]==ChangeListener.class) {
1374                     // Lazily create the event:
1375                     if (changeEvent == null)
1376                         changeEvent = new ChangeEvent(this);
1377                     ((ChangeListener)listeners[i+1]).stateChanged(changeEvent);
1378                 }
1379             }
1380         }
1381 
1382         /**
1383          * Return an array of all the listeners of the given type that
1384          * were added to this model.
1385          *

1386          * @return all of the objects receiving <em>listenerType</em> notifications
1387          *          from this model
1388          *
1389          * @since 1.3
1390          */
1391         public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
1392             return listenerList.getListeners(listenerType);
1393         }
1394 
1395         // --- AttributeSet ----------------------------
1396         // delegated to the immutable field "attributes"
1397 
1398         /**
1399          * Gets the number of attributes that are defined.
1400          *
1401          * @return the number of attributes &gt;= 0
1402          * @see AttributeSet#getAttributeCount
1403          */
1404         public int getAttributeCount() {
1405             return attributes.getAttributeCount();


   1 /*
   2  * Copyright (c) 1997, 2015, 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


 462 
 463     // --- local methods -----------------------------------------------
 464 
 465     /**
 466      * Returns the maximum number of key/value pairs to try and
 467      * compress into unique/immutable sets.  Any sets above this
 468      * limit will use hashtables and be a MutableAttributeSet.
 469      *
 470      * @return the threshold
 471      */
 472     protected int getCompressionThreshold() {
 473         return THRESHOLD;
 474     }
 475 
 476     /**
 477      * Create a compact set of attributes that might be shared.
 478      * This is a hook for subclasses that want to alter the
 479      * behavior of SmallAttributeSet.  This can be reimplemented
 480      * to return an AttributeSet that provides some sort of
 481      * attribute conversion.

 482      * @param a The set of attributes to be represented in the
 483      *  the compact form.
 484      * @return a compact set of attributes that might be shared
 485      */
 486     protected SmallAttributeSet createSmallAttributeSet(AttributeSet a) {
 487         return new SmallAttributeSet(a);
 488     }
 489 
 490     /**
 491      * Create a large set of attributes that should trade off
 492      * space for time.  This set will not be shared.  This is
 493      * a hook for subclasses that want to alter the behavior
 494      * of the larger attribute storage format (which is
 495      * SimpleAttributeSet by default).   This can be reimplemented
 496      * to return a MutableAttributeSet that provides some sort of
 497      * attribute conversion.
 498      *
 499      * @param a The set of attributes to be represented in the
 500      *  the larger form.
 501      * @return a large set of attributes that should trade off
 502      * space for time
 503      */
 504     protected MutableAttributeSet createLargeAttributeSet(AttributeSet a) {
 505         return new SimpleAttributeSet(a);
 506     }
 507 
 508     /**
 509      * Clean the unused immutable sets out of the hashtable.
 510      */
 511     synchronized void removeUnusedSets() {
 512         attributesPool.size(); // force WeakHashMap to expunge stale entries
 513     }
 514 
 515     /**
 516      * Search for an existing attribute set using the current search
 517      * parameters.  If a matching set is found, return it.  If a match
 518      * is not found, we create a new set and add it to the pool.
 519      */
 520     AttributeSet getImmutableUniqueSet() {
 521         // PENDING(prinz) should consider finding a alternative to
 522         // generating extra garbage on search key.


 543     }
 544 
 545     /**
 546      * Converts a StyleContext to a String.
 547      *
 548      * @return the string
 549      */
 550     public String toString() {
 551         removeUnusedSets();
 552         String s = "";
 553         for (SmallAttributeSet set : attributesPool.keySet()) {
 554             s = s + set + "\n";
 555         }
 556         return s;
 557     }
 558 
 559     // --- serialization ---------------------------------------------
 560 
 561     /**
 562      * Context-specific handling of writing out attributes
 563      * @param out the output stream
 564      * @param a the attribute set
 565      * @exception IOException on any I/O error
 566      */
 567     public void writeAttributes(ObjectOutputStream out,
 568                                   AttributeSet a) throws IOException {
 569         writeAttributeSet(out, a);
 570     }
 571 
 572     /**
 573      * Context-specific handling of reading in attributes
 574      * @param in the object stream to read the attribute data from.
 575      * @param a  the attribute set to place the attribute
 576      *   definitions in.
 577      * @exception ClassNotFoundException passed upward if encountered
 578      *  when reading the object stream.
 579      * @exception IOException passed upward if encountered when
 580      *  reading the object stream.
 581      */
 582     public void readAttributes(ObjectInputStream in,
 583                                MutableAttributeSet a) throws ClassNotFoundException, IOException {
 584         readAttributeSet(in, a);
 585     }
 586 
 587     /**
 588      * Writes a set of attributes to the given object stream
 589      * for the purpose of serialization.  This will take
 590      * special care to deal with static attribute keys that
 591      * have been registered wit the
 592      * <code>registerStaticAttributeKey</code> method.
 593      * Any attribute key not registered as a static key
 594      * will be serialized directly.  All values are expected
 595      * to be serializable.
 596      *
 597      * @param out the output stream
 598      * @param a the attribute set
 599      * @exception IOException on any I/O error
 600      */


 680      * by toString should not have the class reference
 681      * in it (ie it should be reimplemented from the
 682      * definition in Object) in order to be the same when
 683      * recomputed later.
 684      *
 685      * @param key the non-null object key
 686      */
 687     public static void registerStaticAttributeKey(Object key) {
 688         String ioFmt = key.getClass().getName() + "." + key.toString();
 689         if (freezeKeyMap == null) {
 690             freezeKeyMap = new Hashtable<Object, String>();
 691             thawKeyMap = new Hashtable<String, Object>();
 692         }
 693         freezeKeyMap.put(key, ioFmt);
 694         thawKeyMap.put(ioFmt, key);
 695     }
 696 
 697     /**
 698      * Returns the object previously registered with
 699      * <code>registerStaticAttributeKey</code>.
 700      * @param key the object key
 701      * @return Returns the object previously registered with
 702      * {@code registerStaticAttributeKey}
 703      */
 704     public static Object getStaticAttribute(Object key) {
 705         if (thawKeyMap == null || key == null) {
 706             return null;
 707         }
 708         return thawKeyMap.get(key);
 709     }
 710 
 711     /**
 712      * Returns the String that <code>key</code> will be registered with.
 713      * @see #getStaticAttribute
 714      * @see #registerStaticAttributeKey
 715      * @param key the object key
 716      * @return the String that {@code key} will be registered with
 717      */
 718     public static Object getStaticAttributeKey(Object key) {
 719         return key.getClass().getName() + "." + key.toString();
 720     }
 721 
 722     private void writeObject(java.io.ObjectOutputStream s)
 723         throws IOException
 724     {
 725         // clean out unused sets before saving
 726         removeUnusedSets();
 727 
 728         s.defaultWriteObject();
 729     }
 730 
 731     private void readObject(ObjectInputStream s)
 732       throws ClassNotFoundException, IOException
 733     {
 734         fontSearch = new FontKey(null, 0, 0);
 735         fontTable = new Hashtable<>();
 736         search = new SimpleAttributeSet();


 772      * to be cleaned out of the hashtable they are stored
 773      * in.
 774      */
 775     private int unusedSets;
 776 
 777     /**
 778      * The threshold for no longer sharing the set of attributes
 779      * in an immutable table.
 780      */
 781     static final int THRESHOLD = 9;
 782 
 783     /**
 784      * This class holds a small number of attributes in an array.
 785      * The storage format is key, value, key, value, etc.  The size
 786      * of the set is the length of the array divided by two.  By
 787      * default, this is the class that will be used to store attributes
 788      * when held in the compact sharable form.
 789      */
 790     public class SmallAttributeSet implements AttributeSet {
 791 
 792         /**
 793          * Constructs a SmallAttributeSet.
 794          * @param attributes the attributes
 795          */
 796         public SmallAttributeSet(Object[] attributes) {
 797             this.attributes = attributes;
 798             updateResolveParent();
 799         }
 800 
 801         /**
 802          * Constructs a SmallAttributeSet.
 803          * @param attrs the attributes
 804          */
 805         public SmallAttributeSet(AttributeSet attrs) {
 806             int n = attrs.getAttributeCount();
 807             Object[] tbl = new Object[2 * n];
 808             Enumeration<?> names = attrs.getAttributeNames();
 809             int i = 0;
 810             while (names.hasMoreElements()) {
 811                 tbl[i] = names.nextElement();
 812                 tbl[i+1] = attrs.getAttribute(tbl[i]);
 813                 i += 2;
 814             }
 815             attributes = tbl;
 816             updateResolveParent();
 817         }
 818 
 819         private void updateResolveParent() {
 820             resolveParent = null;
 821             Object[] tbl = attributes;
 822             for (int i = 0; i < tbl.length; i += 2) {
 823                 if (tbl[i] == StyleConstants.ResolveAttribute) {
 824                     resolveParent = (AttributeSet)tbl[i + 1];


 826                 }
 827             }
 828         }
 829 
 830         Object getLocalAttribute(Object nm) {
 831             if (nm == StyleConstants.ResolveAttribute) {
 832                 return resolveParent;
 833             }
 834             Object[] tbl = attributes;
 835             for (int i = 0; i < tbl.length; i += 2) {
 836                 if (nm.equals(tbl[i])) {
 837                     return tbl[i+1];
 838                 }
 839             }
 840             return null;
 841         }
 842 
 843         // --- Object methods -------------------------
 844 
 845         /**
 846          * Returns a string showing the key/value pairs.
 847          * @return a string showing the key/value pairs
 848          */
 849         public String toString() {
 850             String s = "{";
 851             Object[] tbl = attributes;
 852             for (int i = 0; i < tbl.length; i += 2) {
 853                 if (tbl[i+1] instanceof AttributeSet) {
 854                     // don't recurse
 855                     s = s + tbl[i] + "=" + "AttributeSet" + ",";
 856                 } else {
 857                     s = s + tbl[i] + "=" + tbl[i+1] + ",";
 858                 }
 859             }
 860             s = s + "}";
 861             return s;
 862         }
 863 
 864         /**
 865          * Returns a hashcode for this set of attributes.
 866          * @return     a hashcode value for this set of attributes.
 867          */


1391          * @see EventListenerList
1392          */
1393         protected void fireStateChanged() {
1394             // Guaranteed to return a non-null array
1395             Object[] listeners = listenerList.getListenerList();
1396             // Process the listeners last to first, notifying
1397             // those that are interested in this event
1398             for (int i = listeners.length-2; i>=0; i-=2) {
1399                 if (listeners[i]==ChangeListener.class) {
1400                     // Lazily create the event:
1401                     if (changeEvent == null)
1402                         changeEvent = new ChangeEvent(this);
1403                     ((ChangeListener)listeners[i+1]).stateChanged(changeEvent);
1404                 }
1405             }
1406         }
1407 
1408         /**
1409          * Return an array of all the listeners of the given type that
1410          * were added to this model.
1411          * @param <T> the listener type
1412          * @param listenerType the type of listeners requested
1413          * @return all of the objects receiving <em>listenerType</em> notifications
1414          *          from this model
1415          *
1416          * @since 1.3
1417          */
1418         public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
1419             return listenerList.getListeners(listenerType);
1420         }
1421 
1422         // --- AttributeSet ----------------------------
1423         // delegated to the immutable field "attributes"
1424 
1425         /**
1426          * Gets the number of attributes that are defined.
1427          *
1428          * @return the number of attributes &gt;= 0
1429          * @see AttributeSet#getAttributeCount
1430          */
1431         public int getAttributeCount() {
1432             return attributes.getAttributeCount();


< prev index next >