< prev index next >

src/java.desktop/share/classes/java/awt/Toolkit.java

Print this page


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


  40 import java.awt.dnd.InvalidDnDOperationException;
  41 import java.awt.dnd.peer.DragSourceContextPeer;
  42 import java.net.URL;
  43 import java.io.File;
  44 import java.io.FileInputStream;
  45 
  46 import java.util.*;
  47 import java.beans.PropertyChangeListener;
  48 import java.beans.PropertyChangeSupport;
  49 import sun.awt.AppContext;
  50 
  51 import sun.awt.HeadlessToolkit;
  52 import sun.awt.NullComponentPeer;
  53 import sun.awt.PeerEvent;
  54 import sun.awt.SunToolkit;
  55 import sun.awt.AWTAccessor;
  56 import sun.awt.AWTPermissions;
  57 
  58 import sun.util.CoreResourceBundleControl;
  59 





  60 /**
  61  * This class is the abstract superclass of all actual
  62  * implementations of the Abstract Window Toolkit. Subclasses of
  63  * the <code>Toolkit</code> class are used to bind the various components
  64  * to particular native toolkit implementations.
  65  * <p>
  66  * Many GUI events may be delivered to user
  67  * asynchronously, if the opposite is not specified explicitly.
  68  * As well as
  69  * many GUI operations may be performed asynchronously.
  70  * This fact means that if the state of a component is set, and then
  71  * the state immediately queried, the returned value may not yet
  72  * reflect the requested change.  This behavior includes, but is not
  73  * limited to:
  74  * <ul>
  75  * <li>Scrolling to a specified position.
  76  * <br>For example, calling <code>ScrollPane.setScrollPosition</code>
  77  *     and then <code>getScrollPosition</code> may return an incorrect
  78  *     value if the original request has not yet been processed.
  79  *


 737 
 738                         // Inputstream has been buffered in Properties class
 739                         properties.load(in);
 740                         in.close();
 741                     } catch (Exception e) {
 742                         // System-wide accessibility properties file does
 743                         // not exist;
 744                     }
 745                 }
 746 
 747                 // Get whether a screen magnifier is present.  First check
 748                 // the system property and then check the properties file.
 749                 String magPresent = System.getProperty("javax.accessibility.screen_magnifier_present");
 750                 if (magPresent == null) {
 751                     magPresent = properties.getProperty("screen_magnifier_present", null);
 752                     if (magPresent != null) {
 753                         System.setProperty("javax.accessibility.screen_magnifier_present", magPresent);
 754                     }
 755                 }
 756 
 757                 // Get the names of any assistive technolgies to load.  First
 758                 // check the system property and then check the properties
 759                 // file.
 760                 String classNames = System.getProperty("javax.accessibility.assistive_technologies");
 761                 if (classNames == null) {
 762                     classNames = properties.getProperty("assistive_technologies", null);
 763                     if (classNames != null) {
 764                         System.setProperty("javax.accessibility.assistive_technologies", classNames);
 765                     }
 766                 }
 767                 return classNames;
 768             }
 769         });
 770     }
 771 
 772     /**








































 773      * Loads additional classes into the VM, using the property
 774      * 'assistive_technologies' specified in the Sun reference
 775      * implementation by a line in the 'accessibility.properties'
 776      * file.  The form is "assistive_technologies=..." where
 777      * the "..." is a comma-separated list of assistive technology
 778      * classes to load.  Each class is loaded in the order given
 779      * and a single instance of each is created using
 780      * Class.forName(class).newInstance().  All errors are handled
 781      * via an AWTError exception.
 782      *
 783      * <p>The assumption is made that assistive technology classes are supplied
 784      * as part of INSTALLED (as opposed to: BUNDLED) extensions or specified
 785      * on the class path
 786      * (and therefore can be loaded using the class loader returned by
 787      * a call to <code>ClassLoader.getSystemClassLoader</code>, whose
 788      * delegation parent is the extension class loader for installed
 789      * extensions).
 790      */
 791     private static void loadAssistiveTechnologies() {
 792         // Load any assistive technologies
 793         if (atNames != null) {
 794             ClassLoader cl = ClassLoader.getSystemClassLoader();
 795             StringTokenizer parser = new StringTokenizer(atNames," ,");
 796             String atName;
 797             while (parser.hasMoreTokens()) {
 798                 atName = parser.nextToken();
 799                 try {
 800                     Class<?> clazz;
 801                     if (cl != null) {
 802                         clazz = cl.loadClass(atName);
 803                     } else {
 804                         clazz = Class.forName(atName);
 805                     }
 806                     clazz.newInstance();
 807                 } catch (ClassNotFoundException e) {
 808                     throw new AWTError("Assistive Technology not found: "
 809                             + atName);
 810                 } catch (InstantiationException e) {
 811                     throw new AWTError("Could not instantiate Assistive"
 812                             + " Technology: " + atName);
 813                 } catch (IllegalAccessException e) {
 814                     throw new AWTError("Could not access Assistive"
 815                             + " Technology: " + atName);
 816                 } catch (Exception e) {
 817                     throw new AWTError("Error trying to install Assistive"
 818                             + " Technology: " + atName + " " + e);
 819                 }
 820             }





 821         }
 822     }
 823 
 824     /**
 825      * Gets the default toolkit.
 826      * <p>
 827      * If a system property named <code>"java.awt.headless"</code> is set
 828      * to <code>true</code> then the headless implementation
 829      * of <code>Toolkit</code> is used.
 830      * <p>
 831      * If there is no <code>"java.awt.headless"</code> or it is set to
 832      * <code>false</code> and there is a system property named
 833      * <code>"awt.toolkit"</code>,
 834      * that property is treated as the name of a class that is a subclass
 835      * of <code>Toolkit</code>;
 836      * otherwise the default platform-specific implementation of
 837      * <code>Toolkit</code> is used.
 838      * <p>
 839      * Also loads additional classes into the VM, using the property
 840      * 'assistive_technologies' specified in the Sun reference
 841      * implementation by a line in the 'accessibility.properties'
 842      * file.  The form is "assistive_technologies=..." where
 843      * the "..." is a comma-separated list of assistive technology
 844      * classes to load.  Each class is loaded in the order given
 845      * and a single instance of each is created using
 846      * Class.forName(class).newInstance().  This is done just after
 847      * the AWT toolkit is created.  All errors are handled via an
 848      * AWTError exception.


































 849      * @return    the default toolkit.
 850      * @exception  AWTError  if a toolkit could not be found, or
 851      *                 if one could not be accessed or instantiated.

 852      */
 853     public static synchronized Toolkit getDefaultToolkit() {
 854         if (toolkit == null) {
 855             java.security.AccessController.doPrivileged(
 856                     new java.security.PrivilegedAction<Void>() {
 857                 public Void run() {
 858                     Class<?> cls = null;
 859                     String nm = System.getProperty("awt.toolkit");
 860                     try {
 861                         cls = Class.forName(nm);
 862                     } catch (ClassNotFoundException e) {
 863                         ClassLoader cl = ClassLoader.getSystemClassLoader();
 864                         if (cl != null) {
 865                             try {
 866                                 cls = cl.loadClass(nm);
 867                             } catch (final ClassNotFoundException ignored) {
 868                                 throw new AWTError("Toolkit not found: " + nm);
 869                             }
 870                         }
 871                     }
 872                     try {
 873                         if (cls != null) {
 874                             toolkit = (Toolkit)cls.newInstance();
 875                             if (GraphicsEnvironment.isHeadless()) {
 876                                 toolkit = new HeadlessToolkit(toolkit);
 877                             }
 878                         }
 879                     } catch (final InstantiationException ignored) {
 880                         throw new AWTError("Could not instantiate Toolkit: " + nm);
 881                     } catch (final IllegalAccessException ignored) {
 882                         throw new AWTError("Could not access Toolkit: " + nm);
 883                     }
 884                     return null;
 885                 }
 886             });

 887             loadAssistiveTechnologies();

 888         }
 889         return toolkit;
 890     }
 891 
 892     /**
 893      * Returns an image which gets pixel data from the specified file,
 894      * whose format can be either GIF, JPEG or PNG.
 895      * The underlying toolkit attempts to resolve multiple requests
 896      * with the same filename to the same returned Image.
 897      * <p>
 898      * Since the mechanism required to facilitate this sharing of
 899      * <code>Image</code> objects may continue to hold onto images
 900      * that are no longer in use for an indefinite period of time,
 901      * developers are encouraged to implement their own caching of
 902      * images by using the {@link #createImage(java.lang.String) createImage}
 903      * variant wherever available.
 904      * If the image data contained in the specified file changes,
 905      * the <code>Image</code> object returned from this method may
 906      * still contain stale information which was loaded from the
 907      * file after a prior call.


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


  40 import java.awt.dnd.InvalidDnDOperationException;
  41 import java.awt.dnd.peer.DragSourceContextPeer;
  42 import java.net.URL;
  43 import java.io.File;
  44 import java.io.FileInputStream;
  45 
  46 import java.util.*;
  47 import java.beans.PropertyChangeListener;
  48 import java.beans.PropertyChangeSupport;
  49 import sun.awt.AppContext;
  50 
  51 import sun.awt.HeadlessToolkit;
  52 import sun.awt.NullComponentPeer;
  53 import sun.awt.PeerEvent;
  54 import sun.awt.SunToolkit;
  55 import sun.awt.AWTAccessor;
  56 import sun.awt.AWTPermissions;
  57 
  58 import sun.util.CoreResourceBundleControl;
  59 
  60 import java.security.AccessController;
  61 import java.security.PrivilegedAction;
  62 import java.util.ServiceLoader;
  63 import java.util.stream.Collectors;
  64 import javax.accessibility.AccessibilitySPI;
  65 /**
  66  * This class is the abstract superclass of all actual
  67  * implementations of the Abstract Window Toolkit. Subclasses of
  68  * the <code>Toolkit</code> class are used to bind the various components
  69  * to particular native toolkit implementations.
  70  * <p>
  71  * Many GUI events may be delivered to user
  72  * asynchronously, if the opposite is not specified explicitly.
  73  * As well as
  74  * many GUI operations may be performed asynchronously.
  75  * This fact means that if the state of a component is set, and then
  76  * the state immediately queried, the returned value may not yet
  77  * reflect the requested change.  This behavior includes, but is not
  78  * limited to:
  79  * <ul>
  80  * <li>Scrolling to a specified position.
  81  * <br>For example, calling <code>ScrollPane.setScrollPosition</code>
  82  *     and then <code>getScrollPosition</code> may return an incorrect
  83  *     value if the original request has not yet been processed.
  84  *


 742 
 743                         // Inputstream has been buffered in Properties class
 744                         properties.load(in);
 745                         in.close();
 746                     } catch (Exception e) {
 747                         // System-wide accessibility properties file does
 748                         // not exist;
 749                     }
 750                 }
 751 
 752                 // Get whether a screen magnifier is present.  First check
 753                 // the system property and then check the properties file.
 754                 String magPresent = System.getProperty("javax.accessibility.screen_magnifier_present");
 755                 if (magPresent == null) {
 756                     magPresent = properties.getProperty("screen_magnifier_present", null);
 757                     if (magPresent != null) {
 758                         System.setProperty("javax.accessibility.screen_magnifier_present", magPresent);
 759                     }
 760                 }
 761 
 762                 // Get the names of any assistive technologies to load.  First
 763                 // check the system property and then check the properties
 764                 // file.
 765                 String classNames = System.getProperty("javax.accessibility.assistive_technologies");
 766                 if (classNames == null) {
 767                     classNames = properties.getProperty("assistive_technologies", null);
 768                     if (classNames != null) {
 769                         System.setProperty("javax.accessibility.assistive_technologies", classNames);
 770                     }
 771                 }
 772                 return classNames;
 773             }
 774         });
 775     }
 776 
 777     /**
 778      * Rethrow the AWTError but include the cause.
 779      * 
 780      * @param s the error message
 781      * @param e the original exception
 782      * @throw the new AWTError including the cause (the original exception) 
 783      */
 784     private static void newAWTError(Throwable e, String s) {
 785         AWTError newAWTError = new AWTError(s);
 786         newAWTError.initCause(e);
 787         throw newAWTError;
 788     }
 789     
 790     /**
 791      * When a service provider for Assistive Technology is not found look for a
 792      * supporting class on the class path and instantiate it.
 793      * 
 794      * @param atName the name of the class to be loaded
 795      */
 796     private static void fallbackToLoadClassForAT(String atName) {
 797         ClassLoader cl = ClassLoader.getSystemClassLoader();
 798         try {
 799             Class<?> clazz;
 800             if (cl != null) {
 801                 clazz = cl.loadClass(atName);
 802             } else {
 803                 clazz = Class.forName(atName);
 804             }
 805             clazz.newInstance();
 806         } catch (ClassNotFoundException e) {
 807             newAWTError(e, "Assistive Technology not found: " + atName);
 808         } catch (InstantiationException e) {
 809             newAWTError(e, "Could not instantiate Assistive Technology: " + atName);
 810         } catch (IllegalAccessException e) {
 811             newAWTError(e, "Could not access Assistive Technology: " + atName);
 812         } catch (Exception e) {
 813             newAWTError(e, "Error trying to install Assistive Technology: " + atName);
 814         }
 815     }
 816 
 817     /**
 818      * Loads additional classes into the VM, using the property
 819      * 'assistive_technologies' specified in the Sun reference
 820      * implementation by a line in the 'accessibility.properties'
 821      * file.  The form is "assistive_technologies=..." where
 822      * the "..." is a comma-separated list of assistive technology
 823      * classes to load.  Each class is loaded in the order given
 824      * and a single instance of each is created using
 825      * Class.forName(class).newInstance().  All errors are handled
 826      * via an AWTError exception.
 827      *
 828      * <p>The assumption is made that assistive technology classes are supplied
 829      * as part of INSTALLED (as opposed to: BUNDLED) extensions or specified
 830      * on the class path
 831      * (and therefore can be loaded using the class loader returned by
 832      * a call to {@code ClassLoader.getSystemClassLoader}, whose
 833      * delegation parent is the extension class loader for installed
 834      * extensions).
 835      */
 836     private static void loadAssistiveTechnologies() {
 837         // Load any assistive technologies
 838         if (atNames != null) {
 839             ClassLoader cl = ClassLoader.getSystemClassLoader();
 840             Set<String> names = Arrays.stream(atNames.split(","))
 841                                       .map(String::trim)
 842                                       .collect(Collectors.toSet());
 843             final Map<String, AccessibilitySPI> providers = new HashMap<>();
 844             AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
 845                 for (AccessibilitySPI p : ServiceLoader.load(AccessibilitySPI.class, cl)) {
 846                     String name = p.name();
 847                     if (names.contains(name) && !providers.containsKey(name)) {
 848                         p.activate();
 849                         providers.put(name, p);














 850                     }
 851                 }
 852                 return null;
 853             });
 854             names.stream()
 855                  .filter(n -> !providers.containsKey(n))
 856                  .forEach(Toolkit::fallbackToLoadClassForAT);
 857         }
 858     }
 859 
 860     /**
 861      * Gets the default toolkit.
 862      * <p>
 863      * If a system property named {@code "java.awt.headless"} is set
 864      * to {@code true} then the headless implementation
 865      * of {@code Toolkit} is used.
 866      * <p>
 867      * If there is no {@code "java.awt.headless"} or it is set to
 868      * {@code false} and there is a system property named
 869      * {@code "awt.toolkit"},
 870      * that property is treated as the name of a class that is a subclass
 871      * of {@code Toolkit};
 872      * otherwise the default platform-specific implementation of
 873      * {@code Toolkit} is used.
 874      * <p>
 875      * If this Toolkit is not a headless implementation and if they exist, service
 876      * providers of {@link javax.accessibility.AccessibilitySPI} will be loaded
 877      * if specified by the system property
 878      * {@code javax.accessibility.assistive_technologies}.
 879      * <p>
 880      * An example of setting this property is to invoke Java with
 881      * {@code -Djavax.accessibility.assistive_technologies=MyServiceProvider}.
 882      * In addition to MyServiceProvider other service providers can be specified
 883      * using a comma separated list.  Service providers are loaded after the AWT
 884      * toolkit is created. All errors are handled via an AWTError exception.
 885      * <p>
 886      * The service providers have two methods,
 887      * {@link javax.accessibility.AccessibilitySPI#name name} and
 888      * {@link javax.accessibility.AccessibilitySPI#activate activate}.  The names
 889      * specified in the assistive_technologies property are used to query each
 890      * service provider implementation.  If the requested name matches the name
 891      * of the service provider, the {@code activate} method will be invoked to
 892      * activate the matching service provider.
 893      *
 894      * @implNote
 895      * If assistive technology service providers are not specified with a system
 896      * property this implementation will fall back to looking in a properties file
 897      * located as follows:
 898      * <ul>
 899      * <li> {@code ${user.home}/.accessibility.properties}
 900      * <li> {@code ${java.home}/conf/accessibility.properties}
 901      * </ul>
 902      * Only the first of these files to be located will be consulted.  The requested
 903      * service providers are specified by setting the {@code assistive_technologies=}
 904      * property.  A single provider or a comma separated list of providers can be
 905      * specified.
 906      * <p>
 907      * Assistive technology service providers can be created as follows:
 908      * <ul>
 909      * <li>Create a subclass of {@code javax.accessibility.AccessibilitySPI},
 910      * for example, {@code my.package.ProviderImpl}.
 911      * <li>Add a {@code META-INF/services} directory as a sibling directory
 912      * to the top level directory which contains the implementation.
 913      * <li>In that directory create the file
 914      * {@code META-INF/services/javax.accessibility.AccessibilitySPI}
 915      * containing the package name of the implementation, for example,
 916      * {@code my.package.ProviderImpl}.
 917      * </ul>
 918      *
 919      * @return    the default toolkit.
 920      * @exception  AWTError  if a toolkit could not be found, or
 921      *                 if one could not be accessed or instantiated.
 922      * @see javax.accessibility.AccessibilitySPI
 923      */
 924     public static synchronized Toolkit getDefaultToolkit() {
 925         if (toolkit == null) {
 926             java.security.AccessController.doPrivileged(
 927                     new java.security.PrivilegedAction<Void>() {
 928                 public Void run() {
 929                     Class<?> cls = null;
 930                     String nm = System.getProperty("awt.toolkit");
 931                     try {
 932                         cls = Class.forName(nm);
 933                     } catch (ClassNotFoundException e) {
 934                         ClassLoader cl = ClassLoader.getSystemClassLoader();
 935                         if (cl != null) {
 936                             try {
 937                                 cls = cl.loadClass(nm);
 938                             } catch (final ClassNotFoundException ignored) {
 939                                 throw new AWTError("Toolkit not found: " + nm);
 940                             }
 941                         }
 942                     }
 943                     try {
 944                         if (cls != null) {
 945                             toolkit = (Toolkit)cls.newInstance();
 946                             if (GraphicsEnvironment.isHeadless()) {
 947                                 toolkit = new HeadlessToolkit(toolkit);
 948                             }
 949                         }
 950                     } catch (final InstantiationException ignored) {
 951                         throw new AWTError("Could not instantiate Toolkit: " + nm);
 952                     } catch (final IllegalAccessException ignored) {
 953                         throw new AWTError("Could not access Toolkit: " + nm);
 954                     }
 955                     return null;
 956                 }
 957             });
 958             if (!GraphicsEnvironment.isHeadless()) {
 959                 loadAssistiveTechnologies();
 960             }
 961         }
 962         return toolkit;
 963     }
 964 
 965     /**
 966      * Returns an image which gets pixel data from the specified file,
 967      * whose format can be either GIF, JPEG or PNG.
 968      * The underlying toolkit attempts to resolve multiple requests
 969      * with the same filename to the same returned Image.
 970      * <p>
 971      * Since the mechanism required to facilitate this sharing of
 972      * <code>Image</code> objects may continue to hold onto images
 973      * that are no longer in use for an indefinite period of time,
 974      * developers are encouraged to implement their own caching of
 975      * images by using the {@link #createImage(java.lang.String) createImage}
 976      * variant wherever available.
 977      * If the image data contained in the specified file changes,
 978      * the <code>Image</code> object returned from this method may
 979      * still contain stale information which was loaded from the
 980      * file after a prior call.


< prev index next >