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
23 * questions.
24 */
25
26 package java.awt;
27
28 import java.awt.datatransfer.Clipboard;
29 import java.awt.dnd.DragGestureListener;
30 import java.awt.dnd.DragGestureRecognizer;
31 import java.awt.dnd.DragSource;
32 import java.awt.event.*;
33 import java.awt.im.InputMethodHighlight;
34 import java.awt.image.ColorModel;
35 import java.awt.image.ImageObserver;
36 import java.awt.image.ImageProducer;
37 import java.beans.PropertyChangeEvent;
38 import java.beans.PropertyChangeListener;
39 import java.beans.PropertyChangeSupport;
40 import java.io.File;
41 import java.io.FileInputStream;
42 import java.net.URL;
43 import java.util.ArrayList;
44 import java.util.EventListener;
45 import java.util.HashMap;
46 import java.util.Map;
47 import java.util.MissingResourceException;
48 import java.util.Properties;
49 import java.util.ResourceBundle;
50 import java.util.StringTokenizer;
51 import java.util.WeakHashMap;
52
53 import sun.awt.AWTAccessor;
54 import sun.awt.AWTPermissions;
55 import sun.awt.AppContext;
56 import sun.awt.HeadlessToolkit;
57 import sun.awt.PeerEvent;
58 import sun.awt.SunToolkit;
59
60 import java.security.AccessController;
61 import java.security.PrivilegedAction;
62 import java.util.Arrays;
63 import java.util.ServiceLoader;
64 import java.util.Set;
65 import java.util.stream.Collectors;
66 import javax.accessibility.AccessibilityProvider;
67
68 /**
69 * This class is the abstract superclass of all actual
70 * implementations of the Abstract Window Toolkit. Subclasses of
71 * the {@code Toolkit} class are used to bind the various components
72 * to particular native toolkit implementations.
73 * <p>
74 * Many GUI events may be delivered to user
75 * asynchronously, if the opposite is not specified explicitly.
76 * As well as
77 * many GUI operations may be performed asynchronously.
78 * This fact means that if the state of a component is set, and then
79 * the state immediately queried, the returned value may not yet
80 * reflect the requested change. This behavior includes, but is not
81 * limited to:
82 * <ul>
83 * <li>Scrolling to a specified position.
84 * <br>For example, calling {@code ScrollPane.setScrollPosition}
85 * and then {@code getScrollPosition} may return an incorrect
86 * value if the original request has not yet been processed.
621 * file after a prior call.
622 * Previously loaded image data can be manually discarded by
623 * calling the {@link Image#flush flush} method on the
624 * returned {@code Image}.
625 * <p>
626 * This method first checks if there is a security manager installed.
627 * If so, the method calls the security manager's
628 * {@code checkRead} method with the file specified to ensure
629 * that the access to the image is allowed.
630 * @param filename the name of a file containing pixel data
631 * in a recognized file format.
632 * @return an image which gets its pixel data from
633 * the specified file.
634 * @throws SecurityException if a security manager exists and its
635 * checkRead method doesn't allow the operation.
636 * @see #createImage(java.lang.String)
637 */
638 public abstract Image getImage(String filename);
639
640 /**
641 * Returns an image which gets pixel data from the specified URL.
642 * The pixel data referenced by the specified URL must be in one
643 * of the following formats: GIF, JPEG or PNG.
644 * The underlying toolkit attempts to resolve multiple requests
645 * with the same URL to the same returned Image.
646 * <p>
647 * Since the mechanism required to facilitate this sharing of
648 * {@code Image} objects may continue to hold onto images
649 * that are no longer in use for an indefinite period of time,
650 * developers are encouraged to implement their own caching of
651 * images by using the {@link #createImage(java.net.URL) createImage}
652 * variant wherever available.
653 * If the image data stored at the specified URL changes,
654 * the {@code Image} object returned from this method may
655 * still contain stale information which was fetched from the
656 * URL after a prior call.
657 * Previously loaded image data can be manually discarded by
658 * calling the {@link Image#flush flush} method on the
659 * returned {@code Image}.
660 * <p>
|
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
23 * questions.
24 */
25
26 package java.awt;
27
28 import java.awt.datatransfer.Clipboard;
29 import java.awt.dnd.DragGestureListener;
30 import java.awt.dnd.DragGestureRecognizer;
31 import java.awt.dnd.DragSource;
32 import java.awt.event.*;
33 import java.awt.im.InputMethodHighlight;
34 import java.awt.image.ColorModel;
35 import java.awt.image.ImageObserver;
36 import java.awt.image.ImageProducer;
37 import java.awt.image.MultiResolutionImage;
38 import java.beans.PropertyChangeEvent;
39 import java.beans.PropertyChangeListener;
40 import java.beans.PropertyChangeSupport;
41 import java.io.File;
42 import java.io.FileInputStream;
43 import java.net.URL;
44 import java.util.ArrayList;
45 import java.util.EventListener;
46 import java.util.HashMap;
47 import java.util.Map;
48 import java.util.MissingResourceException;
49 import java.util.Properties;
50 import java.util.ResourceBundle;
51 import java.util.WeakHashMap;
52
53 import sun.awt.AWTAccessor;
54 import sun.awt.AWTPermissions;
55 import sun.awt.AppContext;
56 import sun.awt.HeadlessToolkit;
57 import sun.awt.PeerEvent;
58 import sun.awt.SunToolkit;
59
60 import java.security.AccessController;
61 import java.security.PrivilegedAction;
62 import java.util.Arrays;
63 import java.util.LinkedList;
64 import java.util.ServiceLoader;
65 import java.util.Set;
66 import java.util.stream.Collectors;
67 import javax.accessibility.AccessibilityProvider;
68 import sun.awt.image.MultiResolutionToolkitImage;
69 import sun.awt.image.MultiResolutionToolkitImage.ResolutionVariantItem;
70
71 /**
72 * This class is the abstract superclass of all actual
73 * implementations of the Abstract Window Toolkit. Subclasses of
74 * the {@code Toolkit} class are used to bind the various components
75 * to particular native toolkit implementations.
76 * <p>
77 * Many GUI events may be delivered to user
78 * asynchronously, if the opposite is not specified explicitly.
79 * As well as
80 * many GUI operations may be performed asynchronously.
81 * This fact means that if the state of a component is set, and then
82 * the state immediately queried, the returned value may not yet
83 * reflect the requested change. This behavior includes, but is not
84 * limited to:
85 * <ul>
86 * <li>Scrolling to a specified position.
87 * <br>For example, calling {@code ScrollPane.setScrollPosition}
88 * and then {@code getScrollPosition} may return an incorrect
89 * value if the original request has not yet been processed.
624 * file after a prior call.
625 * Previously loaded image data can be manually discarded by
626 * calling the {@link Image#flush flush} method on the
627 * returned {@code Image}.
628 * <p>
629 * This method first checks if there is a security manager installed.
630 * If so, the method calls the security manager's
631 * {@code checkRead} method with the file specified to ensure
632 * that the access to the image is allowed.
633 * @param filename the name of a file containing pixel data
634 * in a recognized file format.
635 * @return an image which gets its pixel data from
636 * the specified file.
637 * @throws SecurityException if a security manager exists and its
638 * checkRead method doesn't allow the operation.
639 * @see #createImage(java.lang.String)
640 */
641 public abstract Image getImage(String filename);
642
643 /**
644 * The MediaResolutionNamingScheme class stores the resolution variant
645 * qualifier as well as scaled factors associated with it.
646 *
647 * @see #getImageUsingNamingSchemes
648 * @see MultiResolutionImage
649 *
650 * @since 9
651 */
652 public static class MediaResolutionNamingScheme {
653
654 private final String qualifier;
655 private final float scale;
656
657 /**
658 * Creates a new instance of MediaResolutionNamingScheme.
659 *
660 * @param qualifier the resolution-variant qualifier
661 * @param scale the scale associated with the resolution variant qualifier
662 *
663 * @since 9
664 */
665 public MediaResolutionNamingScheme(String qualifier, float scale) {
666 this.qualifier = qualifier;
667 this.scale = scale;
668 }
669
670 /**
671 * @return the resolution-variant qualifier
672 *
673 * @since 9
674 */
675
676 public String getQualifier() {
677 return qualifier;
678 }
679
680 /**
681 * @return scale factor
682 *
683 * @since 9
684 */
685 public float getScale() {
686 return scale;
687 }
688 }
689
690 /**
691 * Returns an image with resolution variants based on the provided media
692 * resolution naming scheme. This method is useful when it is necessary to
693 * provide an image with resolution variants for HiDPI displays.
694 * <p>
695 * For example, if HiDPI display supports scales 1.5 and 2 the following steps
696 * can be used to provide an image together with its high resolution variants.
697 * Put scaled versions of the original image in the same directory using
698 * naming convention {@literal @150pct} for scale 1.5 and {@literal @2x}
699 * for scale 2 The qualifier need to be placed between the image
700 * name and extension:
701 * <ul>
702 * <li>{@literal image_name.ext} - original image</li>
703 * <li>{@literal image_name@150pct.ext} - resolution variant for scale 1.5
704 * and qualifier {@literal @150pct}</li>
705 * <li>{@literal image_name@2x.ext} - resolution variant for scale 2 and
706 * qualifier {@literal @2x}</li>
707 * </ul>
708 * Call {@code getImageUsingNamingSchemes)} method providing only path to the
709 * original image and naming schemes which include defined quilifiers and scales.
710 * <pre> {@code
711 * Image image = toolkit.getImageUsingNamingSchemes(fileName,
712 * new Toolkit.MediaResolutionNamingScheme("@150pct", 1.5f),
713 * new Toolkit.MediaResolutionNamingScheme("@2x", 2f)
714 * );
715 * } </pre>
716 * <p>
717 * The resolution variant is not added if an image for the given naming scheme
718 * is missed. If all resolution variants are missed the returned result
719 * will be the same as call to the {@code getImage(fileName)} method.
720 *
721 * @param fileName file path to the original image
722 * @param namingSchemes array of naming scheme that contains resolution
723 * variant qualifier and associated with it scale factor
724 * @return an image with with resolution variants
725 *
726 * @see #getImage
727 * @see MediaResolutionNamingScheme
728 * @see MultiResolutionImage
729 */
730 public Image getImageUsingNamingSchemes(String fileName,
731 MediaResolutionNamingScheme... namingSchemes) {
732
733 Image baseimage = getImage(fileName);
734
735 if (namingSchemes.length == 0
736 || (baseimage instanceof MultiResolutionImage)) {
737 return baseimage;
738 }
739
740 int slash = fileName.lastIndexOf('/');
741 String name = (slash < 0) ? fileName : fileName.substring(slash + 1);
742
743 int dot = name.lastIndexOf('.');
744 String ext = (dot < 0) ? "" : name.substring(dot);
745 name = (dot < 0) ? name : name.substring(0, dot);
746 String prefix = (slash < 0) ? name : fileName.substring(0, slash + 1) + name;
747
748 java.util.List<ResolutionVariantItem> rvItems = new LinkedList<>();
749
750 for (MediaResolutionNamingScheme scheme : namingSchemes) {
751 String rvFileName = prefix + scheme.getQualifier() + ext;
752 if (SunToolkit.imageExists(rvFileName)) {
753 Image rvImage = toolkit.getImage(rvFileName);
754 float scale = scheme.getScale();
755 rvItems.add(new ResolutionVariantItem(rvImage, scale, scale));
756 }
757 }
758
759 if (rvItems.isEmpty()) {
760 return baseimage;
761 }
762
763 return new MultiResolutionToolkitImage(baseimage, rvItems);
764 }
765
766 /**
767 * Returns an image which gets pixel data from the specified URL.
768 * The pixel data referenced by the specified URL must be in one
769 * of the following formats: GIF, JPEG or PNG.
770 * The underlying toolkit attempts to resolve multiple requests
771 * with the same URL to the same returned Image.
772 * <p>
773 * Since the mechanism required to facilitate this sharing of
774 * {@code Image} objects may continue to hold onto images
775 * that are no longer in use for an indefinite period of time,
776 * developers are encouraged to implement their own caching of
777 * images by using the {@link #createImage(java.net.URL) createImage}
778 * variant wherever available.
779 * If the image data stored at the specified URL changes,
780 * the {@code Image} object returned from this method may
781 * still contain stale information which was fetched from the
782 * URL after a prior call.
783 * Previously loaded image data can be manually discarded by
784 * calling the {@link Image#flush flush} method on the
785 * returned {@code Image}.
786 * <p>
|