|
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.