|
Java example source code file (SunToolkit.java)
The SunToolkit.java Java example source code/* * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package sun.awt; import java.awt.*; import static java.awt.RenderingHints.*; import java.awt.dnd.*; import java.awt.dnd.peer.DragSourceContextPeer; import java.awt.peer.*; import java.awt.event.WindowEvent; import java.awt.event.KeyEvent; import java.awt.image.*; import java.awt.TrayIcon; import java.awt.SystemTray; import java.awt.event.InputEvent; import java.net.URL; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import sun.security.util.SecurityConstants; import sun.util.logging.PlatformLogger; import sun.misc.SoftCache; import sun.font.FontDesignMetrics; import sun.awt.im.InputContext; import sun.awt.image.*; import sun.security.action.GetPropertyAction; import sun.security.action.GetBooleanAction; import java.lang.reflect.InvocationTargetException; import java.security.AccessController; public abstract class SunToolkit extends Toolkit implements WindowClosingSupport, WindowClosingListener, ComponentFactory, InputMethodSupport, KeyboardFocusManagerPeerProvider { // 8014718: logging has been removed from SunToolkit /* Load debug settings for native code */ static { if (AccessController.doPrivileged(new GetBooleanAction("sun.awt.nativedebug"))) { DebugSettings.init(); } }; /** * Special mask for the UngrabEvent events, in addition to the * public masks defined in AWTEvent. Should be used as the mask * value for Toolkit.addAWTEventListener. */ public static final int GRAB_EVENT_MASK = 0x80000000; /* The key to put()/get() the PostEventQueue into/from the AppContext. */ private static final String POST_EVENT_QUEUE_KEY = "PostEventQueue"; /** * Number of buttons. * By default it's taken from the system. If system value does not * fit into int type range, use our own MAX_BUTTONS_SUPPORT value. */ protected static int numberOfButtons = 0; /* XFree standard mention 24 buttons as maximum: * http://www.xfree86.org/current/mouse.4.html * We workaround systems supporting more than 24 buttons. * Otherwise, we have to use long type values as masks * which leads to API change. * InputEvent.BUTTON_DOWN_MASK may contain only 21 masks due to * the 4-bytes limit for the int type. (CR 6799099) * One more bit is reserved for FIRST_HIGH_BIT. */ public final static int MAX_BUTTONS_SUPPORTED = 20; /** * Creates and initializes EventQueue instance for the specified * AppContext. * Note that event queue must be created from createNewAppContext() * only in order to ensure that EventQueue constructor obtains * the correct AppContext. * @param appContext AppContext to associate with the event queue */ private static void initEQ(AppContext appContext) { EventQueue eventQueue; String eqName = System.getProperty("AWT.EventQueueClass", "java.awt.EventQueue"); try { eventQueue = (EventQueue)Class.forName(eqName).newInstance(); } catch (Exception e) { e.printStackTrace(); System.err.println("Failed loading " + eqName + ": " + e); eventQueue = new EventQueue(); } appContext.put(AppContext.EVENT_QUEUE_KEY, eventQueue); PostEventQueue postEventQueue = new PostEventQueue(eventQueue); appContext.put(POST_EVENT_QUEUE_KEY, postEventQueue); } public SunToolkit() { } public boolean useBufferPerWindow() { return false; } public abstract WindowPeer createWindow(Window target) throws HeadlessException; public abstract FramePeer createFrame(Frame target) throws HeadlessException; public abstract FramePeer createLightweightFrame(LightweightFrame target) throws HeadlessException; public abstract DialogPeer createDialog(Dialog target) throws HeadlessException; public abstract ButtonPeer createButton(Button target) throws HeadlessException; public abstract TextFieldPeer createTextField(TextField target) throws HeadlessException; public abstract ChoicePeer createChoice(Choice target) throws HeadlessException; public abstract LabelPeer createLabel(Label target) throws HeadlessException; public abstract ListPeer createList(java.awt.List target) throws HeadlessException; public abstract CheckboxPeer createCheckbox(Checkbox target) throws HeadlessException; public abstract ScrollbarPeer createScrollbar(Scrollbar target) throws HeadlessException; public abstract ScrollPanePeer createScrollPane(ScrollPane target) throws HeadlessException; public abstract TextAreaPeer createTextArea(TextArea target) throws HeadlessException; public abstract FileDialogPeer createFileDialog(FileDialog target) throws HeadlessException; public abstract MenuBarPeer createMenuBar(MenuBar target) throws HeadlessException; public abstract MenuPeer createMenu(Menu target) throws HeadlessException; public abstract PopupMenuPeer createPopupMenu(PopupMenu target) throws HeadlessException; public abstract MenuItemPeer createMenuItem(MenuItem target) throws HeadlessException; public abstract CheckboxMenuItemPeer createCheckboxMenuItem( CheckboxMenuItem target) throws HeadlessException; public abstract DragSourceContextPeer createDragSourceContextPeer( DragGestureEvent dge) throws InvalidDnDOperationException; public abstract TrayIconPeer createTrayIcon(TrayIcon target) throws HeadlessException, AWTException; public abstract SystemTrayPeer createSystemTray(SystemTray target); public abstract boolean isTraySupported(); @SuppressWarnings("deprecation") public abstract FontPeer getFontPeer(String name, int style); public abstract RobotPeer createRobot(Robot target, GraphicsDevice screen) throws AWTException; public abstract KeyboardFocusManagerPeer getKeyboardFocusManagerPeer() throws HeadlessException; /** * The AWT lock is typically only used on Unix platforms to synchronize * access to Xlib, OpenGL, etc. However, these methods are implemented * in SunToolkit so that they can be called from shared code (e.g. * from the OGL pipeline) or from the X11 pipeline regardless of whether * XToolkit or MToolkit is currently in use. There are native macros * (such as AWT_LOCK) defined in awt.h, so if the implementation of these * methods is changed, make sure it is compatible with the native macros. * * Note: The following methods (awtLock(), awtUnlock(), etc) should be * used in place of: * synchronized (getAWTLock()) { * ... * } * * By factoring these methods out specially, we are able to change the * implementation of these methods (e.g. use more advanced locking * mechanisms) without impacting calling code. * * Sample usage: * private void doStuffWithXlib() { * assert !SunToolkit.isAWTLockHeldByCurrentThread(); * SunToolkit.awtLock(); * try { * ... * XlibWrapper.XDoStuff(); * } finally { * SunToolkit.awtUnlock(); * } * } */ private static final ReentrantLock AWT_LOCK = new ReentrantLock(); private static final Condition AWT_LOCK_COND = AWT_LOCK.newCondition(); public static final void awtLock() { AWT_LOCK.lock(); } public static final boolean awtTryLock() { return AWT_LOCK.tryLock(); } public static final void awtUnlock() { AWT_LOCK.unlock(); } public static final void awtLockWait() throws InterruptedException { AWT_LOCK_COND.await(); } public static final void awtLockWait(long timeout) throws InterruptedException { AWT_LOCK_COND.await(timeout, TimeUnit.MILLISECONDS); } public static final void awtLockNotify() { AWT_LOCK_COND.signal(); } public static final void awtLockNotifyAll() { AWT_LOCK_COND.signalAll(); } public static final boolean isAWTLockHeldByCurrentThread() { return AWT_LOCK.isHeldByCurrentThread(); } /* * Create a new AppContext, along with its EventQueue, for a * new ThreadGroup. Browser code, for example, would use this * method to create an AppContext & EventQueue for an Applet. */ public static AppContext createNewAppContext() { ThreadGroup threadGroup = Thread.currentThread().getThreadGroup(); return createNewAppContext(threadGroup); } static final AppContext createNewAppContext(ThreadGroup threadGroup) { // Create appContext before initialization of EventQueue, so all // the calls to AppContext.getAppContext() from EventQueue ctor // return correct values AppContext appContext = new AppContext(threadGroup); initEQ(appContext); return appContext; } static void wakeupEventQueue(EventQueue q, boolean isShutdown){ AWTAccessor.getEventQueueAccessor().wakeup(q, isShutdown); } /* * Fetch the peer associated with the given target (as specified * in the peer creation method). This can be used to determine * things like what the parent peer is. If the target is null * or the target can't be found (either because the a peer was * never created for it or the peer was disposed), a null will * be returned. */ protected static Object targetToPeer(Object target) { if (target != null && !GraphicsEnvironment.isHeadless()) { return AWTAutoShutdown.getInstance().getPeer(target); } return null; } protected static void targetCreatedPeer(Object target, Object peer) { if (target != null && peer != null && !GraphicsEnvironment.isHeadless()) { AWTAutoShutdown.getInstance().registerPeer(target, peer); } } protected static void targetDisposedPeer(Object target, Object peer) { if (target != null && peer != null && !GraphicsEnvironment.isHeadless()) { AWTAutoShutdown.getInstance().unregisterPeer(target, peer); } } // Maps from non-Component/MenuComponent to AppContext. // WeakHashMap<Component,AppContext> private static final Map<Object, AppContext> appContextMap = Collections.synchronizedMap(new WeakHashMap<Object, AppContext>()); /** * Sets the appContext field of target. If target is not a Component or * MenuComponent, this returns false. */ private static boolean setAppContext(Object target, AppContext context) { if (target instanceof Component) { AWTAccessor.getComponentAccessor(). setAppContext((Component)target, context); } else if (target instanceof MenuComponent) { AWTAccessor.getMenuComponentAccessor(). setAppContext((MenuComponent)target, context); } else { return false; } return true; } /** * Returns the appContext field for target. If target is not a * Component or MenuComponent this returns null. */ private static AppContext getAppContext(Object target) { if (target instanceof Component) { return AWTAccessor.getComponentAccessor(). getAppContext((Component)target); } else if (target instanceof MenuComponent) { return AWTAccessor.getMenuComponentAccessor(). getAppContext((MenuComponent)target); } else { return null; } } /* * Fetch the AppContext associated with the given target. * This can be used to determine things like which EventQueue * to use for posting events to a Component. If the target is * null or the target can't be found, a null with be returned. */ public static AppContext targetToAppContext(Object target) { if (target == null || GraphicsEnvironment.isHeadless()) { return null; } AppContext context = getAppContext(target); if (context == null) { // target is not a Component/MenuComponent, try the // appContextMap. context = appContextMap.get(target); } return context; } /** * Sets the synchronous status of focus requests on lightweight * components in the specified window to the specified value. * If the boolean parameter is <code>true then the focus * requests on lightweight components will be performed * synchronously, if it is <code>false, then asynchronously. * By default, all windows have their lightweight request status * set to asynchronous. * <p> * The application can only set the status of lightweight focus * requests to synchronous for any of its windows if it doesn't * perform focus transfers between different heavyweight containers. * In this case the observable focus behaviour is the same as with * asynchronous status. * <p> * If the application performs focus transfer between different * heavyweight containers and sets the lightweight focus request * status to synchronous for any of its windows, then further focus * behaviour is unspecified. * <p> * @param w window for which the lightweight focus request status * should be set * @param status the value of lightweight focus request status */ public static void setLWRequestStatus(Window changed,boolean status){ AWTAccessor.getWindowAccessor().setLWRequestStatus(changed, status); }; public static void checkAndSetPolicy(Container cont) { FocusTraversalPolicy defaultPolicy = KeyboardFocusManager. getCurrentKeyboardFocusManager(). getDefaultFocusTraversalPolicy(); cont.setFocusTraversalPolicy(defaultPolicy); } private static FocusTraversalPolicy createLayoutPolicy() { FocusTraversalPolicy policy = null; try { Class<?> layoutPolicyClass = Class.forName("javax.swing.LayoutFocusTraversalPolicy"); policy = (FocusTraversalPolicy)layoutPolicyClass.newInstance(); } catch (ClassNotFoundException e) { assert false; } catch (InstantiationException e) { assert false; } catch (IllegalAccessException e) { assert false; } return policy; } /* * Insert a mapping from target to AppContext, for later retrieval * via targetToAppContext() above. */ public static void insertTargetMapping(Object target, AppContext appContext) { if (!GraphicsEnvironment.isHeadless()) { if (!setAppContext(target, appContext)) { // Target is not a Component/MenuComponent, use the private Map // instead. appContextMap.put(target, appContext); } } } /* * Post an AWTEvent to the Java EventQueue, using the PostEventQueue * to avoid possibly calling client code (EventQueueSubclass.postEvent()) * on the toolkit (AWT-Windows/AWT-Motif) thread. This function should * not be called under another lock since it locks the EventQueue. * See bugids 4632918, 4526597. */ public static void postEvent(AppContext appContext, AWTEvent event) { if (event == null) { throw new NullPointerException(); } AWTAccessor.SequencedEventAccessor sea = AWTAccessor.getSequencedEventAccessor(); if (sea != null && sea.isSequencedEvent(event)) { AWTEvent nested = sea.getNested(event); if (nested.getID() == WindowEvent.WINDOW_LOST_FOCUS && nested instanceof TimedWindowEvent) { TimedWindowEvent twe = (TimedWindowEvent)nested; ((SunToolkit)Toolkit.getDefaultToolkit()). setWindowDeactivationTime((Window)twe.getSource(), twe.getWhen()); } } // All events posted via this method are system-generated. // Placing the following call here reduces considerably the // number of places throughout the toolkit that would // otherwise have to be modified to precisely identify // system-generated events. setSystemGenerated(event); AppContext eventContext = targetToAppContext(event.getSource()); if (eventContext != null && !eventContext.equals(appContext)) { throw new RuntimeException("Event posted on wrong app context : " + event); } PostEventQueue postEventQueue = (PostEventQueue)appContext.get(POST_EVENT_QUEUE_KEY); if (postEventQueue != null) { postEventQueue.postEvent(event); } } /* * Post AWTEvent of high priority. */ public static void postPriorityEvent(final AWTEvent e) { PeerEvent pe = new PeerEvent(Toolkit.getDefaultToolkit(), new Runnable() { public void run() { AWTAccessor.getAWTEventAccessor().setPosted(e); ((Component)e.getSource()).dispatchEvent(e); } }, PeerEvent.ULTIMATE_PRIORITY_EVENT); postEvent(targetToAppContext(e.getSource()), pe); } /* * Flush any pending events which haven't been posted to the AWT * EventQueue yet. */ public static void flushPendingEvents() { AppContext appContext = AppContext.getAppContext(); flushPendingEvents(appContext); } /* * Flush the PostEventQueue for the right AppContext. * The default flushPendingEvents only flushes the thread-local context, * which is not always correct, c.f. 3746956 */ public static void flushPendingEvents(AppContext appContext) { PostEventQueue postEventQueue = (PostEventQueue)appContext.get(POST_EVENT_QUEUE_KEY); if (postEventQueue != null) { postEventQueue.flush(); } } /* * Execute a chunk of code on the Java event handler thread for the * given target. Does not wait for the execution to occur before * returning to the caller. */ public static void executeOnEventHandlerThread(Object target, Runnable runnable) { executeOnEventHandlerThread(new PeerEvent(target, runnable, PeerEvent.PRIORITY_EVENT)); } /* * Fixed 5064013: the InvocationEvent time should be equals * the time of the ActionEvent */ @SuppressWarnings("serial") public static void executeOnEventHandlerThread(Object target, Runnable runnable, final long when) { executeOnEventHandlerThread( new PeerEvent(target, runnable, PeerEvent.PRIORITY_EVENT) { public long getWhen() { return when; } }); } /* * Execute a chunk of code on the Java event handler thread for the * given target. Does not wait for the execution to occur before * returning to the caller. */ public static void executeOnEventHandlerThread(PeerEvent peerEvent) { postEvent(targetToAppContext(peerEvent.getSource()), peerEvent); } /* * Execute a chunk of code on the Java event handler thread. The * method takes into account provided AppContext and sets * <code>SunToolkit.getDefaultToolkit() as a target of the * event. See 6451487 for detailes. * Does not wait for the execution to occur before returning to * the caller. */ public static void invokeLaterOnAppContext( AppContext appContext, Runnable dispatcher) { postEvent(appContext, new PeerEvent(Toolkit.getDefaultToolkit(), dispatcher, PeerEvent.PRIORITY_EVENT)); } /* * Execute a chunk of code on the Java event handler thread for the * given target. Waits for the execution to occur before returning * to the caller. */ public static void executeOnEDTAndWait(Object target, Runnable runnable) throws InterruptedException, InvocationTargetException { if (EventQueue.isDispatchThread()) { throw new Error("Cannot call executeOnEDTAndWait from any event dispatcher thread"); } class AWTInvocationLock {} Object lock = new AWTInvocationLock(); PeerEvent event = new PeerEvent(target, runnable, lock, true, PeerEvent.PRIORITY_EVENT); synchronized (lock) { executeOnEventHandlerThread(event); while(!event.isDispatched()) { lock.wait(); } } Throwable eventThrowable = event.getThrowable(); if (eventThrowable != null) { throw new InvocationTargetException(eventThrowable); } } /* * Returns true if the calling thread is the event dispatch thread * contained within AppContext which associated with the given target. * Use this call to ensure that a given task is being executed * (or not being) on the event dispatch thread for the given target. */ public static boolean isDispatchThreadForAppContext(Object target) { AppContext appContext = targetToAppContext(target); EventQueue eq = (EventQueue)appContext.get(AppContext.EVENT_QUEUE_KEY); AWTAccessor.EventQueueAccessor accessor = AWTAccessor.getEventQueueAccessor(); return accessor.isDispatchThreadImpl(eq); } public Dimension getScreenSize() { return new Dimension(getScreenWidth(), getScreenHeight()); } protected abstract int getScreenWidth(); protected abstract int getScreenHeight(); @SuppressWarnings("deprecation") public FontMetrics getFontMetrics(Font font) { return FontDesignMetrics.getMetrics(font); } @SuppressWarnings("deprecation") public String[] getFontList() { String[] hardwiredFontList = { Font.DIALOG, Font.SANS_SERIF, Font.SERIF, Font.MONOSPACED, Font.DIALOG_INPUT // -- Obsolete font names from 1.0.2. It was decided that // -- getFontList should not return these old names: // "Helvetica", "TimesRoman", "Courier", "ZapfDingbats" }; return hardwiredFontList; } public PanelPeer createPanel(Panel target) { return (PanelPeer)createComponent(target); } public CanvasPeer createCanvas(Canvas target) { return (CanvasPeer)createComponent(target); } /** * Disables erasing of background on the canvas before painting if * this is supported by the current toolkit. It is recommended to * call this method early, before the Canvas becomes displayable, * because some Toolkit implementations do not support changing * this property once the Canvas becomes displayable. */ public void disableBackgroundErase(Canvas canvas) { disableBackgroundEraseImpl(canvas); } /** * Disables the native erasing of the background on the given * component before painting if this is supported by the current * toolkit. This only has an effect for certain components such as * Canvas, Panel and Window. It is recommended to call this method * early, before the Component becomes displayable, because some * Toolkit implementations do not support changing this property * once the Component becomes displayable. */ public void disableBackgroundErase(Component component) { disableBackgroundEraseImpl(component); } private void disableBackgroundEraseImpl(Component component) { AWTAccessor.getComponentAccessor().setBackgroundEraseDisabled(component, true); } /** * Returns the value of "sun.awt.noerasebackground" property. Default * value is {@code false}. */ public static boolean getSunAwtNoerasebackground() { return AccessController.doPrivileged(new GetBooleanAction("sun.awt.noerasebackground")); } /** * Returns the value of "sun.awt.erasebackgroundonresize" property. Default * value is {@code false}. */ public static boolean getSunAwtErasebackgroundonresize() { return AccessController.doPrivileged(new GetBooleanAction("sun.awt.erasebackgroundonresize")); } static final SoftCache imgCache = new SoftCache(); static Image getImageFromHash(Toolkit tk, URL url) { SecurityManager sm = System.getSecurityManager(); if (sm != null) { try { java.security.Permission perm = url.openConnection().getPermission(); if (perm != null) { try { sm.checkPermission(perm); } catch (SecurityException se) { // fallback to checkRead/checkConnect for pre 1.2 // security managers if ((perm instanceof java.io.FilePermission) && perm.getActions().indexOf("read") != -1) { sm.checkRead(perm.getName()); } else if ((perm instanceof java.net.SocketPermission) && perm.getActions().indexOf("connect") != -1) { sm.checkConnect(url.getHost(), url.getPort()); } else { throw se; } } } } catch (java.io.IOException ioe) { sm.checkConnect(url.getHost(), url.getPort()); } } synchronized (imgCache) { Image img = (Image)imgCache.get(url); if (img == null) { try { img = tk.createImage(new URLImageSource(url)); imgCache.put(url, img); } catch (Exception e) { } } return img; } } static Image getImageFromHash(Toolkit tk, String filename) { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkRead(filename); } synchronized (imgCache) { Image img = (Image)imgCache.get(filename); if (img == null) { try { img = tk.createImage(new FileImageSource(filename)); imgCache.put(filename, img); } catch (Exception e) { } } return img; } } public Image getImage(String filename) { return getImageFromHash(this, filename); } public Image getImage(URL url) { return getImageFromHash(this, url); } public Image createImage(String filename) { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkRead(filename); } return createImage(new FileImageSource(filename)); } public Image createImage(URL url) { SecurityManager sm = System.getSecurityManager(); if (sm != null) { try { java.security.Permission perm = url.openConnection().getPermission(); if (perm != null) { try { sm.checkPermission(perm); } catch (SecurityException se) { // fallback to checkRead/checkConnect for pre 1.2 // security managers if ((perm instanceof java.io.FilePermission) && perm.getActions().indexOf("read") != -1) { sm.checkRead(perm.getName()); } else if ((perm instanceof java.net.SocketPermission) && perm.getActions().indexOf("connect") != -1) { sm.checkConnect(url.getHost(), url.getPort()); } else { throw se; } } } } catch (java.io.IOException ioe) { sm.checkConnect(url.getHost(), url.getPort()); } } return createImage(new URLImageSource(url)); } public Image createImage(byte[] data, int offset, int length) { return createImage(new ByteArrayImageSource(data, offset, length)); } public Image createImage(ImageProducer producer) { return new ToolkitImage(producer); } public int checkImage(Image img, int w, int h, ImageObserver o) { if (!(img instanceof ToolkitImage)) { return ImageObserver.ALLBITS; } ToolkitImage tkimg = (ToolkitImage)img; int repbits; if (w == 0 || h == 0) { repbits = ImageObserver.ALLBITS; } else { repbits = tkimg.getImageRep().check(o); } return tkimg.check(o) | repbits; } public boolean prepareImage(Image img, int w, int h, ImageObserver o) { if (w == 0 || h == 0) { return true; } // Must be a ToolkitImage if (!(img instanceof ToolkitImage)) { return true; } ToolkitImage tkimg = (ToolkitImage)img; if (tkimg.hasError()) { if (o != null) { o.imageUpdate(img, ImageObserver.ERROR|ImageObserver.ABORT, -1, -1, -1, -1); } return false; } ImageRepresentation ir = tkimg.getImageRep(); return ir.prepare(o); } /** * Scans {@code imageList} for best-looking image of specified dimensions. * Image can be scaled and/or padded with transparency. */ public static BufferedImage getScaledIconImage(java.util.List<Image> imageList, int width, int height) { if (width == 0 || height == 0) { return null; } Image bestImage = null; int bestWidth = 0; int bestHeight = 0; double bestSimilarity = 3; //Impossibly high value double bestScaleFactor = 0; for (Iterator<Image> i = imageList.iterator();i.hasNext();) { //Iterate imageList looking for best matching image. //'Similarity' measure is defined as good scale factor and small insets. //best possible similarity is 0 (no scale, no insets). //It's found while the experiments that good-looking result is achieved //with scale factors x1, x3/4, x2/3, xN, x1/N. Image im = i.next(); if (im == null) { continue; } if (im instanceof ToolkitImage) { ImageRepresentation ir = ((ToolkitImage)im).getImageRep(); ir.reconstruct(ImageObserver.ALLBITS); } int iw; int ih; try { iw = im.getWidth(null); ih = im.getHeight(null); } catch (Exception e){ continue; } if (iw > 0 && ih > 0) { //Calc scale factor double scaleFactor = Math.min((double)width / (double)iw, (double)height / (double)ih); //Calculate scaled image dimensions //adjusting scale factor to nearest "good" value int adjw = 0; int adjh = 0; double scaleMeasure = 1; //0 - best (no) scale, 1 - impossibly bad if (scaleFactor >= 2) { //Need to enlarge image more than twice //Round down scale factor to multiply by integer value scaleFactor = Math.floor(scaleFactor); adjw = iw * (int)scaleFactor; adjh = ih * (int)scaleFactor; scaleMeasure = 1.0 - 0.5 / scaleFactor; } else if (scaleFactor >= 1) { //Don't scale scaleFactor = 1.0; adjw = iw; adjh = ih; scaleMeasure = 0; } else if (scaleFactor >= 0.75) { //Multiply by 3/4 scaleFactor = 0.75; adjw = iw * 3 / 4; adjh = ih * 3 / 4; scaleMeasure = 0.3; } else if (scaleFactor >= 0.6666) { //Multiply by 2/3 scaleFactor = 0.6666; adjw = iw * 2 / 3; adjh = ih * 2 / 3; scaleMeasure = 0.33; } else { //Multiply size by 1/scaleDivider //where scaleDivider is minimum possible integer //larger than 1/scaleFactor double scaleDivider = Math.ceil(1.0 / scaleFactor); scaleFactor = 1.0 / scaleDivider; adjw = (int)Math.round((double)iw / scaleDivider); adjh = (int)Math.round((double)ih / scaleDivider); scaleMeasure = 1.0 - 1.0 / scaleDivider; } double similarity = ((double)width - (double)adjw) / (double)width + ((double)height - (double)adjh) / (double)height + //Large padding is bad scaleMeasure; //Large rescale is bad if (similarity < bestSimilarity) { bestSimilarity = similarity; bestScaleFactor = scaleFactor; bestImage = im; bestWidth = adjw; bestHeight = adjh; } if (similarity == 0) break; } } if (bestImage == null) { //No images were found, possibly all are broken return null; } BufferedImage bimage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); Graphics2D g = bimage.createGraphics(); g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); try { int x = (width - bestWidth) / 2; int y = (height - bestHeight) / 2; g.drawImage(bestImage, x, y, bestWidth, bestHeight, null); } finally { g.dispose(); } return bimage; } public static DataBufferInt getScaledIconData(java.util.List<Image> imageList, int width, int height) { BufferedImage bimage = getScaledIconImage(imageList, width, height); if (bimage == null) { return null; } Raster raster = bimage.getRaster(); DataBuffer buffer = raster.getDataBuffer(); return (DataBufferInt)buffer; } protected EventQueue getSystemEventQueueImpl() { return getSystemEventQueueImplPP(); } // Package private implementation static EventQueue getSystemEventQueueImplPP() { return getSystemEventQueueImplPP(AppContext.getAppContext()); } public static EventQueue getSystemEventQueueImplPP(AppContext appContext) { EventQueue theEventQueue = (EventQueue)appContext.get(AppContext.EVENT_QUEUE_KEY); return theEventQueue; } /** * Give native peers the ability to query the native container * given a native component (eg the direct parent may be lightweight). */ public static Container getNativeContainer(Component c) { return Toolkit.getNativeContainer(c); } /** * Gives native peers the ability to query the closest HW component. * If the given component is heavyweight, then it returns this. Otherwise, * it goes one level up in the hierarchy and tests next component. */ public static Component getHeavyweightComponent(Component c) { while (c != null && AWTAccessor.getComponentAccessor().isLightweight(c)) { c = AWTAccessor.getComponentAccessor().getParent(c); } return c; } /** * Returns key modifiers used by Swing to set up a focus accelerator key stroke. */ public int getFocusAcceleratorKeyMask() { return InputEvent.ALT_MASK; } /** * Tests whether specified key modifiers mask can be used to enter a printable * character. This is a default implementation of this method, which reflects * the way things work on Windows: here, pressing ctrl + alt allows user to enter * characters from the extended character set (like euro sign or math symbols) */ public boolean isPrintableCharacterModifiersMask(int mods) { return ((mods & InputEvent.ALT_MASK) == (mods & InputEvent.CTRL_MASK)); } /** * Returns whether popup is allowed to be shown above the task bar. * This is a default implementation of this method, which checks * corresponding security permission. */ public boolean canPopupOverlapTaskBar() { boolean result = true; try { SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission( SecurityConstants.AWT.SET_WINDOW_ALWAYS_ON_TOP_PERMISSION); } } catch (SecurityException se) { // There is no permission to show popups over the task bar result = false; } return result; } /** * Returns a new input method window, with behavior as specified in * {@link java.awt.im.spi.InputMethodContext#createInputMethodWindow}. * If the inputContext is not null, the window should return it from its * getInputContext() method. The window needs to implement * sun.awt.im.InputMethodWindow. * <p> * SunToolkit subclasses can override this method to return better input * method windows. */ public Window createInputMethodWindow(String title, InputContext context) { return new sun.awt.im.SimpleInputMethodWindow(title, context); } /** * Returns whether enableInputMethods should be set to true for peered * TextComponent instances on this platform. False by default. */ public boolean enableInputMethodsForTextComponent() { return false; } private static Locale startupLocale = null; /** * Returns the locale in which the runtime was started. */ public static Locale getStartupLocale() { if (startupLocale == null) { String language, region, country, variant; language = AccessController.doPrivileged( new GetPropertyAction("user.language", "en")); // for compatibility, check for old user.region property region = AccessController.doPrivileged( new GetPropertyAction("user.region")); if (region != null) { // region can be of form country, country_variant, or _variant int i = region.indexOf('_'); if (i >= 0) { country = region.substring(0, i); variant = region.substring(i + 1); } else { country = region; variant = ""; } } else { country = AccessController.doPrivileged( new GetPropertyAction("user.country", "")); variant = AccessController.doPrivileged( new GetPropertyAction("user.variant", "")); } startupLocale = new Locale(language, country, variant); } return startupLocale; } /** * Returns the default keyboard locale of the underlying operating system */ public Locale getDefaultKeyboardLocale() { return getStartupLocale(); } private static String dataTransfererClassName = null; protected static void setDataTransfererClassName(String className) { dataTransfererClassName = className; } public static String getDataTransfererClassName() { if (dataTransfererClassName == null) { Toolkit.getDefaultToolkit(); // transferer set during toolkit init } return dataTransfererClassName; } // Support for window closing event notifications private transient WindowClosingListener windowClosingListener = null; /** * @see sun.awt.WindowClosingSupport#getWindowClosingListener */ public WindowClosingListener getWindowClosingListener() { return windowClosingListener; } /** * @see sun.awt.WindowClosingSupport#setWindowClosingListener */ public void setWindowClosingListener(WindowClosingListener wcl) { windowClosingListener = wcl; } /** * @see sun.awt.WindowClosingListener#windowClosingNotify */ public RuntimeException windowClosingNotify(WindowEvent event) { if (windowClosingListener != null) { return windowClosingListener.windowClosingNotify(event); } else { return null; } } /** * @see sun.awt.WindowClosingListener#windowClosingDelivered */ public RuntimeException windowClosingDelivered(WindowEvent event) { if (windowClosingListener != null) { return windowClosingListener.windowClosingDelivered(event); } else { return null; } } private static DefaultMouseInfoPeer mPeer = null; protected synchronized MouseInfoPeer getMouseInfoPeer() { if (mPeer == null) { mPeer = new DefaultMouseInfoPeer(); } return mPeer; } /** * Returns whether default toolkit needs the support of the xembed * from embedding host(if any). * @return <code>true, if XEmbed is needed, Other Java examples (source code examples)Here is a short list of links related to this Java SunToolkit.java source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.