feat(jdk8): move files to new folder to avoid resources compiled.

This commit is contained in:
2025-09-07 15:25:52 +08:00
parent 3f0047bf6f
commit 8c35cfb1c0
17415 changed files with 217 additions and 213 deletions

View File

@@ -0,0 +1,595 @@
/*
* Copyright (c) 1995, 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 java.applet;
import java.awt.*;
import java.awt.image.ColorModel;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.URL;
import java.net.MalformedURLException;
import java.util.Hashtable;
import java.util.Locale;
import javax.accessibility.*;
/**
* An applet is a small program that is intended not to be run on
* its own, but rather to be embedded inside another application.
* <p>
* The <code>Applet</code> class must be the superclass of any
* applet that is to be embedded in a Web page or viewed by the Java
* Applet Viewer. The <code>Applet</code> class provides a standard
* interface between applets and their environment.
*
* @author Arthur van Hoff
* @author Chris Warth
* @since JDK1.0
*/
public class Applet extends Panel {
/**
* Constructs a new Applet.
* <p>
* Note: Many methods in <code>java.applet.Applet</code>
* may be invoked by the applet only after the applet is
* fully constructed; applet should avoid calling methods
* in <code>java.applet.Applet</code> in the constructor.
*
* @exception HeadlessException if GraphicsEnvironment.isHeadless()
* returns true.
* @see java.awt.GraphicsEnvironment#isHeadless
* @since 1.4
*/
public Applet() throws HeadlessException {
if (GraphicsEnvironment.isHeadless()) {
throw new HeadlessException();
}
}
/**
* Applets can be serialized but the following conventions MUST be followed:
*
* Before Serialization:
* An applet must be in STOPPED state.
*
* After Deserialization:
* The applet will be restored in STOPPED state (and most clients will
* likely move it into RUNNING state).
* The stub field will be restored by the reader.
*/
transient private AppletStub stub;
/* version ID for serialized form. */
private static final long serialVersionUID = -5836846270535785031L;
/**
* Read an applet from an object input stream.
* @exception HeadlessException if
* <code>GraphicsEnvironment.isHeadless()</code> returns
* <code>true</code>
* @serial
* @see java.awt.GraphicsEnvironment#isHeadless
* @since 1.4
*/
private void readObject(ObjectInputStream s)
throws ClassNotFoundException, IOException, HeadlessException {
if (GraphicsEnvironment.isHeadless()) {
throw new HeadlessException();
}
s.defaultReadObject();
}
/**
* Sets this applet's stub. This is done automatically by the system.
* <p>If there is a security manager, its <code> checkPermission </code>
* method is called with the
* <code>AWTPermission("setAppletStub")</code>
* permission if a stub has already been set.
* @param stub the new stub.
* @exception SecurityException if the caller cannot set the stub
*/
public final void setStub(AppletStub stub) {
if (this.stub != null) {
SecurityManager s = System.getSecurityManager();
if (s != null) {
s.checkPermission(new AWTPermission("setAppletStub"));
}
}
this.stub = stub;
}
/**
* Determines if this applet is active. An applet is marked active
* just before its <code>start</code> method is called. It becomes
* inactive just before its <code>stop</code> method is called.
*
* @return <code>true</code> if the applet is active;
* <code>false</code> otherwise.
* @see java.applet.Applet#start()
* @see java.applet.Applet#stop()
*/
public boolean isActive() {
if (stub != null) {
return stub.isActive();
} else { // If stub field not filled in, applet never active
return false;
}
}
/**
* Gets the URL of the document in which this applet is embedded.
* For example, suppose an applet is contained
* within the document:
* <blockquote><pre>
* http://www.oracle.com/technetwork/java/index.html
* </pre></blockquote>
* The document base is:
* <blockquote><pre>
* http://www.oracle.com/technetwork/java/index.html
* </pre></blockquote>
*
* @return the {@link java.net.URL} of the document that contains this
* applet.
* @see java.applet.Applet#getCodeBase()
*/
public URL getDocumentBase() {
return stub.getDocumentBase();
}
/**
* Gets the base URL. This is the URL of the directory which contains this applet.
*
* @return the base {@link java.net.URL} of
* the directory which contains this applet.
* @see java.applet.Applet#getDocumentBase()
*/
public URL getCodeBase() {
return stub.getCodeBase();
}
/**
* Returns the value of the named parameter in the HTML tag. For
* example, if this applet is specified as
* <blockquote><pre>
* &lt;applet code="Clock" width=50 height=50&gt;
* &lt;param name=Color value="blue"&gt;
* &lt;/applet&gt;
* </pre></blockquote>
* <p>
* then a call to <code>getParameter("Color")</code> returns the
* value <code>"blue"</code>.
* <p>
* The <code>name</code> argument is case insensitive.
*
* @param name a parameter name.
* @return the value of the named parameter,
* or <code>null</code> if not set.
*/
public String getParameter(String name) {
return stub.getParameter(name);
}
/**
* Determines this applet's context, which allows the applet to
* query and affect the environment in which it runs.
* <p>
* This environment of an applet represents the document that
* contains the applet.
*
* @return the applet's context.
*/
public AppletContext getAppletContext() {
return stub.getAppletContext();
}
/**
* Requests that this applet be resized.
*
* @param width the new requested width for the applet.
* @param height the new requested height for the applet.
*/
@SuppressWarnings("deprecation")
public void resize(int width, int height) {
Dimension d = size();
if ((d.width != width) || (d.height != height)) {
super.resize(width, height);
if (stub != null) {
stub.appletResize(width, height);
}
}
}
/**
* Requests that this applet be resized.
*
* @param d an object giving the new width and height.
*/
@SuppressWarnings("deprecation")
public void resize(Dimension d) {
resize(d.width, d.height);
}
/**
* Indicates if this container is a validate root.
* <p>
* {@code Applet} objects are the validate roots, and, therefore, they
* override this method to return {@code true}.
*
* @return {@code true}
* @since 1.7
* @see java.awt.Container#isValidateRoot
*/
@Override
public boolean isValidateRoot() {
return true;
}
/**
* Requests that the argument string be displayed in the
* "status window". Many browsers and applet viewers
* provide such a window, where the application can inform users of
* its current state.
*
* @param msg a string to display in the status window.
*/
public void showStatus(String msg) {
getAppletContext().showStatus(msg);
}
/**
* Returns an <code>Image</code> object that can then be painted on
* the screen. The <code>url</code> that is passed as an argument
* must specify an absolute URL.
* <p>
* This method always returns immediately, whether or not the image
* exists. When this applet attempts to draw the image on the screen,
* the data will be loaded. The graphics primitives that draw the
* image will incrementally paint on the screen.
*
* @param url an absolute URL giving the location of the image.
* @return the image at the specified URL.
* @see java.awt.Image
*/
public Image getImage(URL url) {
return getAppletContext().getImage(url);
}
/**
* Returns an <code>Image</code> object that can then be painted on
* the screen. The <code>url</code> argument must specify an absolute
* URL. The <code>name</code> argument is a specifier that is
* relative to the <code>url</code> argument.
* <p>
* This method always returns immediately, whether or not the image
* exists. When this applet attempts to draw the image on the screen,
* the data will be loaded. The graphics primitives that draw the
* image will incrementally paint on the screen.
*
* @param url an absolute URL giving the base location of the image.
* @param name the location of the image, relative to the
* <code>url</code> argument.
* @return the image at the specified URL.
* @see java.awt.Image
*/
public Image getImage(URL url, String name) {
try {
return getImage(new URL(url, name));
} catch (MalformedURLException e) {
return null;
}
}
/**
* Get an audio clip from the given URL.
*
* @param url points to the audio clip
* @return the audio clip at the specified URL.
*
* @since 1.2
*/
public final static AudioClip newAudioClip(URL url) {
return new sun.applet.AppletAudioClip(url);
}
/**
* Returns the <code>AudioClip</code> object specified by the
* <code>URL</code> argument.
* <p>
* This method always returns immediately, whether or not the audio
* clip exists. When this applet attempts to play the audio clip, the
* data will be loaded.
*
* @param url an absolute URL giving the location of the audio clip.
* @return the audio clip at the specified URL.
* @see java.applet.AudioClip
*/
public AudioClip getAudioClip(URL url) {
return getAppletContext().getAudioClip(url);
}
/**
* Returns the <code>AudioClip</code> object specified by the
* <code>URL</code> and <code>name</code> arguments.
* <p>
* This method always returns immediately, whether or not the audio
* clip exists. When this applet attempts to play the audio clip, the
* data will be loaded.
*
* @param url an absolute URL giving the base location of the
* audio clip.
* @param name the location of the audio clip, relative to the
* <code>url</code> argument.
* @return the audio clip at the specified URL.
* @see java.applet.AudioClip
*/
public AudioClip getAudioClip(URL url, String name) {
try {
return getAudioClip(new URL(url, name));
} catch (MalformedURLException e) {
return null;
}
}
/**
* Returns information about this applet. An applet should override
* this method to return a <code>String</code> containing information
* about the author, version, and copyright of the applet.
* <p>
* The implementation of this method provided by the
* <code>Applet</code> class returns <code>null</code>.
*
* @return a string containing information about the author, version, and
* copyright of the applet.
*/
public String getAppletInfo() {
return null;
}
/**
* Gets the locale of the applet. It allows the applet
* to maintain its own locale separated from the locale
* of the browser or appletviewer.
*
* @return the locale of the applet; if no locale has
* been set, the default locale is returned.
* @since JDK1.1
*/
public Locale getLocale() {
Locale locale = super.getLocale();
if (locale == null) {
return Locale.getDefault();
}
return locale;
}
/**
* Returns information about the parameters that are understood by
* this applet. An applet should override this method to return an
* array of <code>Strings</code> describing these parameters.
* <p>
* Each element of the array should be a set of three
* <code>Strings</code> containing the name, the type, and a
* description. For example:
* <blockquote><pre>
* String pinfo[][] = {
* {"fps", "1-10", "frames per second"},
* {"repeat", "boolean", "repeat image loop"},
* {"imgs", "url", "images directory"}
* };
* </pre></blockquote>
* <p>
* The implementation of this method provided by the
* <code>Applet</code> class returns <code>null</code>.
*
* @return an array describing the parameters this applet looks for.
*/
public String[][] getParameterInfo() {
return null;
}
/**
* Plays the audio clip at the specified absolute URL. Nothing
* happens if the audio clip cannot be found.
*
* @param url an absolute URL giving the location of the audio clip.
*/
public void play(URL url) {
AudioClip clip = getAudioClip(url);
if (clip != null) {
clip.play();
}
}
/**
* Plays the audio clip given the URL and a specifier that is
* relative to it. Nothing happens if the audio clip cannot be found.
*
* @param url an absolute URL giving the base location of the
* audio clip.
* @param name the location of the audio clip, relative to the
* <code>url</code> argument.
*/
public void play(URL url, String name) {
AudioClip clip = getAudioClip(url, name);
if (clip != null) {
clip.play();
}
}
/**
* Called by the browser or applet viewer to inform
* this applet that it has been loaded into the system. It is always
* called before the first time that the <code>start</code> method is
* called.
* <p>
* A subclass of <code>Applet</code> should override this method if
* it has initialization to perform. For example, an applet with
* threads would use the <code>init</code> method to create the
* threads and the <code>destroy</code> method to kill them.
* <p>
* The implementation of this method provided by the
* <code>Applet</code> class does nothing.
*
* @see java.applet.Applet#destroy()
* @see java.applet.Applet#start()
* @see java.applet.Applet#stop()
*/
public void init() {
}
/**
* Called by the browser or applet viewer to inform
* this applet that it should start its execution. It is called after
* the <code>init</code> method and each time the applet is revisited
* in a Web page.
* <p>
* A subclass of <code>Applet</code> should override this method if
* it has any operation that it wants to perform each time the Web
* page containing it is visited. For example, an applet with
* animation might want to use the <code>start</code> method to
* resume animation, and the <code>stop</code> method to suspend the
* animation.
* <p>
* Note: some methods, such as <code>getLocationOnScreen</code>, can only
* provide meaningful results if the applet is showing. Because
* <code>isShowing</code> returns <code>false</code> when the applet's
* <code>start</code> is first called, methods requiring
* <code>isShowing</code> to return <code>true</code> should be called from
* a <code>ComponentListener</code>.
* <p>
* The implementation of this method provided by the
* <code>Applet</code> class does nothing.
*
* @see java.applet.Applet#destroy()
* @see java.applet.Applet#init()
* @see java.applet.Applet#stop()
* @see java.awt.Component#isShowing()
* @see java.awt.event.ComponentListener#componentShown(java.awt.event.ComponentEvent)
*/
public void start() {
}
/**
* Called by the browser or applet viewer to inform
* this applet that it should stop its execution. It is called when
* the Web page that contains this applet has been replaced by
* another page, and also just before the applet is to be destroyed.
* <p>
* A subclass of <code>Applet</code> should override this method if
* it has any operation that it wants to perform each time the Web
* page containing it is no longer visible. For example, an applet
* with animation might want to use the <code>start</code> method to
* resume animation, and the <code>stop</code> method to suspend the
* animation.
* <p>
* The implementation of this method provided by the
* <code>Applet</code> class does nothing.
*
* @see java.applet.Applet#destroy()
* @see java.applet.Applet#init()
*/
public void stop() {
}
/**
* Called by the browser or applet viewer to inform
* this applet that it is being reclaimed and that it should destroy
* any resources that it has allocated. The <code>stop</code> method
* will always be called before <code>destroy</code>.
* <p>
* A subclass of <code>Applet</code> should override this method if
* it has any operation that it wants to perform before it is
* destroyed. For example, an applet with threads would use the
* <code>init</code> method to create the threads and the
* <code>destroy</code> method to kill them.
* <p>
* The implementation of this method provided by the
* <code>Applet</code> class does nothing.
*
* @see java.applet.Applet#init()
* @see java.applet.Applet#start()
* @see java.applet.Applet#stop()
*/
public void destroy() {
}
//
// Accessibility support
//
AccessibleContext accessibleContext = null;
/**
* Gets the AccessibleContext associated with this Applet.
* For applets, the AccessibleContext takes the form of an
* AccessibleApplet.
* A new AccessibleApplet instance is created if necessary.
*
* @return an AccessibleApplet that serves as the
* AccessibleContext of this Applet
* @since 1.3
*/
public AccessibleContext getAccessibleContext() {
if (accessibleContext == null) {
accessibleContext = new AccessibleApplet();
}
return accessibleContext;
}
/**
* This class implements accessibility support for the
* <code>Applet</code> class. It provides an implementation of the
* Java Accessibility API appropriate to applet user-interface elements.
* @since 1.3
*/
protected class AccessibleApplet extends AccessibleAWTPanel {
private static final long serialVersionUID = 8127374778187708896L;
/**
* Get the role of this object.
*
* @return an instance of AccessibleRole describing the role of the
* object
*/
public AccessibleRole getAccessibleRole() {
return AccessibleRole.FRAME;
}
/**
* Get the state of this object.
*
* @return an instance of AccessibleStateSet containing the current
* state set of the object
* @see AccessibleState
*/
public AccessibleStateSet getAccessibleStateSet() {
AccessibleStateSet states = super.getAccessibleStateSet();
states.add(AccessibleState.ACTIVE);
return states;
}
}
}

View File

@@ -0,0 +1,194 @@
/*
* Copyright (c) 1995, 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 java.applet;
import java.awt.Image;
import java.awt.Graphics;
import java.awt.image.ColorModel;
import java.net.URL;
import java.util.Enumeration;
import java.io.InputStream;
import java.io.IOException;
import java.util.Iterator;
/**
* This interface corresponds to an applet's environment: the
* document containing the applet and the other applets in the same
* document.
* <p>
* The methods in this interface can be used by an applet to obtain
* information about its environment.
*
* @author Arthur van Hoff
* @since JDK1.0
*/
public interface AppletContext {
/**
* Creates an audio clip.
*
* @param url an absolute URL giving the location of the audio clip.
* @return the audio clip at the specified URL.
*/
AudioClip getAudioClip(URL url);
/**
* Returns an <code>Image</code> object that can then be painted on
* the screen. The <code>url</code> argument that is
* passed as an argument must specify an absolute URL.
* <p>
* This method always returns immediately, whether or not the image
* exists. When the applet attempts to draw the image on the screen,
* the data will be loaded. The graphics primitives that draw the
* image will incrementally paint on the screen.
*
* @param url an absolute URL giving the location of the image.
* @return the image at the specified URL.
* @see java.awt.Image
*/
Image getImage(URL url);
/**
* Finds and returns the applet in the document represented by this
* applet context with the given name. The name can be set in the
* HTML tag by setting the <code>name</code> attribute.
*
* @param name an applet name.
* @return the applet with the given name, or <code>null</code> if
* not found.
*/
Applet getApplet(String name);
/**
* Finds all the applets in the document represented by this applet
* context.
*
* @return an enumeration of all applets in the document represented by
* this applet context.
*/
Enumeration<Applet> getApplets();
/**
* Requests that the browser or applet viewer show the Web page
* indicated by the <code>url</code> argument. The browser or
* applet viewer determines which window or frame to display the
* Web page. This method may be ignored by applet contexts that
* are not browsers.
*
* @param url an absolute URL giving the location of the document.
*/
void showDocument(URL url);
/**
* Requests that the browser or applet viewer show the Web page
* indicated by the <code>url</code> argument. The
* <code>target</code> argument indicates in which HTML frame the
* document is to be displayed.
* The target argument is interpreted as follows:
*
* <center><table border="3" summary="Target arguments and their descriptions">
* <tr><th>Target Argument</th><th>Description</th></tr>
* <tr><td><code>"_self"</code> <td>Show in the window and frame that
* contain the applet.</tr>
* <tr><td><code>"_parent"</code><td>Show in the applet's parent frame. If
* the applet's frame has no parent frame,
* acts the same as "_self".</tr>
* <tr><td><code>"_top"</code> <td>Show in the top-level frame of the applet's
* window. If the applet's frame is the
* top-level frame, acts the same as "_self".</tr>
* <tr><td><code>"_blank"</code> <td>Show in a new, unnamed
* top-level window.</tr>
* <tr><td><i>name</i><td>Show in the frame or window named <i>name</i>. If
* a target named <i>name</i> does not already exist, a
* new top-level window with the specified name is created,
* and the document is shown there.</tr>
* </table> </center>
* <p>
* An applet viewer or browser is free to ignore <code>showDocument</code>.
*
* @param url an absolute URL giving the location of the document.
* @param target a <code>String</code> indicating where to display
* the page.
*/
public void showDocument(URL url, String target);
/**
* Requests that the argument string be displayed in the
* "status window". Many browsers and applet viewers
* provide such a window, where the application can inform users of
* its current state.
*
* @param status a string to display in the status window.
*/
void showStatus(String status);
/**
* Associates the specified stream with the specified key in this
* applet context. If the applet context previously contained a mapping
* for this key, the old value is replaced.
* <p>
* For security reasons, mapping of streams and keys exists for each
* codebase. In other words, applet from one codebase cannot access
* the streams created by an applet from a different codebase
* <p>
* @param key key with which the specified value is to be associated.
* @param stream stream to be associated with the specified key. If this
* parameter is <code>null</code>, the specified key is removed
* in this applet context.
* @throws IOException if the stream size exceeds a certain
* size limit. Size limit is decided by the implementor of this
* interface.
* @since 1.4
*/
public void setStream(String key, InputStream stream)throws IOException;
/**
* Returns the stream to which specified key is associated within this
* applet context. Returns <tt>null</tt> if the applet context contains
* no stream for this key.
* <p>
* For security reasons, mapping of streams and keys exists for each
* codebase. In other words, applet from one codebase cannot access
* the streams created by an applet from a different codebase
* <p>
* @return the stream to which this applet context maps the key
* @param key key whose associated stream is to be returned.
* @since 1.4
*/
public InputStream getStream(String key);
/**
* Finds all the keys of the streams in this applet context.
* <p>
* For security reasons, mapping of streams and keys exists for each
* codebase. In other words, applet from one codebase cannot access
* the streams created by an applet from a different codebase
* <p>
* @return an Iterator of all the names of the streams in this applet
* context.
* @since 1.4
*/
public Iterator<String> getStreamKeys();
}

View File

@@ -0,0 +1,111 @@
/*
* Copyright (c) 1995, 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 java.applet;
import java.net.URL;
/**
* When an applet is first created, an applet stub is attached to it
* using the applet's <code>setStub</code> method. This stub
* serves as the interface between the applet and the browser
* environment or applet viewer environment in which the application
* is running.
*
* @author Arthur van Hoff
* @see java.applet.Applet#setStub(java.applet.AppletStub)
* @since JDK1.0
*/
public interface AppletStub {
/**
* Determines if the applet is active. An applet is active just
* before its <code>start</code> method is called. It becomes
* inactive just before its <code>stop</code> method is called.
*
* @return <code>true</code> if the applet is active;
* <code>false</code> otherwise.
*/
boolean isActive();
/**
* Gets the URL of the document in which the applet is embedded.
* For example, suppose an applet is contained
* within the document:
* <blockquote><pre>
* http://www.oracle.com/technetwork/java/index.html
* </pre></blockquote>
* The document base is:
* <blockquote><pre>
* http://www.oracle.com/technetwork/java/index.html
* </pre></blockquote>
*
* @return the {@link java.net.URL} of the document that contains the
* applet.
* @see java.applet.AppletStub#getCodeBase()
*/
URL getDocumentBase();
/**
* Gets the base URL. This is the URL of the directory which contains the applet.
*
* @return the base {@link java.net.URL} of
* the directory which contains the applet.
* @see java.applet.AppletStub#getDocumentBase()
*/
URL getCodeBase();
/**
* Returns the value of the named parameter in the HTML tag. For
* example, if an applet is specified as
* <blockquote><pre>
* &lt;applet code="Clock" width=50 height=50&gt;
* &lt;param name=Color value="blue"&gt;
* &lt;/applet&gt;
* </pre></blockquote>
* <p>
* then a call to <code>getParameter("Color")</code> returns the
* value <code>"blue"</code>.
*
* @param name a parameter name.
* @return the value of the named parameter,
* or <tt>null</tt> if not set.
*/
String getParameter(String name);
/**
* Returns the applet's context.
*
* @return the applet's context.
*/
AppletContext getAppletContext();
/**
* Called when the applet wants to be resized.
*
* @param width the new requested width for the applet.
* @param height the new requested height for the applet.
*/
void appletResize(int width, int height);
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright (c) 1995, 1997, 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 java.applet;
/**
* The <code>AudioClip</code> interface is a simple abstraction for
* playing a sound clip. Multiple <code>AudioClip</code> items can be
* playing at the same time, and the resulting sound is mixed
* together to produce a composite.
*
* @author Arthur van Hoff
* @since JDK1.0
*/
public interface AudioClip {
/**
* Starts playing this audio clip. Each time this method is called,
* the clip is restarted from the beginning.
*/
void play();
/**
* Starts playing this audio clip in a loop.
*/
void loop();
/**
* Stops playing this audio clip.
*/
void stop();
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright (c) 1995, 1997, 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 java.awt;
/**
* Thrown when a serious Abstract Window Toolkit error has occurred.
*
* @author Arthur van Hoff
*/
public class AWTError extends Error {
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = -1819846354050686206L;
/**
* Constructs an instance of <code>AWTError</code> with the specified
* detail message.
* @param msg the detail message.
* @since JDK1.0
*/
public AWTError(String msg) {
super(msg);
}
}

View File

@@ -0,0 +1,620 @@
/*
* Copyright (c) 1996, 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 java.awt;
import java.util.EventObject;
import java.awt.event.*;
import java.awt.peer.ComponentPeer;
import java.awt.peer.LightweightPeer;
import java.lang.reflect.Field;
import sun.awt.AWTAccessor;
import sun.util.logging.PlatformLogger;
import java.security.AccessControlContext;
import java.security.AccessController;
/**
* The root event class for all AWT events.
* This class and its subclasses supercede the original
* java.awt.Event class.
* Subclasses of this root AWTEvent class defined outside of the
* java.awt.event package should define event ID values greater than
* the value defined by RESERVED_ID_MAX.
* <p>
* The event masks defined in this class are needed by Component subclasses
* which are using Component.enableEvents() to select for event types not
* selected by registered listeners. If a listener is registered on a
* component, the appropriate event mask is already set internally by the
* component.
* <p>
* The masks are also used to specify to which types of events an
* AWTEventListener should listen. The masks are bitwise-ORed together
* and passed to Toolkit.addAWTEventListener.
*
* @see Component#enableEvents
* @see Toolkit#addAWTEventListener
*
* @see java.awt.event.ActionEvent
* @see java.awt.event.AdjustmentEvent
* @see java.awt.event.ComponentEvent
* @see java.awt.event.ContainerEvent
* @see java.awt.event.FocusEvent
* @see java.awt.event.InputMethodEvent
* @see java.awt.event.InvocationEvent
* @see java.awt.event.ItemEvent
* @see java.awt.event.HierarchyEvent
* @see java.awt.event.KeyEvent
* @see java.awt.event.MouseEvent
* @see java.awt.event.MouseWheelEvent
* @see java.awt.event.PaintEvent
* @see java.awt.event.TextEvent
* @see java.awt.event.WindowEvent
*
* @author Carl Quinn
* @author Amy Fowler
* @since 1.1
*/
public abstract class AWTEvent extends EventObject {
private static final PlatformLogger log = PlatformLogger.getLogger("java.awt.AWTEvent");
private byte bdata[];
/**
* The event's id.
* @serial
* @see #getID()
* @see #AWTEvent
*/
protected int id;
/**
* Controls whether or not the event is sent back down to the peer once the
* source has processed it - false means it's sent to the peer; true means
* it's not. Semantic events always have a 'true' value since they were
* generated by the peer in response to a low-level event.
* @serial
* @see #consume
* @see #isConsumed
*/
protected boolean consumed = false;
/*
* The event's AccessControlContext.
*/
private transient volatile AccessControlContext acc =
AccessController.getContext();
/*
* Returns the acc this event was constructed with.
*/
final AccessControlContext getAccessControlContext() {
if (acc == null) {
throw new SecurityException("AWTEvent is missing AccessControlContext");
}
return acc;
}
transient boolean focusManagerIsDispatching = false;
transient boolean isPosted;
/**
* Indicates whether this AWTEvent was generated by the system as
* opposed to by user code.
*/
private transient boolean isSystemGenerated;
/**
* The event mask for selecting component events.
*/
public final static long COMPONENT_EVENT_MASK = 0x01;
/**
* The event mask for selecting container events.
*/
public final static long CONTAINER_EVENT_MASK = 0x02;
/**
* The event mask for selecting focus events.
*/
public final static long FOCUS_EVENT_MASK = 0x04;
/**
* The event mask for selecting key events.
*/
public final static long KEY_EVENT_MASK = 0x08;
/**
* The event mask for selecting mouse events.
*/
public final static long MOUSE_EVENT_MASK = 0x10;
/**
* The event mask for selecting mouse motion events.
*/
public final static long MOUSE_MOTION_EVENT_MASK = 0x20;
/**
* The event mask for selecting window events.
*/
public final static long WINDOW_EVENT_MASK = 0x40;
/**
* The event mask for selecting action events.
*/
public final static long ACTION_EVENT_MASK = 0x80;
/**
* The event mask for selecting adjustment events.
*/
public final static long ADJUSTMENT_EVENT_MASK = 0x100;
/**
* The event mask for selecting item events.
*/
public final static long ITEM_EVENT_MASK = 0x200;
/**
* The event mask for selecting text events.
*/
public final static long TEXT_EVENT_MASK = 0x400;
/**
* The event mask for selecting input method events.
*/
public final static long INPUT_METHOD_EVENT_MASK = 0x800;
/**
* The pseudo event mask for enabling input methods.
* We're using one bit in the eventMask so we don't need
* a separate field inputMethodsEnabled.
*/
final static long INPUT_METHODS_ENABLED_MASK = 0x1000;
/**
* The event mask for selecting paint events.
*/
public final static long PAINT_EVENT_MASK = 0x2000;
/**
* The event mask for selecting invocation events.
*/
public final static long INVOCATION_EVENT_MASK = 0x4000;
/**
* The event mask for selecting hierarchy events.
*/
public final static long HIERARCHY_EVENT_MASK = 0x8000;
/**
* The event mask for selecting hierarchy bounds events.
*/
public final static long HIERARCHY_BOUNDS_EVENT_MASK = 0x10000;
/**
* The event mask for selecting mouse wheel events.
* @since 1.4
*/
public final static long MOUSE_WHEEL_EVENT_MASK = 0x20000;
/**
* The event mask for selecting window state events.
* @since 1.4
*/
public final static long WINDOW_STATE_EVENT_MASK = 0x40000;
/**
* The event mask for selecting window focus events.
* @since 1.4
*/
public final static long WINDOW_FOCUS_EVENT_MASK = 0x80000;
/**
* WARNING: there are more mask defined privately. See
* SunToolkit.GRAB_EVENT_MASK.
*/
/**
* The maximum value for reserved AWT event IDs. Programs defining
* their own event IDs should use IDs greater than this value.
*/
public final static int RESERVED_ID_MAX = 1999;
// security stuff
private static Field inputEvent_CanAccessSystemClipboard_Field = null;
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = -1825314779160409405L;
static {
/* ensure that the necessary native libraries are loaded */
Toolkit.loadLibraries();
if (!GraphicsEnvironment.isHeadless()) {
initIDs();
}
AWTAccessor.setAWTEventAccessor(
new AWTAccessor.AWTEventAccessor() {
public void setPosted(AWTEvent ev) {
ev.isPosted = true;
}
public void setSystemGenerated(AWTEvent ev) {
ev.isSystemGenerated = true;
}
public boolean isSystemGenerated(AWTEvent ev) {
return ev.isSystemGenerated;
}
public AccessControlContext getAccessControlContext(AWTEvent ev) {
return ev.getAccessControlContext();
}
public byte[] getBData(AWTEvent ev) {
return ev.bdata;
}
public void setBData(AWTEvent ev, byte[] bdata) {
ev.bdata = bdata;
}
});
}
private static synchronized Field get_InputEvent_CanAccessSystemClipboard() {
if (inputEvent_CanAccessSystemClipboard_Field == null) {
inputEvent_CanAccessSystemClipboard_Field =
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<Field>() {
public Field run() {
Field field = null;
try {
field = InputEvent.class.
getDeclaredField("canAccessSystemClipboard");
field.setAccessible(true);
return field;
} catch (SecurityException e) {
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("AWTEvent.get_InputEvent_CanAccessSystemClipboard() got SecurityException ", e);
}
} catch (NoSuchFieldException e) {
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("AWTEvent.get_InputEvent_CanAccessSystemClipboard() got NoSuchFieldException ", e);
}
}
return null;
}
});
}
return inputEvent_CanAccessSystemClipboard_Field;
}
/**
* Initialize JNI field and method IDs for fields that may be
* accessed from C.
*/
private static native void initIDs();
/**
* Constructs an AWTEvent object from the parameters of a 1.0-style event.
* @param event the old-style event
*/
public AWTEvent(Event event) {
this(event.target, event.id);
}
/**
* Constructs an AWTEvent object with the specified source object and type.
*
* @param source the object where the event originated
* @param id the event type
*/
public AWTEvent(Object source, int id) {
super(source);
this.id = id;
switch(id) {
case ActionEvent.ACTION_PERFORMED:
case ItemEvent.ITEM_STATE_CHANGED:
case AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED:
case TextEvent.TEXT_VALUE_CHANGED:
consumed = true;
break;
default:
}
}
/**
* Retargets an event to a new source. This method is typically used to
* retarget an event to a lightweight child Component of the original
* heavyweight source.
* <p>
* This method is intended to be used only by event targeting subsystems,
* such as client-defined KeyboardFocusManagers. It is not for general
* client use.
*
* @param newSource the new Object to which the event should be dispatched
* @since 1.4
*/
public void setSource(Object newSource) {
if (source == newSource) {
return;
}
Component comp = null;
if (newSource instanceof Component) {
comp = (Component)newSource;
while (comp != null && comp.peer != null &&
(comp.peer instanceof LightweightPeer)) {
comp = comp.parent;
}
}
synchronized (this) {
source = newSource;
if (comp != null) {
ComponentPeer peer = comp.peer;
if (peer != null) {
nativeSetSource(peer);
}
}
}
}
private native void nativeSetSource(ComponentPeer peer);
/**
* Returns the event type.
*/
public int getID() {
return id;
}
/**
* Returns a String representation of this object.
*/
public String toString() {
String srcName = null;
if (source instanceof Component) {
srcName = ((Component)source).getName();
} else if (source instanceof MenuComponent) {
srcName = ((MenuComponent)source).getName();
}
return getClass().getName() + "[" + paramString() + "] on " +
(srcName != null? srcName : source);
}
/**
* Returns a string representing the state of this <code>Event</code>.
* This method is intended to be used only for debugging purposes, and the
* content and format of the returned string may vary between
* implementations. The returned string may be empty but may not be
* <code>null</code>.
*
* @return a string representation of this event
*/
public String paramString() {
return "";
}
/**
* Consumes this event, if this event can be consumed. Only low-level,
* system events can be consumed
*/
protected void consume() {
switch(id) {
case KeyEvent.KEY_PRESSED:
case KeyEvent.KEY_RELEASED:
case MouseEvent.MOUSE_PRESSED:
case MouseEvent.MOUSE_RELEASED:
case MouseEvent.MOUSE_MOVED:
case MouseEvent.MOUSE_DRAGGED:
case MouseEvent.MOUSE_ENTERED:
case MouseEvent.MOUSE_EXITED:
case MouseEvent.MOUSE_WHEEL:
case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
case InputMethodEvent.CARET_POSITION_CHANGED:
consumed = true;
break;
default:
// event type cannot be consumed
}
}
/**
* Returns whether this event has been consumed.
*/
protected boolean isConsumed() {
return consumed;
}
/**
* Converts a new event to an old one (used for compatibility).
* If the new event cannot be converted (because no old equivalent
* exists) then this returns null.
*
* Note: this method is here instead of in each individual new
* event class in java.awt.event because we don't want to make
* it public and it needs to be called from java.awt.
*/
Event convertToOld() {
Object src = getSource();
int newid = id;
switch(id) {
case KeyEvent.KEY_PRESSED:
case KeyEvent.KEY_RELEASED:
KeyEvent ke = (KeyEvent)this;
if (ke.isActionKey()) {
newid = (id == KeyEvent.KEY_PRESSED?
Event.KEY_ACTION : Event.KEY_ACTION_RELEASE);
}
int keyCode = ke.getKeyCode();
if (keyCode == KeyEvent.VK_SHIFT ||
keyCode == KeyEvent.VK_CONTROL ||
keyCode == KeyEvent.VK_ALT) {
return null; // suppress modifier keys in old event model.
}
// no mask for button1 existed in old Event - strip it out
return new Event(src, ke.getWhen(), newid, 0, 0,
Event.getOldEventKey(ke),
(ke.getModifiers() & ~InputEvent.BUTTON1_MASK));
case MouseEvent.MOUSE_PRESSED:
case MouseEvent.MOUSE_RELEASED:
case MouseEvent.MOUSE_MOVED:
case MouseEvent.MOUSE_DRAGGED:
case MouseEvent.MOUSE_ENTERED:
case MouseEvent.MOUSE_EXITED:
MouseEvent me = (MouseEvent)this;
// no mask for button1 existed in old Event - strip it out
Event olde = new Event(src, me.getWhen(), newid,
me.getX(), me.getY(), 0,
(me.getModifiers() & ~InputEvent.BUTTON1_MASK));
olde.clickCount = me.getClickCount();
return olde;
case FocusEvent.FOCUS_GAINED:
return new Event(src, Event.GOT_FOCUS, null);
case FocusEvent.FOCUS_LOST:
return new Event(src, Event.LOST_FOCUS, null);
case WindowEvent.WINDOW_CLOSING:
case WindowEvent.WINDOW_ICONIFIED:
case WindowEvent.WINDOW_DEICONIFIED:
return new Event(src, newid, null);
case ComponentEvent.COMPONENT_MOVED:
if (src instanceof Frame || src instanceof Dialog) {
Point p = ((Component)src).getLocation();
return new Event(src, 0, Event.WINDOW_MOVED, p.x, p.y, 0, 0);
}
break;
case ActionEvent.ACTION_PERFORMED:
ActionEvent ae = (ActionEvent)this;
String cmd;
if (src instanceof Button) {
cmd = ((Button)src).getLabel();
} else if (src instanceof MenuItem) {
cmd = ((MenuItem)src).getLabel();
} else {
cmd = ae.getActionCommand();
}
return new Event(src, 0, newid, 0, 0, 0, ae.getModifiers(), cmd);
case ItemEvent.ITEM_STATE_CHANGED:
ItemEvent ie = (ItemEvent)this;
Object arg;
if (src instanceof List) {
newid = (ie.getStateChange() == ItemEvent.SELECTED?
Event.LIST_SELECT : Event.LIST_DESELECT);
arg = ie.getItem();
} else {
newid = Event.ACTION_EVENT;
if (src instanceof Choice) {
arg = ie.getItem();
} else { // Checkbox
arg = Boolean.valueOf(ie.getStateChange() == ItemEvent.SELECTED);
}
}
return new Event(src, newid, arg);
case AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED:
AdjustmentEvent aje = (AdjustmentEvent)this;
switch(aje.getAdjustmentType()) {
case AdjustmentEvent.UNIT_INCREMENT:
newid = Event.SCROLL_LINE_DOWN;
break;
case AdjustmentEvent.UNIT_DECREMENT:
newid = Event.SCROLL_LINE_UP;
break;
case AdjustmentEvent.BLOCK_INCREMENT:
newid = Event.SCROLL_PAGE_DOWN;
break;
case AdjustmentEvent.BLOCK_DECREMENT:
newid = Event.SCROLL_PAGE_UP;
break;
case AdjustmentEvent.TRACK:
if (aje.getValueIsAdjusting()) {
newid = Event.SCROLL_ABSOLUTE;
}
else {
newid = Event.SCROLL_END;
}
break;
default:
return null;
}
return new Event(src, newid, Integer.valueOf(aje.getValue()));
default:
}
return null;
}
/**
* Copies all private data from this event into that.
* Space is allocated for the copied data that will be
* freed when the that is finalized. Upon completion,
* this event is not changed.
*/
void copyPrivateDataInto(AWTEvent that) {
that.bdata = this.bdata;
// Copy canAccessSystemClipboard value from this into that.
if (this instanceof InputEvent && that instanceof InputEvent) {
Field field = get_InputEvent_CanAccessSystemClipboard();
if (field != null) {
try {
boolean b = field.getBoolean(this);
field.setBoolean(that, b);
} catch(IllegalAccessException e) {
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("AWTEvent.copyPrivateDataInto() got IllegalAccessException ", e);
}
}
}
}
that.isSystemGenerated = this.isSystemGenerated;
}
void dispatched() {
if (this instanceof InputEvent) {
Field field = get_InputEvent_CanAccessSystemClipboard();
if (field != null) {
try {
field.setBoolean(this, false);
} catch(IllegalAccessException e) {
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("AWTEvent.dispatched() got IllegalAccessException ", e);
}
}
}
}
}
} // class AWTEvent

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,51 @@
/*
* Copyright (c) 1995, 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 java.awt;
/**
* Signals that an Abstract Window Toolkit exception has occurred.
*
* @author Arthur van Hoff
*/
public class AWTException extends Exception {
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = -1900414231151323879L;
/**
* Constructs an instance of <code>AWTException</code> with the
* specified detail message. A detail message is an
* instance of <code>String</code> that describes this particular
* exception.
* @param msg the detail message
* @since JDK1.0
*/
public AWTException(String msg) {
super(msg);
}
}

View File

@@ -0,0 +1,889 @@
/*
* Copyright (c) 2000, 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 java.awt;
import java.awt.event.KeyEvent;
import sun.awt.AppContext;
import java.awt.event.InputEvent;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
import java.io.Serializable;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.lang.reflect.Field;
/**
* An <code>AWTKeyStroke</code> represents a key action on the
* keyboard, or equivalent input device. <code>AWTKeyStroke</code>s
* can correspond to only a press or release of a
* particular key, just as <code>KEY_PRESSED</code> and
* <code>KEY_RELEASED</code> <code>KeyEvent</code>s do;
* alternately, they can correspond to typing a specific Java character, just
* as <code>KEY_TYPED</code> <code>KeyEvent</code>s do.
* In all cases, <code>AWTKeyStroke</code>s can specify modifiers
* (alt, shift, control, meta, altGraph, or a combination thereof) which must be present
* during the action for an exact match.
* <p>
* <code>AWTKeyStrokes</code> are immutable, and are intended
* to be unique. Client code should never create an
* <code>AWTKeyStroke</code> on its own, but should instead use
* a variant of <code>getAWTKeyStroke</code>. Client use of these factory
* methods allows the <code>AWTKeyStroke</code> implementation
* to cache and share instances efficiently.
*
* @see #getAWTKeyStroke
*
* @author Arnaud Weber
* @author David Mendenhall
* @since 1.4
*/
public class AWTKeyStroke implements Serializable {
static final long serialVersionUID = -6430539691155161871L;
private static Map<String, Integer> modifierKeywords;
/**
* Associates VK_XXX (as a String) with code (as Integer). This is
* done to avoid the overhead of the reflective call to find the
* constant.
*/
private static VKCollection vks;
//A key for the collection of AWTKeyStrokes within AppContext.
private static Object APP_CONTEXT_CACHE_KEY = new Object();
//A key withing the cache
private static AWTKeyStroke APP_CONTEXT_KEYSTROKE_KEY = new AWTKeyStroke();
/*
* Reads keystroke class from AppContext and if null, puts there the
* AWTKeyStroke class.
* Must be called under locked AWTKeyStro
*/
private static Class<AWTKeyStroke> getAWTKeyStrokeClass() {
Class<AWTKeyStroke> clazz = (Class)AppContext.getAppContext().get(AWTKeyStroke.class);
if (clazz == null) {
clazz = AWTKeyStroke.class;
AppContext.getAppContext().put(AWTKeyStroke.class, AWTKeyStroke.class);
}
return clazz;
}
private char keyChar = KeyEvent.CHAR_UNDEFINED;
private int keyCode = KeyEvent.VK_UNDEFINED;
private int modifiers;
private boolean onKeyRelease;
static {
/* ensure that the necessary native libraries are loaded */
Toolkit.loadLibraries();
}
/**
* Constructs an <code>AWTKeyStroke</code> with default values.
* The default values used are:
* <table border="1" summary="AWTKeyStroke default values">
* <tr><th>Property</th><th>Default Value</th></tr>
* <tr>
* <td>Key Char</td>
* <td><code>KeyEvent.CHAR_UNDEFINED</code></td>
* </tr>
* <tr>
* <td>Key Code</td>
* <td><code>KeyEvent.VK_UNDEFINED</code></td>
* </tr>
* <tr>
* <td>Modifiers</td>
* <td>none</td>
* </tr>
* <tr>
* <td>On key release?</td>
* <td><code>false</code></td>
* </tr>
* </table>
*
* <code>AWTKeyStroke</code>s should not be constructed
* by client code. Use a variant of <code>getAWTKeyStroke</code>
* instead.
*
* @see #getAWTKeyStroke
*/
protected AWTKeyStroke() {
}
/**
* Constructs an <code>AWTKeyStroke</code> with the specified
* values. <code>AWTKeyStroke</code>s should not be constructed
* by client code. Use a variant of <code>getAWTKeyStroke</code>
* instead.
*
* @param keyChar the character value for a keyboard key
* @param keyCode the key code for this <code>AWTKeyStroke</code>
* @param modifiers a bitwise-ored combination of any modifiers
* @param onKeyRelease <code>true</code> if this
* <code>AWTKeyStroke</code> corresponds
* to a key release; <code>false</code> otherwise
* @see #getAWTKeyStroke
*/
protected AWTKeyStroke(char keyChar, int keyCode, int modifiers,
boolean onKeyRelease) {
this.keyChar = keyChar;
this.keyCode = keyCode;
this.modifiers = modifiers;
this.onKeyRelease = onKeyRelease;
}
/**
* Registers a new class which the factory methods in
* <code>AWTKeyStroke</code> will use when generating new
* instances of <code>AWTKeyStroke</code>s. After invoking this
* method, the factory methods will return instances of the specified
* Class. The specified Class must be either <code>AWTKeyStroke</code>
* or derived from <code>AWTKeyStroke</code>, and it must have a
* no-arg constructor. The constructor can be of any accessibility,
* including <code>private</code>. This operation
* flushes the current <code>AWTKeyStroke</code> cache.
*
* @param subclass the new Class of which the factory methods should create
* instances
* @throws IllegalArgumentException if subclass is <code>null</code>,
* or if subclass does not have a no-arg constructor
* @throws ClassCastException if subclass is not
* <code>AWTKeyStroke</code>, or a class derived from
* <code>AWTKeyStroke</code>
*/
protected static void registerSubclass(Class<?> subclass) {
if (subclass == null) {
throw new IllegalArgumentException("subclass cannot be null");
}
synchronized (AWTKeyStroke.class) {
Class<AWTKeyStroke> keyStrokeClass = (Class)AppContext.getAppContext().get(AWTKeyStroke.class);
if (keyStrokeClass != null && keyStrokeClass.equals(subclass)){
// Already registered
return;
}
}
if (!AWTKeyStroke.class.isAssignableFrom(subclass)) {
throw new ClassCastException("subclass is not derived from AWTKeyStroke");
}
Constructor ctor = getCtor(subclass);
String couldNotInstantiate = "subclass could not be instantiated";
if (ctor == null) {
throw new IllegalArgumentException(couldNotInstantiate);
}
try {
AWTKeyStroke stroke = (AWTKeyStroke)ctor.newInstance((Object[]) null);
if (stroke == null) {
throw new IllegalArgumentException(couldNotInstantiate);
}
} catch (NoSuchMethodError e) {
throw new IllegalArgumentException(couldNotInstantiate);
} catch (ExceptionInInitializerError e) {
throw new IllegalArgumentException(couldNotInstantiate);
} catch (InstantiationException e) {
throw new IllegalArgumentException(couldNotInstantiate);
} catch (IllegalAccessException e) {
throw new IllegalArgumentException(couldNotInstantiate);
} catch (InvocationTargetException e) {
throw new IllegalArgumentException(couldNotInstantiate);
}
synchronized (AWTKeyStroke.class) {
AppContext.getAppContext().put(AWTKeyStroke.class, subclass);
AppContext.getAppContext().remove(APP_CONTEXT_CACHE_KEY);
AppContext.getAppContext().remove(APP_CONTEXT_KEYSTROKE_KEY);
}
}
/* returns noarg Constructor for class with accessible flag. No security
threat as accessible flag is set only for this Constructor object,
not for Class constructor.
*/
private static Constructor getCtor(final Class clazz)
{
Constructor ctor = AccessController.doPrivileged(new PrivilegedAction<Constructor>() {
public Constructor run() {
try {
Constructor ctor = clazz.getDeclaredConstructor((Class[]) null);
if (ctor != null) {
ctor.setAccessible(true);
}
return ctor;
} catch (SecurityException e) {
} catch (NoSuchMethodException e) {
}
return null;
}
});
return (Constructor)ctor;
}
private static synchronized AWTKeyStroke getCachedStroke
(char keyChar, int keyCode, int modifiers, boolean onKeyRelease)
{
Map<AWTKeyStroke, AWTKeyStroke> cache = (Map)AppContext.getAppContext().get(APP_CONTEXT_CACHE_KEY);
AWTKeyStroke cacheKey = (AWTKeyStroke)AppContext.getAppContext().get(APP_CONTEXT_KEYSTROKE_KEY);
if (cache == null) {
cache = new HashMap<>();
AppContext.getAppContext().put(APP_CONTEXT_CACHE_KEY, cache);
}
if (cacheKey == null) {
try {
Class<AWTKeyStroke> clazz = getAWTKeyStrokeClass();
cacheKey = (AWTKeyStroke)getCtor(clazz).newInstance((Object[]) null);
AppContext.getAppContext().put(APP_CONTEXT_KEYSTROKE_KEY, cacheKey);
} catch (InstantiationException e) {
assert(false);
} catch (IllegalAccessException e) {
assert(false);
} catch (InvocationTargetException e) {
assert(false);
}
}
cacheKey.keyChar = keyChar;
cacheKey.keyCode = keyCode;
cacheKey.modifiers = mapNewModifiers(mapOldModifiers(modifiers));
cacheKey.onKeyRelease = onKeyRelease;
AWTKeyStroke stroke = (AWTKeyStroke)cache.get(cacheKey);
if (stroke == null) {
stroke = cacheKey;
cache.put(stroke, stroke);
AppContext.getAppContext().remove(APP_CONTEXT_KEYSTROKE_KEY);
}
return stroke;
}
/**
* Returns a shared instance of an <code>AWTKeyStroke</code>
* that represents a <code>KEY_TYPED</code> event for the
* specified character.
*
* @param keyChar the character value for a keyboard key
* @return an <code>AWTKeyStroke</code> object for that key
*/
public static AWTKeyStroke getAWTKeyStroke(char keyChar) {
return getCachedStroke(keyChar, KeyEvent.VK_UNDEFINED, 0, false);
}
/**
* Returns a shared instance of an {@code AWTKeyStroke}
* that represents a {@code KEY_TYPED} event for the
* specified Character object and a set of modifiers. Note
* that the first parameter is of type Character rather than
* char. This is to avoid inadvertent clashes with
* calls to <code>getAWTKeyStroke(int keyCode, int modifiers)</code>.
*
* The modifiers consist of any combination of following:<ul>
* <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK
* <li>java.awt.event.InputEvent.CTRL_DOWN_MASK
* <li>java.awt.event.InputEvent.META_DOWN_MASK
* <li>java.awt.event.InputEvent.ALT_DOWN_MASK
* <li>java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK
* </ul>
* The old modifiers listed below also can be used, but they are
* mapped to _DOWN_ modifiers. <ul>
* <li>java.awt.event.InputEvent.SHIFT_MASK
* <li>java.awt.event.InputEvent.CTRL_MASK
* <li>java.awt.event.InputEvent.META_MASK
* <li>java.awt.event.InputEvent.ALT_MASK
* <li>java.awt.event.InputEvent.ALT_GRAPH_MASK
* </ul>
* also can be used, but they are mapped to _DOWN_ modifiers.
*
* Since these numbers are all different powers of two, any combination of
* them is an integer in which each bit represents a different modifier
* key. Use 0 to specify no modifiers.
*
* @param keyChar the Character object for a keyboard character
* @param modifiers a bitwise-ored combination of any modifiers
* @return an <code>AWTKeyStroke</code> object for that key
* @throws IllegalArgumentException if <code>keyChar</code> is
* <code>null</code>
*
* @see java.awt.event.InputEvent
*/
public static AWTKeyStroke getAWTKeyStroke(Character keyChar, int modifiers)
{
if (keyChar == null) {
throw new IllegalArgumentException("keyChar cannot be null");
}
return getCachedStroke(keyChar.charValue(), KeyEvent.VK_UNDEFINED,
modifiers, false);
}
/**
* Returns a shared instance of an <code>AWTKeyStroke</code>,
* given a numeric key code and a set of modifiers, specifying
* whether the key is activated when it is pressed or released.
* <p>
* The "virtual key" constants defined in
* <code>java.awt.event.KeyEvent</code> can be
* used to specify the key code. For example:<ul>
* <li><code>java.awt.event.KeyEvent.VK_ENTER</code>
* <li><code>java.awt.event.KeyEvent.VK_TAB</code>
* <li><code>java.awt.event.KeyEvent.VK_SPACE</code>
* </ul>
* Alternatively, the key code may be obtained by calling
* <code>java.awt.event.KeyEvent.getExtendedKeyCodeForChar</code>.
*
* The modifiers consist of any combination of:<ul>
* <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK
* <li>java.awt.event.InputEvent.CTRL_DOWN_MASK
* <li>java.awt.event.InputEvent.META_DOWN_MASK
* <li>java.awt.event.InputEvent.ALT_DOWN_MASK
* <li>java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK
* </ul>
* The old modifiers <ul>
* <li>java.awt.event.InputEvent.SHIFT_MASK
* <li>java.awt.event.InputEvent.CTRL_MASK
* <li>java.awt.event.InputEvent.META_MASK
* <li>java.awt.event.InputEvent.ALT_MASK
* <li>java.awt.event.InputEvent.ALT_GRAPH_MASK
* </ul>
* also can be used, but they are mapped to _DOWN_ modifiers.
*
* Since these numbers are all different powers of two, any combination of
* them is an integer in which each bit represents a different modifier
* key. Use 0 to specify no modifiers.
*
* @param keyCode an int specifying the numeric code for a keyboard key
* @param modifiers a bitwise-ored combination of any modifiers
* @param onKeyRelease <code>true</code> if the <code>AWTKeyStroke</code>
* should represent a key release; <code>false</code> otherwise
* @return an AWTKeyStroke object for that key
*
* @see java.awt.event.KeyEvent
* @see java.awt.event.InputEvent
*/
public static AWTKeyStroke getAWTKeyStroke(int keyCode, int modifiers,
boolean onKeyRelease) {
return getCachedStroke(KeyEvent.CHAR_UNDEFINED, keyCode, modifiers,
onKeyRelease);
}
/**
* Returns a shared instance of an <code>AWTKeyStroke</code>,
* given a numeric key code and a set of modifiers. The returned
* <code>AWTKeyStroke</code> will correspond to a key press.
* <p>
* The "virtual key" constants defined in
* <code>java.awt.event.KeyEvent</code> can be
* used to specify the key code. For example:<ul>
* <li><code>java.awt.event.KeyEvent.VK_ENTER</code>
* <li><code>java.awt.event.KeyEvent.VK_TAB</code>
* <li><code>java.awt.event.KeyEvent.VK_SPACE</code>
* </ul>
* The modifiers consist of any combination of:<ul>
* <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK
* <li>java.awt.event.InputEvent.CTRL_DOWN_MASK
* <li>java.awt.event.InputEvent.META_DOWN_MASK
* <li>java.awt.event.InputEvent.ALT_DOWN_MASK
* <li>java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK
* </ul>
* The old modifiers <ul>
* <li>java.awt.event.InputEvent.SHIFT_MASK
* <li>java.awt.event.InputEvent.CTRL_MASK
* <li>java.awt.event.InputEvent.META_MASK
* <li>java.awt.event.InputEvent.ALT_MASK
* <li>java.awt.event.InputEvent.ALT_GRAPH_MASK
* </ul>
* also can be used, but they are mapped to _DOWN_ modifiers.
*
* Since these numbers are all different powers of two, any combination of
* them is an integer in which each bit represents a different modifier
* key. Use 0 to specify no modifiers.
*
* @param keyCode an int specifying the numeric code for a keyboard key
* @param modifiers a bitwise-ored combination of any modifiers
* @return an <code>AWTKeyStroke</code> object for that key
*
* @see java.awt.event.KeyEvent
* @see java.awt.event.InputEvent
*/
public static AWTKeyStroke getAWTKeyStroke(int keyCode, int modifiers) {
return getCachedStroke(KeyEvent.CHAR_UNDEFINED, keyCode, modifiers,
false);
}
/**
* Returns an <code>AWTKeyStroke</code> which represents the
* stroke which generated a given <code>KeyEvent</code>.
* <p>
* This method obtains the keyChar from a <code>KeyTyped</code>
* event, and the keyCode from a <code>KeyPressed</code> or
* <code>KeyReleased</code> event. The <code>KeyEvent</code> modifiers are
* obtained for all three types of <code>KeyEvent</code>.
*
* @param anEvent the <code>KeyEvent</code> from which to
* obtain the <code>AWTKeyStroke</code>
* @throws NullPointerException if <code>anEvent</code> is null
* @return the <code>AWTKeyStroke</code> that precipitated the event
*/
public static AWTKeyStroke getAWTKeyStrokeForEvent(KeyEvent anEvent) {
int id = anEvent.getID();
switch(id) {
case KeyEvent.KEY_PRESSED:
case KeyEvent.KEY_RELEASED:
return getCachedStroke(KeyEvent.CHAR_UNDEFINED,
anEvent.getKeyCode(),
anEvent.getModifiers(),
(id == KeyEvent.KEY_RELEASED));
case KeyEvent.KEY_TYPED:
return getCachedStroke(anEvent.getKeyChar(),
KeyEvent.VK_UNDEFINED,
anEvent.getModifiers(),
false);
default:
// Invalid ID for this KeyEvent
return null;
}
}
/**
* Parses a string and returns an <code>AWTKeyStroke</code>.
* The string must have the following syntax:
* <pre>
* &lt;modifiers&gt;* (&lt;typedID&gt; | &lt;pressedReleasedID&gt;)
*
* modifiers := shift | control | ctrl | meta | alt | altGraph
* typedID := typed &lt;typedKey&gt;
* typedKey := string of length 1 giving Unicode character.
* pressedReleasedID := (pressed | released) key
* key := KeyEvent key code name, i.e. the name following "VK_".
* </pre>
* If typed, pressed or released is not specified, pressed is assumed. Here
* are some examples:
* <pre>
* "INSERT" =&gt; getAWTKeyStroke(KeyEvent.VK_INSERT, 0);
* "control DELETE" =&gt; getAWTKeyStroke(KeyEvent.VK_DELETE, InputEvent.CTRL_MASK);
* "alt shift X" =&gt; getAWTKeyStroke(KeyEvent.VK_X, InputEvent.ALT_MASK | InputEvent.SHIFT_MASK);
* "alt shift released X" =&gt; getAWTKeyStroke(KeyEvent.VK_X, InputEvent.ALT_MASK | InputEvent.SHIFT_MASK, true);
* "typed a" =&gt; getAWTKeyStroke('a');
* </pre>
*
* @param s a String formatted as described above
* @return an <code>AWTKeyStroke</code> object for that String
* @throws IllegalArgumentException if <code>s</code> is <code>null</code>,
* or is formatted incorrectly
*/
public static AWTKeyStroke getAWTKeyStroke(String s) {
if (s == null) {
throw new IllegalArgumentException("String cannot be null");
}
final String errmsg = "String formatted incorrectly";
StringTokenizer st = new StringTokenizer(s, " ");
int mask = 0;
boolean released = false;
boolean typed = false;
boolean pressed = false;
synchronized (AWTKeyStroke.class) {
if (modifierKeywords == null) {
Map<String, Integer> uninitializedMap = new HashMap<>(8, 1.0f);
uninitializedMap.put("shift",
Integer.valueOf(InputEvent.SHIFT_DOWN_MASK
|InputEvent.SHIFT_MASK));
uninitializedMap.put("control",
Integer.valueOf(InputEvent.CTRL_DOWN_MASK
|InputEvent.CTRL_MASK));
uninitializedMap.put("ctrl",
Integer.valueOf(InputEvent.CTRL_DOWN_MASK
|InputEvent.CTRL_MASK));
uninitializedMap.put("meta",
Integer.valueOf(InputEvent.META_DOWN_MASK
|InputEvent.META_MASK));
uninitializedMap.put("alt",
Integer.valueOf(InputEvent.ALT_DOWN_MASK
|InputEvent.ALT_MASK));
uninitializedMap.put("altGraph",
Integer.valueOf(InputEvent.ALT_GRAPH_DOWN_MASK
|InputEvent.ALT_GRAPH_MASK));
uninitializedMap.put("button1",
Integer.valueOf(InputEvent.BUTTON1_DOWN_MASK));
uninitializedMap.put("button2",
Integer.valueOf(InputEvent.BUTTON2_DOWN_MASK));
uninitializedMap.put("button3",
Integer.valueOf(InputEvent.BUTTON3_DOWN_MASK));
modifierKeywords =
Collections.synchronizedMap(uninitializedMap);
}
}
int count = st.countTokens();
for (int i = 1; i <= count; i++) {
String token = st.nextToken();
if (typed) {
if (token.length() != 1 || i != count) {
throw new IllegalArgumentException(errmsg);
}
return getCachedStroke(token.charAt(0), KeyEvent.VK_UNDEFINED,
mask, false);
}
if (pressed || released || i == count) {
if (i != count) {
throw new IllegalArgumentException(errmsg);
}
String keyCodeName = "VK_" + token;
int keyCode = getVKValue(keyCodeName);
return getCachedStroke(KeyEvent.CHAR_UNDEFINED, keyCode,
mask, released);
}
if (token.equals("released")) {
released = true;
continue;
}
if (token.equals("pressed")) {
pressed = true;
continue;
}
if (token.equals("typed")) {
typed = true;
continue;
}
Integer tokenMask = (Integer)modifierKeywords.get(token);
if (tokenMask != null) {
mask |= tokenMask.intValue();
} else {
throw new IllegalArgumentException(errmsg);
}
}
throw new IllegalArgumentException(errmsg);
}
private static VKCollection getVKCollection() {
if (vks == null) {
vks = new VKCollection();
}
return vks;
}
/**
* Returns the integer constant for the KeyEvent.VK field named
* <code>key</code>. This will throw an
* <code>IllegalArgumentException</code> if <code>key</code> is
* not a valid constant.
*/
private static int getVKValue(String key) {
VKCollection vkCollect = getVKCollection();
Integer value = vkCollect.findCode(key);
if (value == null) {
int keyCode = 0;
final String errmsg = "String formatted incorrectly";
try {
keyCode = KeyEvent.class.getField(key).getInt(KeyEvent.class);
} catch (NoSuchFieldException nsfe) {
throw new IllegalArgumentException(errmsg);
} catch (IllegalAccessException iae) {
throw new IllegalArgumentException(errmsg);
}
value = Integer.valueOf(keyCode);
vkCollect.put(key, value);
}
return value.intValue();
}
/**
* Returns the character for this <code>AWTKeyStroke</code>.
*
* @return a char value
* @see #getAWTKeyStroke(char)
* @see KeyEvent#getKeyChar
*/
public final char getKeyChar() {
return keyChar;
}
/**
* Returns the numeric key code for this <code>AWTKeyStroke</code>.
*
* @return an int containing the key code value
* @see #getAWTKeyStroke(int,int)
* @see KeyEvent#getKeyCode
*/
public final int getKeyCode() {
return keyCode;
}
/**
* Returns the modifier keys for this <code>AWTKeyStroke</code>.
*
* @return an int containing the modifiers
* @see #getAWTKeyStroke(int,int)
*/
public final int getModifiers() {
return modifiers;
}
/**
* Returns whether this <code>AWTKeyStroke</code> represents a key release.
*
* @return <code>true</code> if this <code>AWTKeyStroke</code>
* represents a key release; <code>false</code> otherwise
* @see #getAWTKeyStroke(int,int,boolean)
*/
public final boolean isOnKeyRelease() {
return onKeyRelease;
}
/**
* Returns the type of <code>KeyEvent</code> which corresponds to
* this <code>AWTKeyStroke</code>.
*
* @return <code>KeyEvent.KEY_PRESSED</code>,
* <code>KeyEvent.KEY_TYPED</code>,
* or <code>KeyEvent.KEY_RELEASED</code>
* @see java.awt.event.KeyEvent
*/
public final int getKeyEventType() {
if (keyCode == KeyEvent.VK_UNDEFINED) {
return KeyEvent.KEY_TYPED;
} else {
return (onKeyRelease)
? KeyEvent.KEY_RELEASED
: KeyEvent.KEY_PRESSED;
}
}
/**
* Returns a numeric value for this object that is likely to be unique,
* making it a good choice as the index value in a hash table.
*
* @return an int that represents this object
*/
public int hashCode() {
return (((int)keyChar) + 1) * (2 * (keyCode + 1)) * (modifiers + 1) +
(onKeyRelease ? 1 : 2);
}
/**
* Returns true if this object is identical to the specified object.
*
* @param anObject the Object to compare this object to
* @return true if the objects are identical
*/
public final boolean equals(Object anObject) {
if (anObject instanceof AWTKeyStroke) {
AWTKeyStroke ks = (AWTKeyStroke)anObject;
return (ks.keyChar == keyChar && ks.keyCode == keyCode &&
ks.onKeyRelease == onKeyRelease &&
ks.modifiers == modifiers);
}
return false;
}
/**
* Returns a string that displays and identifies this object's properties.
* The <code>String</code> returned by this method can be passed
* as a parameter to <code>getAWTKeyStroke(String)</code> to produce
* a key stroke equal to this key stroke.
*
* @return a String representation of this object
* @see #getAWTKeyStroke(String)
*/
public String toString() {
if (keyCode == KeyEvent.VK_UNDEFINED) {
return getModifiersText(modifiers) + "typed " + keyChar;
} else {
return getModifiersText(modifiers) +
(onKeyRelease ? "released" : "pressed") + " " +
getVKText(keyCode);
}
}
static String getModifiersText(int modifiers) {
StringBuilder buf = new StringBuilder();
if ((modifiers & InputEvent.SHIFT_DOWN_MASK) != 0 ) {
buf.append("shift ");
}
if ((modifiers & InputEvent.CTRL_DOWN_MASK) != 0 ) {
buf.append("ctrl ");
}
if ((modifiers & InputEvent.META_DOWN_MASK) != 0 ) {
buf.append("meta ");
}
if ((modifiers & InputEvent.ALT_DOWN_MASK) != 0 ) {
buf.append("alt ");
}
if ((modifiers & InputEvent.ALT_GRAPH_DOWN_MASK) != 0 ) {
buf.append("altGraph ");
}
if ((modifiers & InputEvent.BUTTON1_DOWN_MASK) != 0 ) {
buf.append("button1 ");
}
if ((modifiers & InputEvent.BUTTON2_DOWN_MASK) != 0 ) {
buf.append("button2 ");
}
if ((modifiers & InputEvent.BUTTON3_DOWN_MASK) != 0 ) {
buf.append("button3 ");
}
return buf.toString();
}
static String getVKText(int keyCode) {
VKCollection vkCollect = getVKCollection();
Integer key = Integer.valueOf(keyCode);
String name = vkCollect.findName(key);
if (name != null) {
return name.substring(3);
}
int expected_modifiers =
(Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL);
Field[] fields = KeyEvent.class.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
try {
if (fields[i].getModifiers() == expected_modifiers
&& fields[i].getType() == Integer.TYPE
&& fields[i].getName().startsWith("VK_")
&& fields[i].getInt(KeyEvent.class) == keyCode)
{
name = fields[i].getName();
vkCollect.put(name, key);
return name.substring(3);
}
} catch (IllegalAccessException e) {
assert(false);
}
}
return "UNKNOWN";
}
/**
* Returns a cached instance of <code>AWTKeyStroke</code> (or a subclass of
* <code>AWTKeyStroke</code>) which is equal to this instance.
*
* @return a cached instance which is equal to this instance
*/
protected Object readResolve() throws java.io.ObjectStreamException {
synchronized (AWTKeyStroke.class) {
if (getClass().equals(getAWTKeyStrokeClass())) {
return getCachedStroke(keyChar, keyCode, modifiers, onKeyRelease);
}
}
return this;
}
private static int mapOldModifiers(int modifiers) {
if ((modifiers & InputEvent.SHIFT_MASK) != 0) {
modifiers |= InputEvent.SHIFT_DOWN_MASK;
}
if ((modifiers & InputEvent.ALT_MASK) != 0) {
modifiers |= InputEvent.ALT_DOWN_MASK;
}
if ((modifiers & InputEvent.ALT_GRAPH_MASK) != 0) {
modifiers |= InputEvent.ALT_GRAPH_DOWN_MASK;
}
if ((modifiers & InputEvent.CTRL_MASK) != 0) {
modifiers |= InputEvent.CTRL_DOWN_MASK;
}
if ((modifiers & InputEvent.META_MASK) != 0) {
modifiers |= InputEvent.META_DOWN_MASK;
}
modifiers &= InputEvent.SHIFT_DOWN_MASK
| InputEvent.ALT_DOWN_MASK
| InputEvent.ALT_GRAPH_DOWN_MASK
| InputEvent.CTRL_DOWN_MASK
| InputEvent.META_DOWN_MASK
| InputEvent.BUTTON1_DOWN_MASK
| InputEvent.BUTTON2_DOWN_MASK
| InputEvent.BUTTON3_DOWN_MASK;
return modifiers;
}
private static int mapNewModifiers(int modifiers) {
if ((modifiers & InputEvent.SHIFT_DOWN_MASK) != 0) {
modifiers |= InputEvent.SHIFT_MASK;
}
if ((modifiers & InputEvent.ALT_DOWN_MASK) != 0) {
modifiers |= InputEvent.ALT_MASK;
}
if ((modifiers & InputEvent.ALT_GRAPH_DOWN_MASK) != 0) {
modifiers |= InputEvent.ALT_GRAPH_MASK;
}
if ((modifiers & InputEvent.CTRL_DOWN_MASK) != 0) {
modifiers |= InputEvent.CTRL_MASK;
}
if ((modifiers & InputEvent.META_DOWN_MASK) != 0) {
modifiers |= InputEvent.META_MASK;
}
return modifiers;
}
}
class VKCollection {
Map<Integer, String> code2name;
Map<String, Integer> name2code;
public VKCollection() {
code2name = new HashMap<>();
name2code = new HashMap<>();
}
public synchronized void put(String name, Integer code) {
assert((name != null) && (code != null));
assert(findName(code) == null);
assert(findCode(name) == null);
code2name.put(code, name);
name2code.put(name, code);
}
public synchronized Integer findCode(String name) {
assert(name != null);
return (Integer)name2code.get(name);
}
public synchronized String findName(Integer code) {
assert(code != null);
return (String)code2name.get(code);
}
}

View File

@@ -0,0 +1,236 @@
/*
* 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 java.awt;
import java.security.BasicPermission;
/**
* This class is for AWT permissions.
* An <code>AWTPermission</code> contains a target name but
* no actions list; you either have the named permission
* or you don't.
*
* <P>
* The target name is the name of the AWT permission (see below). The naming
* convention follows the hierarchical property naming convention.
* Also, an asterisk could be used to represent all AWT permissions.
*
* <P>
* The following table lists all the possible <code>AWTPermission</code>
* target names, and for each provides a description of what the
* permission allows and a discussion of the risks of granting code
* the permission.
*
* <table border=1 cellpadding=5 summary="AWTPermission target names, descriptions, and associated risks.">
* <tr>
* <th>Permission Target Name</th>
* <th>What the Permission Allows</th>
* <th>Risks of Allowing this Permission</th>
* </tr>
*
* <tr>
* <td>accessClipboard</td>
* <td>Posting and retrieval of information to and from the AWT clipboard</td>
* <td>This would allow malfeasant code to share
* potentially sensitive or confidential information.</td>
* </tr>
*
* <tr>
* <td>accessEventQueue</td>
* <td>Access to the AWT event queue</td>
* <td>After retrieving the AWT event queue,
* malicious code may peek at and even remove existing events
* from its event queue, as well as post bogus events which may purposefully
* cause the application or applet to misbehave in an insecure manner.</td>
* </tr>
*
* <tr>
* <td>accessSystemTray</td>
* <td>Access to the AWT SystemTray instance</td>
* <td>This would allow malicious code to add tray icons to the system tray.
* First, such an icon may look like the icon of some known application
* (such as a firewall or anti-virus) and order a user to do something unsafe
* (with help of balloon messages). Second, the system tray may be glutted with
* tray icons so that no one could add a tray icon anymore.</td>
* </tr>
*
* <tr>
* <td>createRobot</td>
* <td>Create java.awt.Robot objects</td>
* <td>The java.awt.Robot object allows code to generate native-level
* mouse and keyboard events as well as read the screen. It could allow
* malicious code to control the system, run other programs, read the
* display, and deny mouse and keyboard access to the user.</td>
* </tr>
*
* <tr>
* <td>fullScreenExclusive</td>
* <td>Enter full-screen exclusive mode</td>
* <td>Entering full-screen exclusive mode allows direct access to
* low-level graphics card memory. This could be used to spoof the
* system, since the program is in direct control of rendering. Depending on
* the implementation, the security warning may not be shown for the windows
* used to enter the full-screen exclusive mode (assuming that the {@code
* fullScreenExclusive} permission has been granted to this application). Note
* that this behavior does not mean that the {@code
* showWindowWithoutWarningBanner} permission will be automatically granted to
* the application which has the {@code fullScreenExclusive} permission:
* non-full-screen windows will continue to be shown with the security
* warning.</td>
* </tr>
*
* <tr>
* <td>listenToAllAWTEvents</td>
* <td>Listen to all AWT events, system-wide</td>
* <td>After adding an AWT event listener,
* malicious code may scan all AWT events dispatched in the system,
* allowing it to read all user input (such as passwords). Each
* AWT event listener is called from within the context of that
* event queue's EventDispatchThread, so if the accessEventQueue
* permission is also enabled, malicious code could modify the
* contents of AWT event queues system-wide, causing the application
* or applet to misbehave in an insecure manner.</td>
* </tr>
*
* <tr>
* <td>readDisplayPixels</td>
* <td>Readback of pixels from the display screen</td>
* <td>Interfaces such as the java.awt.Composite interface or the
* java.awt.Robot class allow arbitrary code to examine pixels on the
* display enable malicious code to snoop on the activities of the user.</td>
* </tr>
*
* <tr>
* <td>replaceKeyboardFocusManager</td>
* <td>Sets the <code>KeyboardFocusManager</code> for
* a particular thread.
* <td>When <code>SecurityManager</code> is installed, the invoking
* thread must be granted this permission in order to replace
* the current <code>KeyboardFocusManager</code>. If permission
* is not granted, a <code>SecurityException</code> will be thrown.
* </tr>
*
* <tr>
* <td>setAppletStub</td>
* <td>Setting the stub which implements Applet container services</td>
* <td>Malicious code could set an applet's stub and result in unexpected
* behavior or denial of service to an applet.</td>
* </tr>
*
* <tr>
* <td>setWindowAlwaysOnTop</td>
* <td>Setting always-on-top property of the window: {@link Window#setAlwaysOnTop}</td>
* <td>The malicious window might make itself look and behave like a real full desktop, so that
* information entered by the unsuspecting user is captured and subsequently misused </td>
* </tr>
*
* <tr>
* <td>showWindowWithoutWarningBanner</td>
* <td>Display of a window without also displaying a banner warning
* that the window was created by an applet</td>
* <td>Without this warning,
* an applet may pop up windows without the user knowing that they
* belong to an applet. Since users may make security-sensitive
* decisions based on whether or not the window belongs to an applet
* (entering a username and password into a dialog box, for example),
* disabling this warning banner may allow applets to trick the user
* into entering such information.</td>
* </tr>
*
* <tr>
* <td>toolkitModality</td>
* <td>Creating {@link Dialog.ModalityType#TOOLKIT_MODAL TOOLKIT_MODAL} dialogs
* and setting the {@link Dialog.ModalExclusionType#TOOLKIT_EXCLUDE
* TOOLKIT_EXCLUDE} window property.</td>
* <td>When a toolkit-modal dialog is shown from an applet, it blocks all other
* applets in the browser. When launching applications from Java Web Start,
* its windows (such as the security dialog) may also be blocked by toolkit-modal
* dialogs, shown from these applications.</td>
* </tr>
*
* <tr>
* <td>watchMousePointer</td>
* <td>Getting the information about the mouse pointer position at any
* time</td>
* <td>Constantly watching the mouse pointer,
* an applet can make guesses about what the user is doing, i.e. moving
* the mouse to the lower left corner of the screen most likely means that
* the user is about to launch an application. If a virtual keypad is used
* so that keyboard is emulated using the mouse, an applet may guess what
* is being typed.</td>
* </tr>
* </table>
*
* @see java.security.BasicPermission
* @see java.security.Permission
* @see java.security.Permissions
* @see java.security.PermissionCollection
* @see java.lang.SecurityManager
*
*
* @author Marianne Mueller
* @author Roland Schemers
*/
public final class AWTPermission extends BasicPermission {
/** use serialVersionUID from the Java 2 platform for interoperability */
private static final long serialVersionUID = 8890392402588814465L;
/**
* Creates a new <code>AWTPermission</code> with the specified name.
* The name is the symbolic name of the <code>AWTPermission</code>,
* such as "topLevelWindow", "systemClipboard", etc. An asterisk
* may be used to indicate all AWT permissions.
*
* @param name the name of the AWTPermission
*
* @throws NullPointerException if <code>name</code> is <code>null</code>.
* @throws IllegalArgumentException if <code>name</code> is empty.
*/
public AWTPermission(String name)
{
super(name);
}
/**
* Creates a new <code>AWTPermission</code> object with the specified name.
* The name is the symbolic name of the <code>AWTPermission</code>, and the
* actions string is currently unused and should be <code>null</code>.
*
* @param name the name of the <code>AWTPermission</code>
* @param actions should be <code>null</code>
*
* @throws NullPointerException if <code>name</code> is <code>null</code>.
* @throws IllegalArgumentException if <code>name</code> is empty.
*/
public AWTPermission(String name, String actions)
{
super(name, actions);
}
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright (c) 1997, 2002, 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 java.awt;
/**
* An interface for events that know how to dispatch themselves.
* By implementing this interface an event can be placed upon the event
* queue and its <code>dispatch()</code> method will be called when the event
* is dispatched, using the <code>EventDispatchThread</code>.
* <p>
* This is a very useful mechanism for avoiding deadlocks. If
* a thread is executing in a critical section (i.e., it has entered
* one or more monitors), calling other synchronized code may
* cause deadlocks. To avoid the potential deadlocks, an
* <code>ActiveEvent</code> can be created to run the second section of
* code at later time. If there is contention on the monitor,
* the second thread will simply block until the first thread
* has finished its work and exited its monitors.
* <p>
* For security reasons, it is often desirable to use an <code>ActiveEvent</code>
* to avoid calling untrusted code from a critical thread. For
* instance, peer implementations can use this facility to avoid
* making calls into user code from a system thread. Doing so avoids
* potential deadlocks and denial-of-service attacks.
*
* @author Timothy Prinzing
* @since 1.2
*/
public interface ActiveEvent {
/**
* Dispatch the event to its target, listeners of the events source,
* or do whatever it is this event is supposed to do.
*/
public void dispatch();
}

View File

@@ -0,0 +1,160 @@
/*
* Copyright (c) 1996, 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 java.awt;
import java.awt.event.*;
import java.lang.annotation.Native;
/**
* The interface for objects which have an adjustable numeric value
* contained within a bounded range of values.
*
* @author Amy Fowler
* @author Tim Prinzing
*/
public interface Adjustable {
/**
* Indicates that the <code>Adjustable</code> has horizontal orientation.
*/
@Native public static final int HORIZONTAL = 0;
/**
* Indicates that the <code>Adjustable</code> has vertical orientation.
*/
@Native public static final int VERTICAL = 1;
/**
* Indicates that the <code>Adjustable</code> has no orientation.
*/
@Native public static final int NO_ORIENTATION = 2;
/**
* Gets the orientation of the adjustable object.
* @return the orientation of the adjustable object;
* either <code>HORIZONTAL</code>, <code>VERTICAL</code>,
* or <code>NO_ORIENTATION</code>
*/
int getOrientation();
/**
* Sets the minimum value of the adjustable object.
* @param min the minimum value
*/
void setMinimum(int min);
/**
* Gets the minimum value of the adjustable object.
* @return the minimum value of the adjustable object
*/
int getMinimum();
/**
* Sets the maximum value of the adjustable object.
* @param max the maximum value
*/
void setMaximum(int max);
/**
* Gets the maximum value of the adjustable object.
* @return the maximum value of the adjustable object
*/
int getMaximum();
/**
* Sets the unit value increment for the adjustable object.
* @param u the unit increment
*/
void setUnitIncrement(int u);
/**
* Gets the unit value increment for the adjustable object.
* @return the unit value increment for the adjustable object
*/
int getUnitIncrement();
/**
* Sets the block value increment for the adjustable object.
* @param b the block increment
*/
void setBlockIncrement(int b);
/**
* Gets the block value increment for the adjustable object.
* @return the block value increment for the adjustable object
*/
int getBlockIncrement();
/**
* Sets the length of the proportional indicator of the
* adjustable object.
* @param v the length of the indicator
*/
void setVisibleAmount(int v);
/**
* Gets the length of the proportional indicator.
* @return the length of the proportional indicator
*/
int getVisibleAmount();
/**
* Sets the current value of the adjustable object. If
* the value supplied is less than <code>minimum</code>
* or greater than <code>maximum</code> - <code>visibleAmount</code>,
* then one of those values is substituted, as appropriate.
* <p>
* Calling this method does not fire an
* <code>AdjustmentEvent</code>.
*
* @param v the current value, between <code>minimum</code>
* and <code>maximum</code> - <code>visibleAmount</code>
*/
void setValue(int v);
/**
* Gets the current value of the adjustable object.
* @return the current value of the adjustable object
*/
int getValue();
/**
* Adds a listener to receive adjustment events when the value of
* the adjustable object changes.
* @param l the listener to receive events
* @see AdjustmentEvent
*/
void addAdjustmentListener(AdjustmentListener l);
/**
* Removes an adjustment listener.
* @param l the listener being removed
* @see AdjustmentEvent
*/
void removeAdjustmentListener(AdjustmentListener l);
}

View File

@@ -0,0 +1,799 @@
/*
* 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 java.awt;
import java.awt.image.ColorModel;
import java.lang.annotation.Native;
import sun.java2d.SunCompositeContext;
/**
* The <code>AlphaComposite</code> class implements basic alpha
* compositing rules for combining source and destination colors
* to achieve blending and transparency effects with graphics and
* images.
* The specific rules implemented by this class are the basic set
* of 12 rules described in
* T. Porter and T. Duff, "Compositing Digital Images", SIGGRAPH 84,
* 253-259.
* The rest of this documentation assumes some familiarity with the
* definitions and concepts outlined in that paper.
*
* <p>
* This class extends the standard equations defined by Porter and
* Duff to include one additional factor.
* An instance of the <code>AlphaComposite</code> class can contain
* an alpha value that is used to modify the opacity or coverage of
* every source pixel before it is used in the blending equations.
*
* <p>
* It is important to note that the equations defined by the Porter
* and Duff paper are all defined to operate on color components
* that are premultiplied by their corresponding alpha components.
* Since the <code>ColorModel</code> and <code>Raster</code> classes
* allow the storage of pixel data in either premultiplied or
* non-premultiplied form, all input data must be normalized into
* premultiplied form before applying the equations and all results
* might need to be adjusted back to the form required by the destination
* before the pixel values are stored.
*
* <p>
* Also note that this class defines only the equations
* for combining color and alpha values in a purely mathematical
* sense. The accurate application of its equations depends
* on the way the data is retrieved from its sources and stored
* in its destinations.
* See <a href="#caveats">Implementation Caveats</a>
* for further information.
*
* <p>
* The following factors are used in the description of the blending
* equation in the Porter and Duff paper:
*
* <blockquote>
* <table summary="layout">
* <tr><th align=left>Factor&nbsp;&nbsp;<th align=left>Definition
* <tr><td><em>A<sub>s</sub></em><td>the alpha component of the source pixel
* <tr><td><em>C<sub>s</sub></em><td>a color component of the source pixel in premultiplied form
* <tr><td><em>A<sub>d</sub></em><td>the alpha component of the destination pixel
* <tr><td><em>C<sub>d</sub></em><td>a color component of the destination pixel in premultiplied form
* <tr><td><em>F<sub>s</sub></em><td>the fraction of the source pixel that contributes to the output
* <tr><td><em>F<sub>d</sub></em><td>the fraction of the destination pixel that contributes
* to the output
* <tr><td><em>A<sub>r</sub></em><td>the alpha component of the result
* <tr><td><em>C<sub>r</sub></em><td>a color component of the result in premultiplied form
* </table>
* </blockquote>
*
* <p>
* Using these factors, Porter and Duff define 12 ways of choosing
* the blending factors <em>F<sub>s</sub></em> and <em>F<sub>d</sub></em> to
* produce each of 12 desirable visual effects.
* The equations for determining <em>F<sub>s</sub></em> and <em>F<sub>d</sub></em>
* are given in the descriptions of the 12 static fields
* that specify visual effects.
* For example,
* the description for
* <a href="#SRC_OVER"><code>SRC_OVER</code></a>
* specifies that <em>F<sub>s</sub></em> = 1 and <em>F<sub>d</sub></em> = (1-<em>A<sub>s</sub></em>).
* Once a set of equations for determining the blending factors is
* known they can then be applied to each pixel to produce a result
* using the following set of equations:
*
* <pre>
* <em>F<sub>s</sub></em> = <em>f</em>(<em>A<sub>d</sub></em>)
* <em>F<sub>d</sub></em> = <em>f</em>(<em>A<sub>s</sub></em>)
* <em>A<sub>r</sub></em> = <em>A<sub>s</sub></em>*<em>F<sub>s</sub></em> + <em>A<sub>d</sub></em>*<em>F<sub>d</sub></em>
* <em>C<sub>r</sub></em> = <em>C<sub>s</sub></em>*<em>F<sub>s</sub></em> + <em>C<sub>d</sub></em>*<em>F<sub>d</sub></em></pre>
*
* <p>
* The following factors will be used to discuss our extensions to
* the blending equation in the Porter and Duff paper:
*
* <blockquote>
* <table summary="layout">
* <tr><th align=left>Factor&nbsp;&nbsp;<th align=left>Definition
* <tr><td><em>C<sub>sr</sub></em> <td>one of the raw color components of the source pixel
* <tr><td><em>C<sub>dr</sub></em> <td>one of the raw color components of the destination pixel
* <tr><td><em>A<sub>ac</sub></em> <td>the "extra" alpha component from the AlphaComposite instance
* <tr><td><em>A<sub>sr</sub></em> <td>the raw alpha component of the source pixel
* <tr><td><em>A<sub>dr</sub></em><td>the raw alpha component of the destination pixel
* <tr><td><em>A<sub>df</sub></em> <td>the final alpha component stored in the destination
* <tr><td><em>C<sub>df</sub></em> <td>the final raw color component stored in the destination
* </table>
*</blockquote>
*
* <h3>Preparing Inputs</h3>
*
* <p>
* The <code>AlphaComposite</code> class defines an additional alpha
* value that is applied to the source alpha.
* This value is applied as if an implicit SRC_IN rule were first
* applied to the source pixel against a pixel with the indicated
* alpha by multiplying both the raw source alpha and the raw
* source colors by the alpha in the <code>AlphaComposite</code>.
* This leads to the following equation for producing the alpha
* used in the Porter and Duff blending equation:
*
* <pre>
* <em>A<sub>s</sub></em> = <em>A<sub>sr</sub></em> * <em>A<sub>ac</sub></em> </pre>
*
* All of the raw source color components need to be multiplied
* by the alpha in the <code>AlphaComposite</code> instance.
* Additionally, if the source was not in premultiplied form
* then the color components also need to be multiplied by the
* source alpha.
* Thus, the equation for producing the source color components
* for the Porter and Duff equation depends on whether the source
* pixels are premultiplied or not:
*
* <pre>
* <em>C<sub>s</sub></em> = <em>C<sub>sr</sub></em> * <em>A<sub>sr</sub></em> * <em>A<sub>ac</sub></em> (if source is not premultiplied)
* <em>C<sub>s</sub></em> = <em>C<sub>sr</sub></em> * <em>A<sub>ac</sub></em> (if source is premultiplied) </pre>
*
* No adjustment needs to be made to the destination alpha:
*
* <pre>
* <em>A<sub>d</sub></em> = <em>A<sub>dr</sub></em> </pre>
*
* <p>
* The destination color components need to be adjusted only if
* they are not in premultiplied form:
*
* <pre>
* <em>C<sub>d</sub></em> = <em>C<sub>dr</sub></em> * <em>A<sub>d</sub></em> (if destination is not premultiplied)
* <em>C<sub>d</sub></em> = <em>C<sub>dr</sub></em> (if destination is premultiplied) </pre>
*
* <h3>Applying the Blending Equation</h3>
*
* <p>
* The adjusted <em>A<sub>s</sub></em>, <em>A<sub>d</sub></em>,
* <em>C<sub>s</sub></em>, and <em>C<sub>d</sub></em> are used in the standard
* Porter and Duff equations to calculate the blending factors
* <em>F<sub>s</sub></em> and <em>F<sub>d</sub></em> and then the resulting
* premultiplied components <em>A<sub>r</sub></em> and <em>C<sub>r</sub></em>.
*
* <h3>Preparing Results</h3>
*
* <p>
* The results only need to be adjusted if they are to be stored
* back into a destination buffer that holds data that is not
* premultiplied, using the following equations:
*
* <pre>
* <em>A<sub>df</sub></em> = <em>A<sub>r</sub></em>
* <em>C<sub>df</sub></em> = <em>C<sub>r</sub></em> (if dest is premultiplied)
* <em>C<sub>df</sub></em> = <em>C<sub>r</sub></em> / <em>A<sub>r</sub></em> (if dest is not premultiplied) </pre>
*
* Note that since the division is undefined if the resulting alpha
* is zero, the division in that case is omitted to avoid the "divide
* by zero" and the color components are left as
* all zeros.
*
* <h3>Performance Considerations</h3>
*
* <p>
* For performance reasons, it is preferable that
* <code>Raster</code> objects passed to the <code>compose</code>
* method of a {@link CompositeContext} object created by the
* <code>AlphaComposite</code> class have premultiplied data.
* If either the source <code>Raster</code>
* or the destination <code>Raster</code>
* is not premultiplied, however,
* appropriate conversions are performed before and after the compositing
* operation.
*
* <h3><a name="caveats">Implementation Caveats</a></h3>
*
* <ul>
* <li>
* Many sources, such as some of the opaque image types listed
* in the <code>BufferedImage</code> class, do not store alpha values
* for their pixels. Such sources supply an alpha of 1.0 for
* all of their pixels.
*
* <li>
* Many destinations also have no place to store the alpha values
* that result from the blending calculations performed by this class.
* Such destinations thus implicitly discard the resulting
* alpha values that this class produces.
* It is recommended that such destinations should treat their stored
* color values as non-premultiplied and divide the resulting color
* values by the resulting alpha value before storing the color
* values and discarding the alpha value.
*
* <li>
* The accuracy of the results depends on the manner in which pixels
* are stored in the destination.
* An image format that provides at least 8 bits of storage per color
* and alpha component is at least adequate for use as a destination
* for a sequence of a few to a dozen compositing operations.
* An image format with fewer than 8 bits of storage per component
* is of limited use for just one or two compositing operations
* before the rounding errors dominate the results.
* An image format
* that does not separately store
* color components is not a
* good candidate for any type of translucent blending.
* For example, <code>BufferedImage.TYPE_BYTE_INDEXED</code>
* should not be used as a destination for a blending operation
* because every operation
* can introduce large errors, due to
* the need to choose a pixel from a limited palette to match the
* results of the blending equations.
*
* <li>
* Nearly all formats store pixels as discrete integers rather than
* the floating point values used in the reference equations above.
* The implementation can either scale the integer pixel
* values into floating point values in the range 0.0 to 1.0 or
* use slightly modified versions of the equations
* that operate entirely in the integer domain and yet produce
* analogous results to the reference equations.
*
* <p>
* Typically the integer values are related to the floating point
* values in such a way that the integer 0 is equated
* to the floating point value 0.0 and the integer
* 2^<em>n</em>-1 (where <em>n</em> is the number of bits
* in the representation) is equated to 1.0.
* For 8-bit representations, this means that 0x00
* represents 0.0 and 0xff represents
* 1.0.
*
* <li>
* The internal implementation can approximate some of the equations
* and it can also eliminate some steps to avoid unnecessary operations.
* For example, consider a discrete integer image with non-premultiplied
* alpha values that uses 8 bits per component for storage.
* The stored values for a
* nearly transparent darkened red might be:
*
* <pre>
* (A, R, G, B) = (0x01, 0xb0, 0x00, 0x00)</pre>
*
* <p>
* If integer math were being used and this value were being
* composited in
* <a href="#SRC"><code>SRC</code></a>
* mode with no extra alpha, then the math would
* indicate that the results were (in integer format):
*
* <pre>
* (A, R, G, B) = (0x01, 0x01, 0x00, 0x00)</pre>
*
* <p>
* Note that the intermediate values, which are always in premultiplied
* form, would only allow the integer red component to be either 0x00
* or 0x01. When we try to store this result back into a destination
* that is not premultiplied, dividing out the alpha will give us
* very few choices for the non-premultiplied red value.
* In this case an implementation that performs the math in integer
* space without shortcuts is likely to end up with the final pixel
* values of:
*
* <pre>
* (A, R, G, B) = (0x01, 0xff, 0x00, 0x00)</pre>
*
* <p>
* (Note that 0x01 divided by 0x01 gives you 1.0, which is equivalent
* to the value 0xff in an 8-bit storage format.)
*
* <p>
* Alternately, an implementation that uses floating point math
* might produce more accurate results and end up returning to the
* original pixel value with little, if any, roundoff error.
* Or, an implementation using integer math might decide that since
* the equations boil down to a virtual NOP on the color values
* if performed in a floating point space, it can transfer the
* pixel untouched to the destination and avoid all the math entirely.
*
* <p>
* These implementations all attempt to honor the
* same equations, but use different tradeoffs of integer and
* floating point math and reduced or full equations.
* To account for such differences, it is probably best to
* expect only that the premultiplied form of the results to
* match between implementations and image formats. In this
* case both answers, expressed in premultiplied form would
* equate to:
*
* <pre>
* (A, R, G, B) = (0x01, 0x01, 0x00, 0x00)</pre>
*
* <p>
* and thus they would all match.
*
* <li>
* Because of the technique of simplifying the equations for
* calculation efficiency, some implementations might perform
* differently when encountering result alpha values of 0.0
* on a non-premultiplied destination.
* Note that the simplification of removing the divide by alpha
* in the case of the SRC rule is technically not valid if the
* denominator (alpha) is 0.
* But, since the results should only be expected to be accurate
* when viewed in premultiplied form, a resulting alpha of 0
* essentially renders the resulting color components irrelevant
* and so exact behavior in this case should not be expected.
* </ul>
* @see Composite
* @see CompositeContext
*/
public final class AlphaComposite implements Composite {
/**
* Both the color and the alpha of the destination are cleared
* (Porter-Duff Clear rule).
* Neither the source nor the destination is used as input.
*<p>
* <em>F<sub>s</sub></em> = 0 and <em>F<sub>d</sub></em> = 0, thus:
*<pre>
* <em>A<sub>r</sub></em> = 0
* <em>C<sub>r</sub></em> = 0
*</pre>
*/
@Native public static final int CLEAR = 1;
/**
* The source is copied to the destination
* (Porter-Duff Source rule).
* The destination is not used as input.
*<p>
* <em>F<sub>s</sub></em> = 1 and <em>F<sub>d</sub></em> = 0, thus:
*<pre>
* <em>A<sub>r</sub></em> = <em>A<sub>s</sub></em>
* <em>C<sub>r</sub></em> = <em>C<sub>s</sub></em>
*</pre>
*/
@Native public static final int SRC = 2;
/**
* The destination is left untouched
* (Porter-Duff Destination rule).
*<p>
* <em>F<sub>s</sub></em> = 0 and <em>F<sub>d</sub></em> = 1, thus:
*<pre>
* <em>A<sub>r</sub></em> = <em>A<sub>d</sub></em>
* <em>C<sub>r</sub></em> = <em>C<sub>d</sub></em>
*</pre>
* @since 1.4
*/
@Native public static final int DST = 9;
// Note that DST was added in 1.4 so it is numbered out of order...
/**
* The source is composited over the destination
* (Porter-Duff Source Over Destination rule).
*<p>
* <em>F<sub>s</sub></em> = 1 and <em>F<sub>d</sub></em> = (1-<em>A<sub>s</sub></em>), thus:
*<pre>
* <em>A<sub>r</sub></em> = <em>A<sub>s</sub></em> + <em>A<sub>d</sub></em>*(1-<em>A<sub>s</sub></em>)
* <em>C<sub>r</sub></em> = <em>C<sub>s</sub></em> + <em>C<sub>d</sub></em>*(1-<em>A<sub>s</sub></em>)
*</pre>
*/
@Native public static final int SRC_OVER = 3;
/**
* The destination is composited over the source and
* the result replaces the destination
* (Porter-Duff Destination Over Source rule).
*<p>
* <em>F<sub>s</sub></em> = (1-<em>A<sub>d</sub></em>) and <em>F<sub>d</sub></em> = 1, thus:
*<pre>
* <em>A<sub>r</sub></em> = <em>A<sub>s</sub></em>*(1-<em>A<sub>d</sub></em>) + <em>A<sub>d</sub></em>
* <em>C<sub>r</sub></em> = <em>C<sub>s</sub></em>*(1-<em>A<sub>d</sub></em>) + <em>C<sub>d</sub></em>
*</pre>
*/
@Native public static final int DST_OVER = 4;
/**
* The part of the source lying inside of the destination replaces
* the destination
* (Porter-Duff Source In Destination rule).
*<p>
* <em>F<sub>s</sub></em> = <em>A<sub>d</sub></em> and <em>F<sub>d</sub></em> = 0, thus:
*<pre>
* <em>A<sub>r</sub></em> = <em>A<sub>s</sub></em>*<em>A<sub>d</sub></em>
* <em>C<sub>r</sub></em> = <em>C<sub>s</sub></em>*<em>A<sub>d</sub></em>
*</pre>
*/
@Native public static final int SRC_IN = 5;
/**
* The part of the destination lying inside of the source
* replaces the destination
* (Porter-Duff Destination In Source rule).
*<p>
* <em>F<sub>s</sub></em> = 0 and <em>F<sub>d</sub></em> = <em>A<sub>s</sub></em>, thus:
*<pre>
* <em>A<sub>r</sub></em> = <em>A<sub>d</sub></em>*<em>A<sub>s</sub></em>
* <em>C<sub>r</sub></em> = <em>C<sub>d</sub></em>*<em>A<sub>s</sub></em>
*</pre>
*/
@Native public static final int DST_IN = 6;
/**
* The part of the source lying outside of the destination
* replaces the destination
* (Porter-Duff Source Held Out By Destination rule).
*<p>
* <em>F<sub>s</sub></em> = (1-<em>A<sub>d</sub></em>) and <em>F<sub>d</sub></em> = 0, thus:
*<pre>
* <em>A<sub>r</sub></em> = <em>A<sub>s</sub></em>*(1-<em>A<sub>d</sub></em>)
* <em>C<sub>r</sub></em> = <em>C<sub>s</sub></em>*(1-<em>A<sub>d</sub></em>)
*</pre>
*/
@Native public static final int SRC_OUT = 7;
/**
* The part of the destination lying outside of the source
* replaces the destination
* (Porter-Duff Destination Held Out By Source rule).
*<p>
* <em>F<sub>s</sub></em> = 0 and <em>F<sub>d</sub></em> = (1-<em>A<sub>s</sub></em>), thus:
*<pre>
* <em>A<sub>r</sub></em> = <em>A<sub>d</sub></em>*(1-<em>A<sub>s</sub></em>)
* <em>C<sub>r</sub></em> = <em>C<sub>d</sub></em>*(1-<em>A<sub>s</sub></em>)
*</pre>
*/
@Native public static final int DST_OUT = 8;
// Rule 9 is DST which is defined above where it fits into the
// list logically, rather than numerically
//
// public static final int DST = 9;
/**
* The part of the source lying inside of the destination
* is composited onto the destination
* (Porter-Duff Source Atop Destination rule).
*<p>
* <em>F<sub>s</sub></em> = <em>A<sub>d</sub></em> and <em>F<sub>d</sub></em> = (1-<em>A<sub>s</sub></em>), thus:
*<pre>
* <em>A<sub>r</sub></em> = <em>A<sub>s</sub></em>*<em>A<sub>d</sub></em> + <em>A<sub>d</sub></em>*(1-<em>A<sub>s</sub></em>) = <em>A<sub>d</sub></em>
* <em>C<sub>r</sub></em> = <em>C<sub>s</sub></em>*<em>A<sub>d</sub></em> + <em>C<sub>d</sub></em>*(1-<em>A<sub>s</sub></em>)
*</pre>
* @since 1.4
*/
@Native public static final int SRC_ATOP = 10;
/**
* The part of the destination lying inside of the source
* is composited over the source and replaces the destination
* (Porter-Duff Destination Atop Source rule).
*<p>
* <em>F<sub>s</sub></em> = (1-<em>A<sub>d</sub></em>) and <em>F<sub>d</sub></em> = <em>A<sub>s</sub></em>, thus:
*<pre>
* <em>A<sub>r</sub></em> = <em>A<sub>s</sub></em>*(1-<em>A<sub>d</sub></em>) + <em>A<sub>d</sub></em>*<em>A<sub>s</sub></em> = <em>A<sub>s</sub></em>
* <em>C<sub>r</sub></em> = <em>C<sub>s</sub></em>*(1-<em>A<sub>d</sub></em>) + <em>C<sub>d</sub></em>*<em>A<sub>s</sub></em>
*</pre>
* @since 1.4
*/
@Native public static final int DST_ATOP = 11;
/**
* The part of the source that lies outside of the destination
* is combined with the part of the destination that lies outside
* of the source
* (Porter-Duff Source Xor Destination rule).
*<p>
* <em>F<sub>s</sub></em> = (1-<em>A<sub>d</sub></em>) and <em>F<sub>d</sub></em> = (1-<em>A<sub>s</sub></em>), thus:
*<pre>
* <em>A<sub>r</sub></em> = <em>A<sub>s</sub></em>*(1-<em>A<sub>d</sub></em>) + <em>A<sub>d</sub></em>*(1-<em>A<sub>s</sub></em>)
* <em>C<sub>r</sub></em> = <em>C<sub>s</sub></em>*(1-<em>A<sub>d</sub></em>) + <em>C<sub>d</sub></em>*(1-<em>A<sub>s</sub></em>)
*</pre>
* @since 1.4
*/
@Native public static final int XOR = 12;
/**
* <code>AlphaComposite</code> object that implements the opaque CLEAR rule
* with an alpha of 1.0f.
* @see #CLEAR
*/
public static final AlphaComposite Clear = new AlphaComposite(CLEAR);
/**
* <code>AlphaComposite</code> object that implements the opaque SRC rule
* with an alpha of 1.0f.
* @see #SRC
*/
public static final AlphaComposite Src = new AlphaComposite(SRC);
/**
* <code>AlphaComposite</code> object that implements the opaque DST rule
* with an alpha of 1.0f.
* @see #DST
* @since 1.4
*/
public static final AlphaComposite Dst = new AlphaComposite(DST);
/**
* <code>AlphaComposite</code> object that implements the opaque SRC_OVER rule
* with an alpha of 1.0f.
* @see #SRC_OVER
*/
public static final AlphaComposite SrcOver = new AlphaComposite(SRC_OVER);
/**
* <code>AlphaComposite</code> object that implements the opaque DST_OVER rule
* with an alpha of 1.0f.
* @see #DST_OVER
*/
public static final AlphaComposite DstOver = new AlphaComposite(DST_OVER);
/**
* <code>AlphaComposite</code> object that implements the opaque SRC_IN rule
* with an alpha of 1.0f.
* @see #SRC_IN
*/
public static final AlphaComposite SrcIn = new AlphaComposite(SRC_IN);
/**
* <code>AlphaComposite</code> object that implements the opaque DST_IN rule
* with an alpha of 1.0f.
* @see #DST_IN
*/
public static final AlphaComposite DstIn = new AlphaComposite(DST_IN);
/**
* <code>AlphaComposite</code> object that implements the opaque SRC_OUT rule
* with an alpha of 1.0f.
* @see #SRC_OUT
*/
public static final AlphaComposite SrcOut = new AlphaComposite(SRC_OUT);
/**
* <code>AlphaComposite</code> object that implements the opaque DST_OUT rule
* with an alpha of 1.0f.
* @see #DST_OUT
*/
public static final AlphaComposite DstOut = new AlphaComposite(DST_OUT);
/**
* <code>AlphaComposite</code> object that implements the opaque SRC_ATOP rule
* with an alpha of 1.0f.
* @see #SRC_ATOP
* @since 1.4
*/
public static final AlphaComposite SrcAtop = new AlphaComposite(SRC_ATOP);
/**
* <code>AlphaComposite</code> object that implements the opaque DST_ATOP rule
* with an alpha of 1.0f.
* @see #DST_ATOP
* @since 1.4
*/
public static final AlphaComposite DstAtop = new AlphaComposite(DST_ATOP);
/**
* <code>AlphaComposite</code> object that implements the opaque XOR rule
* with an alpha of 1.0f.
* @see #XOR
* @since 1.4
*/
public static final AlphaComposite Xor = new AlphaComposite(XOR);
@Native private static final int MIN_RULE = CLEAR;
@Native private static final int MAX_RULE = XOR;
float extraAlpha;
int rule;
private AlphaComposite(int rule) {
this(rule, 1.0f);
}
private AlphaComposite(int rule, float alpha) {
if (rule < MIN_RULE || rule > MAX_RULE) {
throw new IllegalArgumentException("unknown composite rule");
}
if (alpha >= 0.0f && alpha <= 1.0f) {
this.rule = rule;
this.extraAlpha = alpha;
} else {
throw new IllegalArgumentException("alpha value out of range");
}
}
/**
* Creates an <code>AlphaComposite</code> object with the specified rule.
* @param rule the compositing rule
* @throws IllegalArgumentException if <code>rule</code> is not one of
* the following: {@link #CLEAR}, {@link #SRC}, {@link #DST},
* {@link #SRC_OVER}, {@link #DST_OVER}, {@link #SRC_IN},
* {@link #DST_IN}, {@link #SRC_OUT}, {@link #DST_OUT},
* {@link #SRC_ATOP}, {@link #DST_ATOP}, or {@link #XOR}
*/
public static AlphaComposite getInstance(int rule) {
switch (rule) {
case CLEAR:
return Clear;
case SRC:
return Src;
case DST:
return Dst;
case SRC_OVER:
return SrcOver;
case DST_OVER:
return DstOver;
case SRC_IN:
return SrcIn;
case DST_IN:
return DstIn;
case SRC_OUT:
return SrcOut;
case DST_OUT:
return DstOut;
case SRC_ATOP:
return SrcAtop;
case DST_ATOP:
return DstAtop;
case XOR:
return Xor;
default:
throw new IllegalArgumentException("unknown composite rule");
}
}
/**
* Creates an <code>AlphaComposite</code> object with the specified rule and
* the constant alpha to multiply with the alpha of the source.
* The source is multiplied with the specified alpha before being composited
* with the destination.
* @param rule the compositing rule
* @param alpha the constant alpha to be multiplied with the alpha of
* the source. <code>alpha</code> must be a floating point number in the
* inclusive range [0.0,&nbsp;1.0].
* @throws IllegalArgumentException if
* <code>alpha</code> is less than 0.0 or greater than 1.0, or if
* <code>rule</code> is not one of
* the following: {@link #CLEAR}, {@link #SRC}, {@link #DST},
* {@link #SRC_OVER}, {@link #DST_OVER}, {@link #SRC_IN},
* {@link #DST_IN}, {@link #SRC_OUT}, {@link #DST_OUT},
* {@link #SRC_ATOP}, {@link #DST_ATOP}, or {@link #XOR}
*/
public static AlphaComposite getInstance(int rule, float alpha) {
if (alpha == 1.0f) {
return getInstance(rule);
}
return new AlphaComposite(rule, alpha);
}
/**
* Creates a context for the compositing operation.
* The context contains state that is used in performing
* the compositing operation.
* @param srcColorModel the {@link ColorModel} of the source
* @param dstColorModel the <code>ColorModel</code> of the destination
* @return the <code>CompositeContext</code> object to be used to perform
* compositing operations.
*/
public CompositeContext createContext(ColorModel srcColorModel,
ColorModel dstColorModel,
RenderingHints hints) {
return new SunCompositeContext(this, srcColorModel, dstColorModel);
}
/**
* Returns the alpha value of this <code>AlphaComposite</code>. If this
* <code>AlphaComposite</code> does not have an alpha value, 1.0 is returned.
* @return the alpha value of this <code>AlphaComposite</code>.
*/
public float getAlpha() {
return extraAlpha;
}
/**
* Returns the compositing rule of this <code>AlphaComposite</code>.
* @return the compositing rule of this <code>AlphaComposite</code>.
*/
public int getRule() {
return rule;
}
/**
* Returns a similar <code>AlphaComposite</code> object that uses
* the specified compositing rule.
* If this object already uses the specified compositing rule,
* this object is returned.
* @return an <code>AlphaComposite</code> object derived from
* this object that uses the specified compositing rule.
* @param rule the compositing rule
* @throws IllegalArgumentException if
* <code>rule</code> is not one of
* the following: {@link #CLEAR}, {@link #SRC}, {@link #DST},
* {@link #SRC_OVER}, {@link #DST_OVER}, {@link #SRC_IN},
* {@link #DST_IN}, {@link #SRC_OUT}, {@link #DST_OUT},
* {@link #SRC_ATOP}, {@link #DST_ATOP}, or {@link #XOR}
* @since 1.6
*/
public AlphaComposite derive(int rule) {
return (this.rule == rule)
? this
: getInstance(rule, this.extraAlpha);
}
/**
* Returns a similar <code>AlphaComposite</code> object that uses
* the specified alpha value.
* If this object already has the specified alpha value,
* this object is returned.
* @return an <code>AlphaComposite</code> object derived from
* this object that uses the specified alpha value.
* @param alpha the constant alpha to be multiplied with the alpha of
* the source. <code>alpha</code> must be a floating point number in the
* inclusive range [0.0,&nbsp;1.0].
* @throws IllegalArgumentException if
* <code>alpha</code> is less than 0.0 or greater than 1.0
* @since 1.6
*/
public AlphaComposite derive(float alpha) {
return (this.extraAlpha == alpha)
? this
: getInstance(this.rule, alpha);
}
/**
* Returns the hashcode for this composite.
* @return a hash code for this composite.
*/
public int hashCode() {
return (Float.floatToIntBits(extraAlpha) * 31 + rule);
}
/**
* Determines whether the specified object is equal to this
* <code>AlphaComposite</code>.
* <p>
* The result is <code>true</code> if and only if
* the argument is not <code>null</code> and is an
* <code>AlphaComposite</code> object that has the same
* compositing rule and alpha value as this object.
*
* @param obj the <code>Object</code> to test for equality
* @return <code>true</code> if <code>obj</code> equals this
* <code>AlphaComposite</code>; <code>false</code> otherwise.
*/
public boolean equals(Object obj) {
if (!(obj instanceof AlphaComposite)) {
return false;
}
AlphaComposite ac = (AlphaComposite) obj;
if (rule != ac.rule) {
return false;
}
if (extraAlpha != ac.extraAlpha) {
return false;
}
return true;
}
}

View File

@@ -0,0 +1,56 @@
/*
* Copyright (c) 1999, 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 java.awt;
import sun.util.logging.PlatformLogger;
abstract class AttributeValue {
private static final PlatformLogger log = PlatformLogger.getLogger("java.awt.AttributeValue");
private final int value;
private final String[] names;
protected AttributeValue(int value, String[] names) {
if (log.isLoggable(PlatformLogger.Level.FINEST)) {
log.finest("value = " + value + ", names = " + names);
}
if (log.isLoggable(PlatformLogger.Level.FINER)) {
if ((value < 0) || (names == null) || (value >= names.length)) {
log.finer("Assertion failed");
}
}
this.value = value;
this.names = names;
}
// This hashCode is used by the sun.awt implementation as an array
// index.
public int hashCode() {
return value;
}
public String toString() {
return names[value];
}
}

View File

@@ -0,0 +1,447 @@
/*
* 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 java.awt;
import java.beans.ConstructorProperties;
import java.lang.annotation.Native;
/**
* The <code>BasicStroke</code> class defines a basic set of rendering
* attributes for the outlines of graphics primitives, which are rendered
* with a {@link Graphics2D} object that has its Stroke attribute set to
* this <code>BasicStroke</code>.
* The rendering attributes defined by <code>BasicStroke</code> describe
* the shape of the mark made by a pen drawn along the outline of a
* {@link Shape} and the decorations applied at the ends and joins of
* path segments of the <code>Shape</code>.
* These rendering attributes include:
* <dl>
* <dt><i>width</i>
* <dd>The pen width, measured perpendicularly to the pen trajectory.
* <dt><i>end caps</i>
* <dd>The decoration applied to the ends of unclosed subpaths and
* dash segments. Subpaths that start and end on the same point are
* still considered unclosed if they do not have a CLOSE segment.
* See {@link java.awt.geom.PathIterator#SEG_CLOSE SEG_CLOSE}
* for more information on the CLOSE segment.
* The three different decorations are: {@link #CAP_BUTT},
* {@link #CAP_ROUND}, and {@link #CAP_SQUARE}.
* <dt><i>line joins</i>
* <dd>The decoration applied at the intersection of two path segments
* and at the intersection of the endpoints of a subpath that is closed
* using {@link java.awt.geom.PathIterator#SEG_CLOSE SEG_CLOSE}.
* The three different decorations are: {@link #JOIN_BEVEL},
* {@link #JOIN_MITER}, and {@link #JOIN_ROUND}.
* <dt><i>miter limit</i>
* <dd>The limit to trim a line join that has a JOIN_MITER decoration.
* A line join is trimmed when the ratio of miter length to stroke
* width is greater than the miterlimit value. The miter length is
* the diagonal length of the miter, which is the distance between
* the inside corner and the outside corner of the intersection.
* The smaller the angle formed by two line segments, the longer
* the miter length and the sharper the angle of intersection. The
* default miterlimit value of 10.0f causes all angles less than
* 11 degrees to be trimmed. Trimming miters converts
* the decoration of the line join to bevel.
* <dt><i>dash attributes</i>
* <dd>The definition of how to make a dash pattern by alternating
* between opaque and transparent sections.
* </dl>
* All attributes that specify measurements and distances controlling
* the shape of the returned outline are measured in the same
* coordinate system as the original unstroked <code>Shape</code>
* argument. When a <code>Graphics2D</code> object uses a
* <code>Stroke</code> object to redefine a path during the execution
* of one of its <code>draw</code> methods, the geometry is supplied
* in its original form before the <code>Graphics2D</code> transform
* attribute is applied. Therefore, attributes such as the pen width
* are interpreted in the user space coordinate system of the
* <code>Graphics2D</code> object and are subject to the scaling and
* shearing effects of the user-space-to-device-space transform in that
* particular <code>Graphics2D</code>.
* For example, the width of a rendered shape's outline is determined
* not only by the width attribute of this <code>BasicStroke</code>,
* but also by the transform attribute of the
* <code>Graphics2D</code> object. Consider this code:
* <blockquote><tt>
* // sets the Graphics2D object's Transform attribute
* g2d.scale(10, 10);
* // sets the Graphics2D object's Stroke attribute
* g2d.setStroke(new BasicStroke(1.5f));
* </tt></blockquote>
* Assuming there are no other scaling transforms added to the
* <code>Graphics2D</code> object, the resulting line
* will be approximately 15 pixels wide.
* As the example code demonstrates, a floating-point line
* offers better precision, especially when large transforms are
* used with a <code>Graphics2D</code> object.
* When a line is diagonal, the exact width depends on how the
* rendering pipeline chooses which pixels to fill as it traces the
* theoretical widened outline. The choice of which pixels to turn
* on is affected by the antialiasing attribute because the
* antialiasing rendering pipeline can choose to color
* partially-covered pixels.
* <p>
* For more information on the user space coordinate system and the
* rendering process, see the <code>Graphics2D</code> class comments.
* @see Graphics2D
* @author Jim Graham
*/
public class BasicStroke implements Stroke {
/**
* Joins path segments by extending their outside edges until
* they meet.
*/
@Native public final static int JOIN_MITER = 0;
/**
* Joins path segments by rounding off the corner at a radius
* of half the line width.
*/
@Native public final static int JOIN_ROUND = 1;
/**
* Joins path segments by connecting the outer corners of their
* wide outlines with a straight segment.
*/
@Native public final static int JOIN_BEVEL = 2;
/**
* Ends unclosed subpaths and dash segments with no added
* decoration.
*/
@Native public final static int CAP_BUTT = 0;
/**
* Ends unclosed subpaths and dash segments with a round
* decoration that has a radius equal to half of the width
* of the pen.
*/
@Native public final static int CAP_ROUND = 1;
/**
* Ends unclosed subpaths and dash segments with a square
* projection that extends beyond the end of the segment
* to a distance equal to half of the line width.
*/
@Native public final static int CAP_SQUARE = 2;
float width;
int join;
int cap;
float miterlimit;
float dash[];
float dash_phase;
/**
* Constructs a new <code>BasicStroke</code> with the specified
* attributes.
* @param width the width of this <code>BasicStroke</code>. The
* width must be greater than or equal to 0.0f. If width is
* set to 0.0f, the stroke is rendered as the thinnest
* possible line for the target device and the antialias
* hint setting.
* @param cap the decoration of the ends of a <code>BasicStroke</code>
* @param join the decoration applied where path segments meet
* @param miterlimit the limit to trim the miter join. The miterlimit
* must be greater than or equal to 1.0f.
* @param dash the array representing the dashing pattern
* @param dash_phase the offset to start the dashing pattern
* @throws IllegalArgumentException if <code>width</code> is negative
* @throws IllegalArgumentException if <code>cap</code> is not either
* CAP_BUTT, CAP_ROUND or CAP_SQUARE
* @throws IllegalArgumentException if <code>miterlimit</code> is less
* than 1 and <code>join</code> is JOIN_MITER
* @throws IllegalArgumentException if <code>join</code> is not
* either JOIN_ROUND, JOIN_BEVEL, or JOIN_MITER
* @throws IllegalArgumentException if <code>dash_phase</code>
* is negative and <code>dash</code> is not <code>null</code>
* @throws IllegalArgumentException if the length of
* <code>dash</code> is zero
* @throws IllegalArgumentException if dash lengths are all zero.
*/
@ConstructorProperties({ "lineWidth", "endCap", "lineJoin", "miterLimit", "dashArray", "dashPhase" })
public BasicStroke(float width, int cap, int join, float miterlimit,
float dash[], float dash_phase) {
if (width < 0.0f) {
throw new IllegalArgumentException("negative width");
}
if (cap != CAP_BUTT && cap != CAP_ROUND && cap != CAP_SQUARE) {
throw new IllegalArgumentException("illegal end cap value");
}
if (join == JOIN_MITER) {
if (miterlimit < 1.0f) {
throw new IllegalArgumentException("miter limit < 1");
}
} else if (join != JOIN_ROUND && join != JOIN_BEVEL) {
throw new IllegalArgumentException("illegal line join value");
}
if (dash != null) {
if (dash_phase < 0.0f) {
throw new IllegalArgumentException("negative dash phase");
}
boolean allzero = true;
for (int i = 0; i < dash.length; i++) {
float d = dash[i];
if (d > 0.0) {
allzero = false;
} else if (d < 0.0) {
throw new IllegalArgumentException("negative dash length");
}
}
if (allzero) {
throw new IllegalArgumentException("dash lengths all zero");
}
}
this.width = width;
this.cap = cap;
this.join = join;
this.miterlimit = miterlimit;
if (dash != null) {
this.dash = (float []) dash.clone();
}
this.dash_phase = dash_phase;
}
/**
* Constructs a solid <code>BasicStroke</code> with the specified
* attributes.
* @param width the width of the <code>BasicStroke</code>
* @param cap the decoration of the ends of a <code>BasicStroke</code>
* @param join the decoration applied where path segments meet
* @param miterlimit the limit to trim the miter join
* @throws IllegalArgumentException if <code>width</code> is negative
* @throws IllegalArgumentException if <code>cap</code> is not either
* CAP_BUTT, CAP_ROUND or CAP_SQUARE
* @throws IllegalArgumentException if <code>miterlimit</code> is less
* than 1 and <code>join</code> is JOIN_MITER
* @throws IllegalArgumentException if <code>join</code> is not
* either JOIN_ROUND, JOIN_BEVEL, or JOIN_MITER
*/
public BasicStroke(float width, int cap, int join, float miterlimit) {
this(width, cap, join, miterlimit, null, 0.0f);
}
/**
* Constructs a solid <code>BasicStroke</code> with the specified
* attributes. The <code>miterlimit</code> parameter is
* unnecessary in cases where the default is allowable or the
* line joins are not specified as JOIN_MITER.
* @param width the width of the <code>BasicStroke</code>
* @param cap the decoration of the ends of a <code>BasicStroke</code>
* @param join the decoration applied where path segments meet
* @throws IllegalArgumentException if <code>width</code> is negative
* @throws IllegalArgumentException if <code>cap</code> is not either
* CAP_BUTT, CAP_ROUND or CAP_SQUARE
* @throws IllegalArgumentException if <code>join</code> is not
* either JOIN_ROUND, JOIN_BEVEL, or JOIN_MITER
*/
public BasicStroke(float width, int cap, int join) {
this(width, cap, join, 10.0f, null, 0.0f);
}
/**
* Constructs a solid <code>BasicStroke</code> with the specified
* line width and with default values for the cap and join
* styles.
* @param width the width of the <code>BasicStroke</code>
* @throws IllegalArgumentException if <code>width</code> is negative
*/
public BasicStroke(float width) {
this(width, CAP_SQUARE, JOIN_MITER, 10.0f, null, 0.0f);
}
/**
* Constructs a new <code>BasicStroke</code> with defaults for all
* attributes.
* The default attributes are a solid line of width 1.0, CAP_SQUARE,
* JOIN_MITER, a miter limit of 10.0.
*/
public BasicStroke() {
this(1.0f, CAP_SQUARE, JOIN_MITER, 10.0f, null, 0.0f);
}
/**
* Returns a <code>Shape</code> whose interior defines the
* stroked outline of a specified <code>Shape</code>.
* @param s the <code>Shape</code> boundary be stroked
* @return the <code>Shape</code> of the stroked outline.
*/
public Shape createStrokedShape(Shape s) {
sun.java2d.pipe.RenderingEngine re =
sun.java2d.pipe.RenderingEngine.getInstance();
return re.createStrokedShape(s, width, cap, join, miterlimit,
dash, dash_phase);
}
/**
* Returns the line width. Line width is represented in user space,
* which is the default-coordinate space used by Java 2D. See the
* <code>Graphics2D</code> class comments for more information on
* the user space coordinate system.
* @return the line width of this <code>BasicStroke</code>.
* @see Graphics2D
*/
public float getLineWidth() {
return width;
}
/**
* Returns the end cap style.
* @return the end cap style of this <code>BasicStroke</code> as one
* of the static <code>int</code> values that define possible end cap
* styles.
*/
public int getEndCap() {
return cap;
}
/**
* Returns the line join style.
* @return the line join style of the <code>BasicStroke</code> as one
* of the static <code>int</code> values that define possible line
* join styles.
*/
public int getLineJoin() {
return join;
}
/**
* Returns the limit of miter joins.
* @return the limit of miter joins of the <code>BasicStroke</code>.
*/
public float getMiterLimit() {
return miterlimit;
}
/**
* Returns the array representing the lengths of the dash segments.
* Alternate entries in the array represent the user space lengths
* of the opaque and transparent segments of the dashes.
* As the pen moves along the outline of the <code>Shape</code>
* to be stroked, the user space
* distance that the pen travels is accumulated. The distance
* value is used to index into the dash array.
* The pen is opaque when its current cumulative distance maps
* to an even element of the dash array and transparent otherwise.
* @return the dash array.
*/
public float[] getDashArray() {
if (dash == null) {
return null;
}
return (float[]) dash.clone();
}
/**
* Returns the current dash phase.
* The dash phase is a distance specified in user coordinates that
* represents an offset into the dashing pattern. In other words, the dash
* phase defines the point in the dashing pattern that will correspond to
* the beginning of the stroke.
* @return the dash phase as a <code>float</code> value.
*/
public float getDashPhase() {
return dash_phase;
}
/**
* Returns the hashcode for this stroke.
* @return a hash code for this stroke.
*/
public int hashCode() {
int hash = Float.floatToIntBits(width);
hash = hash * 31 + join;
hash = hash * 31 + cap;
hash = hash * 31 + Float.floatToIntBits(miterlimit);
if (dash != null) {
hash = hash * 31 + Float.floatToIntBits(dash_phase);
for (int i = 0; i < dash.length; i++) {
hash = hash * 31 + Float.floatToIntBits(dash[i]);
}
}
return hash;
}
/**
* Returns true if this BasicStroke represents the same
* stroking operation as the given argument.
*/
/**
* Tests if a specified object is equal to this <code>BasicStroke</code>
* by first testing if it is a <code>BasicStroke</code> and then comparing
* its width, join, cap, miter limit, dash, and dash phase attributes with
* those of this <code>BasicStroke</code>.
* @param obj the specified object to compare to this
* <code>BasicStroke</code>
* @return <code>true</code> if the width, join, cap, miter limit, dash, and
* dash phase are the same for both objects;
* <code>false</code> otherwise.
*/
public boolean equals(Object obj) {
if (!(obj instanceof BasicStroke)) {
return false;
}
BasicStroke bs = (BasicStroke) obj;
if (width != bs.width) {
return false;
}
if (join != bs.join) {
return false;
}
if (cap != bs.cap) {
return false;
}
if (miterlimit != bs.miterlimit) {
return false;
}
if (dash != null) {
if (dash_phase != bs.dash_phase) {
return false;
}
if (!java.util.Arrays.equals(dash, bs.dash)) {
return false;
}
}
else if (bs.dash != null) {
return false;
}
return true;
}
}

View File

@@ -0,0 +1,887 @@
/*
* Copyright (c) 1995, 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 java.awt;
import java.util.Hashtable;
/**
* A border layout lays out a container, arranging and resizing
* its components to fit in five regions:
* north, south, east, west, and center.
* Each region may contain no more than one component, and
* is identified by a corresponding constant:
* <code>NORTH</code>, <code>SOUTH</code>, <code>EAST</code>,
* <code>WEST</code>, and <code>CENTER</code>. When adding a
* component to a container with a border layout, use one of these
* five constants, for example:
* <pre>
* Panel p = new Panel();
* p.setLayout(new BorderLayout());
* p.add(new Button("Okay"), BorderLayout.SOUTH);
* </pre>
* As a convenience, <code>BorderLayout</code> interprets the
* absence of a string specification the same as the constant
* <code>CENTER</code>:
* <pre>
* Panel p2 = new Panel();
* p2.setLayout(new BorderLayout());
* p2.add(new TextArea()); // Same as p.add(new TextArea(), BorderLayout.CENTER);
* </pre>
* <p>
* In addition, <code>BorderLayout</code> supports the relative
* positioning constants, <code>PAGE_START</code>, <code>PAGE_END</code>,
* <code>LINE_START</code>, and <code>LINE_END</code>.
* In a container whose <code>ComponentOrientation</code> is set to
* <code>ComponentOrientation.LEFT_TO_RIGHT</code>, these constants map to
* <code>NORTH</code>, <code>SOUTH</code>, <code>WEST</code>, and
* <code>EAST</code>, respectively.
* <p>
* For compatibility with previous releases, <code>BorderLayout</code>
* also includes the relative positioning constants <code>BEFORE_FIRST_LINE</code>,
* <code>AFTER_LAST_LINE</code>, <code>BEFORE_LINE_BEGINS</code> and
* <code>AFTER_LINE_ENDS</code>. These are equivalent to
* <code>PAGE_START</code>, <code>PAGE_END</code>, <code>LINE_START</code>
* and <code>LINE_END</code> respectively. For
* consistency with the relative positioning constants used by other
* components, the latter constants are preferred.
* <p>
* Mixing both absolute and relative positioning constants can lead to
* unpredictable results. If
* you use both types, the relative constants will take precedence.
* For example, if you add components using both the <code>NORTH</code>
* and <code>PAGE_START</code> constants in a container whose
* orientation is <code>LEFT_TO_RIGHT</code>, only the
* <code>PAGE_START</code> will be layed out.
* <p>
* NOTE: Currently (in the Java 2 platform v1.2),
* <code>BorderLayout</code> does not support vertical
* orientations. The <code>isVertical</code> setting on the container's
* <code>ComponentOrientation</code> is not respected.
* <p>
* The components are laid out according to their
* preferred sizes and the constraints of the container's size.
* The <code>NORTH</code> and <code>SOUTH</code> components may
* be stretched horizontally; the <code>EAST</code> and
* <code>WEST</code> components may be stretched vertically;
* the <code>CENTER</code> component may stretch both horizontally
* and vertically to fill any space left over.
* <p>
* Here is an example of five buttons in an applet laid out using
* the <code>BorderLayout</code> layout manager:
* <p>
* <img src="doc-files/BorderLayout-1.gif"
* alt="Diagram of an applet demonstrating BorderLayout.
* Each section of the BorderLayout contains a Button corresponding to its position in the layout, one of:
* North, West, Center, East, or South."
* style="float:center; margin: 7px 10px;">
* <p>
* The code for this applet is as follows:
*
* <hr><blockquote><pre>
* import java.awt.*;
* import java.applet.Applet;
*
* public class buttonDir extends Applet {
* public void init() {
* setLayout(new BorderLayout());
* add(new Button("North"), BorderLayout.NORTH);
* add(new Button("South"), BorderLayout.SOUTH);
* add(new Button("East"), BorderLayout.EAST);
* add(new Button("West"), BorderLayout.WEST);
* add(new Button("Center"), BorderLayout.CENTER);
* }
* }
* </pre></blockquote><hr>
* <p>
* @author Arthur van Hoff
* @see java.awt.Container#add(String, Component)
* @see java.awt.ComponentOrientation
* @since JDK1.0
*/
public class BorderLayout implements LayoutManager2,
java.io.Serializable {
/**
* Constructs a border layout with the horizontal gaps
* between components.
* The horizontal gap is specified by <code>hgap</code>.
*
* @see #getHgap()
* @see #setHgap(int)
*
* @serial
*/
int hgap;
/**
* Constructs a border layout with the vertical gaps
* between components.
* The vertical gap is specified by <code>vgap</code>.
*
* @see #getVgap()
* @see #setVgap(int)
* @serial
*/
int vgap;
/**
* Constant to specify components location to be the
* north portion of the border layout.
* @serial
* @see #getChild(String, boolean)
* @see #addLayoutComponent
* @see #getLayoutAlignmentX
* @see #getLayoutAlignmentY
* @see #removeLayoutComponent
*/
Component north;
/**
* Constant to specify components location to be the
* west portion of the border layout.
* @serial
* @see #getChild(String, boolean)
* @see #addLayoutComponent
* @see #getLayoutAlignmentX
* @see #getLayoutAlignmentY
* @see #removeLayoutComponent
*/
Component west;
/**
* Constant to specify components location to be the
* east portion of the border layout.
* @serial
* @see #getChild(String, boolean)
* @see #addLayoutComponent
* @see #getLayoutAlignmentX
* @see #getLayoutAlignmentY
* @see #removeLayoutComponent
*/
Component east;
/**
* Constant to specify components location to be the
* south portion of the border layout.
* @serial
* @see #getChild(String, boolean)
* @see #addLayoutComponent
* @see #getLayoutAlignmentX
* @see #getLayoutAlignmentY
* @see #removeLayoutComponent
*/
Component south;
/**
* Constant to specify components location to be the
* center portion of the border layout.
* @serial
* @see #getChild(String, boolean)
* @see #addLayoutComponent
* @see #getLayoutAlignmentX
* @see #getLayoutAlignmentY
* @see #removeLayoutComponent
*/
Component center;
/**
*
* A relative positioning constant, that can be used instead of
* north, south, east, west or center.
* mixing the two types of constants can lead to unpredictable results. If
* you use both types, the relative constants will take precedence.
* For example, if you add components using both the <code>NORTH</code>
* and <code>BEFORE_FIRST_LINE</code> constants in a container whose
* orientation is <code>LEFT_TO_RIGHT</code>, only the
* <code>BEFORE_FIRST_LINE</code> will be layed out.
* This will be the same for lastLine, firstItem, lastItem.
* @serial
*/
Component firstLine;
/**
* A relative positioning constant, that can be used instead of
* north, south, east, west or center.
* Please read Description for firstLine.
* @serial
*/
Component lastLine;
/**
* A relative positioning constant, that can be used instead of
* north, south, east, west or center.
* Please read Description for firstLine.
* @serial
*/
Component firstItem;
/**
* A relative positioning constant, that can be used instead of
* north, south, east, west or center.
* Please read Description for firstLine.
* @serial
*/
Component lastItem;
/**
* The north layout constraint (top of container).
*/
public static final String NORTH = "North";
/**
* The south layout constraint (bottom of container).
*/
public static final String SOUTH = "South";
/**
* The east layout constraint (right side of container).
*/
public static final String EAST = "East";
/**
* The west layout constraint (left side of container).
*/
public static final String WEST = "West";
/**
* The center layout constraint (middle of container).
*/
public static final String CENTER = "Center";
/**
* Synonym for PAGE_START. Exists for compatibility with previous
* versions. PAGE_START is preferred.
*
* @see #PAGE_START
* @since 1.2
*/
public static final String BEFORE_FIRST_LINE = "First";
/**
* Synonym for PAGE_END. Exists for compatibility with previous
* versions. PAGE_END is preferred.
*
* @see #PAGE_END
* @since 1.2
*/
public static final String AFTER_LAST_LINE = "Last";
/**
* Synonym for LINE_START. Exists for compatibility with previous
* versions. LINE_START is preferred.
*
* @see #LINE_START
* @since 1.2
*/
public static final String BEFORE_LINE_BEGINS = "Before";
/**
* Synonym for LINE_END. Exists for compatibility with previous
* versions. LINE_END is preferred.
*
* @see #LINE_END
* @since 1.2
*/
public static final String AFTER_LINE_ENDS = "After";
/**
* The component comes before the first line of the layout's content.
* For Western, left-to-right and top-to-bottom orientations, this is
* equivalent to NORTH.
*
* @see java.awt.Component#getComponentOrientation
* @since 1.4
*/
public static final String PAGE_START = BEFORE_FIRST_LINE;
/**
* The component comes after the last line of the layout's content.
* For Western, left-to-right and top-to-bottom orientations, this is
* equivalent to SOUTH.
*
* @see java.awt.Component#getComponentOrientation
* @since 1.4
*/
public static final String PAGE_END = AFTER_LAST_LINE;
/**
* The component goes at the beginning of the line direction for the
* layout. For Western, left-to-right and top-to-bottom orientations,
* this is equivalent to WEST.
*
* @see java.awt.Component#getComponentOrientation
* @since 1.4
*/
public static final String LINE_START = BEFORE_LINE_BEGINS;
/**
* The component goes at the end of the line direction for the
* layout. For Western, left-to-right and top-to-bottom orientations,
* this is equivalent to EAST.
*
* @see java.awt.Component#getComponentOrientation
* @since 1.4
*/
public static final String LINE_END = AFTER_LINE_ENDS;
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = -8658291919501921765L;
/**
* Constructs a new border layout with
* no gaps between components.
*/
public BorderLayout() {
this(0, 0);
}
/**
* Constructs a border layout with the specified gaps
* between components.
* The horizontal gap is specified by <code>hgap</code>
* and the vertical gap is specified by <code>vgap</code>.
* @param hgap the horizontal gap.
* @param vgap the vertical gap.
*/
public BorderLayout(int hgap, int vgap) {
this.hgap = hgap;
this.vgap = vgap;
}
/**
* Returns the horizontal gap between components.
* @since JDK1.1
*/
public int getHgap() {
return hgap;
}
/**
* Sets the horizontal gap between components.
* @param hgap the horizontal gap between components
* @since JDK1.1
*/
public void setHgap(int hgap) {
this.hgap = hgap;
}
/**
* Returns the vertical gap between components.
* @since JDK1.1
*/
public int getVgap() {
return vgap;
}
/**
* Sets the vertical gap between components.
* @param vgap the vertical gap between components
* @since JDK1.1
*/
public void setVgap(int vgap) {
this.vgap = vgap;
}
/**
* Adds the specified component to the layout, using the specified
* constraint object. For border layouts, the constraint must be
* one of the following constants: <code>NORTH</code>,
* <code>SOUTH</code>, <code>EAST</code>,
* <code>WEST</code>, or <code>CENTER</code>.
* <p>
* Most applications do not call this method directly. This method
* is called when a component is added to a container using the
* <code>Container.add</code> method with the same argument types.
* @param comp the component to be added.
* @param constraints an object that specifies how and where
* the component is added to the layout.
* @see java.awt.Container#add(java.awt.Component, java.lang.Object)
* @exception IllegalArgumentException if the constraint object is not
* a string, or if it not one of the five specified
* constants.
* @since JDK1.1
*/
public void addLayoutComponent(Component comp, Object constraints) {
synchronized (comp.getTreeLock()) {
if ((constraints == null) || (constraints instanceof String)) {
addLayoutComponent((String)constraints, comp);
} else {
throw new IllegalArgumentException("cannot add to layout: constraint must be a string (or null)");
}
}
}
/**
* @deprecated replaced by <code>addLayoutComponent(Component, Object)</code>.
*/
@Deprecated
public void addLayoutComponent(String name, Component comp) {
synchronized (comp.getTreeLock()) {
/* Special case: treat null the same as "Center". */
if (name == null) {
name = "Center";
}
/* Assign the component to one of the known regions of the layout.
*/
if ("Center".equals(name)) {
center = comp;
} else if ("North".equals(name)) {
north = comp;
} else if ("South".equals(name)) {
south = comp;
} else if ("East".equals(name)) {
east = comp;
} else if ("West".equals(name)) {
west = comp;
} else if (BEFORE_FIRST_LINE.equals(name)) {
firstLine = comp;
} else if (AFTER_LAST_LINE.equals(name)) {
lastLine = comp;
} else if (BEFORE_LINE_BEGINS.equals(name)) {
firstItem = comp;
} else if (AFTER_LINE_ENDS.equals(name)) {
lastItem = comp;
} else {
throw new IllegalArgumentException("cannot add to layout: unknown constraint: " + name);
}
}
}
/**
* Removes the specified component from this border layout. This
* method is called when a container calls its <code>remove</code> or
* <code>removeAll</code> methods. Most applications do not call this
* method directly.
* @param comp the component to be removed.
* @see java.awt.Container#remove(java.awt.Component)
* @see java.awt.Container#removeAll()
*/
public void removeLayoutComponent(Component comp) {
synchronized (comp.getTreeLock()) {
if (comp == center) {
center = null;
} else if (comp == north) {
north = null;
} else if (comp == south) {
south = null;
} else if (comp == east) {
east = null;
} else if (comp == west) {
west = null;
}
if (comp == firstLine) {
firstLine = null;
} else if (comp == lastLine) {
lastLine = null;
} else if (comp == firstItem) {
firstItem = null;
} else if (comp == lastItem) {
lastItem = null;
}
}
}
/**
* Gets the component that was added using the given constraint
*
* @param constraints the desired constraint, one of <code>CENTER</code>,
* <code>NORTH</code>, <code>SOUTH</code>,
* <code>WEST</code>, <code>EAST</code>,
* <code>PAGE_START</code>, <code>PAGE_END</code>,
* <code>LINE_START</code>, <code>LINE_END</code>
* @return the component at the given location, or <code>null</code> if
* the location is empty
* @exception IllegalArgumentException if the constraint object is
* not one of the nine specified constants
* @see #addLayoutComponent(java.awt.Component, java.lang.Object)
* @since 1.5
*/
public Component getLayoutComponent(Object constraints) {
if (CENTER.equals(constraints)) {
return center;
} else if (NORTH.equals(constraints)) {
return north;
} else if (SOUTH.equals(constraints)) {
return south;
} else if (WEST.equals(constraints)) {
return west;
} else if (EAST.equals(constraints)) {
return east;
} else if (PAGE_START.equals(constraints)) {
return firstLine;
} else if (PAGE_END.equals(constraints)) {
return lastLine;
} else if (LINE_START.equals(constraints)) {
return firstItem;
} else if (LINE_END.equals(constraints)) {
return lastItem;
} else {
throw new IllegalArgumentException("cannot get component: unknown constraint: " + constraints);
}
}
/**
* Returns the component that corresponds to the given constraint location
* based on the target <code>Container</code>'s component orientation.
* Components added with the relative constraints <code>PAGE_START</code>,
* <code>PAGE_END</code>, <code>LINE_START</code>, and <code>LINE_END</code>
* take precedence over components added with the explicit constraints
* <code>NORTH</code>, <code>SOUTH</code>, <code>WEST</code>, and <code>EAST</code>.
* The <code>Container</code>'s component orientation is used to determine the location of components
* added with <code>LINE_START</code> and <code>LINE_END</code>.
*
* @param constraints the desired absolute position, one of <code>CENTER</code>,
* <code>NORTH</code>, <code>SOUTH</code>,
* <code>EAST</code>, <code>WEST</code>
* @param target the {@code Container} used to obtain
* the constraint location based on the target
* {@code Container}'s component orientation.
* @return the component at the given location, or <code>null</code> if
* the location is empty
* @exception IllegalArgumentException if the constraint object is
* not one of the five specified constants
* @exception NullPointerException if the target parameter is null
* @see #addLayoutComponent(java.awt.Component, java.lang.Object)
* @since 1.5
*/
public Component getLayoutComponent(Container target, Object constraints) {
boolean ltr = target.getComponentOrientation().isLeftToRight();
Component result = null;
if (NORTH.equals(constraints)) {
result = (firstLine != null) ? firstLine : north;
} else if (SOUTH.equals(constraints)) {
result = (lastLine != null) ? lastLine : south;
} else if (WEST.equals(constraints)) {
result = ltr ? firstItem : lastItem;
if (result == null) {
result = west;
}
} else if (EAST.equals(constraints)) {
result = ltr ? lastItem : firstItem;
if (result == null) {
result = east;
}
} else if (CENTER.equals(constraints)) {
result = center;
} else {
throw new IllegalArgumentException("cannot get component: invalid constraint: " + constraints);
}
return result;
}
/**
* Gets the constraints for the specified component
*
* @param comp the component to be queried
* @return the constraint for the specified component,
* or null if component is null or is not present
* in this layout
* @see #addLayoutComponent(java.awt.Component, java.lang.Object)
* @since 1.5
*/
public Object getConstraints(Component comp) {
//fix for 6242148 : API method java.awt.BorderLayout.getConstraints(null) should return null
if (comp == null){
return null;
}
if (comp == center) {
return CENTER;
} else if (comp == north) {
return NORTH;
} else if (comp == south) {
return SOUTH;
} else if (comp == west) {
return WEST;
} else if (comp == east) {
return EAST;
} else if (comp == firstLine) {
return PAGE_START;
} else if (comp == lastLine) {
return PAGE_END;
} else if (comp == firstItem) {
return LINE_START;
} else if (comp == lastItem) {
return LINE_END;
}
return null;
}
/**
* Determines the minimum size of the <code>target</code> container
* using this layout manager.
* <p>
* This method is called when a container calls its
* <code>getMinimumSize</code> method. Most applications do not call
* this method directly.
* @param target the container in which to do the layout.
* @return the minimum dimensions needed to lay out the subcomponents
* of the specified container.
* @see java.awt.Container
* @see java.awt.BorderLayout#preferredLayoutSize
* @see java.awt.Container#getMinimumSize()
*/
public Dimension minimumLayoutSize(Container target) {
synchronized (target.getTreeLock()) {
Dimension dim = new Dimension(0, 0);
boolean ltr = target.getComponentOrientation().isLeftToRight();
Component c = null;
if ((c=getChild(EAST,ltr)) != null) {
Dimension d = c.getMinimumSize();
dim.width += d.width + hgap;
dim.height = Math.max(d.height, dim.height);
}
if ((c=getChild(WEST,ltr)) != null) {
Dimension d = c.getMinimumSize();
dim.width += d.width + hgap;
dim.height = Math.max(d.height, dim.height);
}
if ((c=getChild(CENTER,ltr)) != null) {
Dimension d = c.getMinimumSize();
dim.width += d.width;
dim.height = Math.max(d.height, dim.height);
}
if ((c=getChild(NORTH,ltr)) != null) {
Dimension d = c.getMinimumSize();
dim.width = Math.max(d.width, dim.width);
dim.height += d.height + vgap;
}
if ((c=getChild(SOUTH,ltr)) != null) {
Dimension d = c.getMinimumSize();
dim.width = Math.max(d.width, dim.width);
dim.height += d.height + vgap;
}
Insets insets = target.getInsets();
dim.width += insets.left + insets.right;
dim.height += insets.top + insets.bottom;
return dim;
}
}
/**
* Determines the preferred size of the <code>target</code>
* container using this layout manager, based on the components
* in the container.
* <p>
* Most applications do not call this method directly. This method
* is called when a container calls its <code>getPreferredSize</code>
* method.
* @param target the container in which to do the layout.
* @return the preferred dimensions to lay out the subcomponents
* of the specified container.
* @see java.awt.Container
* @see java.awt.BorderLayout#minimumLayoutSize
* @see java.awt.Container#getPreferredSize()
*/
public Dimension preferredLayoutSize(Container target) {
synchronized (target.getTreeLock()) {
Dimension dim = new Dimension(0, 0);
boolean ltr = target.getComponentOrientation().isLeftToRight();
Component c = null;
if ((c=getChild(EAST,ltr)) != null) {
Dimension d = c.getPreferredSize();
dim.width += d.width + hgap;
dim.height = Math.max(d.height, dim.height);
}
if ((c=getChild(WEST,ltr)) != null) {
Dimension d = c.getPreferredSize();
dim.width += d.width + hgap;
dim.height = Math.max(d.height, dim.height);
}
if ((c=getChild(CENTER,ltr)) != null) {
Dimension d = c.getPreferredSize();
dim.width += d.width;
dim.height = Math.max(d.height, dim.height);
}
if ((c=getChild(NORTH,ltr)) != null) {
Dimension d = c.getPreferredSize();
dim.width = Math.max(d.width, dim.width);
dim.height += d.height + vgap;
}
if ((c=getChild(SOUTH,ltr)) != null) {
Dimension d = c.getPreferredSize();
dim.width = Math.max(d.width, dim.width);
dim.height += d.height + vgap;
}
Insets insets = target.getInsets();
dim.width += insets.left + insets.right;
dim.height += insets.top + insets.bottom;
return dim;
}
}
/**
* Returns the maximum dimensions for this layout given the components
* in the specified target container.
* @param target the component which needs to be laid out
* @see Container
* @see #minimumLayoutSize
* @see #preferredLayoutSize
*/
public Dimension maximumLayoutSize(Container target) {
return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
}
/**
* Returns the alignment along the x axis. This specifies how
* the component would like to be aligned relative to other
* components. The value should be a number between 0 and 1
* where 0 represents alignment along the origin, 1 is aligned
* the furthest away from the origin, 0.5 is centered, etc.
*/
public float getLayoutAlignmentX(Container parent) {
return 0.5f;
}
/**
* Returns the alignment along the y axis. This specifies how
* the component would like to be aligned relative to other
* components. The value should be a number between 0 and 1
* where 0 represents alignment along the origin, 1 is aligned
* the furthest away from the origin, 0.5 is centered, etc.
*/
public float getLayoutAlignmentY(Container parent) {
return 0.5f;
}
/**
* Invalidates the layout, indicating that if the layout manager
* has cached information it should be discarded.
*/
public void invalidateLayout(Container target) {
}
/**
* Lays out the container argument using this border layout.
* <p>
* This method actually reshapes the components in the specified
* container in order to satisfy the constraints of this
* <code>BorderLayout</code> object. The <code>NORTH</code>
* and <code>SOUTH</code> components, if any, are placed at
* the top and bottom of the container, respectively. The
* <code>WEST</code> and <code>EAST</code> components are
* then placed on the left and right, respectively. Finally,
* the <code>CENTER</code> object is placed in any remaining
* space in the middle.
* <p>
* Most applications do not call this method directly. This method
* is called when a container calls its <code>doLayout</code> method.
* @param target the container in which to do the layout.
* @see java.awt.Container
* @see java.awt.Container#doLayout()
*/
public void layoutContainer(Container target) {
synchronized (target.getTreeLock()) {
Insets insets = target.getInsets();
int top = insets.top;
int bottom = target.height - insets.bottom;
int left = insets.left;
int right = target.width - insets.right;
boolean ltr = target.getComponentOrientation().isLeftToRight();
Component c = null;
if ((c=getChild(NORTH,ltr)) != null) {
c.setSize(right - left, c.height);
Dimension d = c.getPreferredSize();
c.setBounds(left, top, right - left, d.height);
top += d.height + vgap;
}
if ((c=getChild(SOUTH,ltr)) != null) {
c.setSize(right - left, c.height);
Dimension d = c.getPreferredSize();
c.setBounds(left, bottom - d.height, right - left, d.height);
bottom -= d.height + vgap;
}
if ((c=getChild(EAST,ltr)) != null) {
c.setSize(c.width, bottom - top);
Dimension d = c.getPreferredSize();
c.setBounds(right - d.width, top, d.width, bottom - top);
right -= d.width + hgap;
}
if ((c=getChild(WEST,ltr)) != null) {
c.setSize(c.width, bottom - top);
Dimension d = c.getPreferredSize();
c.setBounds(left, top, d.width, bottom - top);
left += d.width + hgap;
}
if ((c=getChild(CENTER,ltr)) != null) {
c.setBounds(left, top, right - left, bottom - top);
}
}
}
/**
* Get the component that corresponds to the given constraint location
*
* @param key The desired absolute position,
* either NORTH, SOUTH, EAST, or WEST.
* @param ltr Is the component line direction left-to-right?
*/
private Component getChild(String key, boolean ltr) {
Component result = null;
if (key == NORTH) {
result = (firstLine != null) ? firstLine : north;
}
else if (key == SOUTH) {
result = (lastLine != null) ? lastLine : south;
}
else if (key == WEST) {
result = ltr ? firstItem : lastItem;
if (result == null) {
result = west;
}
}
else if (key == EAST) {
result = ltr ? lastItem : firstItem;
if (result == null) {
result = east;
}
}
else if (key == CENTER) {
result = center;
}
if (result != null && !result.visible) {
result = null;
}
return result;
}
/**
* Returns a string representation of the state of this border layout.
* @return a string representation of this border layout.
*/
public String toString() {
return getClass().getName() + "[hgap=" + hgap + ",vgap=" + vgap + "]";
}
}

View File

@@ -0,0 +1,217 @@
/*
* Copyright (c) 2000, 2011, 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 java.awt;
/**
* Capabilities and properties of buffers.
*
* @see java.awt.image.BufferStrategy#getCapabilities()
* @see GraphicsConfiguration#getBufferCapabilities
* @author Michael Martak
* @since 1.4
*/
public class BufferCapabilities implements Cloneable {
private ImageCapabilities frontCaps;
private ImageCapabilities backCaps;
private FlipContents flipContents;
/**
* Creates a new object for specifying buffering capabilities
* @param frontCaps the capabilities of the front buffer; cannot be
* <code>null</code>
* @param backCaps the capabilities of the back and intermediate buffers;
* cannot be <code>null</code>
* @param flipContents the contents of the back buffer after page-flipping,
* <code>null</code> if page flipping is not used (implies blitting)
* @exception IllegalArgumentException if frontCaps or backCaps are
* <code>null</code>
*/
public BufferCapabilities(ImageCapabilities frontCaps,
ImageCapabilities backCaps, FlipContents flipContents) {
if (frontCaps == null || backCaps == null) {
throw new IllegalArgumentException(
"Image capabilities specified cannot be null");
}
this.frontCaps = frontCaps;
this.backCaps = backCaps;
this.flipContents = flipContents;
}
/**
* @return the image capabilities of the front (displayed) buffer
*/
public ImageCapabilities getFrontBufferCapabilities() {
return frontCaps;
}
/**
* @return the image capabilities of all back buffers (intermediate buffers
* are considered back buffers)
*/
public ImageCapabilities getBackBufferCapabilities() {
return backCaps;
}
/**
* @return whether or not the buffer strategy uses page flipping; a set of
* buffers that uses page flipping
* can swap the contents internally between the front buffer and one or
* more back buffers by switching the video pointer (or by copying memory
* internally). A non-flipping set of
* buffers uses blitting to copy the contents from one buffer to
* another; when this is the case, <code>getFlipContents</code> returns
* <code>null</code>
*/
public boolean isPageFlipping() {
return (getFlipContents() != null);
}
/**
* @return the resulting contents of the back buffer after page-flipping.
* This value is <code>null</code> when the <code>isPageFlipping</code>
* returns <code>false</code>, implying blitting. It can be one of
* <code>FlipContents.UNDEFINED</code>
* (the assumed default), <code>FlipContents.BACKGROUND</code>,
* <code>FlipContents.PRIOR</code>, or
* <code>FlipContents.COPIED</code>.
* @see #isPageFlipping
* @see FlipContents#UNDEFINED
* @see FlipContents#BACKGROUND
* @see FlipContents#PRIOR
* @see FlipContents#COPIED
*/
public FlipContents getFlipContents() {
return flipContents;
}
/**
* @return whether page flipping is only available in full-screen mode. If this
* is <code>true</code>, full-screen exclusive mode is required for
* page-flipping.
* @see #isPageFlipping
* @see GraphicsDevice#setFullScreenWindow
*/
public boolean isFullScreenRequired() {
return false;
}
/**
* @return whether or not
* page flipping can be performed using more than two buffers (one or more
* intermediate buffers as well as the front and back buffer).
* @see #isPageFlipping
*/
public boolean isMultiBufferAvailable() {
return false;
}
/**
* @return a copy of this BufferCapabilities object.
*/
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
// Since we implement Cloneable, this should never happen
throw new InternalError(e);
}
}
// Inner class FlipContents
/**
* A type-safe enumeration of the possible back buffer contents after
* page-flipping
* @since 1.4
*/
public static final class FlipContents extends AttributeValue {
private static int I_UNDEFINED = 0;
private static int I_BACKGROUND = 1;
private static int I_PRIOR = 2;
private static int I_COPIED = 3;
private static final String NAMES[] =
{ "undefined", "background", "prior", "copied" };
/**
* When flip contents are <code>UNDEFINED</code>, the
* contents of the back buffer are undefined after flipping.
* @see #isPageFlipping
* @see #getFlipContents
* @see #BACKGROUND
* @see #PRIOR
* @see #COPIED
*/
public static final FlipContents UNDEFINED =
new FlipContents(I_UNDEFINED);
/**
* When flip contents are <code>BACKGROUND</code>, the
* contents of the back buffer are cleared with the background color after
* flipping.
* @see #isPageFlipping
* @see #getFlipContents
* @see #UNDEFINED
* @see #PRIOR
* @see #COPIED
*/
public static final FlipContents BACKGROUND =
new FlipContents(I_BACKGROUND);
/**
* When flip contents are <code>PRIOR</code>, the
* contents of the back buffer are the prior contents of the front buffer
* (a true page flip).
* @see #isPageFlipping
* @see #getFlipContents
* @see #UNDEFINED
* @see #BACKGROUND
* @see #COPIED
*/
public static final FlipContents PRIOR =
new FlipContents(I_PRIOR);
/**
* When flip contents are <code>COPIED</code>, the
* contents of the back buffer are copied to the front buffer when
* flipping.
* @see #isPageFlipping
* @see #getFlipContents
* @see #UNDEFINED
* @see #BACKGROUND
* @see #PRIOR
*/
public static final FlipContents COPIED =
new FlipContents(I_COPIED);
private FlipContents(int type) {
super(type, NAMES);
}
} // Inner class FlipContents
}

View File

@@ -0,0 +1,675 @@
/*
* Copyright (c) 1995, 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 java.awt;
import java.awt.peer.ButtonPeer;
import java.util.EventListener;
import java.awt.event.*;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.IOException;
import javax.accessibility.*;
/**
* This class creates a labeled button. The application can cause
* some action to happen when the button is pushed. This image
* depicts three views of a "<code>Quit</code>" button as it appears
* under the Solaris operating system:
* <p>
* <img src="doc-files/Button-1.gif" alt="The following context describes the graphic"
* style="float:center; margin: 7px 10px;">
* <p>
* The first view shows the button as it appears normally.
* The second view shows the button
* when it has input focus. Its outline is darkened to let the
* user know that it is an active object. The third view shows the
* button when the user clicks the mouse over the button, and thus
* requests that an action be performed.
* <p>
* The gesture of clicking on a button with the mouse
* is associated with one instance of <code>ActionEvent</code>,
* which is sent out when the mouse is both pressed and released
* over the button. If an application is interested in knowing
* when the button has been pressed but not released, as a separate
* gesture, it can specialize <code>processMouseEvent</code>,
* or it can register itself as a listener for mouse events by
* calling <code>addMouseListener</code>. Both of these methods are
* defined by <code>Component</code>, the abstract superclass of
* all components.
* <p>
* When a button is pressed and released, AWT sends an instance
* of <code>ActionEvent</code> to the button, by calling
* <code>processEvent</code> on the button. The button's
* <code>processEvent</code> method receives all events
* for the button; it passes an action event along by
* calling its own <code>processActionEvent</code> method.
* The latter method passes the action event on to any action
* listeners that have registered an interest in action
* events generated by this button.
* <p>
* If an application wants to perform some action based on
* a button being pressed and released, it should implement
* <code>ActionListener</code> and register the new listener
* to receive events from this button, by calling the button's
* <code>addActionListener</code> method. The application can
* make use of the button's action command as a messaging protocol.
*
* @author Sami Shaio
* @see java.awt.event.ActionEvent
* @see java.awt.event.ActionListener
* @see java.awt.Component#processMouseEvent
* @see java.awt.Component#addMouseListener
* @since JDK1.0
*/
public class Button extends Component implements Accessible {
/**
* The button's label. This value may be null.
* @serial
* @see #getLabel()
* @see #setLabel(String)
*/
String label;
/**
* The action to be performed once a button has been
* pressed. This value may be null.
* @serial
* @see #getActionCommand()
* @see #setActionCommand(String)
*/
String actionCommand;
transient ActionListener actionListener;
private static final String base = "button";
private static int nameCounter = 0;
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = -8774683716313001058L;
static {
/* ensure that the necessary native libraries are loaded */
Toolkit.loadLibraries();
if (!GraphicsEnvironment.isHeadless()) {
initIDs();
}
}
/**
* Initialize JNI field and method IDs for fields that may be
* accessed from C.
*/
private static native void initIDs();
/**
* Constructs a button with an empty string for its label.
*
* @exception HeadlessException if GraphicsEnvironment.isHeadless()
* returns true
* @see java.awt.GraphicsEnvironment#isHeadless
*/
public Button() throws HeadlessException {
this("");
}
/**
* Constructs a button with the specified label.
*
* @param label a string label for the button, or
* <code>null</code> for no label
* @exception HeadlessException if GraphicsEnvironment.isHeadless()
* returns true
* @see java.awt.GraphicsEnvironment#isHeadless
*/
public Button(String label) throws HeadlessException {
GraphicsEnvironment.checkHeadless();
this.label = label;
}
/**
* Construct a name for this component. Called by getName() when the
* name is null.
*/
String constructComponentName() {
synchronized (Button.class) {
return base + nameCounter++;
}
}
/**
* Creates the peer of the button. The button's peer allows the
* application to change the look of the button without changing
* its functionality.
*
* @see java.awt.Toolkit#createButton(java.awt.Button)
* @see java.awt.Component#getToolkit()
*/
public void addNotify() {
synchronized(getTreeLock()) {
if (peer == null)
peer = getToolkit().createButton(this);
super.addNotify();
}
}
/**
* Gets the label of this button.
*
* @return the button's label, or <code>null</code>
* if the button has no label.
* @see java.awt.Button#setLabel
*/
public String getLabel() {
return label;
}
/**
* Sets the button's label to be the specified string.
*
* @param label the new label, or <code>null</code>
* if the button has no label.
* @see java.awt.Button#getLabel
*/
public void setLabel(String label) {
boolean testvalid = false;
synchronized (this) {
if (label != this.label && (this.label == null ||
!this.label.equals(label))) {
this.label = label;
ButtonPeer peer = (ButtonPeer)this.peer;
if (peer != null) {
peer.setLabel(label);
}
testvalid = true;
}
}
// This could change the preferred size of the Component.
if (testvalid) {
invalidateIfValid();
}
}
/**
* Sets the command name for the action event fired
* by this button. By default this action command is
* set to match the label of the button.
*
* @param command a string used to set the button's
* action command.
* If the string is <code>null</code> then the action command
* is set to match the label of the button.
* @see java.awt.event.ActionEvent
* @since JDK1.1
*/
public void setActionCommand(String command) {
actionCommand = command;
}
/**
* Returns the command name of the action event fired by this button.
* If the command name is <code>null</code> (default) then this method
* returns the label of the button.
*/
public String getActionCommand() {
return (actionCommand == null? label : actionCommand);
}
/**
* Adds the specified action listener to receive action events from
* this button. Action events occur when a user presses or releases
* the mouse over this button.
* If l is null, no exception is thrown and no action is performed.
* <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
* >AWT Threading Issues</a> for details on AWT's threading model.
*
* @param l the action listener
* @see #removeActionListener
* @see #getActionListeners
* @see java.awt.event.ActionListener
* @since JDK1.1
*/
public synchronized void addActionListener(ActionListener l) {
if (l == null) {
return;
}
actionListener = AWTEventMulticaster.add(actionListener, l);
newEventsOnly = true;
}
/**
* Removes the specified action listener so that it no longer
* receives action events from this button. Action events occur
* when a user presses or releases the mouse over this button.
* If l is null, no exception is thrown and no action is performed.
* <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
* >AWT Threading Issues</a> for details on AWT's threading model.
*
* @param l the action listener
* @see #addActionListener
* @see #getActionListeners
* @see java.awt.event.ActionListener
* @since JDK1.1
*/
public synchronized void removeActionListener(ActionListener l) {
if (l == null) {
return;
}
actionListener = AWTEventMulticaster.remove(actionListener, l);
}
/**
* Returns an array of all the action listeners
* registered on this button.
*
* @return all of this button's <code>ActionListener</code>s
* or an empty array if no action
* listeners are currently registered
*
* @see #addActionListener
* @see #removeActionListener
* @see java.awt.event.ActionListener
* @since 1.4
*/
public synchronized ActionListener[] getActionListeners() {
return getListeners(ActionListener.class);
}
/**
* Returns an array of all the objects currently registered
* as <code><em>Foo</em>Listener</code>s
* upon this <code>Button</code>.
* <code><em>Foo</em>Listener</code>s are registered using the
* <code>add<em>Foo</em>Listener</code> method.
*
* <p>
* You can specify the <code>listenerType</code> argument
* with a class literal, such as
* <code><em>Foo</em>Listener.class</code>.
* For example, you can query a
* <code>Button</code> <code>b</code>
* for its action listeners with the following code:
*
* <pre>ActionListener[] als = (ActionListener[])(b.getListeners(ActionListener.class));</pre>
*
* If no such listeners exist, this method returns an empty array.
*
* @param listenerType the type of listeners requested; this parameter
* should specify an interface that descends from
* <code>java.util.EventListener</code>
* @return an array of all objects registered as
* <code><em>Foo</em>Listener</code>s on this button,
* or an empty array if no such
* listeners have been added
* @exception ClassCastException if <code>listenerType</code>
* doesn't specify a class or interface that implements
* <code>java.util.EventListener</code>
*
* @see #getActionListeners
* @since 1.3
*/
public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
EventListener l = null;
if (listenerType == ActionListener.class) {
l = actionListener;
} else {
return super.getListeners(listenerType);
}
return AWTEventMulticaster.getListeners(l, listenerType);
}
// REMIND: remove when filtering is done at lower level
boolean eventEnabled(AWTEvent e) {
if (e.id == ActionEvent.ACTION_PERFORMED) {
if ((eventMask & AWTEvent.ACTION_EVENT_MASK) != 0 ||
actionListener != null) {
return true;
}
return false;
}
return super.eventEnabled(e);
}
/**
* Processes events on this button. If an event is
* an instance of <code>ActionEvent</code>, this method invokes
* the <code>processActionEvent</code> method. Otherwise,
* it invokes <code>processEvent</code> on the superclass.
* <p>Note that if the event parameter is <code>null</code>
* the behavior is unspecified and may result in an
* exception.
*
* @param e the event
* @see java.awt.event.ActionEvent
* @see java.awt.Button#processActionEvent
* @since JDK1.1
*/
protected void processEvent(AWTEvent e) {
if (e instanceof ActionEvent) {
processActionEvent((ActionEvent)e);
return;
}
super.processEvent(e);
}
/**
* Processes action events occurring on this button
* by dispatching them to any registered
* <code>ActionListener</code> objects.
* <p>
* This method is not called unless action events are
* enabled for this button. Action events are enabled
* when one of the following occurs:
* <ul>
* <li>An <code>ActionListener</code> object is registered
* via <code>addActionListener</code>.
* <li>Action events are enabled via <code>enableEvents</code>.
* </ul>
* <p>Note that if the event parameter is <code>null</code>
* the behavior is unspecified and may result in an
* exception.
*
* @param e the action event
* @see java.awt.event.ActionListener
* @see java.awt.Button#addActionListener
* @see java.awt.Component#enableEvents
* @since JDK1.1
*/
protected void processActionEvent(ActionEvent e) {
ActionListener listener = actionListener;
if (listener != null) {
listener.actionPerformed(e);
}
}
/**
* Returns a string representing the state of this <code>Button</code>.
* This method is intended to be used only for debugging purposes, and the
* content and format of the returned string may vary between
* implementations. The returned string may be empty but may not be
* <code>null</code>.
*
* @return the parameter string of this button
*/
protected String paramString() {
return super.paramString() + ",label=" + label;
}
/* Serialization support.
*/
/*
* Button Serial Data Version.
* @serial
*/
private int buttonSerializedDataVersion = 1;
/**
* Writes default serializable fields to stream. Writes
* a list of serializable <code>ActionListeners</code>
* as optional data. The non-serializable
* <code>ActionListeners</code> are detected and
* no attempt is made to serialize them.
*
* @serialData <code>null</code> terminated sequence of 0 or
* more pairs: the pair consists of a <code>String</code>
* and an <code>Object</code>; the <code>String</code>
* indicates the type of object and is one of the following:
* <code>actionListenerK</code> indicating an
* <code>ActionListener</code> object
*
* @param s the <code>ObjectOutputStream</code> to write
* @see AWTEventMulticaster#save(ObjectOutputStream, String, EventListener)
* @see java.awt.Component#actionListenerK
* @see #readObject(ObjectInputStream)
*/
private void writeObject(ObjectOutputStream s)
throws IOException
{
s.defaultWriteObject();
AWTEventMulticaster.save(s, actionListenerK, actionListener);
s.writeObject(null);
}
/**
* Reads the <code>ObjectInputStream</code> and if
* it isn't <code>null</code> adds a listener to
* receive action events fired by the button.
* Unrecognized keys or values will be ignored.
*
* @param s the <code>ObjectInputStream</code> to read
* @exception HeadlessException if
* <code>GraphicsEnvironment.isHeadless</code> returns
* <code>true</code>
* @serial
* @see #removeActionListener(ActionListener)
* @see #addActionListener(ActionListener)
* @see java.awt.GraphicsEnvironment#isHeadless
* @see #writeObject(ObjectOutputStream)
*/
private void readObject(ObjectInputStream s)
throws ClassNotFoundException, IOException, HeadlessException
{
GraphicsEnvironment.checkHeadless();
s.defaultReadObject();
Object keyOrNull;
while(null != (keyOrNull = s.readObject())) {
String key = ((String)keyOrNull).intern();
if (actionListenerK == key)
addActionListener((ActionListener)(s.readObject()));
else // skip value for unrecognized key
s.readObject();
}
}
/////////////////
// Accessibility support
////////////////
/**
* Gets the <code>AccessibleContext</code> associated with
* this <code>Button</code>. For buttons, the
* <code>AccessibleContext</code> takes the form of an
* <code>AccessibleAWTButton</code>.
* A new <code>AccessibleAWTButton</code> instance is
* created if necessary.
*
* @return an <code>AccessibleAWTButton</code> that serves as the
* <code>AccessibleContext</code> of this <code>Button</code>
* @beaninfo
* expert: true
* description: The AccessibleContext associated with this Button.
* @since 1.3
*/
public AccessibleContext getAccessibleContext() {
if (accessibleContext == null) {
accessibleContext = new AccessibleAWTButton();
}
return accessibleContext;
}
/**
* This class implements accessibility support for the
* <code>Button</code> class. It provides an implementation of the
* Java Accessibility API appropriate to button user-interface elements.
* @since 1.3
*/
protected class AccessibleAWTButton extends AccessibleAWTComponent
implements AccessibleAction, AccessibleValue
{
/*
* JDK 1.3 serialVersionUID
*/
private static final long serialVersionUID = -5932203980244017102L;
/**
* Get the accessible name of this object.
*
* @return the localized name of the object -- can be null if this
* object does not have a name
*/
public String getAccessibleName() {
if (accessibleName != null) {
return accessibleName;
} else {
if (getLabel() == null) {
return super.getAccessibleName();
} else {
return getLabel();
}
}
}
/**
* Get the AccessibleAction associated with this object. In the
* implementation of the Java Accessibility API for this class,
* return this object, which is responsible for implementing the
* AccessibleAction interface on behalf of itself.
*
* @return this object
*/
public AccessibleAction getAccessibleAction() {
return this;
}
/**
* Get the AccessibleValue associated with this object. In the
* implementation of the Java Accessibility API for this class,
* return this object, which is responsible for implementing the
* AccessibleValue interface on behalf of itself.
*
* @return this object
*/
public AccessibleValue getAccessibleValue() {
return this;
}
/**
* Returns the number of Actions available in this object. The
* default behavior of a button is to have one action - toggle
* the button.
*
* @return 1, the number of Actions in this object
*/
public int getAccessibleActionCount() {
return 1;
}
/**
* Return a description of the specified action of the object.
*
* @param i zero-based index of the actions
*/
public String getAccessibleActionDescription(int i) {
if (i == 0) {
// [[[PENDING: WDW -- need to provide a localized string]]]
return "click";
} else {
return null;
}
}
/**
* Perform the specified Action on the object
*
* @param i zero-based index of actions
* @return true if the the action was performed; else false.
*/
public boolean doAccessibleAction(int i) {
if (i == 0) {
// Simulate a button click
Toolkit.getEventQueue().postEvent(
new ActionEvent(Button.this,
ActionEvent.ACTION_PERFORMED,
Button.this.getActionCommand()));
return true;
} else {
return false;
}
}
/**
* Get the value of this object as a Number.
*
* @return An Integer of 0 if this isn't selected or an Integer of 1 if
* this is selected.
* @see javax.swing.AbstractButton#isSelected()
*/
public Number getCurrentAccessibleValue() {
return Integer.valueOf(0);
}
/**
* Set the value of this object as a Number.
*
* @return True if the value was set.
*/
public boolean setCurrentAccessibleValue(Number n) {
return false;
}
/**
* Get the minimum value of this object as a Number.
*
* @return An Integer of 0.
*/
public Number getMinimumAccessibleValue() {
return Integer.valueOf(0);
}
/**
* Get the maximum value of this object as a Number.
*
* @return An Integer of 0.
*/
public Number getMaximumAccessibleValue() {
return Integer.valueOf(0);
}
/**
* Get the role of this object.
*
* @return an instance of AccessibleRole describing the role of the
* object
* @see AccessibleRole
*/
public AccessibleRole getAccessibleRole() {
return AccessibleRole.PUSH_BUTTON;
}
} // inner class AccessibleAWTButton
}

View File

@@ -0,0 +1,254 @@
/*
* Copyright (c) 1995, 2010, 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 java.awt;
import java.awt.image.BufferStrategy;
import java.awt.peer.CanvasPeer;
import javax.accessibility.*;
/**
* A <code>Canvas</code> component represents a blank rectangular
* area of the screen onto which the application can draw or from
* which the application can trap input events from the user.
* <p>
* An application must subclass the <code>Canvas</code> class in
* order to get useful functionality such as creating a custom
* component. The <code>paint</code> method must be overridden
* in order to perform custom graphics on the canvas.
*
* @author Sami Shaio
* @since JDK1.0
*/
public class Canvas extends Component implements Accessible {
private static final String base = "canvas";
private static int nameCounter = 0;
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = -2284879212465893870L;
/**
* Constructs a new Canvas.
*/
public Canvas() {
}
/**
* Constructs a new Canvas given a GraphicsConfiguration object.
*
* @param config a reference to a GraphicsConfiguration object.
*
* @see GraphicsConfiguration
*/
public Canvas(GraphicsConfiguration config) {
this();
setGraphicsConfiguration(config);
}
@Override
void setGraphicsConfiguration(GraphicsConfiguration gc) {
synchronized(getTreeLock()) {
CanvasPeer peer = (CanvasPeer)getPeer();
if (peer != null) {
gc = peer.getAppropriateGraphicsConfiguration(gc);
}
super.setGraphicsConfiguration(gc);
}
}
/**
* Construct a name for this component. Called by getName() when the
* name is null.
*/
String constructComponentName() {
synchronized (Canvas.class) {
return base + nameCounter++;
}
}
/**
* Creates the peer of the canvas. This peer allows you to change the
* user interface of the canvas without changing its functionality.
* @see java.awt.Toolkit#createCanvas(java.awt.Canvas)
* @see java.awt.Component#getToolkit()
*/
public void addNotify() {
synchronized (getTreeLock()) {
if (peer == null)
peer = getToolkit().createCanvas(this);
super.addNotify();
}
}
/**
* Paints this canvas.
* <p>
* Most applications that subclass <code>Canvas</code> should
* override this method in order to perform some useful operation
* (typically, custom painting of the canvas).
* The default operation is simply to clear the canvas.
* Applications that override this method need not call
* super.paint(g).
*
* @param g the specified Graphics context
* @see #update(Graphics)
* @see Component#paint(Graphics)
*/
public void paint(Graphics g) {
g.clearRect(0, 0, width, height);
}
/**
* Updates this canvas.
* <p>
* This method is called in response to a call to <code>repaint</code>.
* The canvas is first cleared by filling it with the background
* color, and then completely redrawn by calling this canvas's
* <code>paint</code> method.
* Note: applications that override this method should either call
* super.update(g) or incorporate the functionality described
* above into their own code.
*
* @param g the specified Graphics context
* @see #paint(Graphics)
* @see Component#update(Graphics)
*/
public void update(Graphics g) {
g.clearRect(0, 0, width, height);
paint(g);
}
boolean postsOldMouseEvents() {
return true;
}
/**
* Creates a new strategy for multi-buffering on this component.
* Multi-buffering is useful for rendering performance. This method
* attempts to create the best strategy available with the number of
* buffers supplied. It will always create a <code>BufferStrategy</code>
* with that number of buffers.
* A page-flipping strategy is attempted first, then a blitting strategy
* using accelerated buffers. Finally, an unaccelerated blitting
* strategy is used.
* <p>
* Each time this method is called,
* the existing buffer strategy for this component is discarded.
* @param numBuffers number of buffers to create, including the front buffer
* @exception IllegalArgumentException if numBuffers is less than 1.
* @exception IllegalStateException if the component is not displayable
* @see #isDisplayable
* @see #getBufferStrategy
* @since 1.4
*/
public void createBufferStrategy(int numBuffers) {
super.createBufferStrategy(numBuffers);
}
/**
* Creates a new strategy for multi-buffering on this component with the
* required buffer capabilities. This is useful, for example, if only
* accelerated memory or page flipping is desired (as specified by the
* buffer capabilities).
* <p>
* Each time this method
* is called, the existing buffer strategy for this component is discarded.
* @param numBuffers number of buffers to create
* @param caps the required capabilities for creating the buffer strategy;
* cannot be <code>null</code>
* @exception AWTException if the capabilities supplied could not be
* supported or met; this may happen, for example, if there is not enough
* accelerated memory currently available, or if page flipping is specified
* but not possible.
* @exception IllegalArgumentException if numBuffers is less than 1, or if
* caps is <code>null</code>
* @see #getBufferStrategy
* @since 1.4
*/
public void createBufferStrategy(int numBuffers,
BufferCapabilities caps) throws AWTException {
super.createBufferStrategy(numBuffers, caps);
}
/**
* Returns the <code>BufferStrategy</code> used by this component. This
* method will return null if a <code>BufferStrategy</code> has not yet
* been created or has been disposed.
*
* @return the buffer strategy used by this component
* @see #createBufferStrategy
* @since 1.4
*/
public BufferStrategy getBufferStrategy() {
return super.getBufferStrategy();
}
/*
* --- Accessibility Support ---
*
*/
/**
* Gets the AccessibleContext associated with this Canvas.
* For canvases, the AccessibleContext takes the form of an
* AccessibleAWTCanvas.
* A new AccessibleAWTCanvas instance is created if necessary.
*
* @return an AccessibleAWTCanvas that serves as the
* AccessibleContext of this Canvas
* @since 1.3
*/
public AccessibleContext getAccessibleContext() {
if (accessibleContext == null) {
accessibleContext = new AccessibleAWTCanvas();
}
return accessibleContext;
}
/**
* This class implements accessibility support for the
* <code>Canvas</code> class. It provides an implementation of the
* Java Accessibility API appropriate to canvas user-interface elements.
* @since 1.3
*/
protected class AccessibleAWTCanvas extends AccessibleAWTComponent
{
private static final long serialVersionUID = -6325592262103146699L;
/**
* Get the role of this object.
*
* @return an instance of AccessibleRole describing the role of the
* object
* @see AccessibleRole
*/
public AccessibleRole getAccessibleRole() {
return AccessibleRole.CANVAS;
}
} // inner class AccessibleAWTCanvas
}

View File

@@ -0,0 +1,612 @@
/*
* Copyright (c) 1995, 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 java.awt;
import java.util.Hashtable;
import java.util.Vector;
import java.util.Enumeration;
import java.io.Serializable;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamField;
import java.io.IOException;
/**
* A <code>CardLayout</code> object is a layout manager for a
* container. It treats each component in the container as a card.
* Only one card is visible at a time, and the container acts as
* a stack of cards. The first component added to a
* <code>CardLayout</code> object is the visible component when the
* container is first displayed.
* <p>
* The ordering of cards is determined by the container's own internal
* ordering of its component objects. <code>CardLayout</code>
* defines a set of methods that allow an application to flip
* through these cards sequentially, or to show a specified card.
* The {@link CardLayout#addLayoutComponent}
* method can be used to associate a string identifier with a given card
* for fast random access.
*
* @author Arthur van Hoff
* @see java.awt.Container
* @since JDK1.0
*/
public class CardLayout implements LayoutManager2,
Serializable {
private static final long serialVersionUID = -4328196481005934313L;
/*
* This creates a Vector to store associated
* pairs of components and their names.
* @see java.util.Vector
*/
Vector<Card> vector = new Vector<>();
/*
* A pair of Component and String that represents its name.
*/
class Card implements Serializable {
static final long serialVersionUID = 6640330810709497518L;
public String name;
public Component comp;
public Card(String cardName, Component cardComponent) {
name = cardName;
comp = cardComponent;
}
}
/*
* Index of Component currently displayed by CardLayout.
*/
int currentCard = 0;
/*
* A cards horizontal Layout gap (inset). It specifies
* the space between the left and right edges of a
* container and the current component.
* This should be a non negative Integer.
* @see getHgap()
* @see setHgap()
*/
int hgap;
/*
* A cards vertical Layout gap (inset). It specifies
* the space between the top and bottom edges of a
* container and the current component.
* This should be a non negative Integer.
* @see getVgap()
* @see setVgap()
*/
int vgap;
/**
* @serialField tab Hashtable
* deprectated, for forward compatibility only
* @serialField hgap int
* @serialField vgap int
* @serialField vector Vector
* @serialField currentCard int
*/
private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("tab", Hashtable.class),
new ObjectStreamField("hgap", Integer.TYPE),
new ObjectStreamField("vgap", Integer.TYPE),
new ObjectStreamField("vector", Vector.class),
new ObjectStreamField("currentCard", Integer.TYPE)
};
/**
* Creates a new card layout with gaps of size zero.
*/
public CardLayout() {
this(0, 0);
}
/**
* Creates a new card layout with the specified horizontal and
* vertical gaps. The horizontal gaps are placed at the left and
* right edges. The vertical gaps are placed at the top and bottom
* edges.
* @param hgap the horizontal gap.
* @param vgap the vertical gap.
*/
public CardLayout(int hgap, int vgap) {
this.hgap = hgap;
this.vgap = vgap;
}
/**
* Gets the horizontal gap between components.
* @return the horizontal gap between components.
* @see java.awt.CardLayout#setHgap(int)
* @see java.awt.CardLayout#getVgap()
* @since JDK1.1
*/
public int getHgap() {
return hgap;
}
/**
* Sets the horizontal gap between components.
* @param hgap the horizontal gap between components.
* @see java.awt.CardLayout#getHgap()
* @see java.awt.CardLayout#setVgap(int)
* @since JDK1.1
*/
public void setHgap(int hgap) {
this.hgap = hgap;
}
/**
* Gets the vertical gap between components.
* @return the vertical gap between components.
* @see java.awt.CardLayout#setVgap(int)
* @see java.awt.CardLayout#getHgap()
*/
public int getVgap() {
return vgap;
}
/**
* Sets the vertical gap between components.
* @param vgap the vertical gap between components.
* @see java.awt.CardLayout#getVgap()
* @see java.awt.CardLayout#setHgap(int)
* @since JDK1.1
*/
public void setVgap(int vgap) {
this.vgap = vgap;
}
/**
* Adds the specified component to this card layout's internal
* table of names. The object specified by <code>constraints</code>
* must be a string. The card layout stores this string as a key-value
* pair that can be used for random access to a particular card.
* By calling the <code>show</code> method, an application can
* display the component with the specified name.
* @param comp the component to be added.
* @param constraints a tag that identifies a particular
* card in the layout.
* @see java.awt.CardLayout#show(java.awt.Container, java.lang.String)
* @exception IllegalArgumentException if the constraint is not a string.
*/
public void addLayoutComponent(Component comp, Object constraints) {
synchronized (comp.getTreeLock()) {
if (constraints == null){
constraints = "";
}
if (constraints instanceof String) {
addLayoutComponent((String)constraints, comp);
} else {
throw new IllegalArgumentException("cannot add to layout: constraint must be a string");
}
}
}
/**
* @deprecated replaced by
* <code>addLayoutComponent(Component, Object)</code>.
*/
@Deprecated
public void addLayoutComponent(String name, Component comp) {
synchronized (comp.getTreeLock()) {
if (!vector.isEmpty()) {
comp.setVisible(false);
}
for (int i=0; i < vector.size(); i++) {
if (((Card)vector.get(i)).name.equals(name)) {
((Card)vector.get(i)).comp = comp;
return;
}
}
vector.add(new Card(name, comp));
}
}
/**
* Removes the specified component from the layout.
* If the card was visible on top, the next card underneath it is shown.
* @param comp the component to be removed.
* @see java.awt.Container#remove(java.awt.Component)
* @see java.awt.Container#removeAll()
*/
public void removeLayoutComponent(Component comp) {
synchronized (comp.getTreeLock()) {
for (int i = 0; i < vector.size(); i++) {
if (((Card)vector.get(i)).comp == comp) {
// if we remove current component we should show next one
if (comp.isVisible() && (comp.getParent() != null)) {
next(comp.getParent());
}
vector.remove(i);
// correct currentCard if this is necessary
if (currentCard > i) {
currentCard--;
}
break;
}
}
}
}
/**
* Determines the preferred size of the container argument using
* this card layout.
* @param parent the parent container in which to do the layout
* @return the preferred dimensions to lay out the subcomponents
* of the specified container
* @see java.awt.Container#getPreferredSize
* @see java.awt.CardLayout#minimumLayoutSize
*/
public Dimension preferredLayoutSize(Container parent) {
synchronized (parent.getTreeLock()) {
Insets insets = parent.getInsets();
int ncomponents = parent.getComponentCount();
int w = 0;
int h = 0;
for (int i = 0 ; i < ncomponents ; i++) {
Component comp = parent.getComponent(i);
Dimension d = comp.getPreferredSize();
if (d.width > w) {
w = d.width;
}
if (d.height > h) {
h = d.height;
}
}
return new Dimension(insets.left + insets.right + w + hgap*2,
insets.top + insets.bottom + h + vgap*2);
}
}
/**
* Calculates the minimum size for the specified panel.
* @param parent the parent container in which to do the layout
* @return the minimum dimensions required to lay out the
* subcomponents of the specified container
* @see java.awt.Container#doLayout
* @see java.awt.CardLayout#preferredLayoutSize
*/
public Dimension minimumLayoutSize(Container parent) {
synchronized (parent.getTreeLock()) {
Insets insets = parent.getInsets();
int ncomponents = parent.getComponentCount();
int w = 0;
int h = 0;
for (int i = 0 ; i < ncomponents ; i++) {
Component comp = parent.getComponent(i);
Dimension d = comp.getMinimumSize();
if (d.width > w) {
w = d.width;
}
if (d.height > h) {
h = d.height;
}
}
return new Dimension(insets.left + insets.right + w + hgap*2,
insets.top + insets.bottom + h + vgap*2);
}
}
/**
* Returns the maximum dimensions for this layout given the components
* in the specified target container.
* @param target the component which needs to be laid out
* @see Container
* @see #minimumLayoutSize
* @see #preferredLayoutSize
*/
public Dimension maximumLayoutSize(Container target) {
return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
}
/**
* Returns the alignment along the x axis. This specifies how
* the component would like to be aligned relative to other
* components. The value should be a number between 0 and 1
* where 0 represents alignment along the origin, 1 is aligned
* the furthest away from the origin, 0.5 is centered, etc.
*/
public float getLayoutAlignmentX(Container parent) {
return 0.5f;
}
/**
* Returns the alignment along the y axis. This specifies how
* the component would like to be aligned relative to other
* components. The value should be a number between 0 and 1
* where 0 represents alignment along the origin, 1 is aligned
* the furthest away from the origin, 0.5 is centered, etc.
*/
public float getLayoutAlignmentY(Container parent) {
return 0.5f;
}
/**
* Invalidates the layout, indicating that if the layout manager
* has cached information it should be discarded.
*/
public void invalidateLayout(Container target) {
}
/**
* Lays out the specified container using this card layout.
* <p>
* Each component in the <code>parent</code> container is reshaped
* to be the size of the container, minus space for surrounding
* insets, horizontal gaps, and vertical gaps.
*
* @param parent the parent container in which to do the layout
* @see java.awt.Container#doLayout
*/
public void layoutContainer(Container parent) {
synchronized (parent.getTreeLock()) {
Insets insets = parent.getInsets();
int ncomponents = parent.getComponentCount();
Component comp = null;
boolean currentFound = false;
for (int i = 0 ; i < ncomponents ; i++) {
comp = parent.getComponent(i);
comp.setBounds(hgap + insets.left, vgap + insets.top,
parent.width - (hgap*2 + insets.left + insets.right),
parent.height - (vgap*2 + insets.top + insets.bottom));
if (comp.isVisible()) {
currentFound = true;
}
}
if (!currentFound && ncomponents > 0) {
parent.getComponent(0).setVisible(true);
}
}
}
/**
* Make sure that the Container really has a CardLayout installed.
* Otherwise havoc can ensue!
*/
void checkLayout(Container parent) {
if (parent.getLayout() != this) {
throw new IllegalArgumentException("wrong parent for CardLayout");
}
}
/**
* Flips to the first card of the container.
* @param parent the parent container in which to do the layout
* @see java.awt.CardLayout#last
*/
public void first(Container parent) {
synchronized (parent.getTreeLock()) {
checkLayout(parent);
int ncomponents = parent.getComponentCount();
for (int i = 0 ; i < ncomponents ; i++) {
Component comp = parent.getComponent(i);
if (comp.isVisible()) {
comp.setVisible(false);
break;
}
}
if (ncomponents > 0) {
currentCard = 0;
parent.getComponent(0).setVisible(true);
parent.validate();
}
}
}
/**
* Flips to the next card of the specified container. If the
* currently visible card is the last one, this method flips to the
* first card in the layout.
* @param parent the parent container in which to do the layout
* @see java.awt.CardLayout#previous
*/
public void next(Container parent) {
synchronized (parent.getTreeLock()) {
checkLayout(parent);
int ncomponents = parent.getComponentCount();
for (int i = 0 ; i < ncomponents ; i++) {
Component comp = parent.getComponent(i);
if (comp.isVisible()) {
comp.setVisible(false);
currentCard = (i + 1) % ncomponents;
comp = parent.getComponent(currentCard);
comp.setVisible(true);
parent.validate();
return;
}
}
showDefaultComponent(parent);
}
}
/**
* Flips to the previous card of the specified container. If the
* currently visible card is the first one, this method flips to the
* last card in the layout.
* @param parent the parent container in which to do the layout
* @see java.awt.CardLayout#next
*/
public void previous(Container parent) {
synchronized (parent.getTreeLock()) {
checkLayout(parent);
int ncomponents = parent.getComponentCount();
for (int i = 0 ; i < ncomponents ; i++) {
Component comp = parent.getComponent(i);
if (comp.isVisible()) {
comp.setVisible(false);
currentCard = ((i > 0) ? i-1 : ncomponents-1);
comp = parent.getComponent(currentCard);
comp.setVisible(true);
parent.validate();
return;
}
}
showDefaultComponent(parent);
}
}
void showDefaultComponent(Container parent) {
if (parent.getComponentCount() > 0) {
currentCard = 0;
parent.getComponent(0).setVisible(true);
parent.validate();
}
}
/**
* Flips to the last card of the container.
* @param parent the parent container in which to do the layout
* @see java.awt.CardLayout#first
*/
public void last(Container parent) {
synchronized (parent.getTreeLock()) {
checkLayout(parent);
int ncomponents = parent.getComponentCount();
for (int i = 0 ; i < ncomponents ; i++) {
Component comp = parent.getComponent(i);
if (comp.isVisible()) {
comp.setVisible(false);
break;
}
}
if (ncomponents > 0) {
currentCard = ncomponents - 1;
parent.getComponent(currentCard).setVisible(true);
parent.validate();
}
}
}
/**
* Flips to the component that was added to this layout with the
* specified <code>name</code>, using <code>addLayoutComponent</code>.
* If no such component exists, then nothing happens.
* @param parent the parent container in which to do the layout
* @param name the component name
* @see java.awt.CardLayout#addLayoutComponent(java.awt.Component, java.lang.Object)
*/
public void show(Container parent, String name) {
synchronized (parent.getTreeLock()) {
checkLayout(parent);
Component next = null;
int ncomponents = vector.size();
for (int i = 0; i < ncomponents; i++) {
Card card = (Card)vector.get(i);
if (card.name.equals(name)) {
next = card.comp;
currentCard = i;
break;
}
}
if ((next != null) && !next.isVisible()) {
ncomponents = parent.getComponentCount();
for (int i = 0; i < ncomponents; i++) {
Component comp = parent.getComponent(i);
if (comp.isVisible()) {
comp.setVisible(false);
break;
}
}
next.setVisible(true);
parent.validate();
}
}
}
/**
* Returns a string representation of the state of this card layout.
* @return a string representation of this card layout.
*/
public String toString() {
return getClass().getName() + "[hgap=" + hgap + ",vgap=" + vgap + "]";
}
/**
* Reads serializable fields from stream.
*/
private void readObject(ObjectInputStream s)
throws ClassNotFoundException, IOException
{
ObjectInputStream.GetField f = s.readFields();
hgap = f.get("hgap", 0);
vgap = f.get("vgap", 0);
if (f.defaulted("vector")) {
// pre-1.4 stream
Hashtable<String, Component> tab = (Hashtable)f.get("tab", null);
vector = new Vector<>();
if (tab != null && !tab.isEmpty()) {
for (Enumeration<String> e = tab.keys() ; e.hasMoreElements() ; ) {
String key = (String)e.nextElement();
Component comp = (Component)tab.get(key);
vector.add(new Card(key, comp));
if (comp.isVisible()) {
currentCard = vector.size() - 1;
}
}
}
} else {
vector = (Vector)f.get("vector", null);
currentCard = f.get("currentCard", 0);
}
}
/**
* Writes serializable fields to stream.
*/
private void writeObject(ObjectOutputStream s)
throws IOException
{
Hashtable<String, Component> tab = new Hashtable<>();
int ncomponents = vector.size();
for (int i = 0; i < ncomponents; i++) {
Card card = (Card)vector.get(i);
tab.put(card.name, card.comp);
}
ObjectOutputStream.PutField f = s.putFields();
f.put("hgap", hgap);
f.put("vgap", vgap);
f.put("vector", vector);
f.put("currentCard", currentCard);
f.put("tab", tab);
s.writeFields();
}
}

View File

@@ -0,0 +1,866 @@
/*
* Copyright (c) 1995, 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 java.awt;
import java.awt.peer.CheckboxPeer;
import java.awt.event.*;
import java.util.EventListener;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.IOException;
import javax.accessibility.*;
/**
* A check box is a graphical component that can be in either an
* "on" (<code>true</code>) or "off" (<code>false</code>) state.
* Clicking on a check box changes its state from
* "on" to "off," or from "off" to "on."
* <p>
* The following code example creates a set of check boxes in
* a grid layout:
*
* <hr><blockquote><pre>
* setLayout(new GridLayout(3, 1));
* add(new Checkbox("one", null, true));
* add(new Checkbox("two"));
* add(new Checkbox("three"));
* </pre></blockquote><hr>
* <p>
* This image depicts the check boxes and grid layout
* created by this code example:
* <p>
* <img src="doc-files/Checkbox-1.gif" alt="The following context describes the graphic."
* style="float:center; margin: 7px 10px;">
* <p>
* The button labeled <code>one</code> is in the "on" state, and the
* other two are in the "off" state. In this example, which uses the
* <code>GridLayout</code> class, the states of the three check
* boxes are set independently.
* <p>
* Alternatively, several check boxes can be grouped together under
* the control of a single object, using the
* <code>CheckboxGroup</code> class.
* In a check box group, at most one button can be in the "on"
* state at any given time. Clicking on a check box to turn it on
* forces any other check box in the same group that is on
* into the "off" state.
*
* @author Sami Shaio
* @see java.awt.GridLayout
* @see java.awt.CheckboxGroup
* @since JDK1.0
*/
public class Checkbox extends Component implements ItemSelectable, Accessible {
static {
/* ensure that the necessary native libraries are loaded */
Toolkit.loadLibraries();
if (!GraphicsEnvironment.isHeadless()) {
initIDs();
}
}
/**
* The label of the Checkbox.
* This field can be null.
* @serial
* @see #getLabel()
* @see #setLabel(String)
*/
String label;
/**
* The state of the <code>Checkbox</code>.
* @serial
* @see #getState()
* @see #setState(boolean)
*/
boolean state;
/**
* The check box group.
* This field can be null indicating that the checkbox
* is not a group checkbox.
* @serial
* @see #getCheckboxGroup()
* @see #setCheckboxGroup(CheckboxGroup)
*/
CheckboxGroup group;
transient ItemListener itemListener;
private static final String base = "checkbox";
private static int nameCounter = 0;
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = 7270714317450821763L;
/**
* Helper function for setState and CheckboxGroup.setSelectedCheckbox
* Should remain package-private.
*/
void setStateInternal(boolean state) {
this.state = state;
CheckboxPeer peer = (CheckboxPeer)this.peer;
if (peer != null) {
peer.setState(state);
}
}
/**
* Creates a check box with an empty string for its label.
* The state of this check box is set to "off," and it is not
* part of any check box group.
* @exception HeadlessException if GraphicsEnvironment.isHeadless()
* returns true
* @see java.awt.GraphicsEnvironment#isHeadless
*/
public Checkbox() throws HeadlessException {
this("", false, null);
}
/**
* Creates a check box with the specified label. The state
* of this check box is set to "off," and it is not part of
* any check box group.
*
* @param label a string label for this check box,
* or <code>null</code> for no label.
* @exception HeadlessException if
* <code>GraphicsEnvironment.isHeadless</code>
* returns <code>true</code>
* @see java.awt.GraphicsEnvironment#isHeadless
*/
public Checkbox(String label) throws HeadlessException {
this(label, false, null);
}
/**
* Creates a check box with the specified label
* and sets the specified state.
* This check box is not part of any check box group.
*
* @param label a string label for this check box,
* or <code>null</code> for no label
* @param state the initial state of this check box
* @exception HeadlessException if
* <code>GraphicsEnvironment.isHeadless</code>
* returns <code>true</code>
* @see java.awt.GraphicsEnvironment#isHeadless
*/
public Checkbox(String label, boolean state) throws HeadlessException {
this(label, state, null);
}
/**
* Constructs a Checkbox with the specified label, set to the
* specified state, and in the specified check box group.
*
* @param label a string label for this check box,
* or <code>null</code> for no label.
* @param state the initial state of this check box.
* @param group a check box group for this check box,
* or <code>null</code> for no group.
* @exception HeadlessException if
* <code>GraphicsEnvironment.isHeadless</code>
* returns <code>true</code>
* @see java.awt.GraphicsEnvironment#isHeadless
* @since JDK1.1
*/
public Checkbox(String label, boolean state, CheckboxGroup group)
throws HeadlessException {
GraphicsEnvironment.checkHeadless();
this.label = label;
this.state = state;
this.group = group;
if (state && (group != null)) {
group.setSelectedCheckbox(this);
}
}
/**
* Creates a check box with the specified label, in the specified
* check box group, and set to the specified state.
*
* @param label a string label for this check box,
* or <code>null</code> for no label.
* @param group a check box group for this check box,
* or <code>null</code> for no group.
* @param state the initial state of this check box.
* @exception HeadlessException if
* <code>GraphicsEnvironment.isHeadless</code>
* returns <code>true</code>
* @see java.awt.GraphicsEnvironment#isHeadless
* @since JDK1.1
*/
public Checkbox(String label, CheckboxGroup group, boolean state)
throws HeadlessException {
this(label, state, group);
}
/**
* Constructs a name for this component. Called by
* <code>getName</code> when the name is <code>null</code>.
*
* @return a name for this component
*/
String constructComponentName() {
synchronized (Checkbox.class) {
return base + nameCounter++;
}
}
/**
* Creates the peer of the Checkbox. The peer allows you to change the
* look of the Checkbox without changing its functionality.
*
* @see java.awt.Toolkit#createCheckbox(java.awt.Checkbox)
* @see java.awt.Component#getToolkit()
*/
public void addNotify() {
synchronized (getTreeLock()) {
if (peer == null)
peer = getToolkit().createCheckbox(this);
super.addNotify();
}
}
/**
* Gets the label of this check box.
*
* @return the label of this check box, or <code>null</code>
* if this check box has no label.
* @see #setLabel(String)
*/
public String getLabel() {
return label;
}
/**
* Sets this check box's label to be the string argument.
*
* @param label a string to set as the new label, or
* <code>null</code> for no label.
* @see #getLabel
*/
public void setLabel(String label) {
boolean testvalid = false;
synchronized (this) {
if (label != this.label && (this.label == null ||
!this.label.equals(label))) {
this.label = label;
CheckboxPeer peer = (CheckboxPeer)this.peer;
if (peer != null) {
peer.setLabel(label);
}
testvalid = true;
}
}
// This could change the preferred size of the Component.
if (testvalid) {
invalidateIfValid();
}
}
/**
* Determines whether this check box is in the "on" or "off" state.
* The boolean value <code>true</code> indicates the "on" state,
* and <code>false</code> indicates the "off" state.
*
* @return the state of this check box, as a boolean value
* @see #setState
*/
public boolean getState() {
return state;
}
/**
* Sets the state of this check box to the specified state.
* The boolean value <code>true</code> indicates the "on" state,
* and <code>false</code> indicates the "off" state.
*
* <p>Note that this method should be primarily used to
* initialize the state of the checkbox. Programmatically
* setting the state of the checkbox will <i>not</i> trigger
* an <code>ItemEvent</code>. The only way to trigger an
* <code>ItemEvent</code> is by user interaction.
*
* @param state the boolean state of the check box
* @see #getState
*/
public void setState(boolean state) {
/* Cannot hold check box lock when calling group.setSelectedCheckbox. */
CheckboxGroup group = this.group;
if (group != null) {
if (state) {
group.setSelectedCheckbox(this);
} else if (group.getSelectedCheckbox() == this) {
state = true;
}
}
setStateInternal(state);
}
/**
* Returns an array (length 1) containing the checkbox
* label or null if the checkbox is not selected.
* @see ItemSelectable
*/
public Object[] getSelectedObjects() {
if (state) {
Object[] items = new Object[1];
items[0] = label;
return items;
}
return null;
}
/**
* Determines this check box's group.
* @return this check box's group, or <code>null</code>
* if the check box is not part of a check box group.
* @see #setCheckboxGroup(CheckboxGroup)
*/
public CheckboxGroup getCheckboxGroup() {
return group;
}
/**
* Sets this check box's group to the specified check box group.
* If this check box is already in a different check box group,
* it is first taken out of that group.
* <p>
* If the state of this check box is <code>true</code> and the new
* group already has a check box selected, this check box's state
* is changed to <code>false</code>. If the state of this check
* box is <code>true</code> and the new group has no check box
* selected, this check box becomes the selected checkbox for
* the new group and its state is <code>true</code>.
*
* @param g the new check box group, or <code>null</code>
* to remove this check box from any check box group
* @see #getCheckboxGroup
*/
public void setCheckboxGroup(CheckboxGroup g) {
CheckboxGroup oldGroup;
boolean oldState;
/* Do nothing if this check box has already belonged
* to the check box group g.
*/
if (this.group == g) {
return;
}
synchronized (this) {
oldGroup = this.group;
oldState = getState();
this.group = g;
CheckboxPeer peer = (CheckboxPeer)this.peer;
if (peer != null) {
peer.setCheckboxGroup(g);
}
if (this.group != null && getState()) {
if (this.group.getSelectedCheckbox() != null) {
setState(false);
} else {
this.group.setSelectedCheckbox(this);
}
}
}
/* Locking check box below could cause deadlock with
* CheckboxGroup's setSelectedCheckbox method.
*
* Fix for 4726853 by kdm@sparc.spb.su
* Here we should check if this check box was selected
* in the previous group and set selected check box to
* null for that group if so.
*/
if (oldGroup != null && oldState) {
oldGroup.setSelectedCheckbox(null);
}
}
/**
* Adds the specified item listener to receive item events from
* this check box. Item events are sent to listeners in response
* to user input, but not in response to calls to setState().
* If l is null, no exception is thrown and no action is performed.
* <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
* >AWT Threading Issues</a> for details on AWT's threading model.
*
* @param l the item listener
* @see #removeItemListener
* @see #getItemListeners
* @see #setState
* @see java.awt.event.ItemEvent
* @see java.awt.event.ItemListener
* @since JDK1.1
*/
public synchronized void addItemListener(ItemListener l) {
if (l == null) {
return;
}
itemListener = AWTEventMulticaster.add(itemListener, l);
newEventsOnly = true;
}
/**
* Removes the specified item listener so that the item listener
* no longer receives item events from this check box.
* If l is null, no exception is thrown and no action is performed.
* <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
* >AWT Threading Issues</a> for details on AWT's threading model.
*
* @param l the item listener
* @see #addItemListener
* @see #getItemListeners
* @see java.awt.event.ItemEvent
* @see java.awt.event.ItemListener
* @since JDK1.1
*/
public synchronized void removeItemListener(ItemListener l) {
if (l == null) {
return;
}
itemListener = AWTEventMulticaster.remove(itemListener, l);
}
/**
* Returns an array of all the item listeners
* registered on this checkbox.
*
* @return all of this checkbox's <code>ItemListener</code>s
* or an empty array if no item
* listeners are currently registered
*
* @see #addItemListener
* @see #removeItemListener
* @see java.awt.event.ItemEvent
* @see java.awt.event.ItemListener
* @since 1.4
*/
public synchronized ItemListener[] getItemListeners() {
return getListeners(ItemListener.class);
}
/**
* Returns an array of all the objects currently registered
* as <code><em>Foo</em>Listener</code>s
* upon this <code>Checkbox</code>.
* <code><em>Foo</em>Listener</code>s are registered using the
* <code>add<em>Foo</em>Listener</code> method.
*
* <p>
* You can specify the <code>listenerType</code> argument
* with a class literal, such as
* <code><em>Foo</em>Listener.class</code>.
* For example, you can query a
* <code>Checkbox</code> <code>c</code>
* for its item listeners with the following code:
*
* <pre>ItemListener[] ils = (ItemListener[])(c.getListeners(ItemListener.class));</pre>
*
* If no such listeners exist, this method returns an empty array.
*
* @param listenerType the type of listeners requested; this parameter
* should specify an interface that descends from
* <code>java.util.EventListener</code>
* @return an array of all objects registered as
* <code><em>Foo</em>Listener</code>s on this checkbox,
* or an empty array if no such
* listeners have been added
* @exception ClassCastException if <code>listenerType</code>
* doesn't specify a class or interface that implements
* <code>java.util.EventListener</code>
*
* @see #getItemListeners
* @since 1.3
*/
public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
EventListener l = null;
if (listenerType == ItemListener.class) {
l = itemListener;
} else {
return super.getListeners(listenerType);
}
return AWTEventMulticaster.getListeners(l, listenerType);
}
// REMIND: remove when filtering is done at lower level
boolean eventEnabled(AWTEvent e) {
if (e.id == ItemEvent.ITEM_STATE_CHANGED) {
if ((eventMask & AWTEvent.ITEM_EVENT_MASK) != 0 ||
itemListener != null) {
return true;
}
return false;
}
return super.eventEnabled(e);
}
/**
* Processes events on this check box.
* If the event is an instance of <code>ItemEvent</code>,
* this method invokes the <code>processItemEvent</code> method.
* Otherwise, it calls its superclass's <code>processEvent</code> method.
* <p>Note that if the event parameter is <code>null</code>
* the behavior is unspecified and may result in an
* exception.
*
* @param e the event
* @see java.awt.event.ItemEvent
* @see #processItemEvent
* @since JDK1.1
*/
protected void processEvent(AWTEvent e) {
if (e instanceof ItemEvent) {
processItemEvent((ItemEvent)e);
return;
}
super.processEvent(e);
}
/**
* Processes item events occurring on this check box by
* dispatching them to any registered
* <code>ItemListener</code> objects.
* <p>
* This method is not called unless item events are
* enabled for this component. Item events are enabled
* when one of the following occurs:
* <ul>
* <li>An <code>ItemListener</code> object is registered
* via <code>addItemListener</code>.
* <li>Item events are enabled via <code>enableEvents</code>.
* </ul>
* <p>Note that if the event parameter is <code>null</code>
* the behavior is unspecified and may result in an
* exception.
*
* @param e the item event
* @see java.awt.event.ItemEvent
* @see java.awt.event.ItemListener
* @see #addItemListener
* @see java.awt.Component#enableEvents
* @since JDK1.1
*/
protected void processItemEvent(ItemEvent e) {
ItemListener listener = itemListener;
if (listener != null) {
listener.itemStateChanged(e);
}
}
/**
* Returns a string representing the state of this <code>Checkbox</code>.
* This method is intended to be used only for debugging purposes, and the
* content and format of the returned string may vary between
* implementations. The returned string may be empty but may not be
* <code>null</code>.
*
* @return the parameter string of this check box
*/
protected String paramString() {
String str = super.paramString();
String label = this.label;
if (label != null) {
str += ",label=" + label;
}
return str + ",state=" + state;
}
/* Serialization support.
*/
/*
* Serialized data version
* @serial
*/
private int checkboxSerializedDataVersion = 1;
/**
* Writes default serializable fields to stream. Writes
* a list of serializable <code>ItemListeners</code>
* as optional data. The non-serializable
* <code>ItemListeners</code> are detected and
* no attempt is made to serialize them.
*
* @param s the <code>ObjectOutputStream</code> to write
* @serialData <code>null</code> terminated sequence of 0
* or more pairs; the pair consists of a <code>String</code>
* and an <code>Object</code>; the <code>String</code> indicates
* the type of object and is one of the following:
* <code>itemListenerK</code> indicating an
* <code>ItemListener</code> object
*
* @see AWTEventMulticaster#save(ObjectOutputStream, String, EventListener)
* @see java.awt.Component#itemListenerK
* @see #readObject(ObjectInputStream)
*/
private void writeObject(ObjectOutputStream s)
throws java.io.IOException
{
s.defaultWriteObject();
AWTEventMulticaster.save(s, itemListenerK, itemListener);
s.writeObject(null);
}
/**
* Reads the <code>ObjectInputStream</code> and if it
* isn't <code>null</code> adds a listener to receive
* item events fired by the <code>Checkbox</code>.
* Unrecognized keys or values will be ignored.
*
* @param s the <code>ObjectInputStream</code> to read
* @exception HeadlessException if
* <code>GraphicsEnvironment.isHeadless</code> returns
* <code>true</code>
* @serial
* @see #removeItemListener(ItemListener)
* @see #addItemListener(ItemListener)
* @see java.awt.GraphicsEnvironment#isHeadless
* @see #writeObject(ObjectOutputStream)
*/
private void readObject(ObjectInputStream s)
throws ClassNotFoundException, IOException, HeadlessException
{
GraphicsEnvironment.checkHeadless();
s.defaultReadObject();
Object keyOrNull;
while(null != (keyOrNull = s.readObject())) {
String key = ((String)keyOrNull).intern();
if (itemListenerK == key)
addItemListener((ItemListener)(s.readObject()));
else // skip value for unrecognized key
s.readObject();
}
}
/**
* Initialize JNI field and method ids
*/
private static native void initIDs();
/////////////////
// Accessibility support
////////////////
/**
* Gets the AccessibleContext associated with this Checkbox.
* For checkboxes, the AccessibleContext takes the form of an
* AccessibleAWTCheckbox.
* A new AccessibleAWTCheckbox is created if necessary.
*
* @return an AccessibleAWTCheckbox that serves as the
* AccessibleContext of this Checkbox
* @since 1.3
*/
public AccessibleContext getAccessibleContext() {
if (accessibleContext == null) {
accessibleContext = new AccessibleAWTCheckbox();
}
return accessibleContext;
}
/**
* This class implements accessibility support for the
* <code>Checkbox</code> class. It provides an implementation of the
* Java Accessibility API appropriate to checkbox user-interface elements.
* @since 1.3
*/
protected class AccessibleAWTCheckbox extends AccessibleAWTComponent
implements ItemListener, AccessibleAction, AccessibleValue
{
/*
* JDK 1.3 serialVersionUID
*/
private static final long serialVersionUID = 7881579233144754107L;
public AccessibleAWTCheckbox() {
super();
Checkbox.this.addItemListener(this);
}
/**
* Fire accessible property change events when the state of the
* toggle button changes.
*/
public void itemStateChanged(ItemEvent e) {
Checkbox cb = (Checkbox) e.getSource();
if (Checkbox.this.accessibleContext != null) {
if (cb.getState()) {
Checkbox.this.accessibleContext.firePropertyChange(
AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
null, AccessibleState.CHECKED);
} else {
Checkbox.this.accessibleContext.firePropertyChange(
AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
AccessibleState.CHECKED, null);
}
}
}
/**
* Get the AccessibleAction associated with this object. In the
* implementation of the Java Accessibility API for this class,
* return this object, which is responsible for implementing the
* AccessibleAction interface on behalf of itself.
*
* @return this object
*/
public AccessibleAction getAccessibleAction() {
return this;
}
/**
* Get the AccessibleValue associated with this object. In the
* implementation of the Java Accessibility API for this class,
* return this object, which is responsible for implementing the
* AccessibleValue interface on behalf of itself.
*
* @return this object
*/
public AccessibleValue getAccessibleValue() {
return this;
}
/**
* Returns the number of Actions available in this object.
* If there is more than one, the first one is the "default"
* action.
*
* @return the number of Actions in this object
*/
public int getAccessibleActionCount() {
return 0; // To be fully implemented in a future release
}
/**
* Return a description of the specified action of the object.
*
* @param i zero-based index of the actions
*/
public String getAccessibleActionDescription(int i) {
return null; // To be fully implemented in a future release
}
/**
* Perform the specified Action on the object
*
* @param i zero-based index of actions
* @return true if the the action was performed; else false.
*/
public boolean doAccessibleAction(int i) {
return false; // To be fully implemented in a future release
}
/**
* Get the value of this object as a Number. If the value has not been
* set, the return value will be null.
*
* @return value of the object
* @see #setCurrentAccessibleValue
*/
public Number getCurrentAccessibleValue() {
return null; // To be fully implemented in a future release
}
/**
* Set the value of this object as a Number.
*
* @return True if the value was set; else False
* @see #getCurrentAccessibleValue
*/
public boolean setCurrentAccessibleValue(Number n) {
return false; // To be fully implemented in a future release
}
/**
* Get the minimum value of this object as a Number.
*
* @return Minimum value of the object; null if this object does not
* have a minimum value
* @see #getMaximumAccessibleValue
*/
public Number getMinimumAccessibleValue() {
return null; // To be fully implemented in a future release
}
/**
* Get the maximum value of this object as a Number.
*
* @return Maximum value of the object; null if this object does not
* have a maximum value
* @see #getMinimumAccessibleValue
*/
public Number getMaximumAccessibleValue() {
return null; // To be fully implemented in a future release
}
/**
* Get the role of this object.
*
* @return an instance of AccessibleRole describing the role of
* the object
* @see AccessibleRole
*/
public AccessibleRole getAccessibleRole() {
return AccessibleRole.CHECK_BOX;
}
/**
* Get the state set of this object.
*
* @return an instance of AccessibleState containing the current state
* of the object
* @see AccessibleState
*/
public AccessibleStateSet getAccessibleStateSet() {
AccessibleStateSet states = super.getAccessibleStateSet();
if (getState()) {
states.add(AccessibleState.CHECKED);
}
return states;
}
} // inner class AccessibleAWTCheckbox
}

View File

@@ -0,0 +1,150 @@
/*
* Copyright (c) 1995, 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 java.awt;
/**
* The <code>CheckboxGroup</code> class is used to group together
* a set of <code>Checkbox</code> buttons.
* <p>
* Exactly one check box button in a <code>CheckboxGroup</code> can
* be in the "on" state at any given time. Pushing any
* button sets its state to "on" and forces any other button that
* is in the "on" state into the "off" state.
* <p>
* The following code example produces a new check box group,
* with three check boxes:
*
* <hr><blockquote><pre>
* setLayout(new GridLayout(3, 1));
* CheckboxGroup cbg = new CheckboxGroup();
* add(new Checkbox("one", cbg, true));
* add(new Checkbox("two", cbg, false));
* add(new Checkbox("three", cbg, false));
* </pre></blockquote><hr>
* <p>
* This image depicts the check box group created by this example:
* <p>
* <img src="doc-files/CheckboxGroup-1.gif"
* alt="Shows three checkboxes, arranged vertically, labeled one, two, and three. Checkbox one is in the on state."
* style="float:center; margin: 7px 10px;">
* <p>
* @author Sami Shaio
* @see java.awt.Checkbox
* @since JDK1.0
*/
public class CheckboxGroup implements java.io.Serializable {
/**
* The current choice.
* @serial
* @see #getCurrent()
* @see #setCurrent(Checkbox)
*/
Checkbox selectedCheckbox = null;
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = 3729780091441768983L;
/**
* Creates a new instance of <code>CheckboxGroup</code>.
*/
public CheckboxGroup() {
}
/**
* Gets the current choice from this check box group.
* The current choice is the check box in this
* group that is currently in the "on" state,
* or <code>null</code> if all check boxes in the
* group are off.
* @return the check box that is currently in the
* "on" state, or <code>null</code>.
* @see java.awt.Checkbox
* @see java.awt.CheckboxGroup#setSelectedCheckbox
* @since JDK1.1
*/
public Checkbox getSelectedCheckbox() {
return getCurrent();
}
/**
* @deprecated As of JDK version 1.1,
* replaced by <code>getSelectedCheckbox()</code>.
*/
@Deprecated
public Checkbox getCurrent() {
return selectedCheckbox;
}
/**
* Sets the currently selected check box in this group
* to be the specified check box.
* This method sets the state of that check box to "on" and
* sets all other check boxes in the group to be off.
* <p>
* If the check box argument is <tt>null</tt>, all check boxes
* in this check box group are deselected. If the check box argument
* belongs to a different check box group, this method does
* nothing.
* @param box the <code>Checkbox</code> to set as the
* current selection.
* @see java.awt.Checkbox
* @see java.awt.CheckboxGroup#getSelectedCheckbox
* @since JDK1.1
*/
public void setSelectedCheckbox(Checkbox box) {
setCurrent(box);
}
/**
* @deprecated As of JDK version 1.1,
* replaced by <code>setSelectedCheckbox(Checkbox)</code>.
*/
@Deprecated
public synchronized void setCurrent(Checkbox box) {
if (box != null && box.group != this) {
return;
}
Checkbox oldChoice = this.selectedCheckbox;
this.selectedCheckbox = box;
if (oldChoice != null && oldChoice != box && oldChoice.group == this) {
oldChoice.setState(false);
}
if (box != null && oldChoice != box && !box.getState()) {
box.setStateInternal(true);
}
}
/**
* Returns a string representation of this check box group,
* including the value of its current selection.
* @return a string representation of this check box group.
*/
public String toString() {
return getClass().getName() + "[selectedCheckbox=" + selectedCheckbox + "]";
}
}

View File

@@ -0,0 +1,641 @@
/*
* Copyright (c) 1995, 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 java.awt;
import java.awt.peer.CheckboxMenuItemPeer;
import java.awt.event.*;
import java.util.EventListener;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.IOException;
import javax.accessibility.*;
import sun.awt.AWTAccessor;
/**
* This class represents a check box that can be included in a menu.
* Selecting the check box in the menu changes its state from
* "on" to "off" or from "off" to "on."
* <p>
* The following picture depicts a menu which contains an instance
* of <code>CheckBoxMenuItem</code>:
* <p>
* <img src="doc-files/MenuBar-1.gif"
* alt="Menu labeled Examples, containing items Basic, Simple, Check, and More Examples. The Check item is a CheckBoxMenuItem instance, in the off state."
* style="float:center; margin: 7px 10px;">
* <p>
* The item labeled <code>Check</code> shows a check box menu item
* in its "off" state.
* <p>
* When a check box menu item is selected, AWT sends an item event to
* the item. Since the event is an instance of <code>ItemEvent</code>,
* the <code>processEvent</code> method examines the event and passes
* it along to <code>processItemEvent</code>. The latter method redirects
* the event to any <code>ItemListener</code> objects that have
* registered an interest in item events generated by this menu item.
*
* @author Sami Shaio
* @see java.awt.event.ItemEvent
* @see java.awt.event.ItemListener
* @since JDK1.0
*/
public class CheckboxMenuItem extends MenuItem implements ItemSelectable, Accessible {
static {
/* ensure that the necessary native libraries are loaded */
Toolkit.loadLibraries();
if (!GraphicsEnvironment.isHeadless()) {
initIDs();
}
AWTAccessor.setCheckboxMenuItemAccessor(
new AWTAccessor.CheckboxMenuItemAccessor() {
public boolean getState(CheckboxMenuItem cmi) {
return cmi.state;
}
});
}
/**
* The state of a checkbox menu item
* @serial
* @see #getState()
* @see #setState(boolean)
*/
boolean state = false;
transient ItemListener itemListener;
private static final String base = "chkmenuitem";
private static int nameCounter = 0;
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = 6190621106981774043L;
/**
* Create a check box menu item with an empty label.
* The item's state is initially set to "off."
* @exception HeadlessException if GraphicsEnvironment.isHeadless()
* returns true
* @see java.awt.GraphicsEnvironment#isHeadless
* @since JDK1.1
*/
public CheckboxMenuItem() throws HeadlessException {
this("", false);
}
/**
* Create a check box menu item with the specified label.
* The item's state is initially set to "off."
* @param label a string label for the check box menu item,
* or <code>null</code> for an unlabeled menu item.
* @exception HeadlessException if GraphicsEnvironment.isHeadless()
* returns true
* @see java.awt.GraphicsEnvironment#isHeadless
*/
public CheckboxMenuItem(String label) throws HeadlessException {
this(label, false);
}
/**
* Create a check box menu item with the specified label and state.
* @param label a string label for the check box menu item,
* or <code>null</code> for an unlabeled menu item.
* @param state the initial state of the menu item, where
* <code>true</code> indicates "on" and
* <code>false</code> indicates "off."
* @exception HeadlessException if GraphicsEnvironment.isHeadless()
* returns true
* @see java.awt.GraphicsEnvironment#isHeadless
* @since JDK1.1
*/
public CheckboxMenuItem(String label, boolean state)
throws HeadlessException {
super(label);
this.state = state;
}
/**
* Construct a name for this MenuComponent. Called by getName() when
* the name is null.
*/
String constructComponentName() {
synchronized (CheckboxMenuItem.class) {
return base + nameCounter++;
}
}
/**
* Creates the peer of the checkbox item. This peer allows us to
* change the look of the checkbox item without changing its
* functionality.
* Most applications do not call this method directly.
* @see java.awt.Toolkit#createCheckboxMenuItem(java.awt.CheckboxMenuItem)
* @see java.awt.Component#getToolkit()
*/
public void addNotify() {
synchronized (getTreeLock()) {
if (peer == null)
peer = Toolkit.getDefaultToolkit().createCheckboxMenuItem(this);
super.addNotify();
}
}
/**
* Determines whether the state of this check box menu item
* is "on" or "off."
*
* @return the state of this check box menu item, where
* <code>true</code> indicates "on" and
* <code>false</code> indicates "off"
* @see #setState
*/
public boolean getState() {
return state;
}
/**
* Sets this check box menu item to the specified state.
* The boolean value <code>true</code> indicates "on" while
* <code>false</code> indicates "off."
*
* <p>Note that this method should be primarily used to
* initialize the state of the check box menu item.
* Programmatically setting the state of the check box
* menu item will <i>not</i> trigger
* an <code>ItemEvent</code>. The only way to trigger an
* <code>ItemEvent</code> is by user interaction.
*
* @param b <code>true</code> if the check box
* menu item is on, otherwise <code>false</code>
* @see #getState
*/
public synchronized void setState(boolean b) {
state = b;
CheckboxMenuItemPeer peer = (CheckboxMenuItemPeer)this.peer;
if (peer != null) {
peer.setState(b);
}
}
/**
* Returns the an array (length 1) containing the checkbox menu item
* label or null if the checkbox is not selected.
* @see ItemSelectable
*/
public synchronized Object[] getSelectedObjects() {
if (state) {
Object[] items = new Object[1];
items[0] = label;
return items;
}
return null;
}
/**
* Adds the specified item listener to receive item events from
* this check box menu item. Item events are sent in response to user
* actions, but not in response to calls to setState().
* If l is null, no exception is thrown and no action is performed.
* <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
* >AWT Threading Issues</a> for details on AWT's threading model.
*
* @param l the item listener
* @see #removeItemListener
* @see #getItemListeners
* @see #setState
* @see java.awt.event.ItemEvent
* @see java.awt.event.ItemListener
* @since JDK1.1
*/
public synchronized void addItemListener(ItemListener l) {
if (l == null) {
return;
}
itemListener = AWTEventMulticaster.add(itemListener, l);
newEventsOnly = true;
}
/**
* Removes the specified item listener so that it no longer receives
* item events from this check box menu item.
* If l is null, no exception is thrown and no action is performed.
* <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
* >AWT Threading Issues</a> for details on AWT's threading model.
*
* @param l the item listener
* @see #addItemListener
* @see #getItemListeners
* @see java.awt.event.ItemEvent
* @see java.awt.event.ItemListener
* @since JDK1.1
*/
public synchronized void removeItemListener(ItemListener l) {
if (l == null) {
return;
}
itemListener = AWTEventMulticaster.remove(itemListener, l);
}
/**
* Returns an array of all the item listeners
* registered on this checkbox menuitem.
*
* @return all of this checkbox menuitem's <code>ItemListener</code>s
* or an empty array if no item
* listeners are currently registered
*
* @see #addItemListener
* @see #removeItemListener
* @see java.awt.event.ItemEvent
* @see java.awt.event.ItemListener
* @since 1.4
*/
public synchronized ItemListener[] getItemListeners() {
return getListeners(ItemListener.class);
}
/**
* Returns an array of all the objects currently registered
* as <code><em>Foo</em>Listener</code>s
* upon this <code>CheckboxMenuItem</code>.
* <code><em>Foo</em>Listener</code>s are registered using the
* <code>add<em>Foo</em>Listener</code> method.
*
* <p>
* You can specify the <code>listenerType</code> argument
* with a class literal, such as
* <code><em>Foo</em>Listener.class</code>.
* For example, you can query a
* <code>CheckboxMenuItem</code> <code>c</code>
* for its item listeners with the following code:
*
* <pre>ItemListener[] ils = (ItemListener[])(c.getListeners(ItemListener.class));</pre>
*
* If no such listeners exist, this method returns an empty array.
*
* @param listenerType the type of listeners requested; this parameter
* should specify an interface that descends from
* <code>java.util.EventListener</code>
* @return an array of all objects registered as
* <code><em>Foo</em>Listener</code>s on this checkbox menuitem,
* or an empty array if no such
* listeners have been added
* @exception ClassCastException if <code>listenerType</code>
* doesn't specify a class or interface that implements
* <code>java.util.EventListener</code>
*
* @see #getItemListeners
* @since 1.3
*/
public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
EventListener l = null;
if (listenerType == ItemListener.class) {
l = itemListener;
} else {
return super.getListeners(listenerType);
}
return AWTEventMulticaster.getListeners(l, listenerType);
}
// REMIND: remove when filtering is done at lower level
boolean eventEnabled(AWTEvent e) {
if (e.id == ItemEvent.ITEM_STATE_CHANGED) {
if ((eventMask & AWTEvent.ITEM_EVENT_MASK) != 0 ||
itemListener != null) {
return true;
}
return false;
}
return super.eventEnabled(e);
}
/**
* Processes events on this check box menu item.
* If the event is an instance of <code>ItemEvent</code>,
* this method invokes the <code>processItemEvent</code> method.
* If the event is not an item event,
* it invokes <code>processEvent</code> on the superclass.
* <p>
* Check box menu items currently support only item events.
* <p>Note that if the event parameter is <code>null</code>
* the behavior is unspecified and may result in an
* exception.
*
* @param e the event
* @see java.awt.event.ItemEvent
* @see #processItemEvent
* @since JDK1.1
*/
protected void processEvent(AWTEvent e) {
if (e instanceof ItemEvent) {
processItemEvent((ItemEvent)e);
return;
}
super.processEvent(e);
}
/**
* Processes item events occurring on this check box menu item by
* dispatching them to any registered <code>ItemListener</code> objects.
* <p>
* This method is not called unless item events are
* enabled for this menu item. Item events are enabled
* when one of the following occurs:
* <ul>
* <li>An <code>ItemListener</code> object is registered
* via <code>addItemListener</code>.
* <li>Item events are enabled via <code>enableEvents</code>.
* </ul>
* <p>Note that if the event parameter is <code>null</code>
* the behavior is unspecified and may result in an
* exception.
*
* @param e the item event
* @see java.awt.event.ItemEvent
* @see java.awt.event.ItemListener
* @see #addItemListener
* @see java.awt.MenuItem#enableEvents
* @since JDK1.1
*/
protected void processItemEvent(ItemEvent e) {
ItemListener listener = itemListener;
if (listener != null) {
listener.itemStateChanged(e);
}
}
/*
* Post an ItemEvent and toggle state.
*/
void doMenuEvent(long when, int modifiers) {
setState(!state);
Toolkit.getEventQueue().postEvent(
new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED,
getLabel(),
state ? ItemEvent.SELECTED :
ItemEvent.DESELECTED));
}
/**
* Returns a string representing the state of this
* <code>CheckBoxMenuItem</code>. This
* method is intended to be used only for debugging purposes, and the
* content and format of the returned string may vary between
* implementations. The returned string may be empty but may not be
* <code>null</code>.
*
* @return the parameter string of this check box menu item
*/
public String paramString() {
return super.paramString() + ",state=" + state;
}
/* Serialization support.
*/
/*
* Serial Data Version
* @serial
*/
private int checkboxMenuItemSerializedDataVersion = 1;
/**
* Writes default serializable fields to stream. Writes
* a list of serializable <code>ItemListeners</code>
* as optional data. The non-serializable
* <code>ItemListeners</code> are detected and
* no attempt is made to serialize them.
*
* @param s the <code>ObjectOutputStream</code> to write
* @serialData <code>null</code> terminated sequence of
* 0 or more pairs; the pair consists of a <code>String</code>
* and an <code>Object</code>; the <code>String</code> indicates
* the type of object and is one of the following:
* <code>itemListenerK</code> indicating an
* <code>ItemListener</code> object
*
* @see AWTEventMulticaster#save(ObjectOutputStream, String, EventListener)
* @see java.awt.Component#itemListenerK
* @see #readObject(ObjectInputStream)
*/
private void writeObject(ObjectOutputStream s)
throws java.io.IOException
{
s.defaultWriteObject();
AWTEventMulticaster.save(s, itemListenerK, itemListener);
s.writeObject(null);
}
/*
* Reads the <code>ObjectInputStream</code> and if it
* isn't <code>null</code> adds a listener to receive
* item events fired by the <code>Checkbox</code> menu item.
* Unrecognized keys or values will be ignored.
*
* @param s the <code>ObjectInputStream</code> to read
* @serial
* @see removeActionListener()
* @see addActionListener()
* @see #writeObject
*/
private void readObject(ObjectInputStream s)
throws ClassNotFoundException, IOException
{
s.defaultReadObject();
Object keyOrNull;
while(null != (keyOrNull = s.readObject())) {
String key = ((String)keyOrNull).intern();
if (itemListenerK == key)
addItemListener((ItemListener)(s.readObject()));
else // skip value for unrecognized key
s.readObject();
}
}
/**
* Initialize JNI field and method IDs
*/
private static native void initIDs();
/////////////////
// Accessibility support
////////////////
/**
* Gets the AccessibleContext associated with this CheckboxMenuItem.
* For checkbox menu items, the AccessibleContext takes the
* form of an AccessibleAWTCheckboxMenuItem.
* A new AccessibleAWTCheckboxMenuItem is created if necessary.
*
* @return an AccessibleAWTCheckboxMenuItem that serves as the
* AccessibleContext of this CheckboxMenuItem
* @since 1.3
*/
public AccessibleContext getAccessibleContext() {
if (accessibleContext == null) {
accessibleContext = new AccessibleAWTCheckboxMenuItem();
}
return accessibleContext;
}
/**
* Inner class of CheckboxMenuItem used to provide default support for
* accessibility. This class is not meant to be used directly by
* application developers, but is instead meant only to be
* subclassed by menu component developers.
* <p>
* This class implements accessibility support for the
* <code>CheckboxMenuItem</code> class. It provides an implementation
* of the Java Accessibility API appropriate to checkbox menu item
* user-interface elements.
* @since 1.3
*/
protected class AccessibleAWTCheckboxMenuItem extends AccessibleAWTMenuItem
implements AccessibleAction, AccessibleValue
{
/*
* JDK 1.3 serialVersionUID
*/
private static final long serialVersionUID = -1122642964303476L;
/**
* Get the AccessibleAction associated with this object. In the
* implementation of the Java Accessibility API for this class,
* return this object, which is responsible for implementing the
* AccessibleAction interface on behalf of itself.
*
* @return this object
*/
public AccessibleAction getAccessibleAction() {
return this;
}
/**
* Get the AccessibleValue associated with this object. In the
* implementation of the Java Accessibility API for this class,
* return this object, which is responsible for implementing the
* AccessibleValue interface on behalf of itself.
*
* @return this object
*/
public AccessibleValue getAccessibleValue() {
return this;
}
/**
* Returns the number of Actions available in this object.
* If there is more than one, the first one is the "default"
* action.
*
* @return the number of Actions in this object
*/
public int getAccessibleActionCount() {
return 0; // To be fully implemented in a future release
}
/**
* Return a description of the specified action of the object.
*
* @param i zero-based index of the actions
*/
public String getAccessibleActionDescription(int i) {
return null; // To be fully implemented in a future release
}
/**
* Perform the specified Action on the object
*
* @param i zero-based index of actions
* @return true if the action was performed; otherwise false.
*/
public boolean doAccessibleAction(int i) {
return false; // To be fully implemented in a future release
}
/**
* Get the value of this object as a Number. If the value has not been
* set, the return value will be null.
*
* @return value of the object
* @see #setCurrentAccessibleValue
*/
public Number getCurrentAccessibleValue() {
return null; // To be fully implemented in a future release
}
/**
* Set the value of this object as a Number.
*
* @return true if the value was set; otherwise false
* @see #getCurrentAccessibleValue
*/
public boolean setCurrentAccessibleValue(Number n) {
return false; // To be fully implemented in a future release
}
/**
* Get the minimum value of this object as a Number.
*
* @return Minimum value of the object; null if this object does not
* have a minimum value
* @see #getMaximumAccessibleValue
*/
public Number getMinimumAccessibleValue() {
return null; // To be fully implemented in a future release
}
/**
* Get the maximum value of this object as a Number.
*
* @return Maximum value of the object; null if this object does not
* have a maximum value
* @see #getMinimumAccessibleValue
*/
public Number getMaximumAccessibleValue() {
return null; // To be fully implemented in a future release
}
/**
* Get the role of this object.
*
* @return an instance of AccessibleRole describing the role of the
* object
*/
public AccessibleRole getAccessibleRole() {
return AccessibleRole.CHECK_BOX;
}
} // class AccessibleAWTMenuItem
}

View File

@@ -0,0 +1,825 @@
/*
* Copyright (c) 1995, 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 java.awt;
import java.util.*;
import java.awt.peer.ChoicePeer;
import java.awt.event.*;
import java.util.EventListener;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.IOException;
import javax.accessibility.*;
/**
* The <code>Choice</code> class presents a pop-up menu of choices.
* The current choice is displayed as the title of the menu.
* <p>
* The following code example produces a pop-up menu:
*
* <hr><blockquote><pre>
* Choice ColorChooser = new Choice();
* ColorChooser.add("Green");
* ColorChooser.add("Red");
* ColorChooser.add("Blue");
* </pre></blockquote><hr>
* <p>
* After this choice menu has been added to a panel,
* it appears as follows in its normal state:
* <p>
* <img src="doc-files/Choice-1.gif" alt="The following text describes the graphic"
* style="float:center; margin: 7px 10px;">
* <p>
* In the picture, <code>"Green"</code> is the current choice.
* Pushing the mouse button down on the object causes a menu to
* appear with the current choice highlighted.
* <p>
* Some native platforms do not support arbitrary resizing of
* <code>Choice</code> components and the behavior of
* <code>setSize()/getSize()</code> is bound by
* such limitations.
* Native GUI <code>Choice</code> components' size are often bound by such
* attributes as font size and length of items contained within
* the <code>Choice</code>.
* <p>
* @author Sami Shaio
* @author Arthur van Hoff
* @since JDK1.0
*/
public class Choice extends Component implements ItemSelectable, Accessible {
/**
* The items for the <code>Choice</code>.
* This can be a <code>null</code> value.
* @serial
* @see #add(String)
* @see #addItem(String)
* @see #getItem(int)
* @see #getItemCount()
* @see #insert(String, int)
* @see #remove(String)
*/
Vector<String> pItems;
/**
* The index of the current choice for this <code>Choice</code>
* or -1 if nothing is selected.
* @serial
* @see #getSelectedItem()
* @see #select(int)
*/
int selectedIndex = -1;
transient ItemListener itemListener;
private static final String base = "choice";
private static int nameCounter = 0;
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = -4075310674757313071L;
static {
/* ensure that the necessary native libraries are loaded */
Toolkit.loadLibraries();
/* initialize JNI field and method ids */
if (!GraphicsEnvironment.isHeadless()) {
initIDs();
}
}
/**
* Creates a new choice menu. The menu initially has no items in it.
* <p>
* By default, the first item added to the choice menu becomes the
* selected item, until a different selection is made by the user
* by calling one of the <code>select</code> methods.
* @exception HeadlessException if GraphicsEnvironment.isHeadless()
* returns true
* @see java.awt.GraphicsEnvironment#isHeadless
* @see #select(int)
* @see #select(java.lang.String)
*/
public Choice() throws HeadlessException {
GraphicsEnvironment.checkHeadless();
pItems = new Vector<>();
}
/**
* Constructs a name for this component. Called by
* <code>getName</code> when the name is <code>null</code>.
*/
String constructComponentName() {
synchronized (Choice.class) {
return base + nameCounter++;
}
}
/**
* Creates the <code>Choice</code>'s peer. This peer allows us
* to change the look
* of the <code>Choice</code> without changing its functionality.
* @see java.awt.Toolkit#createChoice(java.awt.Choice)
* @see java.awt.Component#getToolkit()
*/
public void addNotify() {
synchronized (getTreeLock()) {
if (peer == null)
peer = getToolkit().createChoice(this);
super.addNotify();
}
}
/**
* Returns the number of items in this <code>Choice</code> menu.
* @return the number of items in this <code>Choice</code> menu
* @see #getItem
* @since JDK1.1
*/
public int getItemCount() {
return countItems();
}
/**
* @deprecated As of JDK version 1.1,
* replaced by <code>getItemCount()</code>.
*/
@Deprecated
public int countItems() {
return pItems.size();
}
/**
* Gets the string at the specified index in this
* <code>Choice</code> menu.
* @param index the index at which to begin
* @see #getItemCount
*/
public String getItem(int index) {
return getItemImpl(index);
}
/*
* This is called by the native code, so client code can't
* be called on the toolkit thread.
*/
final String getItemImpl(int index) {
return pItems.elementAt(index);
}
/**
* Adds an item to this <code>Choice</code> menu.
* @param item the item to be added
* @exception NullPointerException if the item's value is
* <code>null</code>
* @since JDK1.1
*/
public void add(String item) {
addItem(item);
}
/**
* Obsolete as of Java 2 platform v1.1. Please use the
* <code>add</code> method instead.
* <p>
* Adds an item to this <code>Choice</code> menu.
* @param item the item to be added
* @exception NullPointerException if the item's value is equal to
* <code>null</code>
*/
public void addItem(String item) {
synchronized (this) {
insertNoInvalidate(item, pItems.size());
}
// This could change the preferred size of the Component.
invalidateIfValid();
}
/**
* Inserts an item to this <code>Choice</code>,
* but does not invalidate the <code>Choice</code>.
* Client methods must provide their own synchronization before
* invoking this method.
* @param item the item to be added
* @param index the new item position
* @exception NullPointerException if the item's value is equal to
* <code>null</code>
*/
private void insertNoInvalidate(String item, int index) {
if (item == null) {
throw new
NullPointerException("cannot add null item to Choice");
}
pItems.insertElementAt(item, index);
ChoicePeer peer = (ChoicePeer)this.peer;
if (peer != null) {
peer.add(item, index);
}
// no selection or selection shifted up
if (selectedIndex < 0 || selectedIndex >= index) {
select(0);
}
}
/**
* Inserts the item into this choice at the specified position.
* Existing items at an index greater than or equal to
* <code>index</code> are shifted up by one to accommodate
* the new item. If <code>index</code> is greater than or
* equal to the number of items in this choice,
* <code>item</code> is added to the end of this choice.
* <p>
* If the item is the first one being added to the choice,
* then the item becomes selected. Otherwise, if the
* selected item was one of the items shifted, the first
* item in the choice becomes the selected item. If the
* selected item was no among those shifted, it remains
* the selected item.
* @param item the non-<code>null</code> item to be inserted
* @param index the position at which the item should be inserted
* @exception IllegalArgumentException if index is less than 0
*/
public void insert(String item, int index) {
synchronized (this) {
if (index < 0) {
throw new IllegalArgumentException("index less than zero.");
}
/* if the index greater than item count, add item to the end */
index = Math.min(index, pItems.size());
insertNoInvalidate(item, index);
}
// This could change the preferred size of the Component.
invalidateIfValid();
}
/**
* Removes the first occurrence of <code>item</code>
* from the <code>Choice</code> menu. If the item
* being removed is the currently selected item,
* then the first item in the choice becomes the
* selected item. Otherwise, the currently selected
* item remains selected (and the selected index is
* updated accordingly).
* @param item the item to remove from this <code>Choice</code> menu
* @exception IllegalArgumentException if the item doesn't
* exist in the choice menu
* @since JDK1.1
*/
public void remove(String item) {
synchronized (this) {
int index = pItems.indexOf(item);
if (index < 0) {
throw new IllegalArgumentException("item " + item +
" not found in choice");
} else {
removeNoInvalidate(index);
}
}
// This could change the preferred size of the Component.
invalidateIfValid();
}
/**
* Removes an item from the choice menu
* at the specified position. If the item
* being removed is the currently selected item,
* then the first item in the choice becomes the
* selected item. Otherwise, the currently selected
* item remains selected (and the selected index is
* updated accordingly).
* @param position the position of the item
* @throws IndexOutOfBoundsException if the specified
* position is out of bounds
* @since JDK1.1
*/
public void remove(int position) {
synchronized (this) {
removeNoInvalidate(position);
}
// This could change the preferred size of the Component.
invalidateIfValid();
}
/**
* Removes an item from the <code>Choice</code> at the
* specified position, but does not invalidate the <code>Choice</code>.
* Client methods must provide their
* own synchronization before invoking this method.
* @param position the position of the item
*/
private void removeNoInvalidate(int position) {
pItems.removeElementAt(position);
ChoicePeer peer = (ChoicePeer)this.peer;
if (peer != null) {
peer.remove(position);
}
/* Adjust selectedIndex if selected item was removed. */
if (pItems.size() == 0) {
selectedIndex = -1;
} else if (selectedIndex == position) {
select(0);
} else if (selectedIndex > position) {
select(selectedIndex-1);
}
}
/**
* Removes all items from the choice menu.
* @see #remove
* @since JDK1.1
*/
public void removeAll() {
synchronized (this) {
if (peer != null) {
((ChoicePeer)peer).removeAll();
}
pItems.removeAllElements();
selectedIndex = -1;
}
// This could change the preferred size of the Component.
invalidateIfValid();
}
/**
* Gets a representation of the current choice as a string.
* @return a string representation of the currently
* selected item in this choice menu
* @see #getSelectedIndex
*/
public synchronized String getSelectedItem() {
return (selectedIndex >= 0) ? getItem(selectedIndex) : null;
}
/**
* Returns an array (length 1) containing the currently selected
* item. If this choice has no items, returns <code>null</code>.
* @see ItemSelectable
*/
public synchronized Object[] getSelectedObjects() {
if (selectedIndex >= 0) {
Object[] items = new Object[1];
items[0] = getItem(selectedIndex);
return items;
}
return null;
}
/**
* Returns the index of the currently selected item.
* If nothing is selected, returns -1.
*
* @return the index of the currently selected item, or -1 if nothing
* is currently selected
* @see #getSelectedItem
*/
public int getSelectedIndex() {
return selectedIndex;
}
/**
* Sets the selected item in this <code>Choice</code> menu to be the
* item at the specified position.
*
* <p>Note that this method should be primarily used to
* initially select an item in this component.
* Programmatically calling this method will <i>not</i> trigger
* an <code>ItemEvent</code>. The only way to trigger an
* <code>ItemEvent</code> is by user interaction.
*
* @param pos the position of the selected item
* @exception IllegalArgumentException if the specified
* position is greater than the
* number of items or less than zero
* @see #getSelectedItem
* @see #getSelectedIndex
*/
public synchronized void select(int pos) {
if ((pos >= pItems.size()) || (pos < 0)) {
throw new IllegalArgumentException("illegal Choice item position: " + pos);
}
if (pItems.size() > 0) {
selectedIndex = pos;
ChoicePeer peer = (ChoicePeer)this.peer;
if (peer != null) {
peer.select(pos);
}
}
}
/**
* Sets the selected item in this <code>Choice</code> menu
* to be the item whose name is equal to the specified string.
* If more than one item matches (is equal to) the specified string,
* the one with the smallest index is selected.
*
* <p>Note that this method should be primarily used to
* initially select an item in this component.
* Programmatically calling this method will <i>not</i> trigger
* an <code>ItemEvent</code>. The only way to trigger an
* <code>ItemEvent</code> is by user interaction.
*
* @param str the specified string
* @see #getSelectedItem
* @see #getSelectedIndex
*/
public synchronized void select(String str) {
int index = pItems.indexOf(str);
if (index >= 0) {
select(index);
}
}
/**
* Adds the specified item listener to receive item events from
* this <code>Choice</code> menu. Item events are sent in response
* to user input, but not in response to calls to <code>select</code>.
* If l is <code>null</code>, no exception is thrown and no action
* is performed.
* <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
* >AWT Threading Issues</a> for details on AWT's threading model.
* @param l the item listener
* @see #removeItemListener
* @see #getItemListeners
* @see #select
* @see java.awt.event.ItemEvent
* @see java.awt.event.ItemListener
* @since JDK1.1
*/
public synchronized void addItemListener(ItemListener l) {
if (l == null) {
return;
}
itemListener = AWTEventMulticaster.add(itemListener, l);
newEventsOnly = true;
}
/**
* Removes the specified item listener so that it no longer receives
* item events from this <code>Choice</code> menu.
* If l is <code>null</code>, no exception is thrown and no
* action is performed.
* <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
* >AWT Threading Issues</a> for details on AWT's threading model.
* @param l the item listener
* @see #addItemListener
* @see #getItemListeners
* @see java.awt.event.ItemEvent
* @see java.awt.event.ItemListener
* @since JDK1.1
*/
public synchronized void removeItemListener(ItemListener l) {
if (l == null) {
return;
}
itemListener = AWTEventMulticaster.remove(itemListener, l);
}
/**
* Returns an array of all the item listeners
* registered on this choice.
*
* @return all of this choice's <code>ItemListener</code>s
* or an empty array if no item
* listeners are currently registered
*
* @see #addItemListener
* @see #removeItemListener
* @see java.awt.event.ItemEvent
* @see java.awt.event.ItemListener
* @since 1.4
*/
public synchronized ItemListener[] getItemListeners() {
return getListeners(ItemListener.class);
}
/**
* Returns an array of all the objects currently registered
* as <code><em>Foo</em>Listener</code>s
* upon this <code>Choice</code>.
* <code><em>Foo</em>Listener</code>s are registered using the
* <code>add<em>Foo</em>Listener</code> method.
*
* <p>
* You can specify the <code>listenerType</code> argument
* with a class literal, such as
* <code><em>Foo</em>Listener.class</code>.
* For example, you can query a
* <code>Choice</code> <code>c</code>
* for its item listeners with the following code:
*
* <pre>ItemListener[] ils = (ItemListener[])(c.getListeners(ItemListener.class));</pre>
*
* If no such listeners exist, this method returns an empty array.
*
* @param listenerType the type of listeners requested; this parameter
* should specify an interface that descends from
* <code>java.util.EventListener</code>
* @return an array of all objects registered as
* <code><em>Foo</em>Listener</code>s on this choice,
* or an empty array if no such
* listeners have been added
* @exception ClassCastException if <code>listenerType</code>
* doesn't specify a class or interface that implements
* <code>java.util.EventListener</code>
*
* @see #getItemListeners
* @since 1.3
*/
public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
EventListener l = null;
if (listenerType == ItemListener.class) {
l = itemListener;
} else {
return super.getListeners(listenerType);
}
return AWTEventMulticaster.getListeners(l, listenerType);
}
// REMIND: remove when filtering is done at lower level
boolean eventEnabled(AWTEvent e) {
if (e.id == ItemEvent.ITEM_STATE_CHANGED) {
if ((eventMask & AWTEvent.ITEM_EVENT_MASK) != 0 ||
itemListener != null) {
return true;
}
return false;
}
return super.eventEnabled(e);
}
/**
* Processes events on this choice. If the event is an
* instance of <code>ItemEvent</code>, it invokes the
* <code>processItemEvent</code> method. Otherwise, it calls its
* superclass's <code>processEvent</code> method.
* <p>Note that if the event parameter is <code>null</code>
* the behavior is unspecified and may result in an
* exception.
*
* @param e the event
* @see java.awt.event.ItemEvent
* @see #processItemEvent
* @since JDK1.1
*/
protected void processEvent(AWTEvent e) {
if (e instanceof ItemEvent) {
processItemEvent((ItemEvent)e);
return;
}
super.processEvent(e);
}
/**
* Processes item events occurring on this <code>Choice</code>
* menu by dispatching them to any registered
* <code>ItemListener</code> objects.
* <p>
* This method is not called unless item events are
* enabled for this component. Item events are enabled
* when one of the following occurs:
* <ul>
* <li>An <code>ItemListener</code> object is registered
* via <code>addItemListener</code>.
* <li>Item events are enabled via <code>enableEvents</code>.
* </ul>
* <p>Note that if the event parameter is <code>null</code>
* the behavior is unspecified and may result in an
* exception.
*
* @param e the item event
* @see java.awt.event.ItemEvent
* @see java.awt.event.ItemListener
* @see #addItemListener(ItemListener)
* @see java.awt.Component#enableEvents
* @since JDK1.1
*/
protected void processItemEvent(ItemEvent e) {
ItemListener listener = itemListener;
if (listener != null) {
listener.itemStateChanged(e);
}
}
/**
* Returns a string representing the state of this <code>Choice</code>
* menu. This method is intended to be used only for debugging purposes,
* and the content and format of the returned string may vary between
* implementations. The returned string may be empty but may not be
* <code>null</code>.
*
* @return the parameter string of this <code>Choice</code> menu
*/
protected String paramString() {
return super.paramString() + ",current=" + getSelectedItem();
}
/* Serialization support.
*/
/*
* Choice Serial Data Version.
* @serial
*/
private int choiceSerializedDataVersion = 1;
/**
* Writes default serializable fields to stream. Writes
* a list of serializable <code>ItemListeners</code>
* as optional data. The non-serializable
* <code>ItemListeners</code> are detected and
* no attempt is made to serialize them.
*
* @param s the <code>ObjectOutputStream</code> to write
* @serialData <code>null</code> terminated sequence of 0
* or more pairs; the pair consists of a <code>String</code>
* and an <code>Object</code>; the <code>String</code> indicates
* the type of object and is one of the following:
* <code>itemListenerK</code> indicating an
* <code>ItemListener</code> object
*
* @see AWTEventMulticaster#save(ObjectOutputStream, String, EventListener)
* @see java.awt.Component#itemListenerK
* @see #readObject(ObjectInputStream)
*/
private void writeObject(ObjectOutputStream s)
throws java.io.IOException
{
s.defaultWriteObject();
AWTEventMulticaster.save(s, itemListenerK, itemListener);
s.writeObject(null);
}
/**
* Reads the <code>ObjectInputStream</code> and if it
* isn't <code>null</code> adds a listener to receive
* item events fired by the <code>Choice</code> item.
* Unrecognized keys or values will be ignored.
*
* @param s the <code>ObjectInputStream</code> to read
* @exception HeadlessException if
* <code>GraphicsEnvironment.isHeadless</code> returns
* <code>true</code>
* @serial
* @see #removeItemListener(ItemListener)
* @see #addItemListener(ItemListener)
* @see java.awt.GraphicsEnvironment#isHeadless
* @see #writeObject(ObjectOutputStream)
*/
private void readObject(ObjectInputStream s)
throws ClassNotFoundException, IOException, HeadlessException
{
GraphicsEnvironment.checkHeadless();
s.defaultReadObject();
Object keyOrNull;
while(null != (keyOrNull = s.readObject())) {
String key = ((String)keyOrNull).intern();
if (itemListenerK == key)
addItemListener((ItemListener)(s.readObject()));
else // skip value for unrecognized key
s.readObject();
}
}
/**
* Initialize JNI field and method IDs
*/
private static native void initIDs();
/////////////////
// Accessibility support
////////////////
/**
* Gets the <code>AccessibleContext</code> associated with this
* <code>Choice</code>. For <code>Choice</code> components,
* the <code>AccessibleContext</code> takes the form of an
* <code>AccessibleAWTChoice</code>. A new <code>AccessibleAWTChoice</code>
* instance is created if necessary.
*
* @return an <code>AccessibleAWTChoice</code> that serves as the
* <code>AccessibleContext</code> of this <code>Choice</code>
* @since 1.3
*/
public AccessibleContext getAccessibleContext() {
if (accessibleContext == null) {
accessibleContext = new AccessibleAWTChoice();
}
return accessibleContext;
}
/**
* This class implements accessibility support for the
* <code>Choice</code> class. It provides an implementation of the
* Java Accessibility API appropriate to choice user-interface elements.
* @since 1.3
*/
protected class AccessibleAWTChoice extends AccessibleAWTComponent
implements AccessibleAction
{
/*
* JDK 1.3 serialVersionUID
*/
private static final long serialVersionUID = 7175603582428509322L;
public AccessibleAWTChoice() {
super();
}
/**
* Get the AccessibleAction associated with this object. In the
* implementation of the Java Accessibility API for this class,
* return this object, which is responsible for implementing the
* AccessibleAction interface on behalf of itself.
*
* @return this object
* @see AccessibleAction
*/
public AccessibleAction getAccessibleAction() {
return this;
}
/**
* Get the role of this object.
*
* @return an instance of AccessibleRole describing the role of the
* object
* @see AccessibleRole
*/
public AccessibleRole getAccessibleRole() {
return AccessibleRole.COMBO_BOX;
}
/**
* Returns the number of accessible actions available in this object
* If there are more than one, the first one is considered the "default"
* action of the object.
*
* @return the zero-based number of Actions in this object
*/
public int getAccessibleActionCount() {
return 0; // To be fully implemented in a future release
}
/**
* Returns a description of the specified action of the object.
*
* @param i zero-based index of the actions
* @return a String description of the action
* @see #getAccessibleActionCount
*/
public String getAccessibleActionDescription(int i) {
return null; // To be fully implemented in a future release
}
/**
* Perform the specified Action on the object
*
* @param i zero-based index of actions
* @return true if the action was performed; otherwise false.
* @see #getAccessibleActionCount
*/
public boolean doAccessibleAction(int i) {
return false; // To be fully implemented in a future release
}
} // inner class AccessibleAWTChoice
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,83 @@
/*
* Copyright (c) 1997, 2007, 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 java.awt;
import java.awt.image.ColorModel;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import sun.awt.image.IntegerComponentRaster;
import java.util.Arrays;
class ColorPaintContext implements PaintContext {
int color;
WritableRaster savedTile;
protected ColorPaintContext(int color, ColorModel cm) {
this.color = color;
}
public void dispose() {
}
/*
* Returns the RGB value representing the color in the default sRGB
* {@link ColorModel}.
* (Bits 24-31 are alpha, 16-23 are red, 8-15 are green, 0-7 are
* blue).
* @return the RGB value of the color in the default sRGB
* <code>ColorModel</code>.
* @see java.awt.image.ColorModel#getRGBdefault
* @see #getRed
* @see #getGreen
* @see #getBlue
*/
int getRGB() {
return color;
}
public ColorModel getColorModel() {
return ColorModel.getRGBdefault();
}
public synchronized Raster getRaster(int x, int y, int w, int h) {
WritableRaster t = savedTile;
if (t == null || w > t.getWidth() || h > t.getHeight()) {
t = getColorModel().createCompatibleWritableRaster(w, h);
IntegerComponentRaster icr = (IntegerComponentRaster) t;
Arrays.fill(icr.getDataStorage(), color);
// Note - markDirty is probably unnecessary since icr is brand new
icr.markDirty();
if (w <= 64 && h <= 64) {
savedTile = t;
}
}
return t;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,202 @@
/*
* Copyright (c) 1998, 2006, 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.
*/
/*
* (C) Copyright IBM Corp. 1998 - All Rights Reserved
*
* The original version of this source code and documentation is copyrighted
* and owned by IBM, Inc. These materials are provided under terms of a
* License Agreement between IBM and Sun. This technology is protected by
* multiple US and International patents. This notice and attribution to IBM
* may not be removed.
*
*/
package java.awt;
import java.util.Locale;
import java.util.ResourceBundle;
/**
* The ComponentOrientation class encapsulates the language-sensitive
* orientation that is to be used to order the elements of a component
* or of text. It is used to reflect the differences in this ordering
* between Western alphabets, Middle Eastern (such as Hebrew), and Far
* Eastern (such as Japanese).
* <p>
* Fundamentally, this governs items (such as characters) which are laid out
* in lines, with the lines then laid out in a block. This also applies
* to items in a widget: for example, in a check box where the box is
* positioned relative to the text.
* <p>
* There are four different orientations used in modern languages
* as in the following table.<br>
* <pre>
* LT RT TL TR
* A B C C B A A D G G D A
* D E F F E D B E H H E B
* G H I I H G C F I I F C
* </pre><br>
* (In the header, the two-letter abbreviation represents the item direction
* in the first letter, and the line direction in the second. For example,
* LT means "items left-to-right, lines top-to-bottom",
* TL means "items top-to-bottom, lines left-to-right", and so on.)
* <p>
* The orientations are:
* <ul>
* <li>LT - Western Europe (optional for Japanese, Chinese, Korean)
* <li>RT - Middle East (Arabic, Hebrew)
* <li>TR - Japanese, Chinese, Korean
* <li>TL - Mongolian
* </ul>
* Components whose view and controller code depends on orientation
* should use the <code>isLeftToRight()</code> and
* <code>isHorizontal()</code> methods to
* determine their behavior. They should not include switch-like
* code that keys off of the constants, such as:
* <pre>
* if (orientation == LEFT_TO_RIGHT) {
* ...
* } else if (orientation == RIGHT_TO_LEFT) {
* ...
* } else {
* // Oops
* }
* </pre>
* This is unsafe, since more constants may be added in the future and
* since it is not guaranteed that orientation objects will be unique.
*/
public final class ComponentOrientation implements java.io.Serializable
{
/*
* serialVersionUID
*/
private static final long serialVersionUID = -4113291392143563828L;
// Internal constants used in the implementation
private static final int UNK_BIT = 1;
private static final int HORIZ_BIT = 2;
private static final int LTR_BIT = 4;
/**
* Items run left to right and lines flow top to bottom
* Examples: English, French.
*/
public static final ComponentOrientation LEFT_TO_RIGHT =
new ComponentOrientation(HORIZ_BIT|LTR_BIT);
/**
* Items run right to left and lines flow top to bottom
* Examples: Arabic, Hebrew.
*/
public static final ComponentOrientation RIGHT_TO_LEFT =
new ComponentOrientation(HORIZ_BIT);
/**
* Indicates that a component's orientation has not been set.
* To preserve the behavior of existing applications,
* isLeftToRight will return true for this value.
*/
public static final ComponentOrientation UNKNOWN =
new ComponentOrientation(HORIZ_BIT|LTR_BIT|UNK_BIT);
/**
* Are lines horizontal?
* This will return true for horizontal, left-to-right writing
* systems such as Roman.
*/
public boolean isHorizontal() {
return (orientation & HORIZ_BIT) != 0;
}
/**
* HorizontalLines: Do items run left-to-right?<br>
* Vertical Lines: Do lines run left-to-right?<br>
* This will return true for horizontal, left-to-right writing
* systems such as Roman.
*/
public boolean isLeftToRight() {
return (orientation & LTR_BIT) != 0;
}
/**
* Returns the orientation that is appropriate for the given locale.
* @param locale the specified locale
*/
public static ComponentOrientation getOrientation(Locale locale) {
// A more flexible implementation would consult a ResourceBundle
// to find the appropriate orientation. Until pluggable locales
// are introduced however, the flexiblity isn't really needed.
// So we choose efficiency instead.
String lang = locale.getLanguage();
if( "iw".equals(lang) || "ar".equals(lang)
|| "fa".equals(lang) || "ur".equals(lang) )
{
return RIGHT_TO_LEFT;
} else {
return LEFT_TO_RIGHT;
}
}
/**
* Returns the orientation appropriate for the given ResourceBundle's
* localization. Three approaches are tried, in the following order:
* <ol>
* <li>Retrieve a ComponentOrientation object from the ResourceBundle
* using the string "Orientation" as the key.
* <li>Use the ResourceBundle.getLocale to determine the bundle's
* locale, then return the orientation for that locale.
* <li>Return the default locale's orientation.
* </ol>
*
* @deprecated As of J2SE 1.4, use {@link #getOrientation(java.util.Locale)}.
*/
@Deprecated
public static ComponentOrientation getOrientation(ResourceBundle bdl)
{
ComponentOrientation result = null;
try {
result = (ComponentOrientation)bdl.getObject("Orientation");
}
catch (Exception e) {
}
if (result == null) {
result = getOrientation(bdl.getLocale());
}
if (result == null) {
result = getOrientation(Locale.getDefault());
}
return result;
}
private int orientation;
private ComponentOrientation(int value)
{
orientation = value;
}
}

View File

@@ -0,0 +1,86 @@
/*
* Copyright (c) 1997, 1998, 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 java.awt;
import java.awt.image.ColorModel;
/**
* The <code>Composite</code> interface, along with
* {@link CompositeContext}, defines the methods to compose a draw
* primitive with the underlying graphics area.
* After the <code>Composite</code> is set in the
* {@link Graphics2D} context, it combines a shape, text, or an image
* being rendered with the colors that have already been rendered
* according to pre-defined rules. The classes
* implementing this interface provide the rules and a method to create
* the context for a particular operation.
* <code>CompositeContext</code> is an environment used by the
* compositing operation, which is created by the <code>Graphics2D</code>
* prior to the start of the operation. <code>CompositeContext</code>
* contains private information and resources needed for a compositing
* operation. When the <code>CompositeContext</code> is no longer needed,
* the <code>Graphics2D</code> object disposes of it in order to reclaim
* resources allocated for the operation.
* <p>
* Instances of classes implementing <code>Composite</code> must be
* immutable because the <code>Graphics2D</code> does not clone
* these objects when they are set as an attribute with the
* <code>setComposite</code> method or when the <code>Graphics2D</code>
* object is cloned. This is to avoid undefined rendering behavior of
* <code>Graphics2D</code>, resulting from the modification of
* the <code>Composite</code> object after it has been set in the
* <code>Graphics2D</code> context.
* <p>
* Since this interface must expose the contents of pixels on the
* target device or image to potentially arbitrary code, the use of
* custom objects which implement this interface when rendering directly
* to a screen device is governed by the <code>readDisplayPixels</code>
* {@link AWTPermission}. The permission check will occur when such
* a custom object is passed to the <code>setComposite</code> method
* of a <code>Graphics2D</code> retrieved from a {@link Component}.
* @see AlphaComposite
* @see CompositeContext
* @see Graphics2D#setComposite
*/
public interface Composite {
/**
* Creates a context containing state that is used to perform
* the compositing operation. In a multi-threaded environment,
* several contexts can exist simultaneously for a single
* <code>Composite</code> object.
* @param srcColorModel the {@link ColorModel} of the source
* @param dstColorModel the <code>ColorModel</code> of the destination
* @param hints the hint that the context object uses to choose between
* rendering alternatives
* @return the <code>CompositeContext</code> object used to perform the
* compositing operation.
*/
public CompositeContext createContext(ColorModel srcColorModel,
ColorModel dstColorModel,
RenderingHints hints);
}

View File

@@ -0,0 +1,68 @@
/*
* Copyright (c) 1997, 1998, 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 java.awt;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
/**
* The <code>CompositeContext</code> interface defines the encapsulated
* and optimized environment for a compositing operation.
* <code>CompositeContext</code> objects maintain state for
* compositing operations. In a multi-threaded environment, several
* contexts can exist simultaneously for a single {@link Composite}
* object.
* @see Composite
*/
public interface CompositeContext {
/**
* Releases resources allocated for a context.
*/
public void dispose();
/**
* Composes the two source {@link Raster} objects and
* places the result in the destination
* {@link WritableRaster}. Note that the destination
* can be the same object as either the first or second
* source. Note that <code>dstIn</code> and
* <code>dstOut</code> must be compatible with the
* <code>dstColorModel</code> passed to the
* {@link Composite#createContext(java.awt.image.ColorModel, java.awt.image.ColorModel, java.awt.RenderingHints) createContext}
* method of the <code>Composite</code> interface.
* @param src the first source for the compositing operation
* @param dstIn the second source for the compositing operation
* @param dstOut the <code>WritableRaster</code> into which the
* result of the operation is stored
* @see Composite
*/
public void compose(Raster src,
Raster dstIn,
WritableRaster dstOut);
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright (c) 1998, 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 java.awt;
/**
* Conditional is used by the EventDispatchThread's message pumps to
* determine if a given pump should continue to run, or should instead exit
* and yield control to the parent pump.
*
* @author David Mendenhall
*/
interface Conditional {
boolean evaluate();
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,605 @@
/*
* Copyright (c) 2000, 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 java.awt;
import java.util.List;
import java.util.ArrayList;
import sun.util.logging.PlatformLogger;
/**
* A FocusTraversalPolicy that determines traversal order based on the order
* of child Components in a Container. From a particular focus cycle root, the
* policy makes a pre-order traversal of the Component hierarchy, and traverses
* a Container's children according to the ordering of the array returned by
* <code>Container.getComponents()</code>. Portions of the hierarchy that are
* not visible and displayable will not be searched.
* <p>
* By default, ContainerOrderFocusTraversalPolicy implicitly transfers focus
* down-cycle. That is, during normal forward focus traversal, the Component
* traversed after a focus cycle root will be the focus-cycle-root's default
* Component to focus. This behavior can be disabled using the
* <code>setImplicitDownCycleTraversal</code> method.
* <p>
* By default, methods of this class will return a Component only if it is
* visible, displayable, enabled, and focusable. Subclasses can modify this
* behavior by overriding the <code>accept</code> method.
* <p>
* This policy takes into account <a
* href="doc-files/FocusSpec.html#FocusTraversalPolicyProviders">focus traversal
* policy providers</a>. When searching for first/last/next/previous Component,
* if a focus traversal policy provider is encountered, its focus traversal
* policy is used to perform the search operation.
*
* @author David Mendenhall
*
* @see Container#getComponents
* @since 1.4
*/
public class ContainerOrderFocusTraversalPolicy extends FocusTraversalPolicy
implements java.io.Serializable
{
private static final PlatformLogger log = PlatformLogger.getLogger("java.awt.ContainerOrderFocusTraversalPolicy");
final private int FORWARD_TRAVERSAL = 0;
final private int BACKWARD_TRAVERSAL = 1;
/*
* JDK 1.4 serialVersionUID
*/
private static final long serialVersionUID = 486933713763926351L;
private boolean implicitDownCycleTraversal = true;
/**
* Used by getComponentAfter and getComponentBefore for efficiency. In
* order to maintain compliance with the specification of
* FocusTraversalPolicy, if traversal wraps, we should invoke
* getFirstComponent or getLastComponent. These methods may be overriden in
* subclasses to behave in a non-generic way. However, in the generic case,
* these methods will simply return the first or last Components of the
* sorted list, respectively. Since getComponentAfter and
* getComponentBefore have already built the list before determining
* that they need to invoke getFirstComponent or getLastComponent, the
* list should be reused if possible.
*/
transient private Container cachedRoot;
transient private List<Component> cachedCycle;
/*
* We suppose to use getFocusTraversalCycle & getComponentIndex methods in order
* to divide the policy into two parts:
* 1) Making the focus traversal cycle.
* 2) Traversing the cycle.
* The 1st point assumes producing a list of components representing the focus
* traversal cycle. The two methods mentioned above should implement this logic.
* The 2nd point assumes implementing the common concepts of operating on the
* cycle: traversing back and forth, retrieving the initial/default/first/last
* component. These concepts are described in the AWT Focus Spec and they are
* applied to the FocusTraversalPolicy in general.
* Thus, a descendant of this policy may wish to not reimplement the logic of
* the 2nd point but just override the implementation of the 1st one.
* A striking example of such a descendant is the javax.swing.SortingFocusTraversalPolicy.
*/
/*protected*/ private List<Component> getFocusTraversalCycle(Container aContainer) {
List<Component> cycle = new ArrayList<Component>();
enumerateCycle(aContainer, cycle);
return cycle;
}
/*protected*/ private int getComponentIndex(List<Component> cycle, Component aComponent) {
return cycle.indexOf(aComponent);
}
private void enumerateCycle(Container container, List<Component> cycle) {
if (!(container.isVisible() && container.isDisplayable())) {
return;
}
cycle.add(container);
Component[] components = container.getComponents();
for (int i = 0; i < components.length; i++) {
Component comp = components[i];
if (comp instanceof Container) {
Container cont = (Container)comp;
if (!cont.isFocusCycleRoot() && !cont.isFocusTraversalPolicyProvider()) {
enumerateCycle(cont, cycle);
continue;
}
}
cycle.add(comp);
}
}
private Container getTopmostProvider(Container focusCycleRoot, Component aComponent) {
Container aCont = aComponent.getParent();
Container ftp = null;
while (aCont != focusCycleRoot && aCont != null) {
if (aCont.isFocusTraversalPolicyProvider()) {
ftp = aCont;
}
aCont = aCont.getParent();
}
if (aCont == null) {
return null;
}
return ftp;
}
/*
* Checks if a new focus cycle takes place and returns a Component to traverse focus to.
* @param comp a possible focus cycle root or policy provider
* @param traversalDirection the direction of the traversal
* @return a Component to traverse focus to if {@code comp} is a root or provider
* and implicit down-cycle is set, otherwise {@code null}
*/
private Component getComponentDownCycle(Component comp, int traversalDirection) {
Component retComp = null;
if (comp instanceof Container) {
Container cont = (Container)comp;
if (cont.isFocusCycleRoot()) {
if (getImplicitDownCycleTraversal()) {
retComp = cont.getFocusTraversalPolicy().getDefaultComponent(cont);
if (retComp != null && log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("### Transfered focus down-cycle to " + retComp +
" in the focus cycle root " + cont);
}
} else {
return null;
}
} else if (cont.isFocusTraversalPolicyProvider()) {
retComp = (traversalDirection == FORWARD_TRAVERSAL ?
cont.getFocusTraversalPolicy().getDefaultComponent(cont) :
cont.getFocusTraversalPolicy().getLastComponent(cont));
if (retComp != null && log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("### Transfered focus to " + retComp + " in the FTP provider " + cont);
}
}
}
return retComp;
}
/**
* Returns the Component that should receive the focus after aComponent.
* aContainer must be a focus cycle root of aComponent or a focus traversal policy provider.
* <p>
* By default, ContainerOrderFocusTraversalPolicy implicitly transfers
* focus down-cycle. That is, during normal forward focus traversal, the
* Component traversed after a focus cycle root will be the focus-cycle-
* root's default Component to focus. This behavior can be disabled using
* the <code>setImplicitDownCycleTraversal</code> method.
* <p>
* If aContainer is <a href="doc-files/FocusSpec.html#FocusTraversalPolicyProviders">focus
* traversal policy provider</a>, the focus is always transferred down-cycle.
*
* @param aContainer a focus cycle root of aComponent or a focus traversal policy provider
* @param aComponent a (possibly indirect) child of aContainer, or
* aContainer itself
* @return the Component that should receive the focus after aComponent, or
* null if no suitable Component can be found
* @throws IllegalArgumentException if aContainer is not a focus cycle
* root of aComponent or focus traversal policy provider, or if either aContainer or
* aComponent is null
*/
public Component getComponentAfter(Container aContainer, Component aComponent) {
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("### Searching in " + aContainer + " for component after " + aComponent);
}
if (aContainer == null || aComponent == null) {
throw new IllegalArgumentException("aContainer and aComponent cannot be null");
}
if (!aContainer.isFocusTraversalPolicyProvider() && !aContainer.isFocusCycleRoot()) {
throw new IllegalArgumentException("aContainer should be focus cycle root or focus traversal policy provider");
} else if (aContainer.isFocusCycleRoot() && !aComponent.isFocusCycleRoot(aContainer)) {
throw new IllegalArgumentException("aContainer is not a focus cycle root of aComponent");
}
synchronized(aContainer.getTreeLock()) {
if (!(aContainer.isVisible() && aContainer.isDisplayable())) {
return null;
}
// Before all the ckecks below we first see if it's an FTP provider or a focus cycle root.
// If it's the case just go down cycle (if it's set to "implicit").
Component comp = getComponentDownCycle(aComponent, FORWARD_TRAVERSAL);
if (comp != null) {
return comp;
}
// See if the component is inside of policy provider.
Container provider = getTopmostProvider(aContainer, aComponent);
if (provider != null) {
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("### Asking FTP " + provider + " for component after " + aComponent);
}
// FTP knows how to find component after the given. We don't.
FocusTraversalPolicy policy = provider.getFocusTraversalPolicy();
Component afterComp = policy.getComponentAfter(provider, aComponent);
// Null result means that we overstepped the limit of the FTP's cycle.
// In that case we must quit the cycle, otherwise return the component found.
if (afterComp != null) {
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("### FTP returned " + afterComp);
}
return afterComp;
}
aComponent = provider;
}
List<Component> cycle = getFocusTraversalCycle(aContainer);
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("### Cycle is " + cycle + ", component is " + aComponent);
}
int index = getComponentIndex(cycle, aComponent);
if (index < 0) {
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("### Didn't find component " + aComponent + " in a cycle " + aContainer);
}
return getFirstComponent(aContainer);
}
for (index++; index < cycle.size(); index++) {
comp = cycle.get(index);
if (accept(comp)) {
return comp;
} else if ((comp = getComponentDownCycle(comp, FORWARD_TRAVERSAL)) != null) {
return comp;
}
}
if (aContainer.isFocusCycleRoot()) {
this.cachedRoot = aContainer;
this.cachedCycle = cycle;
comp = getFirstComponent(aContainer);
this.cachedRoot = null;
this.cachedCycle = null;
return comp;
}
}
return null;
}
/**
* Returns the Component that should receive the focus before aComponent.
* aContainer must be a focus cycle root of aComponent or a <a
* href="doc-files/FocusSpec.html#FocusTraversalPolicyProviders">focus traversal policy
* provider</a>.
*
* @param aContainer a focus cycle root of aComponent or focus traversal policy provider
* @param aComponent a (possibly indirect) child of aContainer, or
* aContainer itself
* @return the Component that should receive the focus before aComponent,
* or null if no suitable Component can be found
* @throws IllegalArgumentException if aContainer is not a focus cycle
* root of aComponent or focus traversal policy provider, or if either aContainer or
* aComponent is null
*/
public Component getComponentBefore(Container aContainer, Component aComponent) {
if (aContainer == null || aComponent == null) {
throw new IllegalArgumentException("aContainer and aComponent cannot be null");
}
if (!aContainer.isFocusTraversalPolicyProvider() && !aContainer.isFocusCycleRoot()) {
throw new IllegalArgumentException("aContainer should be focus cycle root or focus traversal policy provider");
} else if (aContainer.isFocusCycleRoot() && !aComponent.isFocusCycleRoot(aContainer)) {
throw new IllegalArgumentException("aContainer is not a focus cycle root of aComponent");
}
synchronized(aContainer.getTreeLock()) {
if (!(aContainer.isVisible() && aContainer.isDisplayable())) {
return null;
}
// See if the component is inside of policy provider.
Container provider = getTopmostProvider(aContainer, aComponent);
if (provider != null) {
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("### Asking FTP " + provider + " for component after " + aComponent);
}
// FTP knows how to find component after the given. We don't.
FocusTraversalPolicy policy = provider.getFocusTraversalPolicy();
Component beforeComp = policy.getComponentBefore(provider, aComponent);
// Null result means that we overstepped the limit of the FTP's cycle.
// In that case we must quit the cycle, otherwise return the component found.
if (beforeComp != null) {
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("### FTP returned " + beforeComp);
}
return beforeComp;
}
aComponent = provider;
// If the provider is traversable it's returned.
if (accept(aComponent)) {
return aComponent;
}
}
List<Component> cycle = getFocusTraversalCycle(aContainer);
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("### Cycle is " + cycle + ", component is " + aComponent);
}
int index = getComponentIndex(cycle, aComponent);
if (index < 0) {
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("### Didn't find component " + aComponent + " in a cycle " + aContainer);
}
return getLastComponent(aContainer);
}
Component comp = null;
Component tryComp = null;
for (index--; index>=0; index--) {
comp = cycle.get(index);
if (comp != aContainer && (tryComp = getComponentDownCycle(comp, BACKWARD_TRAVERSAL)) != null) {
return tryComp;
} else if (accept(comp)) {
return comp;
}
}
if (aContainer.isFocusCycleRoot()) {
this.cachedRoot = aContainer;
this.cachedCycle = cycle;
comp = getLastComponent(aContainer);
this.cachedRoot = null;
this.cachedCycle = null;
return comp;
}
}
return null;
}
/**
* Returns the first Component in the traversal cycle. This method is used
* to determine the next Component to focus when traversal wraps in the
* forward direction.
*
* @param aContainer the focus cycle root or focus traversal policy provider whose first
* Component is to be returned
* @return the first Component in the traversal cycle of aContainer,
* or null if no suitable Component can be found
* @throws IllegalArgumentException if aContainer is null
*/
public Component getFirstComponent(Container aContainer) {
List<Component> cycle;
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("### Getting first component in " + aContainer);
}
if (aContainer == null) {
throw new IllegalArgumentException("aContainer cannot be null");
}
synchronized(aContainer.getTreeLock()) {
if (!(aContainer.isVisible() && aContainer.isDisplayable())) {
return null;
}
if (this.cachedRoot == aContainer) {
cycle = this.cachedCycle;
} else {
cycle = getFocusTraversalCycle(aContainer);
}
if (cycle.size() == 0) {
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("### Cycle is empty");
}
return null;
}
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("### Cycle is " + cycle);
}
for (Component comp : cycle) {
if (accept(comp)) {
return comp;
} else if (comp != aContainer &&
(comp = getComponentDownCycle(comp, FORWARD_TRAVERSAL)) != null)
{
return comp;
}
}
}
return null;
}
/**
* Returns the last Component in the traversal cycle. This method is used
* to determine the next Component to focus when traversal wraps in the
* reverse direction.
*
* @param aContainer the focus cycle root or focus traversal policy provider whose last
* Component is to be returned
* @return the last Component in the traversal cycle of aContainer,
* or null if no suitable Component can be found
* @throws IllegalArgumentException if aContainer is null
*/
public Component getLastComponent(Container aContainer) {
List<Component> cycle;
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("### Getting last component in " + aContainer);
}
if (aContainer == null) {
throw new IllegalArgumentException("aContainer cannot be null");
}
synchronized(aContainer.getTreeLock()) {
if (!(aContainer.isVisible() && aContainer.isDisplayable())) {
return null;
}
if (this.cachedRoot == aContainer) {
cycle = this.cachedCycle;
} else {
cycle = getFocusTraversalCycle(aContainer);
}
if (cycle.size() == 0) {
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("### Cycle is empty");
}
return null;
}
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("### Cycle is " + cycle);
}
for (int i= cycle.size() - 1; i >= 0; i--) {
Component comp = cycle.get(i);
if (accept(comp)) {
return comp;
} else if (comp instanceof Container && comp != aContainer) {
Container cont = (Container)comp;
if (cont.isFocusTraversalPolicyProvider()) {
Component retComp = cont.getFocusTraversalPolicy().getLastComponent(cont);
if (retComp != null) {
return retComp;
}
}
}
}
}
return null;
}
/**
* Returns the default Component to focus. This Component will be the first
* to receive focus when traversing down into a new focus traversal cycle
* rooted at aContainer. The default implementation of this method
* returns the same Component as <code>getFirstComponent</code>.
*
* @param aContainer the focus cycle root or focus traversal policy provider whose default
* Component is to be returned
* @return the default Component in the traversal cycle of aContainer,
* or null if no suitable Component can be found
* @see #getFirstComponent
* @throws IllegalArgumentException if aContainer is null
*/
public Component getDefaultComponent(Container aContainer) {
return getFirstComponent(aContainer);
}
/**
* Sets whether this ContainerOrderFocusTraversalPolicy transfers focus
* down-cycle implicitly. If <code>true</code>, during normal forward focus
* traversal, the Component traversed after a focus cycle root will be the
* focus-cycle-root's default Component to focus. If <code>false</code>,
* the next Component in the focus traversal cycle rooted at the specified
* focus cycle root will be traversed instead. The default value for this
* property is <code>true</code>.
*
* @param implicitDownCycleTraversal whether this
* ContainerOrderFocusTraversalPolicy transfers focus down-cycle
* implicitly
* @see #getImplicitDownCycleTraversal
* @see #getFirstComponent
*/
public void setImplicitDownCycleTraversal(boolean implicitDownCycleTraversal) {
this.implicitDownCycleTraversal = implicitDownCycleTraversal;
}
/**
* Returns whether this ContainerOrderFocusTraversalPolicy transfers focus
* down-cycle implicitly. If <code>true</code>, during normal forward focus
* traversal, the Component traversed after a focus cycle root will be the
* focus-cycle-root's default Component to focus. If <code>false</code>,
* the next Component in the focus traversal cycle rooted at the specified
* focus cycle root will be traversed instead.
*
* @return whether this ContainerOrderFocusTraversalPolicy transfers focus
* down-cycle implicitly
* @see #setImplicitDownCycleTraversal
* @see #getFirstComponent
*/
public boolean getImplicitDownCycleTraversal() {
return implicitDownCycleTraversal;
}
/**
* Determines whether a Component is an acceptable choice as the new
* focus owner. By default, this method will accept a Component if and
* only if it is visible, displayable, enabled, and focusable.
*
* @param aComponent the Component whose fitness as a focus owner is to
* be tested
* @return <code>true</code> if aComponent is visible, displayable,
* enabled, and focusable; <code>false</code> otherwise
*/
protected boolean accept(Component aComponent) {
if (!aComponent.canBeFocusOwner()) {
return false;
}
// Verify that the Component is recursively enabled. Disabling a
// heavyweight Container disables its children, whereas disabling
// a lightweight Container does not.
if (!(aComponent instanceof Window)) {
for (Container enableTest = aComponent.getParent();
enableTest != null;
enableTest = enableTest.getParent())
{
if (!(enableTest.isEnabled() || enableTest.isLightweight())) {
return false;
}
if (enableTest instanceof Window) {
break;
}
}
}
return true;
}
}

View File

@@ -0,0 +1,475 @@
/*
* Copyright (c) 1996, 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 java.awt;
import java.io.File;
import java.io.FileInputStream;
import java.beans.ConstructorProperties;
import java.util.Hashtable;
import java.util.Properties;
import java.util.StringTokenizer;
import java.security.AccessController;
import sun.util.logging.PlatformLogger;
import sun.awt.AWTAccessor;
/**
* A class to encapsulate the bitmap representation of the mouse cursor.
*
* @see Component#setCursor
* @author Amy Fowler
*/
public class Cursor implements java.io.Serializable {
/**
* The default cursor type (gets set if no cursor is defined).
*/
public static final int DEFAULT_CURSOR = 0;
/**
* The crosshair cursor type.
*/
public static final int CROSSHAIR_CURSOR = 1;
/**
* The text cursor type.
*/
public static final int TEXT_CURSOR = 2;
/**
* The wait cursor type.
*/
public static final int WAIT_CURSOR = 3;
/**
* The south-west-resize cursor type.
*/
public static final int SW_RESIZE_CURSOR = 4;
/**
* The south-east-resize cursor type.
*/
public static final int SE_RESIZE_CURSOR = 5;
/**
* The north-west-resize cursor type.
*/
public static final int NW_RESIZE_CURSOR = 6;
/**
* The north-east-resize cursor type.
*/
public static final int NE_RESIZE_CURSOR = 7;
/**
* The north-resize cursor type.
*/
public static final int N_RESIZE_CURSOR = 8;
/**
* The south-resize cursor type.
*/
public static final int S_RESIZE_CURSOR = 9;
/**
* The west-resize cursor type.
*/
public static final int W_RESIZE_CURSOR = 10;
/**
* The east-resize cursor type.
*/
public static final int E_RESIZE_CURSOR = 11;
/**
* The hand cursor type.
*/
public static final int HAND_CURSOR = 12;
/**
* The move cursor type.
*/
public static final int MOVE_CURSOR = 13;
/**
* @deprecated As of JDK version 1.7, the {@link #getPredefinedCursor(int)}
* method should be used instead.
*/
@Deprecated
protected static Cursor predefined[] = new Cursor[14];
/**
* This field is a private replacement for 'predefined' array.
*/
private final static Cursor[] predefinedPrivate = new Cursor[14];
/* Localization names and default values */
static final String[][] cursorProperties = {
{ "AWT.DefaultCursor", "Default Cursor" },
{ "AWT.CrosshairCursor", "Crosshair Cursor" },
{ "AWT.TextCursor", "Text Cursor" },
{ "AWT.WaitCursor", "Wait Cursor" },
{ "AWT.SWResizeCursor", "Southwest Resize Cursor" },
{ "AWT.SEResizeCursor", "Southeast Resize Cursor" },
{ "AWT.NWResizeCursor", "Northwest Resize Cursor" },
{ "AWT.NEResizeCursor", "Northeast Resize Cursor" },
{ "AWT.NResizeCursor", "North Resize Cursor" },
{ "AWT.SResizeCursor", "South Resize Cursor" },
{ "AWT.WResizeCursor", "West Resize Cursor" },
{ "AWT.EResizeCursor", "East Resize Cursor" },
{ "AWT.HandCursor", "Hand Cursor" },
{ "AWT.MoveCursor", "Move Cursor" },
};
/**
* The chosen cursor type initially set to
* the <code>DEFAULT_CURSOR</code>.
*
* @serial
* @see #getType()
*/
int type = DEFAULT_CURSOR;
/**
* The type associated with all custom cursors.
*/
public static final int CUSTOM_CURSOR = -1;
/*
* hashtable, filesystem dir prefix, filename, and properties for custom cursors support
*/
private static final Hashtable<String,Cursor> systemCustomCursors = new Hashtable<>(1);
private static final String systemCustomCursorDirPrefix = initCursorDir();
private static String initCursorDir() {
String jhome = java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction("java.home"));
return jhome +
File.separator + "lib" + File.separator + "images" +
File.separator + "cursors" + File.separator;
}
private static final String systemCustomCursorPropertiesFile = systemCustomCursorDirPrefix + "cursors.properties";
private static Properties systemCustomCursorProperties = null;
private static final String CursorDotPrefix = "Cursor.";
private static final String DotFileSuffix = ".File";
private static final String DotHotspotSuffix = ".HotSpot";
private static final String DotNameSuffix = ".Name";
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = 8028237497568985504L;
private static final PlatformLogger log = PlatformLogger.getLogger("java.awt.Cursor");
static {
/* ensure that the necessary native libraries are loaded */
Toolkit.loadLibraries();
if (!GraphicsEnvironment.isHeadless()) {
initIDs();
}
AWTAccessor.setCursorAccessor(
new AWTAccessor.CursorAccessor() {
public long getPData(Cursor cursor) {
return cursor.pData;
}
public void setPData(Cursor cursor, long pData) {
cursor.pData = pData;
}
public int getType(Cursor cursor) {
return cursor.type;
}
});
}
/**
* Initialize JNI field and method IDs for fields that may be
* accessed from C.
*/
private static native void initIDs();
/**
* Hook into native data.
*/
private transient long pData;
private transient Object anchor = new Object();
static class CursorDisposer implements sun.java2d.DisposerRecord {
volatile long pData;
public CursorDisposer(long pData) {
this.pData = pData;
}
public void dispose() {
if (pData != 0) {
finalizeImpl(pData);
}
}
}
transient CursorDisposer disposer;
private void setPData(long pData) {
this.pData = pData;
if (GraphicsEnvironment.isHeadless()) {
return;
}
if (disposer == null) {
disposer = new CursorDisposer(pData);
// anchor is null after deserialization
if (anchor == null) {
anchor = new Object();
}
sun.java2d.Disposer.addRecord(anchor, disposer);
} else {
disposer.pData = pData;
}
}
/**
* The user-visible name of the cursor.
*
* @serial
* @see #getName()
*/
protected String name;
/**
* Returns a cursor object with the specified predefined type.
*
* @param type the type of predefined cursor
* @return the specified predefined cursor
* @throws IllegalArgumentException if the specified cursor type is
* invalid
*/
static public Cursor getPredefinedCursor(int type) {
if (type < Cursor.DEFAULT_CURSOR || type > Cursor.MOVE_CURSOR) {
throw new IllegalArgumentException("illegal cursor type");
}
Cursor c = predefinedPrivate[type];
if (c == null) {
predefinedPrivate[type] = c = new Cursor(type);
}
// fill 'predefined' array for backwards compatibility.
if (predefined[type] == null) {
predefined[type] = c;
}
return c;
}
/**
* Returns a system-specific custom cursor object matching the
* specified name. Cursor names are, for example: "Invalid.16x16"
*
* @param name a string describing the desired system-specific custom cursor
* @return the system specific custom cursor named
* @exception HeadlessException if
* <code>GraphicsEnvironment.isHeadless</code> returns true
*/
static public Cursor getSystemCustomCursor(final String name)
throws AWTException, HeadlessException {
GraphicsEnvironment.checkHeadless();
Cursor cursor = systemCustomCursors.get(name);
if (cursor == null) {
synchronized(systemCustomCursors) {
if (systemCustomCursorProperties == null)
loadSystemCustomCursorProperties();
}
String prefix = CursorDotPrefix + name;
String key = prefix + DotFileSuffix;
if (!systemCustomCursorProperties.containsKey(key)) {
if (log.isLoggable(PlatformLogger.Level.FINER)) {
log.finer("Cursor.getSystemCustomCursor(" + name + ") returned null");
}
return null;
}
final String fileName =
systemCustomCursorProperties.getProperty(key);
String localized = systemCustomCursorProperties.getProperty(prefix + DotNameSuffix);
if (localized == null) localized = name;
String hotspot = systemCustomCursorProperties.getProperty(prefix + DotHotspotSuffix);
if (hotspot == null)
throw new AWTException("no hotspot property defined for cursor: " + name);
StringTokenizer st = new StringTokenizer(hotspot, ",");
if (st.countTokens() != 2)
throw new AWTException("failed to parse hotspot property for cursor: " + name);
int x = 0;
int y = 0;
try {
x = Integer.parseInt(st.nextToken());
y = Integer.parseInt(st.nextToken());
} catch (NumberFormatException nfe) {
throw new AWTException("failed to parse hotspot property for cursor: " + name);
}
try {
final int fx = x;
final int fy = y;
final String flocalized = localized;
cursor = java.security.AccessController.<Cursor>doPrivileged(
new java.security.PrivilegedExceptionAction<Cursor>() {
public Cursor run() throws Exception {
Toolkit toolkit = Toolkit.getDefaultToolkit();
Image image = toolkit.getImage(
systemCustomCursorDirPrefix + fileName);
return toolkit.createCustomCursor(
image, new Point(fx,fy), flocalized);
}
});
} catch (Exception e) {
throw new AWTException(
"Exception: " + e.getClass() + " " + e.getMessage() +
" occurred while creating cursor " + name);
}
if (cursor == null) {
if (log.isLoggable(PlatformLogger.Level.FINER)) {
log.finer("Cursor.getSystemCustomCursor(" + name + ") returned null");
}
} else {
systemCustomCursors.put(name, cursor);
}
}
return cursor;
}
/**
* Return the system default cursor.
*/
static public Cursor getDefaultCursor() {
return getPredefinedCursor(Cursor.DEFAULT_CURSOR);
}
/**
* Creates a new cursor object with the specified type.
* @param type the type of cursor
* @throws IllegalArgumentException if the specified cursor type
* is invalid
*/
@ConstructorProperties({"type"})
public Cursor(int type) {
if (type < Cursor.DEFAULT_CURSOR || type > Cursor.MOVE_CURSOR) {
throw new IllegalArgumentException("illegal cursor type");
}
this.type = type;
// Lookup localized name.
name = Toolkit.getProperty(cursorProperties[type][0],
cursorProperties[type][1]);
}
/**
* Creates a new custom cursor object with the specified name.<p>
* Note: this constructor should only be used by AWT implementations
* as part of their support for custom cursors. Applications should
* use Toolkit.createCustomCursor().
* @param name the user-visible name of the cursor.
* @see java.awt.Toolkit#createCustomCursor
*/
protected Cursor(String name) {
this.type = Cursor.CUSTOM_CURSOR;
this.name = name;
}
/**
* Returns the type for this cursor.
*/
public int getType() {
return type;
}
/**
* Returns the name of this cursor.
* @return a localized description of this cursor.
* @since 1.2
*/
public String getName() {
return name;
}
/**
* Returns a string representation of this cursor.
* @return a string representation of this cursor.
* @since 1.2
*/
public String toString() {
return getClass().getName() + "[" + getName() + "]";
}
/*
* load the cursor.properties file
*/
private static void loadSystemCustomCursorProperties() throws AWTException {
synchronized(systemCustomCursors) {
systemCustomCursorProperties = new Properties();
try {
AccessController.<Object>doPrivileged(
new java.security.PrivilegedExceptionAction<Object>() {
public Object run() throws Exception {
FileInputStream fis = null;
try {
fis = new FileInputStream(
systemCustomCursorPropertiesFile);
systemCustomCursorProperties.load(fis);
} finally {
if (fis != null)
fis.close();
}
return null;
}
});
} catch (Exception e) {
systemCustomCursorProperties = null;
throw new AWTException("Exception: " + e.getClass() + " " +
e.getMessage() + " occurred while loading: " +
systemCustomCursorPropertiesFile);
}
}
}
private native static void finalizeImpl(long pData);
}

View File

@@ -0,0 +1,128 @@
/*
* Copyright (c) 2000, 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 java.awt;
import java.awt.peer.ComponentPeer;
/**
* A FocusTraversalPolicy that determines traversal order based on the order
* of child Components in a Container. From a particular focus cycle root, the
* policy makes a pre-order traversal of the Component hierarchy, and traverses
* a Container's children according to the ordering of the array returned by
* <code>Container.getComponents()</code>. Portions of the hierarchy that are
* not visible and displayable will not be searched.
* <p>
* If client code has explicitly set the focusability of a Component by either
* overriding <code>Component.isFocusTraversable()</code> or
* <code>Component.isFocusable()</code>, or by calling
* <code>Component.setFocusable()</code>, then a DefaultFocusTraversalPolicy
* behaves exactly like a ContainerOrderFocusTraversalPolicy. If, however, the
* Component is relying on default focusability, then a
* DefaultFocusTraversalPolicy will reject all Components with non-focusable
* peers. This is the default FocusTraversalPolicy for all AWT Containers.
* <p>
* The focusability of a peer is implementation-dependent. Sun recommends that
* all implementations for a particular native platform construct peers with
* the same focusability. The recommendations for Windows and Unix are that
* Canvases, Labels, Panels, Scrollbars, ScrollPanes, Windows, and lightweight
* Components have non-focusable peers, and all other Components have focusable
* peers. These recommendations are used in the Sun AWT implementations. Note
* that the focusability of a Component's peer is different from, and does not
* impact, the focusability of the Component itself.
* <p>
* Please see
* <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
* How to Use the Focus Subsystem</a>,
* a section in <em>The Java Tutorial</em>, and the
* <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
* for more information.
*
* @author David Mendenhall
*
* @see Container#getComponents
* @see Component#isFocusable
* @see Component#setFocusable
* @since 1.4
*/
public class DefaultFocusTraversalPolicy
extends ContainerOrderFocusTraversalPolicy
{
/*
* serialVersionUID
*/
private static final long serialVersionUID = 8876966522510157497L;
/**
* Determines whether a Component is an acceptable choice as the new
* focus owner. The Component must be visible, displayable, and enabled
* to be accepted. If client code has explicitly set the focusability
* of the Component by either overriding
* <code>Component.isFocusTraversable()</code> or
* <code>Component.isFocusable()</code>, or by calling
* <code>Component.setFocusable()</code>, then the Component will be
* accepted if and only if it is focusable. If, however, the Component is
* relying on default focusability, then all Canvases, Labels, Panels,
* Scrollbars, ScrollPanes, Windows, and lightweight Components will be
* rejected.
*
* @param aComponent the Component whose fitness as a focus owner is to
* be tested
* @return <code>true</code> if aComponent meets the above requirements;
* <code>false</code> otherwise
*/
protected boolean accept(Component aComponent) {
if (!(aComponent.isVisible() && aComponent.isDisplayable() &&
aComponent.isEnabled()))
{
return false;
}
// Verify that the Component is recursively enabled. Disabling a
// heavyweight Container disables its children, whereas disabling
// a lightweight Container does not.
if (!(aComponent instanceof Window)) {
for (Container enableTest = aComponent.getParent();
enableTest != null;
enableTest = enableTest.getParent())
{
if (!(enableTest.isEnabled() || enableTest.isLightweight())) {
return false;
}
if (enableTest instanceof Window) {
break;
}
}
}
boolean focusable = aComponent.isFocusable();
if (aComponent.isFocusTraversableOverridden()) {
return focusable;
}
ComponentPeer peer = aComponent.getPeer();
return (peer != null && peer.isFocusable());
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,483 @@
/*
* Copyright (c) 2005, 2018, 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 java.awt;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URI;
import java.net.URL;
import java.net.MalformedURLException;
import java.awt.AWTPermission;
import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
import java.awt.peer.DesktopPeer;
import sun.awt.SunToolkit;
import sun.awt.HeadlessToolkit;
import java.io.FilePermission;
import sun.security.util.SecurityConstants;
/**
* The {@code Desktop} class allows a Java application to launch
* associated applications registered on the native desktop to handle
* a {@link java.net.URI} or a file.
*
* <p> Supported operations include:
* <ul>
* <li>launching the user-default browser to show a specified
* URI;</li>
* <li>launching the user-default mail client with an optional
* {@code mailto} URI;</li>
* <li>launching a registered application to open, edit or print a
* specified file.</li>
* </ul>
*
* <p> This class provides methods corresponding to these
* operations. The methods look for the associated application
* registered on the current platform, and launch it to handle a URI
* or file. If there is no associated application or the associated
* application fails to be launched, an exception is thrown.
*
* <p> An application is registered to a URI or file type; for
* example, the {@code "sxi"} file extension is typically registered
* to StarOffice. The mechanism of registering, accessing, and
* launching the associated application is platform-dependent.
*
* <p> Each operation is an action type represented by the {@link
* Desktop.Action} class.
*
* <p> Note: when some action is invoked and the associated
* application is executed, it will be executed on the same system as
* the one on which the Java application was launched.
*
* @since 1.6
* @author Armin Chen
* @author George Zhang
*/
public class Desktop {
/**
* Represents an action type. Each platform supports a different
* set of actions. You may use the {@link Desktop#isSupported}
* method to determine if the given action is supported by the
* current platform.
* @see java.awt.Desktop#isSupported(java.awt.Desktop.Action)
* @since 1.6
*/
public static enum Action {
/**
* Represents an "open" action.
* @see Desktop#open(java.io.File)
*/
OPEN,
/**
* Represents an "edit" action.
* @see Desktop#edit(java.io.File)
*/
EDIT,
/**
* Represents a "print" action.
* @see Desktop#print(java.io.File)
*/
PRINT,
/**
* Represents a "mail" action.
* @see Desktop#mail()
* @see Desktop#mail(java.net.URI)
*/
MAIL,
/**
* Represents a "browse" action.
* @see Desktop#browse(java.net.URI)
*/
BROWSE
};
private DesktopPeer peer;
/**
* Suppresses default constructor for noninstantiability.
*/
private Desktop() {
peer = Toolkit.getDefaultToolkit().createDesktopPeer(this);
}
/**
* Returns the <code>Desktop</code> instance of the current
* browser context. On some platforms the Desktop API may not be
* supported; use the {@link #isDesktopSupported} method to
* determine if the current desktop is supported.
* @return the Desktop instance of the current browser context
* @throws HeadlessException if {@link
* GraphicsEnvironment#isHeadless()} returns {@code true}
* @throws UnsupportedOperationException if this class is not
* supported on the current platform
* @see #isDesktopSupported()
* @see java.awt.GraphicsEnvironment#isHeadless
*/
public static synchronized Desktop getDesktop(){
if (GraphicsEnvironment.isHeadless()) throw new HeadlessException();
if (!Desktop.isDesktopSupported()) {
throw new UnsupportedOperationException("Desktop API is not " +
"supported on the current platform");
}
sun.awt.AppContext context = sun.awt.AppContext.getAppContext();
Desktop desktop = (Desktop)context.get(Desktop.class);
if (desktop == null) {
desktop = new Desktop();
context.put(Desktop.class, desktop);
}
return desktop;
}
/**
* Tests whether this class is supported on the current platform.
* If it's supported, use {@link #getDesktop()} to retrieve an
* instance.
*
* @return <code>true</code> if this class is supported on the
* current platform; <code>false</code> otherwise
* @see #getDesktop()
*/
public static boolean isDesktopSupported(){
Toolkit defaultToolkit = Toolkit.getDefaultToolkit();
if (defaultToolkit instanceof SunToolkit) {
return ((SunToolkit)defaultToolkit).isDesktopSupported();
}
return false;
}
/**
* Tests whether an action is supported on the current platform.
*
* <p>Even when the platform supports an action, a file or URI may
* not have a registered application for the action. For example,
* most of the platforms support the {@link Desktop.Action#OPEN}
* action. But for a specific file, there may not be an
* application registered to open it. In this case, {@link
* #isSupported} may return {@code true}, but the corresponding
* action method will throw an {@link IOException}.
*
* @param action the specified {@link Action}
* @return <code>true</code> if the specified action is supported on
* the current platform; <code>false</code> otherwise
* @see Desktop.Action
*/
public boolean isSupported(Action action) {
return peer.isSupported(action);
}
/**
* Checks if the file is a valid file and readable.
*
* @throws SecurityException If a security manager exists and its
* {@link SecurityManager#checkRead(java.lang.String)} method
* denies read access to the file
* @throws NullPointerException if file is null
* @throws IllegalArgumentException if file doesn't exist
*/
private static void checkFileValidation(File file) {
if (!file.exists()) {
throw new IllegalArgumentException("The file: "
+ file.getPath() + " doesn't exist.");
}
}
/**
* Checks if the action type is supported.
*
* @param actionType the action type in question
* @throws UnsupportedOperationException if the specified action type is not
* supported on the current platform
*/
private void checkActionSupport(Action actionType){
if (!isSupported(actionType)) {
throw new UnsupportedOperationException("The " + actionType.name()
+ " action is not supported on the current platform!");
}
}
/**
* Calls to the security manager's <code>checkPermission</code> method with
* an <code>AWTPermission("showWindowWithoutWarningBanner")</code>
* permission.
*/
private void checkAWTPermission(){
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new AWTPermission(
"showWindowWithoutWarningBanner"));
}
}
/**
* Launches the associated application to open the file.
*
* <p> If the specified file is a directory, the file manager of
* the current platform is launched to open it.
*
* @param file the file to be opened with the associated application
* @throws NullPointerException if {@code file} is {@code null}
* @throws IllegalArgumentException if the specified file doesn't
* exist
* @throws UnsupportedOperationException if the current platform
* does not support the {@link Desktop.Action#OPEN} action
* @throws IOException if the specified file has no associated
* application or the associated application fails to be launched
* @throws SecurityException if a security manager exists and its
* {@link java.lang.SecurityManager#checkRead(java.lang.String)}
* method denies read access to the file, or it denies the
* <code>AWTPermission("showWindowWithoutWarningBanner")</code>
* permission, or the calling thread is not allowed to create a
* subprocess
* @see java.awt.AWTPermission
*/
public void open(File file) throws IOException {
file = new File(file.getPath());
checkAWTPermission();
checkExec();
checkActionSupport(Action.OPEN);
checkFileValidation(file);
peer.open(file);
}
/**
* Launches the associated editor application and opens a file for
* editing.
*
* @param file the file to be opened for editing
* @throws NullPointerException if the specified file is {@code null}
* @throws IllegalArgumentException if the specified file doesn't
* exist
* @throws UnsupportedOperationException if the current platform
* does not support the {@link Desktop.Action#EDIT} action
* @throws IOException if the specified file has no associated
* editor, or the associated application fails to be launched
* @throws SecurityException if a security manager exists and its
* {@link java.lang.SecurityManager#checkRead(java.lang.String)}
* method denies read access to the file, or {@link
* java.lang.SecurityManager#checkWrite(java.lang.String)} method
* denies write access to the file, or it denies the
* <code>AWTPermission("showWindowWithoutWarningBanner")</code>
* permission, or the calling thread is not allowed to create a
* subprocess
* @see java.awt.AWTPermission
*/
public void edit(File file) throws IOException {
file = new File(file.getPath());
checkAWTPermission();
checkExec();
checkActionSupport(Action.EDIT);
file.canWrite();
checkFileValidation(file);
peer.edit(file);
}
/**
* Prints a file with the native desktop printing facility, using
* the associated application's print command.
*
* @param file the file to be printed
* @throws NullPointerException if the specified file is {@code
* null}
* @throws IllegalArgumentException if the specified file doesn't
* exist
* @throws UnsupportedOperationException if the current platform
* does not support the {@link Desktop.Action#PRINT} action
* @throws IOException if the specified file has no associated
* application that can be used to print it
* @throws SecurityException if a security manager exists and its
* {@link java.lang.SecurityManager#checkRead(java.lang.String)}
* method denies read access to the file, or its {@link
* java.lang.SecurityManager#checkPrintJobAccess()} method denies
* the permission to print the file, or the calling thread is not
* allowed to create a subprocess
*/
public void print(File file) throws IOException {
file = new File(file.getPath());
checkExec();
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPrintJobAccess();
}
checkActionSupport(Action.PRINT);
checkFileValidation(file);
peer.print(file);
}
/**
* Launches the default browser to display a {@code URI}.
* If the default browser is not able to handle the specified
* {@code URI}, the application registered for handling
* {@code URIs} of the specified type is invoked. The application
* is determined from the protocol and path of the {@code URI}, as
* defined by the {@code URI} class.
* <p>
* If the calling thread does not have the necessary permissions,
* and this is invoked from within an applet,
* {@code AppletContext.showDocument()} is used. Similarly, if the calling
* does not have the necessary permissions, and this is invoked from within
* a Java Web Started application, {@code BasicService.showDocument()}
* is used.
*
* @param uri the URI to be displayed in the user default browser
* @throws NullPointerException if {@code uri} is {@code null}
* @throws UnsupportedOperationException if the current platform
* does not support the {@link Desktop.Action#BROWSE} action
* @throws IOException if the user default browser is not found,
* or it fails to be launched, or the default handler application
* failed to be launched
* @throws SecurityException if a security manager exists and it
* denies the
* <code>AWTPermission("showWindowWithoutWarningBanner")</code>
* permission, or the calling thread is not allowed to create a
* subprocess; and not invoked from within an applet or Java Web Started
* application
* @throws IllegalArgumentException if the necessary permissions
* are not available and the URI can not be converted to a {@code URL}
* @see java.net.URI
* @see java.awt.AWTPermission
* @see java.applet.AppletContext
*/
public void browse(URI uri) throws IOException {
SecurityException securityException = null;
try {
checkAWTPermission();
checkExec();
} catch (SecurityException e) {
securityException = e;
}
checkActionSupport(Action.BROWSE);
if (uri == null) {
throw new NullPointerException();
}
if (securityException == null) {
peer.browse(uri);
return;
}
// Calling thread doesn't have necessary priviledges.
// Delegate to DesktopBrowse so that it can work in
// applet/webstart.
URL url = null;
try {
url = uri.toURL();
} catch (MalformedURLException e) {
throw new IllegalArgumentException("Unable to convert URI to URL", e);
}
sun.awt.DesktopBrowse db = sun.awt.DesktopBrowse.getInstance();
if (db == null) {
// Not in webstart/applet, throw the exception.
throw securityException;
}
db.browse(url);
}
/**
* Launches the mail composing window of the user default mail
* client.
*
* @throws UnsupportedOperationException if the current platform
* does not support the {@link Desktop.Action#MAIL} action
* @throws IOException if the user default mail client is not
* found, or it fails to be launched
* @throws SecurityException if a security manager exists and it
* denies the
* <code>AWTPermission("showWindowWithoutWarningBanner")</code>
* permission, or the calling thread is not allowed to create a
* subprocess
* @see java.awt.AWTPermission
*/
public void mail() throws IOException {
checkAWTPermission();
checkExec();
checkActionSupport(Action.MAIL);
URI mailtoURI = null;
try{
mailtoURI = new URI("mailto:?");
peer.mail(mailtoURI);
} catch (URISyntaxException e){
// won't reach here.
}
}
/**
* Launches the mail composing window of the user default mail
* client, filling the message fields specified by a {@code
* mailto:} URI.
*
* <p> A <code>mailto:</code> URI can specify message fields
* including <i>"to"</i>, <i>"cc"</i>, <i>"subject"</i>,
* <i>"body"</i>, etc. See <a
* href="http://www.ietf.org/rfc/rfc2368.txt">The mailto URL
* scheme (RFC 2368)</a> for the {@code mailto:} URI specification
* details.
*
* @param mailtoURI the specified {@code mailto:} URI
* @throws NullPointerException if the specified URI is {@code
* null}
* @throws IllegalArgumentException if the URI scheme is not
* <code>"mailto"</code>
* @throws UnsupportedOperationException if the current platform
* does not support the {@link Desktop.Action#MAIL} action
* @throws IOException if the user default mail client is not
* found or fails to be launched
* @throws SecurityException if a security manager exists and it
* denies the
* <code>AWTPermission("showWindowWithoutWarningBanner")</code>
* permission, or the calling thread is not allowed to create a
* subprocess
* @see java.net.URI
* @see java.awt.AWTPermission
*/
public void mail(URI mailtoURI) throws IOException {
checkAWTPermission();
checkExec();
checkActionSupport(Action.MAIL);
if (mailtoURI == null) throw new NullPointerException();
if (!"mailto".equalsIgnoreCase(mailtoURI.getScheme())) {
throw new IllegalArgumentException("URI scheme is not \"mailto\"");
}
peer.mail(mailtoURI);
}
private void checkExec() throws SecurityException {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new FilePermission("<<ALL FILES>>",
SecurityConstants.FILE_EXECUTE_ACTION));
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,239 @@
/*
* Copyright (c) 1995, 2008, 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 java.awt;
import java.awt.geom.Dimension2D;
import java.beans.Transient;
/**
* The <code>Dimension</code> class encapsulates the width and
* height of a component (in integer precision) in a single object.
* The class is
* associated with certain properties of components. Several methods
* defined by the <code>Component</code> class and the
* <code>LayoutManager</code> interface return a
* <code>Dimension</code> object.
* <p>
* Normally the values of <code>width</code>
* and <code>height</code> are non-negative integers.
* The constructors that allow you to create a dimension do
* not prevent you from setting a negative value for these properties.
* If the value of <code>width</code> or <code>height</code> is
* negative, the behavior of some methods defined by other objects is
* undefined.
*
* @author Sami Shaio
* @author Arthur van Hoff
* @see java.awt.Component
* @see java.awt.LayoutManager
* @since 1.0
*/
public class Dimension extends Dimension2D implements java.io.Serializable {
/**
* The width dimension; negative values can be used.
*
* @serial
* @see #getSize
* @see #setSize
* @since 1.0
*/
public int width;
/**
* The height dimension; negative values can be used.
*
* @serial
* @see #getSize
* @see #setSize
* @since 1.0
*/
public int height;
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = 4723952579491349524L;
/**
* Initialize JNI field and method IDs
*/
private static native void initIDs();
static {
/* ensure that the necessary native libraries are loaded */
Toolkit.loadLibraries();
if (!GraphicsEnvironment.isHeadless()) {
initIDs();
}
}
/**
* Creates an instance of <code>Dimension</code> with a width
* of zero and a height of zero.
*/
public Dimension() {
this(0, 0);
}
/**
* Creates an instance of <code>Dimension</code> whose width
* and height are the same as for the specified dimension.
*
* @param d the specified dimension for the
* <code>width</code> and
* <code>height</code> values
*/
public Dimension(Dimension d) {
this(d.width, d.height);
}
/**
* Constructs a <code>Dimension</code> and initializes
* it to the specified width and specified height.
*
* @param width the specified width
* @param height the specified height
*/
public Dimension(int width, int height) {
this.width = width;
this.height = height;
}
/**
* {@inheritDoc}
* @since 1.2
*/
public double getWidth() {
return width;
}
/**
* {@inheritDoc}
* @since 1.2
*/
public double getHeight() {
return height;
}
/**
* Sets the size of this <code>Dimension</code> object to
* the specified width and height in double precision.
* Note that if <code>width</code> or <code>height</code>
* are larger than <code>Integer.MAX_VALUE</code>, they will
* be reset to <code>Integer.MAX_VALUE</code>.
*
* @param width the new width for the <code>Dimension</code> object
* @param height the new height for the <code>Dimension</code> object
* @since 1.2
*/
public void setSize(double width, double height) {
this.width = (int) Math.ceil(width);
this.height = (int) Math.ceil(height);
}
/**
* Gets the size of this <code>Dimension</code> object.
* This method is included for completeness, to parallel the
* <code>getSize</code> method defined by <code>Component</code>.
*
* @return the size of this dimension, a new instance of
* <code>Dimension</code> with the same width and height
* @see java.awt.Dimension#setSize
* @see java.awt.Component#getSize
* @since 1.1
*/
@Transient
public Dimension getSize() {
return new Dimension(width, height);
}
/**
* Sets the size of this <code>Dimension</code> object to the specified size.
* This method is included for completeness, to parallel the
* <code>setSize</code> method defined by <code>Component</code>.
* @param d the new size for this <code>Dimension</code> object
* @see java.awt.Dimension#getSize
* @see java.awt.Component#setSize
* @since 1.1
*/
public void setSize(Dimension d) {
setSize(d.width, d.height);
}
/**
* Sets the size of this <code>Dimension</code> object
* to the specified width and height.
* This method is included for completeness, to parallel the
* <code>setSize</code> method defined by <code>Component</code>.
*
* @param width the new width for this <code>Dimension</code> object
* @param height the new height for this <code>Dimension</code> object
* @see java.awt.Dimension#getSize
* @see java.awt.Component#setSize
* @since 1.1
*/
public void setSize(int width, int height) {
this.width = width;
this.height = height;
}
/**
* Checks whether two dimension objects have equal values.
*/
public boolean equals(Object obj) {
if (obj instanceof Dimension) {
Dimension d = (Dimension)obj;
return (width == d.width) && (height == d.height);
}
return false;
}
/**
* Returns the hash code for this <code>Dimension</code>.
*
* @return a hash code for this <code>Dimension</code>
*/
public int hashCode() {
int sum = width + height;
return sum * (sum + 1)/2 + width;
}
/**
* Returns a string representation of the values of this
* <code>Dimension</code> object's <code>height</code> and
* <code>width</code> fields. This method is intended to be used only
* for debugging purposes, and the content and format of the returned
* string may vary between implementations. The returned string may be
* empty but may not be <code>null</code>.
*
* @return a string representation of this <code>Dimension</code>
* object
*/
public String toString() {
return getClass().getName() + "[width=" + width + ",height=" + height + "]";
}
}

View File

@@ -0,0 +1,159 @@
/*
* Copyright (c) 2000, 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 java.awt;
import java.lang.annotation.Native;
/**
* The <code>DisplayMode</code> class encapsulates the bit depth, height,
* width, and refresh rate of a <code>GraphicsDevice</code>. The ability to
* change graphics device's display mode is platform- and
* configuration-dependent and may not always be available
* (see {@link GraphicsDevice#isDisplayChangeSupported}).
* <p>
* For more information on full-screen exclusive mode API, see the
* <a href="https://docs.oracle.com/javase/tutorial/extra/fullscreen/index.html">
* Full-Screen Exclusive Mode API Tutorial</a>.
*
* @see GraphicsDevice
* @see GraphicsDevice#isDisplayChangeSupported
* @see GraphicsDevice#getDisplayModes
* @see GraphicsDevice#setDisplayMode
* @author Michael Martak
* @since 1.4
*/
public final class DisplayMode {
private Dimension size;
private int bitDepth;
private int refreshRate;
/**
* Create a new display mode object with the supplied parameters.
* @param width the width of the display, in pixels
* @param height the height of the display, in pixels
* @param bitDepth the bit depth of the display, in bits per
* pixel. This can be <code>BIT_DEPTH_MULTI</code> if multiple
* bit depths are available.
* @param refreshRate the refresh rate of the display, in hertz.
* This can be <code>REFRESH_RATE_UNKNOWN</code> if the
* information is not available.
* @see #BIT_DEPTH_MULTI
* @see #REFRESH_RATE_UNKNOWN
*/
public DisplayMode(int width, int height, int bitDepth, int refreshRate) {
this.size = new Dimension(width, height);
this.bitDepth = bitDepth;
this.refreshRate = refreshRate;
}
/**
* Returns the height of the display, in pixels.
* @return the height of the display, in pixels
*/
public int getHeight() {
return size.height;
}
/**
* Returns the width of the display, in pixels.
* @return the width of the display, in pixels
*/
public int getWidth() {
return size.width;
}
/**
* Value of the bit depth if multiple bit depths are supported in this
* display mode.
* @see #getBitDepth
*/
@Native public final static int BIT_DEPTH_MULTI = -1;
/**
* Returns the bit depth of the display, in bits per pixel. This may be
* <code>BIT_DEPTH_MULTI</code> if multiple bit depths are supported in
* this display mode.
*
* @return the bit depth of the display, in bits per pixel.
* @see #BIT_DEPTH_MULTI
*/
public int getBitDepth() {
return bitDepth;
}
/**
* Value of the refresh rate if not known.
* @see #getRefreshRate
*/
@Native public final static int REFRESH_RATE_UNKNOWN = 0;
/**
* Returns the refresh rate of the display, in hertz. This may be
* <code>REFRESH_RATE_UNKNOWN</code> if the information is not available.
*
* @return the refresh rate of the display, in hertz.
* @see #REFRESH_RATE_UNKNOWN
*/
public int getRefreshRate() {
return refreshRate;
}
/**
* Returns whether the two display modes are equal.
* @return whether the two display modes are equal
*/
public boolean equals(DisplayMode dm) {
if (dm == null) {
return false;
}
return (getHeight() == dm.getHeight()
&& getWidth() == dm.getWidth()
&& getBitDepth() == dm.getBitDepth()
&& getRefreshRate() == dm.getRefreshRate());
}
/**
* {@inheritDoc}
*/
public boolean equals(Object dm) {
if (dm instanceof DisplayMode) {
return equals((DisplayMode)dm);
} else {
return false;
}
}
/**
* {@inheritDoc}
*/
public int hashCode() {
return getWidth() + getHeight() + getBitDepth() * 7
+ getRefreshRate() * 13;
}
}

View File

@@ -0,0 +1,879 @@
/*
* Copyright (c) 1995, 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 java.awt;
import java.awt.event.*;
import java.io.*;
/**
* <b>NOTE:</b> The <code>Event</code> class is obsolete and is
* available only for backwards compatibility. It has been replaced
* by the <code>AWTEvent</code> class and its subclasses.
* <p>
* <code>Event</code> is a platform-independent class that
* encapsulates events from the platform's Graphical User
* Interface in the Java&nbsp;1.0 event model. In Java&nbsp;1.1
* and later versions, the <code>Event</code> class is maintained
* only for backwards compatibility. The information in this
* class description is provided to assist programmers in
* converting Java&nbsp;1.0 programs to the new event model.
* <p>
* In the Java&nbsp;1.0 event model, an event contains an
* {@link Event#id} field
* that indicates what type of event it is and which other
* <code>Event</code> variables are relevant for the event.
* <p>
* For keyboard events, {@link Event#key}
* contains a value indicating which key was activated, and
* {@link Event#modifiers} contains the
* modifiers for that event. For the KEY_PRESS and KEY_RELEASE
* event ids, the value of <code>key</code> is the unicode
* character code for the key. For KEY_ACTION and
* KEY_ACTION_RELEASE, the value of <code>key</code> is
* one of the defined action-key identifiers in the
* <code>Event</code> class (<code>PGUP</code>,
* <code>PGDN</code>, <code>F1</code>, <code>F2</code>, etc).
*
* @author Sami Shaio
* @since JDK1.0
*/
public class Event implements java.io.Serializable {
private transient long data;
/* Modifier constants */
/**
* This flag indicates that the Shift key was down when the event
* occurred.
*/
public static final int SHIFT_MASK = 1 << 0;
/**
* This flag indicates that the Control key was down when the event
* occurred.
*/
public static final int CTRL_MASK = 1 << 1;
/**
* This flag indicates that the Meta key was down when the event
* occurred. For mouse events, this flag indicates that the right
* button was pressed or released.
*/
public static final int META_MASK = 1 << 2;
/**
* This flag indicates that the Alt key was down when
* the event occurred. For mouse events, this flag indicates that the
* middle mouse button was pressed or released.
*/
public static final int ALT_MASK = 1 << 3;
/* Action keys */
/**
* The Home key, a non-ASCII action key.
*/
public static final int HOME = 1000;
/**
* The End key, a non-ASCII action key.
*/
public static final int END = 1001;
/**
* The Page Up key, a non-ASCII action key.
*/
public static final int PGUP = 1002;
/**
* The Page Down key, a non-ASCII action key.
*/
public static final int PGDN = 1003;
/**
* The Up Arrow key, a non-ASCII action key.
*/
public static final int UP = 1004;
/**
* The Down Arrow key, a non-ASCII action key.
*/
public static final int DOWN = 1005;
/**
* The Left Arrow key, a non-ASCII action key.
*/
public static final int LEFT = 1006;
/**
* The Right Arrow key, a non-ASCII action key.
*/
public static final int RIGHT = 1007;
/**
* The F1 function key, a non-ASCII action key.
*/
public static final int F1 = 1008;
/**
* The F2 function key, a non-ASCII action key.
*/
public static final int F2 = 1009;
/**
* The F3 function key, a non-ASCII action key.
*/
public static final int F3 = 1010;
/**
* The F4 function key, a non-ASCII action key.
*/
public static final int F4 = 1011;
/**
* The F5 function key, a non-ASCII action key.
*/
public static final int F5 = 1012;
/**
* The F6 function key, a non-ASCII action key.
*/
public static final int F6 = 1013;
/**
* The F7 function key, a non-ASCII action key.
*/
public static final int F7 = 1014;
/**
* The F8 function key, a non-ASCII action key.
*/
public static final int F8 = 1015;
/**
* The F9 function key, a non-ASCII action key.
*/
public static final int F9 = 1016;
/**
* The F10 function key, a non-ASCII action key.
*/
public static final int F10 = 1017;
/**
* The F11 function key, a non-ASCII action key.
*/
public static final int F11 = 1018;
/**
* The F12 function key, a non-ASCII action key.
*/
public static final int F12 = 1019;
/**
* The Print Screen key, a non-ASCII action key.
*/
public static final int PRINT_SCREEN = 1020;
/**
* The Scroll Lock key, a non-ASCII action key.
*/
public static final int SCROLL_LOCK = 1021;
/**
* The Caps Lock key, a non-ASCII action key.
*/
public static final int CAPS_LOCK = 1022;
/**
* The Num Lock key, a non-ASCII action key.
*/
public static final int NUM_LOCK = 1023;
/**
* The Pause key, a non-ASCII action key.
*/
public static final int PAUSE = 1024;
/**
* The Insert key, a non-ASCII action key.
*/
public static final int INSERT = 1025;
/* Non-action keys */
/**
* The Enter key.
*/
public static final int ENTER = '\n';
/**
* The BackSpace key.
*/
public static final int BACK_SPACE = '\b';
/**
* The Tab key.
*/
public static final int TAB = '\t';
/**
* The Escape key.
*/
public static final int ESCAPE = 27;
/**
* The Delete key.
*/
public static final int DELETE = 127;
/* Base for all window events. */
private static final int WINDOW_EVENT = 200;
/**
* The user has asked the window manager to kill the window.
*/
public static final int WINDOW_DESTROY = 1 + WINDOW_EVENT;
/**
* The user has asked the window manager to expose the window.
*/
public static final int WINDOW_EXPOSE = 2 + WINDOW_EVENT;
/**
* The user has asked the window manager to iconify the window.
*/
public static final int WINDOW_ICONIFY = 3 + WINDOW_EVENT;
/**
* The user has asked the window manager to de-iconify the window.
*/
public static final int WINDOW_DEICONIFY = 4 + WINDOW_EVENT;
/**
* The user has asked the window manager to move the window.
*/
public static final int WINDOW_MOVED = 5 + WINDOW_EVENT;
/* Base for all keyboard events. */
private static final int KEY_EVENT = 400;
/**
* The user has pressed a normal key.
*/
public static final int KEY_PRESS = 1 + KEY_EVENT;
/**
* The user has released a normal key.
*/
public static final int KEY_RELEASE = 2 + KEY_EVENT;
/**
* The user has pressed a non-ASCII <em>action</em> key.
* The <code>key</code> field contains a value that indicates
* that the event occurred on one of the action keys, which
* comprise the 12 function keys, the arrow (cursor) keys,
* Page Up, Page Down, Home, End, Print Screen, Scroll Lock,
* Caps Lock, Num Lock, Pause, and Insert.
*/
public static final int KEY_ACTION = 3 + KEY_EVENT;
/**
* The user has released a non-ASCII <em>action</em> key.
* The <code>key</code> field contains a value that indicates
* that the event occurred on one of the action keys, which
* comprise the 12 function keys, the arrow (cursor) keys,
* Page Up, Page Down, Home, End, Print Screen, Scroll Lock,
* Caps Lock, Num Lock, Pause, and Insert.
*/
public static final int KEY_ACTION_RELEASE = 4 + KEY_EVENT;
/* Base for all mouse events. */
private static final int MOUSE_EVENT = 500;
/**
* The user has pressed the mouse button. The <code>ALT_MASK</code>
* flag indicates that the middle button has been pressed.
* The <code>META_MASK</code>flag indicates that the
* right button has been pressed.
* @see java.awt.Event#ALT_MASK
* @see java.awt.Event#META_MASK
*/
public static final int MOUSE_DOWN = 1 + MOUSE_EVENT;
/**
* The user has released the mouse button. The <code>ALT_MASK</code>
* flag indicates that the middle button has been released.
* The <code>META_MASK</code>flag indicates that the
* right button has been released.
* @see java.awt.Event#ALT_MASK
* @see java.awt.Event#META_MASK
*/
public static final int MOUSE_UP = 2 + MOUSE_EVENT;
/**
* The mouse has moved with no button pressed.
*/
public static final int MOUSE_MOVE = 3 + MOUSE_EVENT;
/**
* The mouse has entered a component.
*/
public static final int MOUSE_ENTER = 4 + MOUSE_EVENT;
/**
* The mouse has exited a component.
*/
public static final int MOUSE_EXIT = 5 + MOUSE_EVENT;
/**
* The user has moved the mouse with a button pressed. The
* <code>ALT_MASK</code> flag indicates that the middle
* button is being pressed. The <code>META_MASK</code> flag indicates
* that the right button is being pressed.
* @see java.awt.Event#ALT_MASK
* @see java.awt.Event#META_MASK
*/
public static final int MOUSE_DRAG = 6 + MOUSE_EVENT;
/* Scrolling events */
private static final int SCROLL_EVENT = 600;
/**
* The user has activated the <em>line up</em>
* area of a scroll bar.
*/
public static final int SCROLL_LINE_UP = 1 + SCROLL_EVENT;
/**
* The user has activated the <em>line down</em>
* area of a scroll bar.
*/
public static final int SCROLL_LINE_DOWN = 2 + SCROLL_EVENT;
/**
* The user has activated the <em>page up</em>
* area of a scroll bar.
*/
public static final int SCROLL_PAGE_UP = 3 + SCROLL_EVENT;
/**
* The user has activated the <em>page down</em>
* area of a scroll bar.
*/
public static final int SCROLL_PAGE_DOWN = 4 + SCROLL_EVENT;
/**
* The user has moved the bubble (thumb) in a scroll bar,
* moving to an "absolute" position, rather than to
* an offset from the last position.
*/
public static final int SCROLL_ABSOLUTE = 5 + SCROLL_EVENT;
/**
* The scroll begin event.
*/
public static final int SCROLL_BEGIN = 6 + SCROLL_EVENT;
/**
* The scroll end event.
*/
public static final int SCROLL_END = 7 + SCROLL_EVENT;
/* List Events */
private static final int LIST_EVENT = 700;
/**
* An item in a list has been selected.
*/
public static final int LIST_SELECT = 1 + LIST_EVENT;
/**
* An item in a list has been deselected.
*/
public static final int LIST_DESELECT = 2 + LIST_EVENT;
/* Misc Event */
private static final int MISC_EVENT = 1000;
/**
* This event indicates that the user wants some action to occur.
*/
public static final int ACTION_EVENT = 1 + MISC_EVENT;
/**
* A file loading event.
*/
public static final int LOAD_FILE = 2 + MISC_EVENT;
/**
* A file saving event.
*/
public static final int SAVE_FILE = 3 + MISC_EVENT;
/**
* A component gained the focus.
*/
public static final int GOT_FOCUS = 4 + MISC_EVENT;
/**
* A component lost the focus.
*/
public static final int LOST_FOCUS = 5 + MISC_EVENT;
/**
* The target component. This indicates the component over which the
* event occurred or with which the event is associated.
* This object has been replaced by AWTEvent.getSource()
*
* @serial
* @see java.awt.AWTEvent#getSource()
*/
public Object target;
/**
* The time stamp.
* Replaced by InputEvent.getWhen().
*
* @serial
* @see java.awt.event.InputEvent#getWhen()
*/
public long when;
/**
* Indicates which type of event the event is, and which
* other <code>Event</code> variables are relevant for the event.
* This has been replaced by AWTEvent.getID()
*
* @serial
* @see java.awt.AWTEvent#getID()
*/
public int id;
/**
* The <i>x</i> coordinate of the event.
* Replaced by MouseEvent.getX()
*
* @serial
* @see java.awt.event.MouseEvent#getX()
*/
public int x;
/**
* The <i>y</i> coordinate of the event.
* Replaced by MouseEvent.getY()
*
* @serial
* @see java.awt.event.MouseEvent#getY()
*/
public int y;
/**
* The key code of the key that was pressed in a keyboard event.
* This has been replaced by KeyEvent.getKeyCode()
*
* @serial
* @see java.awt.event.KeyEvent#getKeyCode()
*/
public int key;
/**
* The key character that was pressed in a keyboard event.
*/
// public char keyChar;
/**
* The state of the modifier keys.
* This is replaced with InputEvent.getModifiers()
* In java 1.1 MouseEvent and KeyEvent are subclasses
* of InputEvent.
*
* @serial
* @see java.awt.event.InputEvent#getModifiers()
*/
public int modifiers;
/**
* For <code>MOUSE_DOWN</code> events, this field indicates the
* number of consecutive clicks. For other events, its value is
* <code>0</code>.
* This field has been replaced by MouseEvent.getClickCount().
*
* @serial
* @see java.awt.event.MouseEvent#getClickCount()
*/
public int clickCount;
/**
* An arbitrary argument of the event. The value of this field
* depends on the type of event.
* <code>arg</code> has been replaced by event specific property.
*
* @serial
*/
public Object arg;
/**
* The next event. This field is set when putting events into a
* linked list.
* This has been replaced by EventQueue.
*
* @serial
* @see java.awt.EventQueue
*/
public Event evt;
/* table for mapping old Event action keys to KeyEvent virtual keys. */
private static final int actionKeyCodes[][] = {
/* virtual key action key */
{ KeyEvent.VK_HOME, Event.HOME },
{ KeyEvent.VK_END, Event.END },
{ KeyEvent.VK_PAGE_UP, Event.PGUP },
{ KeyEvent.VK_PAGE_DOWN, Event.PGDN },
{ KeyEvent.VK_UP, Event.UP },
{ KeyEvent.VK_DOWN, Event.DOWN },
{ KeyEvent.VK_LEFT, Event.LEFT },
{ KeyEvent.VK_RIGHT, Event.RIGHT },
{ KeyEvent.VK_F1, Event.F1 },
{ KeyEvent.VK_F2, Event.F2 },
{ KeyEvent.VK_F3, Event.F3 },
{ KeyEvent.VK_F4, Event.F4 },
{ KeyEvent.VK_F5, Event.F5 },
{ KeyEvent.VK_F6, Event.F6 },
{ KeyEvent.VK_F7, Event.F7 },
{ KeyEvent.VK_F8, Event.F8 },
{ KeyEvent.VK_F9, Event.F9 },
{ KeyEvent.VK_F10, Event.F10 },
{ KeyEvent.VK_F11, Event.F11 },
{ KeyEvent.VK_F12, Event.F12 },
{ KeyEvent.VK_PRINTSCREEN, Event.PRINT_SCREEN },
{ KeyEvent.VK_SCROLL_LOCK, Event.SCROLL_LOCK },
{ KeyEvent.VK_CAPS_LOCK, Event.CAPS_LOCK },
{ KeyEvent.VK_NUM_LOCK, Event.NUM_LOCK },
{ KeyEvent.VK_PAUSE, Event.PAUSE },
{ KeyEvent.VK_INSERT, Event.INSERT }
};
/**
* This field controls whether or not the event is sent back
* down to the peer once the target has processed it -
* false means it's sent to the peer, true means it's not.
*
* @serial
* @see #isConsumed()
*/
private boolean consumed = false;
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = 5488922509400504703L;
static {
/* ensure that the necessary native libraries are loaded */
Toolkit.loadLibraries();
if (!GraphicsEnvironment.isHeadless()) {
initIDs();
}
}
/**
* Initialize JNI field and method IDs for fields that may be
accessed from C.
*/
private static native void initIDs();
/**
* <b>NOTE:</b> The <code>Event</code> class is obsolete and is
* available only for backwards compatibility. It has been replaced
* by the <code>AWTEvent</code> class and its subclasses.
* <p>
* Creates an instance of <code>Event</code> with the specified target
* component, time stamp, event type, <i>x</i> and <i>y</i>
* coordinates, keyboard key, state of the modifier keys, and
* argument.
* @param target the target component.
* @param when the time stamp.
* @param id the event type.
* @param x the <i>x</i> coordinate.
* @param y the <i>y</i> coordinate.
* @param key the key pressed in a keyboard event.
* @param modifiers the state of the modifier keys.
* @param arg the specified argument.
*/
public Event(Object target, long when, int id, int x, int y, int key,
int modifiers, Object arg) {
this.target = target;
this.when = when;
this.id = id;
this.x = x;
this.y = y;
this.key = key;
this.modifiers = modifiers;
this.arg = arg;
this.data = 0;
this.clickCount = 0;
switch(id) {
case ACTION_EVENT:
case WINDOW_DESTROY:
case WINDOW_ICONIFY:
case WINDOW_DEICONIFY:
case WINDOW_MOVED:
case SCROLL_LINE_UP:
case SCROLL_LINE_DOWN:
case SCROLL_PAGE_UP:
case SCROLL_PAGE_DOWN:
case SCROLL_ABSOLUTE:
case SCROLL_BEGIN:
case SCROLL_END:
case LIST_SELECT:
case LIST_DESELECT:
consumed = true; // these types are not passed back to peer
break;
default:
}
}
/**
* <b>NOTE:</b> The <code>Event</code> class is obsolete and is
* available only for backwards compatibility. It has been replaced
* by the <code>AWTEvent</code> class and its subclasses.
* <p>
* Creates an instance of <code>Event</code>, with the specified target
* component, time stamp, event type, <i>x</i> and <i>y</i>
* coordinates, keyboard key, state of the modifier keys, and an
* argument set to <code>null</code>.
* @param target the target component.
* @param when the time stamp.
* @param id the event type.
* @param x the <i>x</i> coordinate.
* @param y the <i>y</i> coordinate.
* @param key the key pressed in a keyboard event.
* @param modifiers the state of the modifier keys.
*/
public Event(Object target, long when, int id, int x, int y, int key, int modifiers) {
this(target, when, id, x, y, key, modifiers, null);
}
/**
* <b>NOTE:</b> The <code>Event</code> class is obsolete and is
* available only for backwards compatibility. It has been replaced
* by the <code>AWTEvent</code> class and its subclasses.
* <p>
* Creates an instance of <code>Event</code> with the specified
* target component, event type, and argument.
* @param target the target component.
* @param id the event type.
* @param arg the specified argument.
*/
public Event(Object target, int id, Object arg) {
this(target, 0, id, 0, 0, 0, 0, arg);
}
/**
* <b>NOTE:</b> The <code>Event</code> class is obsolete and is
* available only for backwards compatibility. It has been replaced
* by the <code>AWTEvent</code> class and its subclasses.
* <p>
* Translates this event so that its <i>x</i> and <i>y</i>
* coordinates are increased by <i>dx</i> and <i>dy</i>,
* respectively.
* <p>
* This method translates an event relative to the given component.
* This involves, at a minimum, translating the coordinates into the
* local coordinate system of the given component. It may also involve
* translating a region in the case of an expose event.
* @param dx the distance to translate the <i>x</i> coordinate.
* @param dy the distance to translate the <i>y</i> coordinate.
*/
public void translate(int dx, int dy) {
this.x += dx;
this.y += dy;
}
/**
* <b>NOTE:</b> The <code>Event</code> class is obsolete and is
* available only for backwards compatibility. It has been replaced
* by the <code>AWTEvent</code> class and its subclasses.
* <p>
* Checks if the Shift key is down.
* @return <code>true</code> if the key is down;
* <code>false</code> otherwise.
* @see java.awt.Event#modifiers
* @see java.awt.Event#controlDown
* @see java.awt.Event#metaDown
*/
public boolean shiftDown() {
return (modifiers & SHIFT_MASK) != 0;
}
/**
* <b>NOTE:</b> The <code>Event</code> class is obsolete and is
* available only for backwards compatibility. It has been replaced
* by the <code>AWTEvent</code> class and its subclasses.
* <p>
* Checks if the Control key is down.
* @return <code>true</code> if the key is down;
* <code>false</code> otherwise.
* @see java.awt.Event#modifiers
* @see java.awt.Event#shiftDown
* @see java.awt.Event#metaDown
*/
public boolean controlDown() {
return (modifiers & CTRL_MASK) != 0;
}
/**
* <b>NOTE:</b> The <code>Event</code> class is obsolete and is
* available only for backwards compatibility. It has been replaced
* by the <code>AWTEvent</code> class and its subclasses.
* <p>
* Checks if the Meta key is down.
*
* @return <code>true</code> if the key is down;
* <code>false</code> otherwise.
* @see java.awt.Event#modifiers
* @see java.awt.Event#shiftDown
* @see java.awt.Event#controlDown
*/
public boolean metaDown() {
return (modifiers & META_MASK) != 0;
}
/**
* <b>NOTE:</b> The <code>Event</code> class is obsolete and is
* available only for backwards compatibility. It has been replaced
* by the <code>AWTEvent</code> class and its subclasses.
*/
void consume() {
switch(id) {
case KEY_PRESS:
case KEY_RELEASE:
case KEY_ACTION:
case KEY_ACTION_RELEASE:
consumed = true;
break;
default:
// event type cannot be consumed
}
}
/**
* <b>NOTE:</b> The <code>Event</code> class is obsolete and is
* available only for backwards compatibility. It has been replaced
* by the <code>AWTEvent</code> class and its subclasses.
*/
boolean isConsumed() {
return consumed;
}
/*
* <b>NOTE:</b> The <code>Event</code> class is obsolete and is
* available only for backwards compatibility. It has been replaced
* by the <code>AWTEvent</code> class and its subclasses.
* <p>
* Returns the integer key-code associated with the key in this event,
* as described in java.awt.Event.
*/
static int getOldEventKey(KeyEvent e) {
int keyCode = e.getKeyCode();
for (int i = 0; i < actionKeyCodes.length; i++) {
if (actionKeyCodes[i][0] == keyCode) {
return actionKeyCodes[i][1];
}
}
return (int)e.getKeyChar();
}
/*
* <b>NOTE:</b> The <code>Event</code> class is obsolete and is
* available only for backwards compatibility. It has been replaced
* by the <code>AWTEvent</code> class and its subclasses.
* <p>
* Returns a new KeyEvent char which corresponds to the int key
* of this old event.
*/
char getKeyEventChar() {
for (int i = 0; i < actionKeyCodes.length; i++) {
if (actionKeyCodes[i][1] == key) {
return KeyEvent.CHAR_UNDEFINED;
}
}
return (char)key;
}
/**
* <b>NOTE:</b> The <code>Event</code> class is obsolete and is
* available only for backwards compatibility. It has been replaced
* by the <code>AWTEvent</code> class and its subclasses.
* <p>
* Returns a string representing the state of this <code>Event</code>.
* This method is intended to be used only for debugging purposes, and the
* content and format of the returned string may vary between
* implementations. The returned string may be empty but may not be
* <code>null</code>.
*
* @return the parameter string of this event
*/
protected String paramString() {
String str = "id=" + id + ",x=" + x + ",y=" + y;
if (key != 0) {
str += ",key=" + key;
}
if (shiftDown()) {
str += ",shift";
}
if (controlDown()) {
str += ",control";
}
if (metaDown()) {
str += ",meta";
}
if (target != null) {
str += ",target=" + target;
}
if (arg != null) {
str += ",arg=" + arg;
}
return str;
}
/**
* <b>NOTE:</b> The <code>Event</code> class is obsolete and is
* available only for backwards compatibility. It has been replaced
* by the <code>AWTEvent</code> class and its subclasses.
* <p>
* Returns a representation of this event's values as a string.
* @return a string that represents the event and the values
* of its member fields.
* @see java.awt.Event#paramString
* @since JDK1.1
*/
public String toString() {
return getClass().getName() + "[" + paramString() + "]";
}
}

View File

@@ -0,0 +1,296 @@
/*
* Copyright (c) 1996, 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 java.awt;
import java.awt.event.MouseEvent;
import java.awt.event.ActionEvent;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import sun.util.logging.PlatformLogger;
import sun.awt.dnd.SunDragSourceContextPeer;
import sun.awt.EventQueueDelegate;
/**
* EventDispatchThread is a package-private AWT class which takes
* events off the EventQueue and dispatches them to the appropriate
* AWT components.
*
* The Thread starts a "permanent" event pump with a call to
* pumpEvents(Conditional) in its run() method. Event handlers can choose to
* block this event pump at any time, but should start a new pump (<b>not</b>
* a new EventDispatchThread) by again calling pumpEvents(Conditional). This
* secondary event pump will exit automatically as soon as the Condtional
* evaluate()s to false and an additional Event is pumped and dispatched.
*
* @author Tom Ball
* @author Amy Fowler
* @author Fred Ecks
* @author David Mendenhall
*
* @since 1.1
*/
class EventDispatchThread extends Thread {
private static final PlatformLogger eventLog = PlatformLogger.getLogger("java.awt.event.EventDispatchThread");
private EventQueue theQueue;
private volatile boolean doDispatch = true;
private static final int ANY_EVENT = -1;
private ArrayList<EventFilter> eventFilters = new ArrayList<EventFilter>();
EventDispatchThread(ThreadGroup group, String name, EventQueue queue) {
super(group, name);
setEventQueue(queue);
}
/*
* Must be called on EDT only, that's why no synchronization
*/
public void stopDispatching() {
doDispatch = false;
}
public void run() {
try {
pumpEvents(new Conditional() {
public boolean evaluate() {
return true;
}
});
} finally {
getEventQueue().detachDispatchThread(this);
}
}
void pumpEvents(Conditional cond) {
pumpEvents(ANY_EVENT, cond);
}
void pumpEventsForHierarchy(Conditional cond, Component modalComponent) {
pumpEventsForHierarchy(ANY_EVENT, cond, modalComponent);
}
void pumpEvents(int id, Conditional cond) {
pumpEventsForHierarchy(id, cond, null);
}
void pumpEventsForHierarchy(int id, Conditional cond, Component modalComponent) {
pumpEventsForFilter(id, cond, new HierarchyEventFilter(modalComponent));
}
void pumpEventsForFilter(Conditional cond, EventFilter filter) {
pumpEventsForFilter(ANY_EVENT, cond, filter);
}
void pumpEventsForFilter(int id, Conditional cond, EventFilter filter) {
addEventFilter(filter);
doDispatch = true;
while (doDispatch && !isInterrupted() && cond.evaluate()) {
pumpOneEventForFilters(id);
}
removeEventFilter(filter);
}
void addEventFilter(EventFilter filter) {
if (eventLog.isLoggable(PlatformLogger.Level.FINEST)) {
eventLog.finest("adding the event filter: " + filter);
}
synchronized (eventFilters) {
if (!eventFilters.contains(filter)) {
if (filter instanceof ModalEventFilter) {
ModalEventFilter newFilter = (ModalEventFilter)filter;
int k = 0;
for (k = 0; k < eventFilters.size(); k++) {
EventFilter f = eventFilters.get(k);
if (f instanceof ModalEventFilter) {
ModalEventFilter cf = (ModalEventFilter)f;
if (cf.compareTo(newFilter) > 0) {
break;
}
}
}
eventFilters.add(k, filter);
} else {
eventFilters.add(filter);
}
}
}
}
void removeEventFilter(EventFilter filter) {
if (eventLog.isLoggable(PlatformLogger.Level.FINEST)) {
eventLog.finest("removing the event filter: " + filter);
}
synchronized (eventFilters) {
eventFilters.remove(filter);
}
}
boolean filterAndCheckEvent(AWTEvent event) {
boolean eventOK = true;
synchronized (eventFilters) {
for (int i = eventFilters.size() - 1; i >= 0; i--) {
EventFilter f = eventFilters.get(i);
EventFilter.FilterAction accept = f.acceptEvent(event);
if (accept == EventFilter.FilterAction.REJECT) {
eventOK = false;
break;
} else if (accept == EventFilter.FilterAction.ACCEPT_IMMEDIATELY) {
break;
}
}
}
return eventOK && SunDragSourceContextPeer.checkEvent(event);
}
void pumpOneEventForFilters(int id) {
AWTEvent event = null;
boolean eventOK = false;
try {
EventQueue eq = null;
EventQueueDelegate.Delegate delegate = null;
do {
// EventQueue may change during the dispatching
eq = getEventQueue();
delegate = EventQueueDelegate.getDelegate();
if (delegate != null && id == ANY_EVENT) {
event = delegate.getNextEvent(eq);
} else {
event = (id == ANY_EVENT) ? eq.getNextEvent() : eq.getNextEvent(id);
}
eventOK = filterAndCheckEvent(event);
if (!eventOK) {
event.consume();
}
}
while (eventOK == false);
if (eventLog.isLoggable(PlatformLogger.Level.FINEST)) {
eventLog.finest("Dispatching: " + event);
}
Object handle = null;
if (delegate != null) {
handle = delegate.beforeDispatch(event);
}
eq.dispatchEvent(event);
if (delegate != null) {
delegate.afterDispatch(event, handle);
}
}
catch (ThreadDeath death) {
doDispatch = false;
throw death;
}
catch (InterruptedException interruptedException) {
doDispatch = false; // AppContext.dispose() interrupts all
// Threads in the AppContext
}
catch (Throwable e) {
processException(e);
}
}
private void processException(Throwable e) {
if (eventLog.isLoggable(PlatformLogger.Level.FINE)) {
eventLog.fine("Processing exception: " + e);
}
getUncaughtExceptionHandler().uncaughtException(this, e);
}
public synchronized EventQueue getEventQueue() {
return theQueue;
}
public synchronized void setEventQueue(EventQueue eq) {
theQueue = eq;
}
private static class HierarchyEventFilter implements EventFilter {
private Component modalComponent;
public HierarchyEventFilter(Component modalComponent) {
this.modalComponent = modalComponent;
}
public FilterAction acceptEvent(AWTEvent event) {
if (modalComponent != null) {
int eventID = event.getID();
boolean mouseEvent = (eventID >= MouseEvent.MOUSE_FIRST) &&
(eventID <= MouseEvent.MOUSE_LAST);
boolean actionEvent = (eventID >= ActionEvent.ACTION_FIRST) &&
(eventID <= ActionEvent.ACTION_LAST);
boolean windowClosingEvent = (eventID == WindowEvent.WINDOW_CLOSING);
/*
* filter out MouseEvent and ActionEvent that's outside
* the modalComponent hierarchy.
* KeyEvent is handled by using enqueueKeyEvent
* in Dialog.show
*/
if (Component.isInstanceOf(modalComponent, "javax.swing.JInternalFrame")) {
/*
* Modal internal frames are handled separately. If event is
* for some component from another heavyweight than modalComp,
* it is accepted. If heavyweight is the same - we still accept
* event and perform further filtering in LightweightDispatcher
*/
return windowClosingEvent ? FilterAction.REJECT : FilterAction.ACCEPT;
}
if (mouseEvent || actionEvent || windowClosingEvent) {
Object o = event.getSource();
if (o instanceof sun.awt.ModalExclude) {
// Exclude this object from modality and
// continue to pump it's events.
return FilterAction.ACCEPT;
} else if (o instanceof Component) {
Component c = (Component) o;
// 5.0u3 modal exclusion
boolean modalExcluded = false;
if (modalComponent instanceof Container) {
while (c != modalComponent && c != null) {
if ((c instanceof Window) &&
(sun.awt.SunToolkit.isModalExcluded((Window)c))) {
// Exclude this window and all its children from
// modality and continue to pump it's events.
modalExcluded = true;
break;
}
c = c.getParent();
}
}
if (!modalExcluded && (c != modalComponent)) {
return FilterAction.REJECT;
}
}
}
}
return FilterAction.ACCEPT;
}
}
}

View File

@@ -0,0 +1,61 @@
/*
* Copyright (c) 2005, 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 java.awt;
interface EventFilter {
/**
* Enumeration for possible values for <code>acceptEvent(AWTEvent ev)</code> method.
* @see EventDispatchThread#pumpEventsForFilter
*/
static enum FilterAction {
/**
* ACCEPT means that this filter do not filter the event and allowes other
* active filters to proceed it. If all the active filters accept the event, it
* is dispatched by the <code>EventDispatchThread</code>
* @see EventDispatchThread#pumpEventsForFilter
*/
ACCEPT,
/**
* REJECT means that this filter filter the event. No other filters are queried,
* and the event is not dispatched by the <code>EventDispatchedThread</code>
* @see EventDispatchThread#pumpEventsForFilter
*/
REJECT,
/**
* ACCEPT_IMMEDIATELY means that this filter do not filter the event, no other
* filters are queried and to proceed it, and it is dispatched by the
* <code>EventDispatchThread</code>
* It is not recommended to use ACCEPT_IMMEDIATELY as there may be some active
* filters not queried yet that do not accept this event. It is primarily used
* by modal filters.
* @see EventDispatchThread#pumpEventsForFilter
* @see ModalEventFilter
*/
ACCEPT_IMMEDIATELY
};
FilterAction acceptEvent(AWTEvent ev);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,583 @@
/*
* Copyright (c) 1995, 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 java.awt;
import java.awt.peer.FileDialogPeer;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.File;
import sun.awt.AWTAccessor;
/**
* The <code>FileDialog</code> class displays a dialog window
* from which the user can select a file.
* <p>
* Since it is a modal dialog, when the application calls
* its <code>show</code> method to display the dialog,
* it blocks the rest of the application until the user has
* chosen a file.
*
* @see Window#show
*
* @author Sami Shaio
* @author Arthur van Hoff
* @since JDK1.0
*/
public class FileDialog extends Dialog {
/**
* This constant value indicates that the purpose of the file
* dialog window is to locate a file from which to read.
*/
public static final int LOAD = 0;
/**
* This constant value indicates that the purpose of the file
* dialog window is to locate a file to which to write.
*/
public static final int SAVE = 1;
/*
* There are two <code>FileDialog</code> modes: <code>LOAD</code> and
* <code>SAVE</code>.
* This integer will represent one or the other.
* If the mode is not specified it will default to <code>LOAD</code>.
*
* @serial
* @see getMode()
* @see setMode()
* @see java.awt.FileDialog#LOAD
* @see java.awt.FileDialog#SAVE
*/
int mode;
/*
* The string specifying the directory to display
* in the file dialog. This variable may be <code>null</code>.
*
* @serial
* @see getDirectory()
* @see setDirectory()
*/
String dir;
/*
* The string specifying the initial value of the
* filename text field in the file dialog.
* This variable may be <code>null</code>.
*
* @serial
* @see getFile()
* @see setFile()
*/
String file;
/**
* Contains the File instances for all the files that the user selects.
*
* @serial
* @see #getFiles
* @since 1.7
*/
private File[] files;
/**
* Represents whether the file dialog allows the multiple file selection.
*
* @serial
* @see #setMultipleMode
* @see #isMultipleMode
* @since 1.7
*/
private boolean multipleMode = false;
/*
* The filter used as the file dialog's filename filter.
* The file dialog will only be displaying files whose
* names are accepted by this filter.
* This variable may be <code>null</code>.
*
* @serial
* @see #getFilenameFilter()
* @see #setFilenameFilter()
* @see FileNameFilter
*/
FilenameFilter filter;
private static final String base = "filedlg";
private static int nameCounter = 0;
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = 5035145889651310422L;
static {
/* ensure that the necessary native libraries are loaded */
Toolkit.loadLibraries();
if (!GraphicsEnvironment.isHeadless()) {
initIDs();
}
}
static {
AWTAccessor.setFileDialogAccessor(
new AWTAccessor.FileDialogAccessor() {
public void setFiles(FileDialog fileDialog, File files[]) {
fileDialog.setFiles(files);
}
public void setFile(FileDialog fileDialog, String file) {
fileDialog.file = ("".equals(file)) ? null : file;
}
public void setDirectory(FileDialog fileDialog, String directory) {
fileDialog.dir = ("".equals(directory)) ? null : directory;
}
public boolean isMultipleMode(FileDialog fileDialog) {
synchronized (fileDialog.getObjectLock()) {
return fileDialog.multipleMode;
}
}
});
}
/**
* Initialize JNI field and method IDs for fields that may be
accessed from C.
*/
private static native void initIDs();
/**
* Creates a file dialog for loading a file. The title of the
* file dialog is initially empty. This is a convenience method for
* <code>FileDialog(parent, "", LOAD)</code>.
*
* @param parent the owner of the dialog
* @since JDK1.1
*/
public FileDialog(Frame parent) {
this(parent, "", LOAD);
}
/**
* Creates a file dialog window with the specified title for loading
* a file. The files shown are those in the current directory.
* This is a convenience method for
* <code>FileDialog(parent, title, LOAD)</code>.
*
* @param parent the owner of the dialog
* @param title the title of the dialog
*/
public FileDialog(Frame parent, String title) {
this(parent, title, LOAD);
}
/**
* Creates a file dialog window with the specified title for loading
* or saving a file.
* <p>
* If the value of <code>mode</code> is <code>LOAD</code>, then the
* file dialog is finding a file to read, and the files shown are those
* in the current directory. If the value of
* <code>mode</code> is <code>SAVE</code>, the file dialog is finding
* a place to write a file.
*
* @param parent the owner of the dialog
* @param title the title of the dialog
* @param mode the mode of the dialog; either
* <code>FileDialog.LOAD</code> or <code>FileDialog.SAVE</code>
* @exception IllegalArgumentException if an illegal file
* dialog mode is supplied
* @see java.awt.FileDialog#LOAD
* @see java.awt.FileDialog#SAVE
*/
public FileDialog(Frame parent, String title, int mode) {
super(parent, title, true);
this.setMode(mode);
setLayout(null);
}
/**
* Creates a file dialog for loading a file. The title of the
* file dialog is initially empty. This is a convenience method for
* <code>FileDialog(parent, "", LOAD)</code>.
*
* @param parent the owner of the dialog
* @exception java.lang.IllegalArgumentException if the <code>parent</code>'s
* <code>GraphicsConfiguration</code>
* is not from a screen device;
* @exception java.lang.IllegalArgumentException if <code>parent</code>
* is <code>null</code>; this exception is always thrown when
* <code>GraphicsEnvironment.isHeadless</code>
* returns <code>true</code>
* @see java.awt.GraphicsEnvironment#isHeadless
* @since 1.5
*/
public FileDialog(Dialog parent) {
this(parent, "", LOAD);
}
/**
* Creates a file dialog window with the specified title for loading
* a file. The files shown are those in the current directory.
* This is a convenience method for
* <code>FileDialog(parent, title, LOAD)</code>.
*
* @param parent the owner of the dialog
* @param title the title of the dialog; a <code>null</code> value
* will be accepted without causing a
* <code>NullPointerException</code> to be thrown
* @exception java.lang.IllegalArgumentException if the <code>parent</code>'s
* <code>GraphicsConfiguration</code>
* is not from a screen device;
* @exception java.lang.IllegalArgumentException if <code>parent</code>
* is <code>null</code>; this exception is always thrown when
* <code>GraphicsEnvironment.isHeadless</code>
* returns <code>true</code>
* @see java.awt.GraphicsEnvironment#isHeadless
* @since 1.5
*/
public FileDialog(Dialog parent, String title) {
this(parent, title, LOAD);
}
/**
* Creates a file dialog window with the specified title for loading
* or saving a file.
* <p>
* If the value of <code>mode</code> is <code>LOAD</code>, then the
* file dialog is finding a file to read, and the files shown are those
* in the current directory. If the value of
* <code>mode</code> is <code>SAVE</code>, the file dialog is finding
* a place to write a file.
*
* @param parent the owner of the dialog
* @param title the title of the dialog; a <code>null</code> value
* will be accepted without causing a
* <code>NullPointerException</code> to be thrown
* @param mode the mode of the dialog; either
* <code>FileDialog.LOAD</code> or <code>FileDialog.SAVE</code>
* @exception java.lang.IllegalArgumentException if an illegal
* file dialog mode is supplied;
* @exception java.lang.IllegalArgumentException if the <code>parent</code>'s
* <code>GraphicsConfiguration</code>
* is not from a screen device;
* @exception java.lang.IllegalArgumentException if <code>parent</code>
* is <code>null</code>; this exception is always thrown when
* <code>GraphicsEnvironment.isHeadless</code>
* returns <code>true</code>
* @see java.awt.GraphicsEnvironment#isHeadless
* @see java.awt.FileDialog#LOAD
* @see java.awt.FileDialog#SAVE
* @since 1.5
*/
public FileDialog(Dialog parent, String title, int mode) {
super(parent, title, true);
this.setMode(mode);
setLayout(null);
}
/**
* Constructs a name for this component. Called by <code>getName()</code>
* when the name is <code>null</code>.
*/
String constructComponentName() {
synchronized (FileDialog.class) {
return base + nameCounter++;
}
}
/**
* Creates the file dialog's peer. The peer allows us to change the look
* of the file dialog without changing its functionality.
*/
public void addNotify() {
synchronized(getTreeLock()) {
if (parent != null && parent.getPeer() == null) {
parent.addNotify();
}
if (peer == null)
peer = getToolkit().createFileDialog(this);
super.addNotify();
}
}
/**
* Indicates whether this file dialog box is for loading from a file
* or for saving to a file.
*
* @return the mode of this file dialog window, either
* <code>FileDialog.LOAD</code> or
* <code>FileDialog.SAVE</code>
* @see java.awt.FileDialog#LOAD
* @see java.awt.FileDialog#SAVE
* @see java.awt.FileDialog#setMode
*/
public int getMode() {
return mode;
}
/**
* Sets the mode of the file dialog. If <code>mode</code> is not
* a legal value, an exception will be thrown and <code>mode</code>
* will not be set.
*
* @param mode the mode for this file dialog, either
* <code>FileDialog.LOAD</code> or
* <code>FileDialog.SAVE</code>
* @see java.awt.FileDialog#LOAD
* @see java.awt.FileDialog#SAVE
* @see java.awt.FileDialog#getMode
* @exception IllegalArgumentException if an illegal file
* dialog mode is supplied
* @since JDK1.1
*/
public void setMode(int mode) {
switch (mode) {
case LOAD:
case SAVE:
this.mode = mode;
break;
default:
throw new IllegalArgumentException("illegal file dialog mode");
}
}
/**
* Gets the directory of this file dialog.
*
* @return the (potentially <code>null</code> or invalid)
* directory of this <code>FileDialog</code>
* @see java.awt.FileDialog#setDirectory
*/
public String getDirectory() {
return dir;
}
/**
* Sets the directory of this file dialog window to be the
* specified directory. Specifying a <code>null</code> or an
* invalid directory implies an implementation-defined default.
* This default will not be realized, however, until the user
* has selected a file. Until this point, <code>getDirectory()</code>
* will return the value passed into this method.
* <p>
* Specifying "" as the directory is exactly equivalent to
* specifying <code>null</code> as the directory.
*
* @param dir the specified directory
* @see java.awt.FileDialog#getDirectory
*/
public void setDirectory(String dir) {
this.dir = (dir != null && dir.equals("")) ? null : dir;
FileDialogPeer peer = (FileDialogPeer)this.peer;
if (peer != null) {
peer.setDirectory(this.dir);
}
}
/**
* Gets the selected file of this file dialog. If the user
* selected <code>CANCEL</code>, the returned file is <code>null</code>.
*
* @return the currently selected file of this file dialog window,
* or <code>null</code> if none is selected
* @see java.awt.FileDialog#setFile
*/
public String getFile() {
return file;
}
/**
* Returns files that the user selects.
* <p>
* If the user cancels the file dialog,
* then the method returns an empty array.
*
* @return files that the user selects or an empty array
* if the user cancels the file dialog.
* @see #setFile(String)
* @see #getFile
* @since 1.7
*/
public File[] getFiles() {
synchronized (getObjectLock()) {
if (files != null) {
return files.clone();
} else {
return new File[0];
}
}
}
/**
* Stores the names of all the files that the user selects.
*
* Note that the method is private and it's intended to be used
* by the peers through the AWTAccessor API.
*
* @param files the array that contains the short names of
* all the files that the user selects.
*
* @see #getFiles
* @since 1.7
*/
private void setFiles(File files[]) {
synchronized (getObjectLock()) {
this.files = files;
}
}
/**
* Sets the selected file for this file dialog window to be the
* specified file. This file becomes the default file if it is set
* before the file dialog window is first shown.
* <p>
* When the dialog is shown, the specified file is selected. The kind of
* selection depends on the file existence, the dialog type, and the native
* platform. E.g., the file could be highlighted in the file list, or a
* file name editbox could be populated with the file name.
* <p>
* This method accepts either a full file path, or a file name with an
* extension if used together with the {@code setDirectory} method.
* <p>
* Specifying "" as the file is exactly equivalent to specifying
* {@code null} as the file.
*
* @param file the file being set
* @see #getFile
* @see #getFiles
*/
public void setFile(String file) {
this.file = (file != null && file.equals("")) ? null : file;
FileDialogPeer peer = (FileDialogPeer)this.peer;
if (peer != null) {
peer.setFile(this.file);
}
}
/**
* Enables or disables multiple file selection for the file dialog.
*
* @param enable if {@code true}, multiple file selection is enabled;
* {@code false} - disabled.
* @see #isMultipleMode
* @since 1.7
*/
public void setMultipleMode(boolean enable) {
synchronized (getObjectLock()) {
this.multipleMode = enable;
}
}
/**
* Returns whether the file dialog allows the multiple file selection.
*
* @return {@code true} if the file dialog allows the multiple
* file selection; {@code false} otherwise.
* @see #setMultipleMode
* @since 1.7
*/
public boolean isMultipleMode() {
synchronized (getObjectLock()) {
return multipleMode;
}
}
/**
* Determines this file dialog's filename filter. A filename filter
* allows the user to specify which files appear in the file dialog
* window. Filename filters do not function in Sun's reference
* implementation for Microsoft Windows.
*
* @return this file dialog's filename filter
* @see java.io.FilenameFilter
* @see java.awt.FileDialog#setFilenameFilter
*/
public FilenameFilter getFilenameFilter() {
return filter;
}
/**
* Sets the filename filter for this file dialog window to the
* specified filter.
* Filename filters do not function in Sun's reference
* implementation for Microsoft Windows.
*
* @param filter the specified filter
* @see java.io.FilenameFilter
* @see java.awt.FileDialog#getFilenameFilter
*/
public synchronized void setFilenameFilter(FilenameFilter filter) {
this.filter = filter;
FileDialogPeer peer = (FileDialogPeer)this.peer;
if (peer != null) {
peer.setFilenameFilter(filter);
}
}
/**
* Reads the <code>ObjectInputStream</code> and performs
* a backwards compatibility check by converting
* either a <code>dir</code> or a <code>file</code>
* equal to an empty string to <code>null</code>.
*
* @param s the <code>ObjectInputStream</code> to read
*/
private void readObject(ObjectInputStream s)
throws ClassNotFoundException, IOException
{
s.defaultReadObject();
// 1.1 Compatibility: "" is not converted to null in 1.1
if (dir != null && dir.equals("")) {
dir = null;
}
if (file != null && file.equals("")) {
file = null;
}
}
/**
* Returns a string representing the state of this <code>FileDialog</code>
* window. This method is intended to be used only for debugging purposes,
* and the content and format of the returned string may vary between
* implementations. The returned string may be empty but may not be
* <code>null</code>.
*
* @return the parameter string of this file dialog window
*/
protected String paramString() {
String str = super.paramString();
str += ",dir= " + dir;
str += ",file= " + file;
return str + ((mode == LOAD) ? ",load" : ",save");
}
boolean postsOldMouseEvents() {
return false;
}
}

View File

@@ -0,0 +1,696 @@
/*
* Copyright (c) 1995, 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 java.awt;
import java.io.ObjectInputStream;
import java.io.IOException;
/**
* A flow layout arranges components in a directional flow, much
* like lines of text in a paragraph. The flow direction is
* determined by the container's <code>componentOrientation</code>
* property and may be one of two values:
* <ul>
* <li><code>ComponentOrientation.LEFT_TO_RIGHT</code>
* <li><code>ComponentOrientation.RIGHT_TO_LEFT</code>
* </ul>
* Flow layouts are typically used
* to arrange buttons in a panel. It arranges buttons
* horizontally until no more buttons fit on the same line.
* The line alignment is determined by the <code>align</code>
* property. The possible values are:
* <ul>
* <li>{@link #LEFT LEFT}
* <li>{@link #RIGHT RIGHT}
* <li>{@link #CENTER CENTER}
* <li>{@link #LEADING LEADING}
* <li>{@link #TRAILING TRAILING}
* </ul>
* <p>
* For example, the following picture shows an applet using the flow
* layout manager (its default layout manager) to position three buttons:
* <p>
* <img src="doc-files/FlowLayout-1.gif"
* ALT="Graphic of Layout for Three Buttons"
* style="float:center; margin: 7px 10px;">
* <p>
* Here is the code for this applet:
*
* <hr><blockquote><pre>
* import java.awt.*;
* import java.applet.Applet;
*
* public class myButtons extends Applet {
* Button button1, button2, button3;
* public void init() {
* button1 = new Button("Ok");
* button2 = new Button("Open");
* button3 = new Button("Close");
* add(button1);
* add(button2);
* add(button3);
* }
* }
* </pre></blockquote><hr>
* <p>
* A flow layout lets each component assume its natural (preferred) size.
*
* @author Arthur van Hoff
* @author Sami Shaio
* @since JDK1.0
* @see ComponentOrientation
*/
public class FlowLayout implements LayoutManager, java.io.Serializable {
/**
* This value indicates that each row of components
* should be left-justified.
*/
public static final int LEFT = 0;
/**
* This value indicates that each row of components
* should be centered.
*/
public static final int CENTER = 1;
/**
* This value indicates that each row of components
* should be right-justified.
*/
public static final int RIGHT = 2;
/**
* This value indicates that each row of components
* should be justified to the leading edge of the container's
* orientation, for example, to the left in left-to-right orientations.
*
* @see java.awt.Component#getComponentOrientation
* @see java.awt.ComponentOrientation
* @since 1.2
*/
public static final int LEADING = 3;
/**
* This value indicates that each row of components
* should be justified to the trailing edge of the container's
* orientation, for example, to the right in left-to-right orientations.
*
* @see java.awt.Component#getComponentOrientation
* @see java.awt.ComponentOrientation
* @since 1.2
*/
public static final int TRAILING = 4;
/**
* <code>align</code> is the property that determines
* how each row distributes empty space.
* It can be one of the following values:
* <ul>
* <li><code>LEFT</code>
* <li><code>RIGHT</code>
* <li><code>CENTER</code>
* </ul>
*
* @serial
* @see #getAlignment
* @see #setAlignment
*/
int align; // This is for 1.1 serialization compatibility
/**
* <code>newAlign</code> is the property that determines
* how each row distributes empty space for the Java 2 platform,
* v1.2 and greater.
* It can be one of the following three values:
* <ul>
* <li><code>LEFT</code>
* <li><code>RIGHT</code>
* <li><code>CENTER</code>
* <li><code>LEADING</code>
* <li><code>TRAILING</code>
* </ul>
*
* @serial
* @since 1.2
* @see #getAlignment
* @see #setAlignment
*/
int newAlign; // This is the one we actually use
/**
* The flow layout manager allows a seperation of
* components with gaps. The horizontal gap will
* specify the space between components and between
* the components and the borders of the
* <code>Container</code>.
*
* @serial
* @see #getHgap()
* @see #setHgap(int)
*/
int hgap;
/**
* The flow layout manager allows a seperation of
* components with gaps. The vertical gap will
* specify the space between rows and between the
* the rows and the borders of the <code>Container</code>.
*
* @serial
* @see #getHgap()
* @see #setHgap(int)
*/
int vgap;
/**
* If true, components will be aligned on their baseline.
*/
private boolean alignOnBaseline;
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = -7262534875583282631L;
/**
* Constructs a new <code>FlowLayout</code> with a centered alignment and a
* default 5-unit horizontal and vertical gap.
*/
public FlowLayout() {
this(CENTER, 5, 5);
}
/**
* Constructs a new <code>FlowLayout</code> with the specified
* alignment and a default 5-unit horizontal and vertical gap.
* The value of the alignment argument must be one of
* <code>FlowLayout.LEFT</code>, <code>FlowLayout.RIGHT</code>,
* <code>FlowLayout.CENTER</code>, <code>FlowLayout.LEADING</code>,
* or <code>FlowLayout.TRAILING</code>.
* @param align the alignment value
*/
public FlowLayout(int align) {
this(align, 5, 5);
}
/**
* Creates a new flow layout manager with the indicated alignment
* and the indicated horizontal and vertical gaps.
* <p>
* The value of the alignment argument must be one of
* <code>FlowLayout.LEFT</code>, <code>FlowLayout.RIGHT</code>,
* <code>FlowLayout.CENTER</code>, <code>FlowLayout.LEADING</code>,
* or <code>FlowLayout.TRAILING</code>.
* @param align the alignment value
* @param hgap the horizontal gap between components
* and between the components and the
* borders of the <code>Container</code>
* @param vgap the vertical gap between components
* and between the components and the
* borders of the <code>Container</code>
*/
public FlowLayout(int align, int hgap, int vgap) {
this.hgap = hgap;
this.vgap = vgap;
setAlignment(align);
}
/**
* Gets the alignment for this layout.
* Possible values are <code>FlowLayout.LEFT</code>,
* <code>FlowLayout.RIGHT</code>, <code>FlowLayout.CENTER</code>,
* <code>FlowLayout.LEADING</code>,
* or <code>FlowLayout.TRAILING</code>.
* @return the alignment value for this layout
* @see java.awt.FlowLayout#setAlignment
* @since JDK1.1
*/
public int getAlignment() {
return newAlign;
}
/**
* Sets the alignment for this layout.
* Possible values are
* <ul>
* <li><code>FlowLayout.LEFT</code>
* <li><code>FlowLayout.RIGHT</code>
* <li><code>FlowLayout.CENTER</code>
* <li><code>FlowLayout.LEADING</code>
* <li><code>FlowLayout.TRAILING</code>
* </ul>
* @param align one of the alignment values shown above
* @see #getAlignment()
* @since JDK1.1
*/
public void setAlignment(int align) {
this.newAlign = align;
// this.align is used only for serialization compatibility,
// so set it to a value compatible with the 1.1 version
// of the class
switch (align) {
case LEADING:
this.align = LEFT;
break;
case TRAILING:
this.align = RIGHT;
break;
default:
this.align = align;
break;
}
}
/**
* Gets the horizontal gap between components
* and between the components and the borders
* of the <code>Container</code>
*
* @return the horizontal gap between components
* and between the components and the borders
* of the <code>Container</code>
* @see java.awt.FlowLayout#setHgap
* @since JDK1.1
*/
public int getHgap() {
return hgap;
}
/**
* Sets the horizontal gap between components and
* between the components and the borders of the
* <code>Container</code>.
*
* @param hgap the horizontal gap between components
* and between the components and the borders
* of the <code>Container</code>
* @see java.awt.FlowLayout#getHgap
* @since JDK1.1
*/
public void setHgap(int hgap) {
this.hgap = hgap;
}
/**
* Gets the vertical gap between components and
* between the components and the borders of the
* <code>Container</code>.
*
* @return the vertical gap between components
* and between the components and the borders
* of the <code>Container</code>
* @see java.awt.FlowLayout#setVgap
* @since JDK1.1
*/
public int getVgap() {
return vgap;
}
/**
* Sets the vertical gap between components and between
* the components and the borders of the <code>Container</code>.
*
* @param vgap the vertical gap between components
* and between the components and the borders
* of the <code>Container</code>
* @see java.awt.FlowLayout#getVgap
* @since JDK1.1
*/
public void setVgap(int vgap) {
this.vgap = vgap;
}
/**
* Sets whether or not components should be vertically aligned along their
* baseline. Components that do not have a baseline will be centered.
* The default is false.
*
* @param alignOnBaseline whether or not components should be
* vertically aligned on their baseline
* @since 1.6
*/
public void setAlignOnBaseline(boolean alignOnBaseline) {
this.alignOnBaseline = alignOnBaseline;
}
/**
* Returns true if components are to be vertically aligned along
* their baseline. The default is false.
*
* @return true if components are to be vertically aligned along
* their baseline
* @since 1.6
*/
public boolean getAlignOnBaseline() {
return alignOnBaseline;
}
/**
* Adds the specified component to the layout.
* Not used by this class.
* @param name the name of the component
* @param comp the component to be added
*/
public void addLayoutComponent(String name, Component comp) {
}
/**
* Removes the specified component from the layout.
* Not used by this class.
* @param comp the component to remove
* @see java.awt.Container#removeAll
*/
public void removeLayoutComponent(Component comp) {
}
/**
* Returns the preferred dimensions for this layout given the
* <i>visible</i> components in the specified target container.
*
* @param target the container that needs to be laid out
* @return the preferred dimensions to lay out the
* subcomponents of the specified container
* @see Container
* @see #minimumLayoutSize
* @see java.awt.Container#getPreferredSize
*/
public Dimension preferredLayoutSize(Container target) {
synchronized (target.getTreeLock()) {
Dimension dim = new Dimension(0, 0);
int nmembers = target.getComponentCount();
boolean firstVisibleComponent = true;
boolean useBaseline = getAlignOnBaseline();
int maxAscent = 0;
int maxDescent = 0;
for (int i = 0 ; i < nmembers ; i++) {
Component m = target.getComponent(i);
if (m.isVisible()) {
Dimension d = m.getPreferredSize();
dim.height = Math.max(dim.height, d.height);
if (firstVisibleComponent) {
firstVisibleComponent = false;
} else {
dim.width += hgap;
}
dim.width += d.width;
if (useBaseline) {
int baseline = m.getBaseline(d.width, d.height);
if (baseline >= 0) {
maxAscent = Math.max(maxAscent, baseline);
maxDescent = Math.max(maxDescent, d.height - baseline);
}
}
}
}
if (useBaseline) {
dim.height = Math.max(maxAscent + maxDescent, dim.height);
}
Insets insets = target.getInsets();
dim.width += insets.left + insets.right + hgap*2;
dim.height += insets.top + insets.bottom + vgap*2;
return dim;
}
}
/**
* Returns the minimum dimensions needed to layout the <i>visible</i>
* components contained in the specified target container.
* @param target the container that needs to be laid out
* @return the minimum dimensions to lay out the
* subcomponents of the specified container
* @see #preferredLayoutSize
* @see java.awt.Container
* @see java.awt.Container#doLayout
*/
public Dimension minimumLayoutSize(Container target) {
synchronized (target.getTreeLock()) {
boolean useBaseline = getAlignOnBaseline();
Dimension dim = new Dimension(0, 0);
int nmembers = target.getComponentCount();
int maxAscent = 0;
int maxDescent = 0;
boolean firstVisibleComponent = true;
for (int i = 0 ; i < nmembers ; i++) {
Component m = target.getComponent(i);
if (m.visible) {
Dimension d = m.getMinimumSize();
dim.height = Math.max(dim.height, d.height);
if (firstVisibleComponent) {
firstVisibleComponent = false;
} else {
dim.width += hgap;
}
dim.width += d.width;
if (useBaseline) {
int baseline = m.getBaseline(d.width, d.height);
if (baseline >= 0) {
maxAscent = Math.max(maxAscent, baseline);
maxDescent = Math.max(maxDescent,
dim.height - baseline);
}
}
}
}
if (useBaseline) {
dim.height = Math.max(maxAscent + maxDescent, dim.height);
}
Insets insets = target.getInsets();
dim.width += insets.left + insets.right + hgap*2;
dim.height += insets.top + insets.bottom + vgap*2;
return dim;
}
}
/**
* Centers the elements in the specified row, if there is any slack.
* @param target the component which needs to be moved
* @param x the x coordinate
* @param y the y coordinate
* @param width the width dimensions
* @param height the height dimensions
* @param rowStart the beginning of the row
* @param rowEnd the the ending of the row
* @param useBaseline Whether or not to align on baseline.
* @param ascent Ascent for the components. This is only valid if
* useBaseline is true.
* @param descent Ascent for the components. This is only valid if
* useBaseline is true.
* @return actual row height
*/
private int moveComponents(Container target, int x, int y, int width, int height,
int rowStart, int rowEnd, boolean ltr,
boolean useBaseline, int[] ascent,
int[] descent) {
switch (newAlign) {
case LEFT:
x += ltr ? 0 : width;
break;
case CENTER:
x += width / 2;
break;
case RIGHT:
x += ltr ? width : 0;
break;
case LEADING:
break;
case TRAILING:
x += width;
break;
}
int maxAscent = 0;
int nonbaselineHeight = 0;
int baselineOffset = 0;
if (useBaseline) {
int maxDescent = 0;
for (int i = rowStart ; i < rowEnd ; i++) {
Component m = target.getComponent(i);
if (m.visible) {
if (ascent[i] >= 0) {
maxAscent = Math.max(maxAscent, ascent[i]);
maxDescent = Math.max(maxDescent, descent[i]);
}
else {
nonbaselineHeight = Math.max(m.getHeight(),
nonbaselineHeight);
}
}
}
height = Math.max(maxAscent + maxDescent, nonbaselineHeight);
baselineOffset = (height - maxAscent - maxDescent) / 2;
}
for (int i = rowStart ; i < rowEnd ; i++) {
Component m = target.getComponent(i);
if (m.isVisible()) {
int cy;
if (useBaseline && ascent[i] >= 0) {
cy = y + baselineOffset + maxAscent - ascent[i];
}
else {
cy = y + (height - m.height) / 2;
}
if (ltr) {
m.setLocation(x, cy);
} else {
m.setLocation(target.width - x - m.width, cy);
}
x += m.width + hgap;
}
}
return height;
}
/**
* Lays out the container. This method lets each
* <i>visible</i> component take
* its preferred size by reshaping the components in the
* target container in order to satisfy the alignment of
* this <code>FlowLayout</code> object.
*
* @param target the specified component being laid out
* @see Container
* @see java.awt.Container#doLayout
*/
public void layoutContainer(Container target) {
synchronized (target.getTreeLock()) {
Insets insets = target.getInsets();
int maxwidth = target.width - (insets.left + insets.right + hgap*2);
int nmembers = target.getComponentCount();
int x = 0, y = insets.top + vgap;
int rowh = 0, start = 0;
boolean ltr = target.getComponentOrientation().isLeftToRight();
boolean useBaseline = getAlignOnBaseline();
int[] ascent = null;
int[] descent = null;
if (useBaseline) {
ascent = new int[nmembers];
descent = new int[nmembers];
}
for (int i = 0 ; i < nmembers ; i++) {
Component m = target.getComponent(i);
if (m.isVisible()) {
Dimension d = m.getPreferredSize();
m.setSize(d.width, d.height);
if (useBaseline) {
int baseline = m.getBaseline(d.width, d.height);
if (baseline >= 0) {
ascent[i] = baseline;
descent[i] = d.height - baseline;
}
else {
ascent[i] = -1;
}
}
if ((x == 0) || ((x + d.width) <= maxwidth)) {
if (x > 0) {
x += hgap;
}
x += d.width;
rowh = Math.max(rowh, d.height);
} else {
rowh = moveComponents(target, insets.left + hgap, y,
maxwidth - x, rowh, start, i, ltr,
useBaseline, ascent, descent);
x = d.width;
y += vgap + rowh;
rowh = d.height;
start = i;
}
}
}
moveComponents(target, insets.left + hgap, y, maxwidth - x, rowh,
start, nmembers, ltr, useBaseline, ascent, descent);
}
}
//
// the internal serial version which says which version was written
// - 0 (default) for versions before the Java 2 platform, v1.2
// - 1 for version >= Java 2 platform v1.2, which includes "newAlign" field
//
private static final int currentSerialVersion = 1;
/**
* This represent the <code>currentSerialVersion</code>
* which is bein used. It will be one of two values :
* <code>0</code> versions before Java 2 platform v1.2..
* <code>1</code> versions after Java 2 platform v1.2..
*
* @serial
* @since 1.2
*/
private int serialVersionOnStream = currentSerialVersion;
/**
* Reads this object out of a serialization stream, handling
* objects written by older versions of the class that didn't contain all
* of the fields we use now..
*/
private void readObject(ObjectInputStream stream)
throws IOException, ClassNotFoundException
{
stream.defaultReadObject();
if (serialVersionOnStream < 1) {
// "newAlign" field wasn't present, so use the old "align" field.
setAlignment(this.align);
}
serialVersionOnStream = currentSerialVersion;
}
/**
* Returns a string representation of this <code>FlowLayout</code>
* object and its values.
* @return a string representation of this layout
*/
public String toString() {
String str = "";
switch (align) {
case LEFT: str = ",align=left"; break;
case CENTER: str = ",align=center"; break;
case RIGHT: str = ",align=right"; break;
case LEADING: str = ",align=leading"; break;
case TRAILING: str = ",align=trailing"; break;
}
return getClass().getName() + "[hgap=" + hgap + ",vgap=" + vgap + str + "]";
}
}

View File

@@ -0,0 +1,175 @@
/*
* Copyright (c) 2000, 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 java.awt;
/**
* A FocusTraversalPolicy defines the order in which Components with a
* particular focus cycle root are traversed. Instances can apply the policy to
* arbitrary focus cycle roots, allowing themselves to be shared across
* Containers. They do not need to be reinitialized when the focus cycle roots
* of a Component hierarchy change.
* <p>
* The core responsibility of a FocusTraversalPolicy is to provide algorithms
* determining the next and previous Components to focus when traversing
* forward or backward in a UI. Each FocusTraversalPolicy must also provide
* algorithms for determining the first, last, and default Components in a
* traversal cycle. First and last Components are used when normal forward and
* backward traversal, respectively, wraps. The default Component is the first
* to receive focus when traversing down into a new focus traversal cycle.
* A FocusTraversalPolicy can optionally provide an algorithm for determining
* a Window's initial Component. The initial Component is the first to receive
* focus when a Window is first made visible.
* <p>
* FocusTraversalPolicy takes into account <a
* href="doc-files/FocusSpec.html#FocusTraversalPolicyProviders">focus traversal
* policy providers</a>. When searching for first/last/next/previous Component,
* if a focus traversal policy provider is encountered, its focus traversal
* policy is used to perform the search operation.
* <p>
* Please see
* <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
* How to Use the Focus Subsystem</a>,
* a section in <em>The Java Tutorial</em>, and the
* <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
* for more information.
*
* @author David Mendenhall
*
* @see Container#setFocusTraversalPolicy
* @see Container#getFocusTraversalPolicy
* @see Container#setFocusCycleRoot
* @see Container#isFocusCycleRoot
* @see Container#setFocusTraversalPolicyProvider
* @see Container#isFocusTraversalPolicyProvider
* @see KeyboardFocusManager#setDefaultFocusTraversalPolicy
* @see KeyboardFocusManager#getDefaultFocusTraversalPolicy
* @since 1.4
*/
public abstract class FocusTraversalPolicy {
/**
* Returns the Component that should receive the focus after aComponent.
* aContainer must be a focus cycle root of aComponent or a focus traversal
* policy provider.
*
* @param aContainer a focus cycle root of aComponent or focus traversal
* policy provider
* @param aComponent a (possibly indirect) child of aContainer, or
* aContainer itself
* @return the Component that should receive the focus after aComponent, or
* null if no suitable Component can be found
* @throws IllegalArgumentException if aContainer is not a focus cycle
* root of aComponent or a focus traversal policy provider, or if
* either aContainer or aComponent is null
*/
public abstract Component getComponentAfter(Container aContainer,
Component aComponent);
/**
* Returns the Component that should receive the focus before aComponent.
* aContainer must be a focus cycle root of aComponent or a focus traversal
* policy provider.
*
* @param aContainer a focus cycle root of aComponent or focus traversal
* policy provider
* @param aComponent a (possibly indirect) child of aContainer, or
* aContainer itself
* @return the Component that should receive the focus before aComponent,
* or null if no suitable Component can be found
* @throws IllegalArgumentException if aContainer is not a focus cycle
* root of aComponent or a focus traversal policy provider, or if
* either aContainer or aComponent is null
*/
public abstract Component getComponentBefore(Container aContainer,
Component aComponent);
/**
* Returns the first Component in the traversal cycle. This method is used
* to determine the next Component to focus when traversal wraps in the
* forward direction.
*
* @param aContainer the focus cycle root or focus traversal policy provider
* whose first Component is to be returned
* @return the first Component in the traversal cycle of aContainer,
* or null if no suitable Component can be found
* @throws IllegalArgumentException if aContainer is null
*/
public abstract Component getFirstComponent(Container aContainer);
/**
* Returns the last Component in the traversal cycle. This method is used
* to determine the next Component to focus when traversal wraps in the
* reverse direction.
*
* @param aContainer the focus cycle root or focus traversal policy
* provider whose last Component is to be returned
* @return the last Component in the traversal cycle of aContainer,
* or null if no suitable Component can be found
* @throws IllegalArgumentException if aContainer is null
*/
public abstract Component getLastComponent(Container aContainer);
/**
* Returns the default Component to focus. This Component will be the first
* to receive focus when traversing down into a new focus traversal cycle
* rooted at aContainer.
*
* @param aContainer the focus cycle root or focus traversal policy
* provider whose default Component is to be returned
* @return the default Component in the traversal cycle of aContainer,
* or null if no suitable Component can be found
* @throws IllegalArgumentException if aContainer is null
*/
public abstract Component getDefaultComponent(Container aContainer);
/**
* Returns the Component that should receive the focus when a Window is
* made visible for the first time. Once the Window has been made visible
* by a call to <code>show()</code> or <code>setVisible(true)</code>, the
* initial Component will not be used again. Instead, if the Window loses
* and subsequently regains focus, or is made invisible or undisplayable
* and subsequently made visible and displayable, the Window's most
* recently focused Component will become the focus owner. The default
* implementation of this method returns the default Component.
*
* @param window the Window whose initial Component is to be returned
* @return the Component that should receive the focus when window is made
* visible for the first time, or null if no suitable Component can
* be found
* @see #getDefaultComponent
* @see Window#getMostRecentFocusOwner
* @throws IllegalArgumentException if window is null
*/
public Component getInitialComponent(Window window) {
if ( window == null ){
throw new IllegalArgumentException("window cannot be equal to null.");
}
Component def = getDefaultComponent(window);
if (def == null && window.isFocusableWindow()) {
def = window;
}
return def;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,51 @@
/*
* Copyright (c) 1999, 2004, 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 java.awt;
/**
* Thrown by method createFont in the <code>Font</code> class to indicate
* that the specified font is bad.
*
* @author Parry Kejriwal
* @see java.awt.Font
* @since 1.3
*/
public
class FontFormatException extends Exception {
/*
* serialVersionUID
*/
private static final long serialVersionUID = -4481290147811361272L;
/**
* Report a FontFormatException for the reason specified.
* @param reason a <code>String</code> message indicating why
* the font is not accepted.
*/
public FontFormatException(String reason) {
super (reason);
}
}

View File

@@ -0,0 +1,642 @@
/*
* Copyright (c) 1995, 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 java.awt;
import java.awt.Graphics2D;
import java.awt.font.FontRenderContext;
import java.awt.font.LineMetrics;
import java.awt.geom.Rectangle2D;
import java.text.CharacterIterator;
/**
* The <code>FontMetrics</code> class defines a font metrics object, which
* encapsulates information about the rendering of a particular font on a
* particular screen.
* <p>
* <b>Note to subclassers</b>: Since many of these methods form closed,
* mutually recursive loops, you must take care that you implement
* at least one of the methods in each such loop to prevent
* infinite recursion when your subclass is used.
* In particular, the following is the minimal suggested set of methods
* to override in order to ensure correctness and prevent infinite
* recursion (though other subsets are equally feasible):
* <ul>
* <li>{@link #getAscent()}
* <li>{@link #getLeading()}
* <li>{@link #getMaxAdvance()}
* <li>{@link #charWidth(char)}
* <li>{@link #charsWidth(char[], int, int)}
* </ul>
* <p>
* <img src="doc-files/FontMetrics-1.gif" alt="The letter 'p' showing its 'reference point'"
* style="border:15px; float:right; margin: 7px 10px;">
* Note that the implementations of these methods are
* inefficient, so they are usually overridden with more efficient
* toolkit-specific implementations.
* <p>
* When an application asks to place a character at the position
* (<i>x</i>,&nbsp;<i>y</i>), the character is placed so that its
* reference point (shown as the dot in the accompanying image) is
* put at that position. The reference point specifies a horizontal
* line called the <i>baseline</i> of the character. In normal
* printing, the baselines of characters should align.
* <p>
* In addition, every character in a font has an <i>ascent</i>, a
* <i>descent</i>, and an <i>advance width</i>. The ascent is the
* amount by which the character ascends above the baseline. The
* descent is the amount by which the character descends below the
* baseline. The advance width indicates the position at which AWT
* should place the next character.
* <p>
* An array of characters or a string can also have an ascent, a
* descent, and an advance width. The ascent of the array is the
* maximum ascent of any character in the array. The descent is the
* maximum descent of any character in the array. The advance width
* is the sum of the advance widths of each of the characters in the
* character array. The advance of a <code>String</code> is the
* distance along the baseline of the <code>String</code>. This
* distance is the width that should be used for centering or
* right-aligning the <code>String</code>.
* <p>Note that the advance of a <code>String</code> is not necessarily
* the sum of the advances of its characters measured in isolation
* because the width of a character can vary depending on its context.
* For example, in Arabic text, the shape of a character can change
* in order to connect to other characters. Also, in some scripts,
* certain character sequences can be represented by a single shape,
* called a <em>ligature</em>. Measuring characters individually does
* not account for these transformations.
* <p>Font metrics are baseline-relative, meaning that they are
* generally independent of the rotation applied to the font (modulo
* possible grid hinting effects). See {@link java.awt.Font Font}.
*
* @author Jim Graham
* @see java.awt.Font
* @since JDK1.0
*/
public abstract class FontMetrics implements java.io.Serializable {
static {
/* ensure that the necessary native libraries are loaded */
Toolkit.loadLibraries();
if (!GraphicsEnvironment.isHeadless()) {
initIDs();
}
}
private static final FontRenderContext
DEFAULT_FRC = new FontRenderContext(null, false, false);
/**
* The actual {@link Font} from which the font metrics are
* created.
* This cannot be null.
*
* @serial
* @see #getFont()
*/
protected Font font;
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = 1681126225205050147L;
/**
* Creates a new <code>FontMetrics</code> object for finding out
* height and width information about the specified <code>Font</code>
* and specific character glyphs in that <code>Font</code>.
* @param font the <code>Font</code>
* @see java.awt.Font
*/
protected FontMetrics(Font font) {
this.font = font;
}
/**
* Gets the <code>Font</code> described by this
* <code>FontMetrics</code> object.
* @return the <code>Font</code> described by this
* <code>FontMetrics</code> object.
*/
public Font getFont() {
return font;
}
/**
* Gets the <code>FontRenderContext</code> used by this
* <code>FontMetrics</code> object to measure text.
* <p>
* Note that methods in this class which take a <code>Graphics</code>
* parameter measure text using the <code>FontRenderContext</code>
* of that <code>Graphics</code> object, and not this
* <code>FontRenderContext</code>
* @return the <code>FontRenderContext</code> used by this
* <code>FontMetrics</code> object.
* @since 1.6
*/
public FontRenderContext getFontRenderContext() {
return DEFAULT_FRC;
}
/**
* Determines the <em>standard leading</em> of the
* <code>Font</code> described by this <code>FontMetrics</code>
* object. The standard leading, or
* interline spacing, is the logical amount of space to be reserved
* between the descent of one line of text and the ascent of the next
* line. The height metric is calculated to include this extra space.
* @return the standard leading of the <code>Font</code>.
* @see #getHeight()
* @see #getAscent()
* @see #getDescent()
*/
public int getLeading() {
return 0;
}
/**
* Determines the <em>font ascent</em> of the <code>Font</code>
* described by this <code>FontMetrics</code> object. The font ascent
* is the distance from the font's baseline to the top of most
* alphanumeric characters. Some characters in the <code>Font</code>
* might extend above the font ascent line.
* @return the font ascent of the <code>Font</code>.
* @see #getMaxAscent()
*/
public int getAscent() {
return font.getSize();
}
/**
* Determines the <em>font descent</em> of the <code>Font</code>
* described by this
* <code>FontMetrics</code> object. The font descent is the distance
* from the font's baseline to the bottom of most alphanumeric
* characters with descenders. Some characters in the
* <code>Font</code> might extend
* below the font descent line.
* @return the font descent of the <code>Font</code>.
* @see #getMaxDescent()
*/
public int getDescent() {
return 0;
}
/**
* Gets the standard height of a line of text in this font. This
* is the distance between the baseline of adjacent lines of text.
* It is the sum of the leading + ascent + descent. Due to rounding
* this may not be the same as getAscent() + getDescent() + getLeading().
* There is no guarantee that lines of text spaced at this distance are
* disjoint; such lines may overlap if some characters overshoot
* either the standard ascent or the standard descent metric.
* @return the standard height of the font.
* @see #getLeading()
* @see #getAscent()
* @see #getDescent()
*/
public int getHeight() {
return getLeading() + getAscent() + getDescent();
}
/**
* Determines the maximum ascent of the <code>Font</code>
* described by this <code>FontMetrics</code> object. No character
* extends further above the font's baseline than this height.
* @return the maximum ascent of any character in the
* <code>Font</code>.
* @see #getAscent()
*/
public int getMaxAscent() {
return getAscent();
}
/**
* Determines the maximum descent of the <code>Font</code>
* described by this <code>FontMetrics</code> object. No character
* extends further below the font's baseline than this height.
* @return the maximum descent of any character in the
* <code>Font</code>.
* @see #getDescent()
*/
public int getMaxDescent() {
return getDescent();
}
/**
* For backward compatibility only.
* @return the maximum descent of any character in the
* <code>Font</code>.
* @see #getMaxDescent()
* @deprecated As of JDK version 1.1.1,
* replaced by <code>getMaxDescent()</code>.
*/
@Deprecated
public int getMaxDecent() {
return getMaxDescent();
}
/**
* Gets the maximum advance width of any character in this
* <code>Font</code>. The advance is the
* distance from the leftmost point to the rightmost point on the
* string's baseline. The advance of a <code>String</code> is
* not necessarily the sum of the advances of its characters.
* @return the maximum advance width of any character
* in the <code>Font</code>, or <code>-1</code> if the
* maximum advance width is not known.
*/
public int getMaxAdvance() {
return -1;
}
/**
* Returns the advance width of the specified character in this
* <code>Font</code>. The advance is the
* distance from the leftmost point to the rightmost point on the
* character's baseline. Note that the advance of a
* <code>String</code> is not necessarily the sum of the advances
* of its characters.
*
* <p>This method doesn't validate the specified character to be a
* valid Unicode code point. The caller must validate the
* character value using {@link
* java.lang.Character#isValidCodePoint(int)
* Character.isValidCodePoint} if necessary.
*
* @param codePoint the character (Unicode code point) to be measured
* @return the advance width of the specified character
* in the <code>Font</code> described by this
* <code>FontMetrics</code> object.
* @see #charsWidth(char[], int, int)
* @see #stringWidth(String)
*/
public int charWidth(int codePoint) {
if (!Character.isValidCodePoint(codePoint)) {
codePoint = 0xffff; // substitute missing glyph width
}
if (codePoint < 256) {
return getWidths()[codePoint];
} else {
char[] buffer = new char[2];
int len = Character.toChars(codePoint, buffer, 0);
return charsWidth(buffer, 0, len);
}
}
/**
* Returns the advance width of the specified character in this
* <code>Font</code>. The advance is the
* distance from the leftmost point to the rightmost point on the
* character's baseline. Note that the advance of a
* <code>String</code> is not necessarily the sum of the advances
* of its characters.
*
* <p><b>Note:</b> This method cannot handle <a
* href="../lang/Character.html#supplementary"> supplementary
* characters</a>. To support all Unicode characters, including
* supplementary characters, use the {@link #charWidth(int)} method.
*
* @param ch the character to be measured
* @return the advance width of the specified character
* in the <code>Font</code> described by this
* <code>FontMetrics</code> object.
* @see #charsWidth(char[], int, int)
* @see #stringWidth(String)
*/
public int charWidth(char ch) {
if (ch < 256) {
return getWidths()[ch];
}
char data[] = {ch};
return charsWidth(data, 0, 1);
}
/**
* Returns the total advance width for showing the specified
* <code>String</code> in this <code>Font</code>. The advance
* is the distance from the leftmost point to the rightmost point
* on the string's baseline.
* <p>
* Note that the advance of a <code>String</code> is
* not necessarily the sum of the advances of its characters.
* @param str the <code>String</code> to be measured
* @return the advance width of the specified <code>String</code>
* in the <code>Font</code> described by this
* <code>FontMetrics</code>.
* @throws NullPointerException if str is null.
* @see #bytesWidth(byte[], int, int)
* @see #charsWidth(char[], int, int)
* @see #getStringBounds(String, Graphics)
*/
public int stringWidth(String str) {
int len = str.length();
char data[] = new char[len];
str.getChars(0, len, data, 0);
return charsWidth(data, 0, len);
}
/**
* Returns the total advance width for showing the specified array
* of characters in this <code>Font</code>. The advance is the
* distance from the leftmost point to the rightmost point on the
* string's baseline. The advance of a <code>String</code>
* is not necessarily the sum of the advances of its characters.
* This is equivalent to measuring a <code>String</code> of the
* characters in the specified range.
* @param data the array of characters to be measured
* @param off the start offset of the characters in the array
* @param len the number of characters to be measured from the array
* @return the advance width of the subarray of the specified
* <code>char</code> array in the font described by
* this <code>FontMetrics</code> object.
* @throws NullPointerException if <code>data</code> is null.
* @throws IndexOutOfBoundsException if the <code>off</code>
* and <code>len</code> arguments index characters outside
* the bounds of the <code>data</code> array.
* @see #charWidth(int)
* @see #charWidth(char)
* @see #bytesWidth(byte[], int, int)
* @see #stringWidth(String)
*/
public int charsWidth(char data[], int off, int len) {
return stringWidth(new String(data, off, len));
}
/**
* Returns the total advance width for showing the specified array
* of bytes in this <code>Font</code>. The advance is the
* distance from the leftmost point to the rightmost point on the
* string's baseline. The advance of a <code>String</code>
* is not necessarily the sum of the advances of its characters.
* This is equivalent to measuring a <code>String</code> of the
* characters in the specified range.
* @param data the array of bytes to be measured
* @param off the start offset of the bytes in the array
* @param len the number of bytes to be measured from the array
* @return the advance width of the subarray of the specified
* <code>byte</code> array in the <code>Font</code>
* described by
* this <code>FontMetrics</code> object.
* @throws NullPointerException if <code>data</code> is null.
* @throws IndexOutOfBoundsException if the <code>off</code>
* and <code>len</code> arguments index bytes outside
* the bounds of the <code>data</code> array.
* @see #charsWidth(char[], int, int)
* @see #stringWidth(String)
*/
public int bytesWidth(byte data[], int off, int len) {
return stringWidth(new String(data, 0, off, len));
}
/**
* Gets the advance widths of the first 256 characters in the
* <code>Font</code>. The advance is the
* distance from the leftmost point to the rightmost point on the
* character's baseline. Note that the advance of a
* <code>String</code> is not necessarily the sum of the advances
* of its characters.
* @return an array storing the advance widths of the
* characters in the <code>Font</code>
* described by this <code>FontMetrics</code> object.
*/
public int[] getWidths() {
int widths[] = new int[256];
for (char ch = 0 ; ch < 256 ; ch++) {
widths[ch] = charWidth(ch);
}
return widths;
}
/**
* Checks to see if the <code>Font</code> has uniform line metrics. A
* composite font may consist of several different fonts to cover
* various character sets. In such cases, the
* <code>FontLineMetrics</code> objects are not uniform.
* Different fonts may have a different ascent, descent, metrics and
* so on. This information is sometimes necessary for line
* measuring and line breaking.
* @return <code>true</code> if the font has uniform line metrics;
* <code>false</code> otherwise.
* @see java.awt.Font#hasUniformLineMetrics()
*/
public boolean hasUniformLineMetrics() {
return font.hasUniformLineMetrics();
}
/**
* Returns the {@link LineMetrics} object for the specified
* <code>String</code> in the specified {@link Graphics} context.
* @param str the specified <code>String</code>
* @param context the specified <code>Graphics</code> context
* @return a <code>LineMetrics</code> object created with the
* specified <code>String</code> and <code>Graphics</code> context.
* @see java.awt.Font#getLineMetrics(String, FontRenderContext)
*/
public LineMetrics getLineMetrics( String str, Graphics context) {
return font.getLineMetrics(str, myFRC(context));
}
/**
* Returns the {@link LineMetrics} object for the specified
* <code>String</code> in the specified {@link Graphics} context.
* @param str the specified <code>String</code>
* @param beginIndex the initial offset of <code>str</code>
* @param limit the end offset of <code>str</code>
* @param context the specified <code>Graphics</code> context
* @return a <code>LineMetrics</code> object created with the
* specified <code>String</code> and <code>Graphics</code> context.
* @see java.awt.Font#getLineMetrics(String, int, int, FontRenderContext)
*/
public LineMetrics getLineMetrics( String str,
int beginIndex, int limit,
Graphics context) {
return font.getLineMetrics(str, beginIndex, limit, myFRC(context));
}
/**
* Returns the {@link LineMetrics} object for the specified
* character array in the specified {@link Graphics} context.
* @param chars the specified character array
* @param beginIndex the initial offset of <code>chars</code>
* @param limit the end offset of <code>chars</code>
* @param context the specified <code>Graphics</code> context
* @return a <code>LineMetrics</code> object created with the
* specified character array and <code>Graphics</code> context.
* @see java.awt.Font#getLineMetrics(char[], int, int, FontRenderContext)
*/
public LineMetrics getLineMetrics(char [] chars,
int beginIndex, int limit,
Graphics context) {
return font.getLineMetrics(
chars, beginIndex, limit, myFRC(context));
}
/**
* Returns the {@link LineMetrics} object for the specified
* {@link CharacterIterator} in the specified {@link Graphics}
* context.
* @param ci the specified <code>CharacterIterator</code>
* @param beginIndex the initial offset in <code>ci</code>
* @param limit the end index of <code>ci</code>
* @param context the specified <code>Graphics</code> context
* @return a <code>LineMetrics</code> object created with the
* specified arguments.
* @see java.awt.Font#getLineMetrics(CharacterIterator, int, int, FontRenderContext)
*/
public LineMetrics getLineMetrics(CharacterIterator ci,
int beginIndex, int limit,
Graphics context) {
return font.getLineMetrics(ci, beginIndex, limit, myFRC(context));
}
/**
* Returns the bounds of the specified <code>String</code> in the
* specified <code>Graphics</code> context. The bounds is used
* to layout the <code>String</code>.
* <p>Note: The returned bounds is in baseline-relative coordinates
* (see {@link java.awt.FontMetrics class notes}).
* @param str the specified <code>String</code>
* @param context the specified <code>Graphics</code> context
* @return a {@link Rectangle2D} that is the bounding box of the
* specified <code>String</code> in the specified
* <code>Graphics</code> context.
* @see java.awt.Font#getStringBounds(String, FontRenderContext)
*/
public Rectangle2D getStringBounds( String str, Graphics context) {
return font.getStringBounds(str, myFRC(context));
}
/**
* Returns the bounds of the specified <code>String</code> in the
* specified <code>Graphics</code> context. The bounds is used
* to layout the <code>String</code>.
* <p>Note: The returned bounds is in baseline-relative coordinates
* (see {@link java.awt.FontMetrics class notes}).
* @param str the specified <code>String</code>
* @param beginIndex the offset of the beginning of <code>str</code>
* @param limit the end offset of <code>str</code>
* @param context the specified <code>Graphics</code> context
* @return a <code>Rectangle2D</code> that is the bounding box of the
* specified <code>String</code> in the specified
* <code>Graphics</code> context.
* @see java.awt.Font#getStringBounds(String, int, int, FontRenderContext)
*/
public Rectangle2D getStringBounds( String str,
int beginIndex, int limit,
Graphics context) {
return font.getStringBounds(str, beginIndex, limit,
myFRC(context));
}
/**
* Returns the bounds of the specified array of characters
* in the specified <code>Graphics</code> context.
* The bounds is used to layout the <code>String</code>
* created with the specified array of characters,
* <code>beginIndex</code> and <code>limit</code>.
* <p>Note: The returned bounds is in baseline-relative coordinates
* (see {@link java.awt.FontMetrics class notes}).
* @param chars an array of characters
* @param beginIndex the initial offset of the array of
* characters
* @param limit the end offset of the array of characters
* @param context the specified <code>Graphics</code> context
* @return a <code>Rectangle2D</code> that is the bounding box of the
* specified character array in the specified
* <code>Graphics</code> context.
* @see java.awt.Font#getStringBounds(char[], int, int, FontRenderContext)
*/
public Rectangle2D getStringBounds( char [] chars,
int beginIndex, int limit,
Graphics context) {
return font.getStringBounds(chars, beginIndex, limit,
myFRC(context));
}
/**
* Returns the bounds of the characters indexed in the specified
* <code>CharacterIterator</code> in the
* specified <code>Graphics</code> context.
* <p>Note: The returned bounds is in baseline-relative coordinates
* (see {@link java.awt.FontMetrics class notes}).
* @param ci the specified <code>CharacterIterator</code>
* @param beginIndex the initial offset in <code>ci</code>
* @param limit the end index of <code>ci</code>
* @param context the specified <code>Graphics</code> context
* @return a <code>Rectangle2D</code> that is the bounding box of the
* characters indexed in the specified <code>CharacterIterator</code>
* in the specified <code>Graphics</code> context.
* @see java.awt.Font#getStringBounds(CharacterIterator, int, int, FontRenderContext)
*/
public Rectangle2D getStringBounds(CharacterIterator ci,
int beginIndex, int limit,
Graphics context) {
return font.getStringBounds(ci, beginIndex, limit,
myFRC(context));
}
/**
* Returns the bounds for the character with the maximum bounds
* in the specified <code>Graphics</code> context.
* @param context the specified <code>Graphics</code> context
* @return a <code>Rectangle2D</code> that is the
* bounding box for the character with the maximum bounds.
* @see java.awt.Font#getMaxCharBounds(FontRenderContext)
*/
public Rectangle2D getMaxCharBounds(Graphics context) {
return font.getMaxCharBounds(myFRC(context));
}
private FontRenderContext myFRC(Graphics context) {
if (context instanceof Graphics2D) {
return ((Graphics2D)context).getFontRenderContext();
}
return DEFAULT_FRC;
}
/**
* Returns a representation of this <code>FontMetrics</code>
* object's values as a <code>String</code>.
* @return a <code>String</code> representation of this
* <code>FontMetrics</code> object.
* @since JDK1.0.
*/
public String toString() {
return getClass().getName() +
"[font=" + getFont() +
"ascent=" + getAscent() +
", descent=" + getDescent() +
", height=" + getHeight() + "]";
}
/**
* Initialize JNI field and method IDs
*/
private static native void initIDs();
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,278 @@
/*
* Copyright (c) 1997, 2010, 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 java.awt;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.AffineTransform;
import java.awt.image.ColorModel;
import java.beans.ConstructorProperties;
/**
* The <code>GradientPaint</code> class provides a way to fill
* a {@link Shape} with a linear color gradient pattern.
* If {@link Point} P1 with {@link Color} C1 and <code>Point</code> P2 with
* <code>Color</code> C2 are specified in user space, the
* <code>Color</code> on the P1, P2 connecting line is proportionally
* changed from C1 to C2. Any point P not on the extended P1, P2
* connecting line has the color of the point P' that is the perpendicular
* projection of P on the extended P1, P2 connecting line.
* Points on the extended line outside of the P1, P2 segment can be colored
* in one of two ways.
* <ul>
* <li>
* If the gradient is cyclic then the points on the extended P1, P2
* connecting line cycle back and forth between the colors C1 and C2.
* <li>
* If the gradient is acyclic then points on the P1 side of the segment
* have the constant <code>Color</code> C1 while points on the P2 side
* have the constant <code>Color</code> C2.
* </ul>
*
* @see Paint
* @see Graphics2D#setPaint
* @version 10 Feb 1997
*/
public class GradientPaint implements Paint {
Point2D.Float p1;
Point2D.Float p2;
Color color1;
Color color2;
boolean cyclic;
/**
* Constructs a simple acyclic <code>GradientPaint</code> object.
* @param x1 x coordinate of the first specified
* <code>Point</code> in user space
* @param y1 y coordinate of the first specified
* <code>Point</code> in user space
* @param color1 <code>Color</code> at the first specified
* <code>Point</code>
* @param x2 x coordinate of the second specified
* <code>Point</code> in user space
* @param y2 y coordinate of the second specified
* <code>Point</code> in user space
* @param color2 <code>Color</code> at the second specified
* <code>Point</code>
* @throws NullPointerException if either one of colors is null
*/
public GradientPaint(float x1,
float y1,
Color color1,
float x2,
float y2,
Color color2) {
if ((color1 == null) || (color2 == null)) {
throw new NullPointerException("Colors cannot be null");
}
p1 = new Point2D.Float(x1, y1);
p2 = new Point2D.Float(x2, y2);
this.color1 = color1;
this.color2 = color2;
}
/**
* Constructs a simple acyclic <code>GradientPaint</code> object.
* @param pt1 the first specified <code>Point</code> in user space
* @param color1 <code>Color</code> at the first specified
* <code>Point</code>
* @param pt2 the second specified <code>Point</code> in user space
* @param color2 <code>Color</code> at the second specified
* <code>Point</code>
* @throws NullPointerException if either one of colors or points
* is null
*/
public GradientPaint(Point2D pt1,
Color color1,
Point2D pt2,
Color color2) {
if ((color1 == null) || (color2 == null) ||
(pt1 == null) || (pt2 == null)) {
throw new NullPointerException("Colors and points should be non-null");
}
p1 = new Point2D.Float((float)pt1.getX(), (float)pt1.getY());
p2 = new Point2D.Float((float)pt2.getX(), (float)pt2.getY());
this.color1 = color1;
this.color2 = color2;
}
/**
* Constructs either a cyclic or acyclic <code>GradientPaint</code>
* object depending on the <code>boolean</code> parameter.
* @param x1 x coordinate of the first specified
* <code>Point</code> in user space
* @param y1 y coordinate of the first specified
* <code>Point</code> in user space
* @param color1 <code>Color</code> at the first specified
* <code>Point</code>
* @param x2 x coordinate of the second specified
* <code>Point</code> in user space
* @param y2 y coordinate of the second specified
* <code>Point</code> in user space
* @param color2 <code>Color</code> at the second specified
* <code>Point</code>
* @param cyclic <code>true</code> if the gradient pattern should cycle
* repeatedly between the two colors; <code>false</code> otherwise
*/
public GradientPaint(float x1,
float y1,
Color color1,
float x2,
float y2,
Color color2,
boolean cyclic) {
this (x1, y1, color1, x2, y2, color2);
this.cyclic = cyclic;
}
/**
* Constructs either a cyclic or acyclic <code>GradientPaint</code>
* object depending on the <code>boolean</code> parameter.
* @param pt1 the first specified <code>Point</code>
* in user space
* @param color1 <code>Color</code> at the first specified
* <code>Point</code>
* @param pt2 the second specified <code>Point</code>
* in user space
* @param color2 <code>Color</code> at the second specified
* <code>Point</code>
* @param cyclic <code>true</code> if the gradient pattern should cycle
* repeatedly between the two colors; <code>false</code> otherwise
* @throws NullPointerException if either one of colors or points
* is null
*/
@ConstructorProperties({ "point1", "color1", "point2", "color2", "cyclic" })
public GradientPaint(Point2D pt1,
Color color1,
Point2D pt2,
Color color2,
boolean cyclic) {
this (pt1, color1, pt2, color2);
this.cyclic = cyclic;
}
/**
* Returns a copy of the point P1 that anchors the first color.
* @return a {@link Point2D} object that is a copy of the point
* that anchors the first color of this
* <code>GradientPaint</code>.
*/
public Point2D getPoint1() {
return new Point2D.Float(p1.x, p1.y);
}
/**
* Returns the color C1 anchored by the point P1.
* @return a <code>Color</code> object that is the color
* anchored by P1.
*/
public Color getColor1() {
return color1;
}
/**
* Returns a copy of the point P2 which anchors the second color.
* @return a {@link Point2D} object that is a copy of the point
* that anchors the second color of this
* <code>GradientPaint</code>.
*/
public Point2D getPoint2() {
return new Point2D.Float(p2.x, p2.y);
}
/**
* Returns the color C2 anchored by the point P2.
* @return a <code>Color</code> object that is the color
* anchored by P2.
*/
public Color getColor2() {
return color2;
}
/**
* Returns <code>true</code> if the gradient cycles repeatedly
* between the two colors C1 and C2.
* @return <code>true</code> if the gradient cycles repeatedly
* between the two colors; <code>false</code> otherwise.
*/
public boolean isCyclic() {
return cyclic;
}
/**
* Creates and returns a {@link PaintContext} used to
* generate a linear color gradient pattern.
* See the {@link Paint#createContext specification} of the
* method in the {@link Paint} interface for information
* on null parameter handling.
*
* @param cm the preferred {@link ColorModel} which represents the most convenient
* format for the caller to receive the pixel data, or {@code null}
* if there is no preference.
* @param deviceBounds the device space bounding box
* of the graphics primitive being rendered.
* @param userBounds the user space bounding box
* of the graphics primitive being rendered.
* @param xform the {@link AffineTransform} from user
* space into device space.
* @param hints the set of hints that the context object can use to
* choose between rendering alternatives.
* @return the {@code PaintContext} for
* generating color patterns.
* @see Paint
* @see PaintContext
* @see ColorModel
* @see Rectangle
* @see Rectangle2D
* @see AffineTransform
* @see RenderingHints
*/
public PaintContext createContext(ColorModel cm,
Rectangle deviceBounds,
Rectangle2D userBounds,
AffineTransform xform,
RenderingHints hints) {
return new GradientPaintContext(cm, p1, p2, xform,
color1, color2, cyclic);
}
/**
* Returns the transparency mode for this <code>GradientPaint</code>.
* @return an integer value representing this <code>GradientPaint</code>
* object's transparency mode.
* @see Transparency
*/
public int getTransparency() {
int a1 = color1.getAlpha();
int a2 = color2.getAlpha();
return (((a1 & a2) == 0xff) ? OPAQUE : TRANSLUCENT);
}
}

View File

@@ -0,0 +1,295 @@
/*
* 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 java.awt;
import java.awt.image.Raster;
import sun.awt.image.IntegerComponentRaster;
import java.awt.image.ColorModel;
import java.awt.image.DirectColorModel;
import java.awt.geom.Point2D;
import java.awt.geom.AffineTransform;
import java.awt.geom.NoninvertibleTransformException;
import java.lang.ref.WeakReference;
class GradientPaintContext implements PaintContext {
static ColorModel xrgbmodel =
new DirectColorModel(24, 0x00ff0000, 0x0000ff00, 0x000000ff);
static ColorModel xbgrmodel =
new DirectColorModel(24, 0x000000ff, 0x0000ff00, 0x00ff0000);
static ColorModel cachedModel;
static WeakReference<Raster> cached;
static synchronized Raster getCachedRaster(ColorModel cm, int w, int h) {
if (cm == cachedModel) {
if (cached != null) {
Raster ras = (Raster) cached.get();
if (ras != null &&
ras.getWidth() >= w &&
ras.getHeight() >= h)
{
cached = null;
return ras;
}
}
}
return cm.createCompatibleWritableRaster(w, h);
}
static synchronized void putCachedRaster(ColorModel cm, Raster ras) {
if (cached != null) {
Raster cras = (Raster) cached.get();
if (cras != null) {
int cw = cras.getWidth();
int ch = cras.getHeight();
int iw = ras.getWidth();
int ih = ras.getHeight();
if (cw >= iw && ch >= ih) {
return;
}
if (cw * ch >= iw * ih) {
return;
}
}
}
cachedModel = cm;
cached = new WeakReference<>(ras);
}
double x1;
double y1;
double dx;
double dy;
boolean cyclic;
int interp[];
Raster saved;
ColorModel model;
public GradientPaintContext(ColorModel cm,
Point2D p1, Point2D p2, AffineTransform xform,
Color c1, Color c2, boolean cyclic) {
// First calculate the distance moved in user space when
// we move a single unit along the X & Y axes in device space.
Point2D xvec = new Point2D.Double(1, 0);
Point2D yvec = new Point2D.Double(0, 1);
try {
AffineTransform inverse = xform.createInverse();
inverse.deltaTransform(xvec, xvec);
inverse.deltaTransform(yvec, yvec);
} catch (NoninvertibleTransformException e) {
xvec.setLocation(0, 0);
yvec.setLocation(0, 0);
}
// Now calculate the (square of the) user space distance
// between the anchor points. This value equals:
// (UserVec . UserVec)
double udx = p2.getX() - p1.getX();
double udy = p2.getY() - p1.getY();
double ulenSq = udx * udx + udy * udy;
if (ulenSq <= Double.MIN_VALUE) {
dx = 0;
dy = 0;
} else {
// Now calculate the proportional distance moved along the
// vector from p1 to p2 when we move a unit along X & Y in
// device space.
//
// The length of the projection of the Device Axis Vector is
// its dot product with the Unit User Vector:
// (DevAxisVec . (UserVec / Len(UserVec))
//
// The "proportional" length is that length divided again
// by the length of the User Vector:
// (DevAxisVec . (UserVec / Len(UserVec))) / Len(UserVec)
// which simplifies to:
// ((DevAxisVec . UserVec) / Len(UserVec)) / Len(UserVec)
// which simplifies to:
// (DevAxisVec . UserVec) / LenSquared(UserVec)
dx = (xvec.getX() * udx + xvec.getY() * udy) / ulenSq;
dy = (yvec.getX() * udx + yvec.getY() * udy) / ulenSq;
if (cyclic) {
dx = dx % 1.0;
dy = dy % 1.0;
} else {
// We are acyclic
if (dx < 0) {
// If we are using the acyclic form below, we need
// dx to be non-negative for simplicity of scanning
// across the scan lines for the transition points.
// To ensure that constraint, we negate the dx/dy
// values and swap the points and colors.
Point2D p = p1; p1 = p2; p2 = p;
Color c = c1; c1 = c2; c2 = c;
dx = -dx;
dy = -dy;
}
}
}
Point2D dp1 = xform.transform(p1, null);
this.x1 = dp1.getX();
this.y1 = dp1.getY();
this.cyclic = cyclic;
int rgb1 = c1.getRGB();
int rgb2 = c2.getRGB();
int a1 = (rgb1 >> 24) & 0xff;
int r1 = (rgb1 >> 16) & 0xff;
int g1 = (rgb1 >> 8) & 0xff;
int b1 = (rgb1 ) & 0xff;
int da = ((rgb2 >> 24) & 0xff) - a1;
int dr = ((rgb2 >> 16) & 0xff) - r1;
int dg = ((rgb2 >> 8) & 0xff) - g1;
int db = ((rgb2 ) & 0xff) - b1;
if (a1 == 0xff && da == 0) {
model = xrgbmodel;
if (cm instanceof DirectColorModel) {
DirectColorModel dcm = (DirectColorModel) cm;
int tmp = dcm.getAlphaMask();
if ((tmp == 0 || tmp == 0xff) &&
dcm.getRedMask() == 0xff &&
dcm.getGreenMask() == 0xff00 &&
dcm.getBlueMask() == 0xff0000)
{
model = xbgrmodel;
tmp = r1; r1 = b1; b1 = tmp;
tmp = dr; dr = db; db = tmp;
}
}
} else {
model = ColorModel.getRGBdefault();
}
interp = new int[cyclic ? 513 : 257];
for (int i = 0; i <= 256; i++) {
float rel = i / 256.0f;
int rgb =
(((int) (a1 + da * rel)) << 24) |
(((int) (r1 + dr * rel)) << 16) |
(((int) (g1 + dg * rel)) << 8) |
(((int) (b1 + db * rel)) );
interp[i] = rgb;
if (cyclic) {
interp[512 - i] = rgb;
}
}
}
/**
* Release the resources allocated for the operation.
*/
public void dispose() {
if (saved != null) {
putCachedRaster(model, saved);
saved = null;
}
}
/**
* Return the ColorModel of the output.
*/
public ColorModel getColorModel() {
return model;
}
/**
* Return a Raster containing the colors generated for the graphics
* operation.
* @param x,y,w,h The area in device space for which colors are
* generated.
*/
public Raster getRaster(int x, int y, int w, int h) {
double rowrel = (x - x1) * dx + (y - y1) * dy;
Raster rast = saved;
if (rast == null || rast.getWidth() < w || rast.getHeight() < h) {
rast = getCachedRaster(model, w, h);
saved = rast;
}
IntegerComponentRaster irast = (IntegerComponentRaster) rast;
int off = irast.getDataOffset(0);
int adjust = irast.getScanlineStride() - w;
int[] pixels = irast.getDataStorage();
if (cyclic) {
cycleFillRaster(pixels, off, adjust, w, h, rowrel, dx, dy);
} else {
clipFillRaster(pixels, off, adjust, w, h, rowrel, dx, dy);
}
irast.markDirty();
return rast;
}
void cycleFillRaster(int[] pixels, int off, int adjust, int w, int h,
double rowrel, double dx, double dy) {
rowrel = rowrel % 2.0;
int irowrel = ((int) (rowrel * (1 << 30))) << 1;
int idx = (int) (-dx * (1 << 31));
int idy = (int) (-dy * (1 << 31));
while (--h >= 0) {
int icolrel = irowrel;
for (int j = w; j > 0; j--) {
pixels[off++] = interp[icolrel >>> 23];
icolrel += idx;
}
off += adjust;
irowrel += idy;
}
}
void clipFillRaster(int[] pixels, int off, int adjust, int w, int h,
double rowrel, double dx, double dy) {
while (--h >= 0) {
double colrel = rowrel;
int j = w;
if (colrel <= 0.0) {
int rgb = interp[0];
do {
pixels[off++] = rgb;
colrel += dx;
} while (--j > 0 && colrel <= 0.0);
}
while (colrel < 1.0 && --j >= 0) {
pixels[off++] = interp[(int) (colrel * 256)];
colrel += dx;
}
if (j > 0) {
int rgb = interp[256];
do {
pixels[off++] = rgb;
} while (--j > 0);
}
off += adjust;
rowrel += dy;
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,146 @@
/*
* Copyright (c) 1999, 2000, 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 java.awt;
import java.awt.peer.LightweightPeer;
import sun.awt.SunGraphicsCallback;
abstract class GraphicsCallback extends SunGraphicsCallback {
static final class PaintCallback extends GraphicsCallback {
private static PaintCallback instance = new PaintCallback();
private PaintCallback() {}
public void run(Component comp, Graphics cg) {
comp.paint(cg);
}
static PaintCallback getInstance() {
return instance;
}
}
static final class PrintCallback extends GraphicsCallback {
private static PrintCallback instance = new PrintCallback();
private PrintCallback() {}
public void run(Component comp, Graphics cg) {
comp.print(cg);
}
static PrintCallback getInstance() {
return instance;
}
}
static final class PaintAllCallback extends GraphicsCallback {
private static PaintAllCallback instance = new PaintAllCallback();
private PaintAllCallback() {}
public void run(Component comp, Graphics cg) {
comp.paintAll(cg);
}
static PaintAllCallback getInstance() {
return instance;
}
}
static final class PrintAllCallback extends GraphicsCallback {
private static PrintAllCallback instance = new PrintAllCallback();
private PrintAllCallback() {}
public void run(Component comp, Graphics cg) {
comp.printAll(cg);
}
static PrintAllCallback getInstance() {
return instance;
}
}
static final class PeerPaintCallback extends GraphicsCallback {
private static PeerPaintCallback instance = new PeerPaintCallback();
private PeerPaintCallback() {}
public void run(Component comp, Graphics cg) {
comp.validate();
if (comp.peer instanceof LightweightPeer) {
comp.lightweightPaint(cg);
} else {
comp.peer.paint(cg);
}
}
static PeerPaintCallback getInstance() {
return instance;
}
}
static final class PeerPrintCallback extends GraphicsCallback {
private static PeerPrintCallback instance = new PeerPrintCallback();
private PeerPrintCallback() {}
public void run(Component comp, Graphics cg) {
comp.validate();
if (comp.peer instanceof LightweightPeer) {
comp.lightweightPrint(cg);
} else {
comp.peer.print(cg);
}
}
static PeerPrintCallback getInstance() {
return instance;
}
}
static final class PaintHeavyweightComponentsCallback
extends GraphicsCallback
{
private static PaintHeavyweightComponentsCallback instance =
new PaintHeavyweightComponentsCallback();
private PaintHeavyweightComponentsCallback() {}
public void run(Component comp, Graphics cg) {
if (comp.peer instanceof LightweightPeer) {
comp.paintHeavyweightComponents(cg);
} else {
comp.paintAll(cg);
}
}
static PaintHeavyweightComponentsCallback getInstance() {
return instance;
}
}
static final class PrintHeavyweightComponentsCallback
extends GraphicsCallback
{
private static PrintHeavyweightComponentsCallback instance =
new PrintHeavyweightComponentsCallback();
private PrintHeavyweightComponentsCallback() {}
public void run(Component comp, Graphics cg) {
if (comp.peer instanceof LightweightPeer) {
comp.printHeavyweightComponents(cg);
} else {
comp.printAll(cg);
}
}
static PrintHeavyweightComponentsCallback getInstance() {
return instance;
}
}
}

View File

@@ -0,0 +1,111 @@
/*
* Copyright (c) 1997, 2007, 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 java.awt;
import java.io.*;
/**
* The <code>GraphicsConfigTemplate</code> class is used to obtain a valid
* {@link GraphicsConfiguration}. A user instantiates one of these
* objects and then sets all non-default attributes as desired. The
* {@link GraphicsDevice#getBestConfiguration} method found in the
* {@link GraphicsDevice} class is then called with this
* <code>GraphicsConfigTemplate</code>. A valid
* <code>GraphicsConfiguration</code> is returned that meets or exceeds
* what was requested in the <code>GraphicsConfigTemplate</code>.
* @see GraphicsDevice
* @see GraphicsConfiguration
*
* @since 1.2
*/
public abstract class GraphicsConfigTemplate implements Serializable {
/*
* serialVersionUID
*/
private static final long serialVersionUID = -8061369279557787079L;
/**
* This class is an abstract class so only subclasses can be
* instantiated.
*/
public GraphicsConfigTemplate() {
}
/**
* Value used for "Enum" (Integer) type. States that this
* feature is required for the <code>GraphicsConfiguration</code>
* object. If this feature is not available, do not select the
* <code>GraphicsConfiguration</code> object.
*/
public static final int REQUIRED = 1;
/**
* Value used for "Enum" (Integer) type. States that this
* feature is desired for the <code>GraphicsConfiguration</code>
* object. A selection with this feature is preferred over a
* selection that does not include this feature, although both
* selections can be considered valid matches.
*/
public static final int PREFERRED = 2;
/**
* Value used for "Enum" (Integer) type. States that this
* feature is not necessary for the selection of the
* <code>GraphicsConfiguration</code> object. A selection
* without this feature is preferred over a selection that
* includes this feature since it is not used.
*/
public static final int UNNECESSARY = 3;
/**
* Returns the "best" configuration possible that passes the
* criteria defined in the <code>GraphicsConfigTemplate</code>.
* @param gc the array of <code>GraphicsConfiguration</code>
* objects to choose from.
* @return a <code>GraphicsConfiguration</code> object that is
* the best configuration possible.
* @see GraphicsConfiguration
*/
public abstract GraphicsConfiguration
getBestConfiguration(GraphicsConfiguration[] gc);
/**
* Returns a <code>boolean</code> indicating whether or
* not the specified <code>GraphicsConfiguration</code> can be
* used to create a drawing surface that supports the indicated
* features.
* @param gc the <code>GraphicsConfiguration</code> object to test
* @return <code>true</code> if this
* <code>GraphicsConfiguration</code> object can be used to create
* surfaces that support the indicated features;
* <code>false</code> if the <code>GraphicsConfiguration</code> can
* not be used to create a drawing surface usable by this Java(tm)
* API.
*/
public abstract boolean
isGraphicsConfigSupported(GraphicsConfiguration gc);
}

View File

@@ -0,0 +1,454 @@
/*
* 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 java.awt;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.VolatileImage;
import java.awt.image.WritableRaster;
import sun.awt.image.SunVolatileImage;
/**
* The <code>GraphicsConfiguration</code> class describes the
* characteristics of a graphics destination such as a printer or monitor.
* There can be many <code>GraphicsConfiguration</code> objects associated
* with a single graphics device, representing different drawing modes or
* capabilities. The corresponding native structure will vary from platform
* to platform. For example, on X11 windowing systems,
* each visual is a different <code>GraphicsConfiguration</code>.
* On Microsoft Windows, <code>GraphicsConfiguration</code>s represent
* PixelFormats available in the current resolution and color depth.
* <p>
* In a virtual device multi-screen environment in which the desktop
* area could span multiple physical screen devices, the bounds of the
* <code>GraphicsConfiguration</code> objects are relative to the
* virtual coordinate system. When setting the location of a
* component, use {@link #getBounds() getBounds} to get the bounds of
* the desired <code>GraphicsConfiguration</code> and offset the location
* with the coordinates of the <code>GraphicsConfiguration</code>,
* as the following code sample illustrates:
* </p>
*
* <pre>
* Frame f = new Frame(gc); // where gc is a GraphicsConfiguration
* Rectangle bounds = gc.getBounds();
* f.setLocation(10 + bounds.x, 10 + bounds.y); </pre>
*
* <p>
* To determine if your environment is a virtual device
* environment, call <code>getBounds</code> on all of the
* <code>GraphicsConfiguration</code> objects in your system. If
* any of the origins of the returned bounds is not (0,&nbsp;0),
* your environment is a virtual device environment.
*
* <p>
* You can also use <code>getBounds</code> to determine the bounds
* of the virtual device. To do this, first call <code>getBounds</code> on all
* of the <code>GraphicsConfiguration</code> objects in your
* system. Then calculate the union of all of the bounds returned
* from the calls to <code>getBounds</code>. The union is the
* bounds of the virtual device. The following code sample
* calculates the bounds of the virtual device.
*
* <pre>{@code
* Rectangle virtualBounds = new Rectangle();
* GraphicsEnvironment ge = GraphicsEnvironment.
* getLocalGraphicsEnvironment();
* GraphicsDevice[] gs =
* ge.getScreenDevices();
* for (int j = 0; j < gs.length; j++) {
* GraphicsDevice gd = gs[j];
* GraphicsConfiguration[] gc =
* gd.getConfigurations();
* for (int i=0; i < gc.length; i++) {
* virtualBounds =
* virtualBounds.union(gc[i].getBounds());
* }
* } }</pre>
*
* @see Window
* @see Frame
* @see GraphicsEnvironment
* @see GraphicsDevice
*/
/*
* REMIND: What to do about capabilities?
* The
* capabilities of the device can be determined by enumerating the possible
* capabilities and checking if the GraphicsConfiguration
* implements the interface for that capability.
*
*/
public abstract class GraphicsConfiguration {
private static BufferCapabilities defaultBufferCaps;
private static ImageCapabilities defaultImageCaps;
/**
* This is an abstract class that cannot be instantiated directly.
* Instances must be obtained from a suitable factory or query method.
*
* @see GraphicsDevice#getConfigurations
* @see GraphicsDevice#getDefaultConfiguration
* @see GraphicsDevice#getBestConfiguration
* @see Graphics2D#getDeviceConfiguration
*/
protected GraphicsConfiguration() {
}
/**
* Returns the {@link GraphicsDevice} associated with this
* <code>GraphicsConfiguration</code>.
* @return a <code>GraphicsDevice</code> object that is
* associated with this <code>GraphicsConfiguration</code>.
*/
public abstract GraphicsDevice getDevice();
/**
* Returns a {@link BufferedImage} with a data layout and color model
* compatible with this <code>GraphicsConfiguration</code>. This
* method has nothing to do with memory-mapping
* a device. The returned <code>BufferedImage</code> has
* a layout and color model that is closest to this native device
* configuration and can therefore be optimally blitted to this
* device.
* @param width the width of the returned <code>BufferedImage</code>
* @param height the height of the returned <code>BufferedImage</code>
* @return a <code>BufferedImage</code> whose data layout and color
* model is compatible with this <code>GraphicsConfiguration</code>.
*/
public BufferedImage createCompatibleImage(int width, int height) {
ColorModel model = getColorModel();
WritableRaster raster =
model.createCompatibleWritableRaster(width, height);
return new BufferedImage(model, raster,
model.isAlphaPremultiplied(), null);
}
/**
* Returns a <code>BufferedImage</code> that supports the specified
* transparency and has a data layout and color model
* compatible with this <code>GraphicsConfiguration</code>. This
* method has nothing to do with memory-mapping
* a device. The returned <code>BufferedImage</code> has a layout and
* color model that can be optimally blitted to a device
* with this <code>GraphicsConfiguration</code>.
* @param width the width of the returned <code>BufferedImage</code>
* @param height the height of the returned <code>BufferedImage</code>
* @param transparency the specified transparency mode
* @return a <code>BufferedImage</code> whose data layout and color
* model is compatible with this <code>GraphicsConfiguration</code>
* and also supports the specified transparency.
* @throws IllegalArgumentException if the transparency is not a valid value
* @see Transparency#OPAQUE
* @see Transparency#BITMASK
* @see Transparency#TRANSLUCENT
*/
public BufferedImage createCompatibleImage(int width, int height,
int transparency)
{
if (getColorModel().getTransparency() == transparency) {
return createCompatibleImage(width, height);
}
ColorModel cm = getColorModel(transparency);
if (cm == null) {
throw new IllegalArgumentException("Unknown transparency: " +
transparency);
}
WritableRaster wr = cm.createCompatibleWritableRaster(width, height);
return new BufferedImage(cm, wr, cm.isAlphaPremultiplied(), null);
}
/**
* Returns a {@link VolatileImage} with a data layout and color model
* compatible with this <code>GraphicsConfiguration</code>.
* The returned <code>VolatileImage</code>
* may have data that is stored optimally for the underlying graphics
* device and may therefore benefit from platform-specific rendering
* acceleration.
* @param width the width of the returned <code>VolatileImage</code>
* @param height the height of the returned <code>VolatileImage</code>
* @return a <code>VolatileImage</code> whose data layout and color
* model is compatible with this <code>GraphicsConfiguration</code>.
* @see Component#createVolatileImage(int, int)
* @since 1.4
*/
public VolatileImage createCompatibleVolatileImage(int width, int height) {
VolatileImage vi = null;
try {
vi = createCompatibleVolatileImage(width, height,
null, Transparency.OPAQUE);
} catch (AWTException e) {
// shouldn't happen: we're passing in null caps
assert false;
}
return vi;
}
/**
* Returns a {@link VolatileImage} with a data layout and color model
* compatible with this <code>GraphicsConfiguration</code>.
* The returned <code>VolatileImage</code>
* may have data that is stored optimally for the underlying graphics
* device and may therefore benefit from platform-specific rendering
* acceleration.
* @param width the width of the returned <code>VolatileImage</code>
* @param height the height of the returned <code>VolatileImage</code>
* @param transparency the specified transparency mode
* @return a <code>VolatileImage</code> whose data layout and color
* model is compatible with this <code>GraphicsConfiguration</code>.
* @throws IllegalArgumentException if the transparency is not a valid value
* @see Transparency#OPAQUE
* @see Transparency#BITMASK
* @see Transparency#TRANSLUCENT
* @see Component#createVolatileImage(int, int)
* @since 1.5
*/
public VolatileImage createCompatibleVolatileImage(int width, int height,
int transparency)
{
VolatileImage vi = null;
try {
vi = createCompatibleVolatileImage(width, height, null, transparency);
} catch (AWTException e) {
// shouldn't happen: we're passing in null caps
assert false;
}
return vi;
}
/**
* Returns a {@link VolatileImage} with a data layout and color model
* compatible with this <code>GraphicsConfiguration</code>, using
* the specified image capabilities.
* If the <code>caps</code> parameter is null, it is effectively ignored
* and this method will create a VolatileImage without regard to
* <code>ImageCapabilities</code> constraints.
*
* The returned <code>VolatileImage</code> has
* a layout and color model that is closest to this native device
* configuration and can therefore be optimally blitted to this
* device.
* @return a <code>VolatileImage</code> whose data layout and color
* model is compatible with this <code>GraphicsConfiguration</code>.
* @param width the width of the returned <code>VolatileImage</code>
* @param height the height of the returned <code>VolatileImage</code>
* @param caps the image capabilities
* @exception AWTException if the supplied image capabilities could not
* be met by this graphics configuration
* @since 1.4
*/
public VolatileImage createCompatibleVolatileImage(int width, int height,
ImageCapabilities caps) throws AWTException
{
return createCompatibleVolatileImage(width, height, caps,
Transparency.OPAQUE);
}
/**
* Returns a {@link VolatileImage} with a data layout and color model
* compatible with this <code>GraphicsConfiguration</code>, using
* the specified image capabilities and transparency value.
* If the <code>caps</code> parameter is null, it is effectively ignored
* and this method will create a VolatileImage without regard to
* <code>ImageCapabilities</code> constraints.
*
* The returned <code>VolatileImage</code> has
* a layout and color model that is closest to this native device
* configuration and can therefore be optimally blitted to this
* device.
* @param width the width of the returned <code>VolatileImage</code>
* @param height the height of the returned <code>VolatileImage</code>
* @param caps the image capabilities
* @param transparency the specified transparency mode
* @return a <code>VolatileImage</code> whose data layout and color
* model is compatible with this <code>GraphicsConfiguration</code>.
* @see Transparency#OPAQUE
* @see Transparency#BITMASK
* @see Transparency#TRANSLUCENT
* @throws IllegalArgumentException if the transparency is not a valid value
* @exception AWTException if the supplied image capabilities could not
* be met by this graphics configuration
* @see Component#createVolatileImage(int, int)
* @since 1.5
*/
public VolatileImage createCompatibleVolatileImage(int width, int height,
ImageCapabilities caps, int transparency) throws AWTException
{
VolatileImage vi =
new SunVolatileImage(this, width, height, transparency, caps);
if (caps != null && caps.isAccelerated() &&
!vi.getCapabilities().isAccelerated())
{
throw new AWTException("Supplied image capabilities could not " +
"be met by this graphics configuration.");
}
return vi;
}
/**
* Returns the {@link ColorModel} associated with this
* <code>GraphicsConfiguration</code>.
* @return a <code>ColorModel</code> object that is associated with
* this <code>GraphicsConfiguration</code>.
*/
public abstract ColorModel getColorModel();
/**
* Returns the <code>ColorModel</code> associated with this
* <code>GraphicsConfiguration</code> that supports the specified
* transparency.
* @param transparency the specified transparency mode
* @return a <code>ColorModel</code> object that is associated with
* this <code>GraphicsConfiguration</code> and supports the
* specified transparency or null if the transparency is not a valid
* value.
* @see Transparency#OPAQUE
* @see Transparency#BITMASK
* @see Transparency#TRANSLUCENT
*/
public abstract ColorModel getColorModel(int transparency);
/**
* Returns the default {@link AffineTransform} for this
* <code>GraphicsConfiguration</code>. This
* <code>AffineTransform</code> is typically the Identity transform
* for most normal screens. The default <code>AffineTransform</code>
* maps coordinates onto the device such that 72 user space
* coordinate units measure approximately 1 inch in device
* space. The normalizing transform can be used to make
* this mapping more exact. Coordinates in the coordinate space
* defined by the default <code>AffineTransform</code> for screen and
* printer devices have the origin in the upper left-hand corner of
* the target region of the device, with X coordinates
* increasing to the right and Y coordinates increasing downwards.
* For image buffers not associated with a device, such as those not
* created by <code>createCompatibleImage</code>,
* this <code>AffineTransform</code> is the Identity transform.
* @return the default <code>AffineTransform</code> for this
* <code>GraphicsConfiguration</code>.
*/
public abstract AffineTransform getDefaultTransform();
/**
*
* Returns a <code>AffineTransform</code> that can be concatenated
* with the default <code>AffineTransform</code>
* of a <code>GraphicsConfiguration</code> so that 72 units in user
* space equals 1 inch in device space.
* <p>
* For a particular {@link Graphics2D}, g, one
* can reset the transformation to create
* such a mapping by using the following pseudocode:
* <pre>
* GraphicsConfiguration gc = g.getDeviceConfiguration();
*
* g.setTransform(gc.getDefaultTransform());
* g.transform(gc.getNormalizingTransform());
* </pre>
* Note that sometimes this <code>AffineTransform</code> is identity,
* such as for printers or metafile output, and that this
* <code>AffineTransform</code> is only as accurate as the information
* supplied by the underlying system. For image buffers not
* associated with a device, such as those not created by
* <code>createCompatibleImage</code>, this
* <code>AffineTransform</code> is the Identity transform
* since there is no valid distance measurement.
* @return an <code>AffineTransform</code> to concatenate to the
* default <code>AffineTransform</code> so that 72 units in user
* space is mapped to 1 inch in device space.
*/
public abstract AffineTransform getNormalizingTransform();
/**
* Returns the bounds of the <code>GraphicsConfiguration</code>
* in the device coordinates. In a multi-screen environment
* with a virtual device, the bounds can have negative X
* or Y origins.
* @return the bounds of the area covered by this
* <code>GraphicsConfiguration</code>.
* @since 1.3
*/
public abstract Rectangle getBounds();
private static class DefaultBufferCapabilities extends BufferCapabilities {
public DefaultBufferCapabilities(ImageCapabilities imageCaps) {
super(imageCaps, imageCaps, null);
}
}
/**
* Returns the buffering capabilities of this
* <code>GraphicsConfiguration</code>.
* @return the buffering capabilities of this graphics
* configuration object
* @since 1.4
*/
public BufferCapabilities getBufferCapabilities() {
if (defaultBufferCaps == null) {
defaultBufferCaps = new DefaultBufferCapabilities(
getImageCapabilities());
}
return defaultBufferCaps;
}
/**
* Returns the image capabilities of this
* <code>GraphicsConfiguration</code>.
* @return the image capabilities of this graphics
* configuration object
* @since 1.4
*/
public ImageCapabilities getImageCapabilities() {
if (defaultImageCaps == null) {
defaultImageCaps = new ImageCapabilities(false);
}
return defaultImageCaps;
}
/**
* Returns whether this {@code GraphicsConfiguration} supports
* the {@link GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSLUCENT
* PERPIXEL_TRANSLUCENT} kind of translucency.
*
* @return whether the given GraphicsConfiguration supports
* the translucency effects.
*
* @see Window#setBackground(Color)
*
* @since 1.7
*/
public boolean isTranslucencyCapable() {
// Overridden in subclasses
return false;
}
}

View File

@@ -0,0 +1,594 @@
/*
* 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 java.awt;
import java.awt.image.ColorModel;
import sun.awt.AWTAccessor;
import sun.awt.AppContext;
import sun.awt.SunToolkit;
/**
* The <code>GraphicsDevice</code> class describes the graphics devices
* that might be available in a particular graphics environment. These
* include screen and printer devices. Note that there can be many screens
* and many printers in an instance of {@link GraphicsEnvironment}. Each
* graphics device has one or more {@link GraphicsConfiguration} objects
* associated with it. These objects specify the different configurations
* in which the <code>GraphicsDevice</code> can be used.
* <p>
* In a multi-screen environment, the <code>GraphicsConfiguration</code>
* objects can be used to render components on multiple screens. The
* following code sample demonstrates how to create a <code>JFrame</code>
* object for each <code>GraphicsConfiguration</code> on each screen
* device in the <code>GraphicsEnvironment</code>:
* <pre>{@code
* GraphicsEnvironment ge = GraphicsEnvironment.
* getLocalGraphicsEnvironment();
* GraphicsDevice[] gs = ge.getScreenDevices();
* for (int j = 0; j < gs.length; j++) {
* GraphicsDevice gd = gs[j];
* GraphicsConfiguration[] gc =
* gd.getConfigurations();
* for (int i=0; i < gc.length; i++) {
* JFrame f = new
* JFrame(gs[j].getDefaultConfiguration());
* Canvas c = new Canvas(gc[i]);
* Rectangle gcBounds = gc[i].getBounds();
* int xoffs = gcBounds.x;
* int yoffs = gcBounds.y;
* f.getContentPane().add(c);
* f.setLocation((i*50)+xoffs, (i*60)+yoffs);
* f.show();
* }
* }
* }</pre>
* <p>
* For more information on full-screen exclusive mode API, see the
* <a href="https://docs.oracle.com/javase/tutorial/extra/fullscreen/index.html">
* Full-Screen Exclusive Mode API Tutorial</a>.
*
* @see GraphicsEnvironment
* @see GraphicsConfiguration
*/
public abstract class GraphicsDevice {
private Window fullScreenWindow;
private AppContext fullScreenAppContext; // tracks which AppContext
// created the FS window
// this lock is used for making synchronous changes to the AppContext's
// current full screen window
private final Object fsAppContextLock = new Object();
private Rectangle windowedModeBounds;
/**
* This is an abstract class that cannot be instantiated directly.
* Instances must be obtained from a suitable factory or query method.
* @see GraphicsEnvironment#getScreenDevices
* @see GraphicsEnvironment#getDefaultScreenDevice
* @see GraphicsConfiguration#getDevice
*/
protected GraphicsDevice() {
}
/**
* Device is a raster screen.
*/
public final static int TYPE_RASTER_SCREEN = 0;
/**
* Device is a printer.
*/
public final static int TYPE_PRINTER = 1;
/**
* Device is an image buffer. This buffer can reside in device
* or system memory but it is not physically viewable by the user.
*/
public final static int TYPE_IMAGE_BUFFER = 2;
/**
* Kinds of translucency supported by the underlying system.
*
* @see #isWindowTranslucencySupported
*
* @since 1.7
*/
public static enum WindowTranslucency {
/**
* Represents support in the underlying system for windows each pixel
* of which is guaranteed to be either completely opaque, with
* an alpha value of 1.0, or completely transparent, with an alpha
* value of 0.0.
*/
PERPIXEL_TRANSPARENT,
/**
* Represents support in the underlying system for windows all of
* the pixels of which have the same alpha value between or including
* 0.0 and 1.0.
*/
TRANSLUCENT,
/**
* Represents support in the underlying system for windows that
* contain or might contain pixels with arbitrary alpha values
* between and including 0.0 and 1.0.
*/
PERPIXEL_TRANSLUCENT;
}
/**
* Returns the type of this <code>GraphicsDevice</code>.
* @return the type of this <code>GraphicsDevice</code>, which can
* either be TYPE_RASTER_SCREEN, TYPE_PRINTER or TYPE_IMAGE_BUFFER.
* @see #TYPE_RASTER_SCREEN
* @see #TYPE_PRINTER
* @see #TYPE_IMAGE_BUFFER
*/
public abstract int getType();
/**
* Returns the identification string associated with this
* <code>GraphicsDevice</code>.
* <p>
* A particular program might use more than one
* <code>GraphicsDevice</code> in a <code>GraphicsEnvironment</code>.
* This method returns a <code>String</code> identifying a
* particular <code>GraphicsDevice</code> in the local
* <code>GraphicsEnvironment</code>. Although there is
* no public method to set this <code>String</code>, a programmer can
* use the <code>String</code> for debugging purposes. Vendors of
* the Java&trade; Runtime Environment can
* format the return value of the <code>String</code>. To determine
* how to interpret the value of the <code>String</code>, contact the
* vendor of your Java Runtime. To find out who the vendor is, from
* your program, call the
* {@link System#getProperty(String) getProperty} method of the
* System class with "java.vendor".
* @return a <code>String</code> that is the identification
* of this <code>GraphicsDevice</code>.
*/
public abstract String getIDstring();
/**
* Returns all of the <code>GraphicsConfiguration</code>
* objects associated with this <code>GraphicsDevice</code>.
* @return an array of <code>GraphicsConfiguration</code>
* objects that are associated with this
* <code>GraphicsDevice</code>.
*/
public abstract GraphicsConfiguration[] getConfigurations();
/**
* Returns the default <code>GraphicsConfiguration</code>
* associated with this <code>GraphicsDevice</code>.
* @return the default <code>GraphicsConfiguration</code>
* of this <code>GraphicsDevice</code>.
*/
public abstract GraphicsConfiguration getDefaultConfiguration();
/**
* Returns the "best" configuration possible that passes the
* criteria defined in the {@link GraphicsConfigTemplate}.
* @param gct the <code>GraphicsConfigTemplate</code> object
* used to obtain a valid <code>GraphicsConfiguration</code>
* @return a <code>GraphicsConfiguration</code> that passes
* the criteria defined in the specified
* <code>GraphicsConfigTemplate</code>.
* @see GraphicsConfigTemplate
*/
public GraphicsConfiguration
getBestConfiguration(GraphicsConfigTemplate gct) {
GraphicsConfiguration[] configs = getConfigurations();
return gct.getBestConfiguration(configs);
}
/**
* Returns <code>true</code> if this <code>GraphicsDevice</code>
* supports full-screen exclusive mode.
* If a SecurityManager is installed, its
* <code>checkPermission</code> method will be called
* with <code>AWTPermission("fullScreenExclusive")</code>.
* <code>isFullScreenSupported</code> returns true only if
* that permission is granted.
* @return whether full-screen exclusive mode is available for
* this graphics device
* @see java.awt.AWTPermission
* @since 1.4
*/
public boolean isFullScreenSupported() {
return false;
}
/**
* Enter full-screen mode, or return to windowed mode. The entered
* full-screen mode may be either exclusive or simulated. Exclusive
* mode is only available if <code>isFullScreenSupported</code>
* returns <code>true</code>.
* <p>
* Exclusive mode implies:
* <ul>
* <li>Windows cannot overlap the full-screen window. All other application
* windows will always appear beneath the full-screen window in the Z-order.
* <li>There can be only one full-screen window on a device at any time,
* so calling this method while there is an existing full-screen Window
* will cause the existing full-screen window to
* return to windowed mode.
* <li>Input method windows are disabled. It is advisable to call
* <code>Component.enableInputMethods(false)</code> to make a component
* a non-client of the input method framework.
* </ul>
* <p>
* The simulated full-screen mode places and resizes the window to the maximum
* possible visible area of the screen. However, the native windowing system
* may modify the requested geometry-related data, so that the {@code Window} object
* is placed and sized in a way that corresponds closely to the desktop settings.
* <p>
* When entering full-screen mode, if the window to be used as a
* full-screen window is not visible, this method will make it visible.
* It will remain visible when returning to windowed mode.
* <p>
* When entering full-screen mode, all the translucency effects are reset for
* the window. Its shape is set to {@code null}, the opacity value is set to
* 1.0f, and the background color alpha is set to 255 (completely opaque).
* These values are not restored when returning to windowed mode.
* <p>
* It is unspecified and platform-dependent how decorated windows operate
* in full-screen mode. For this reason, it is recommended to turn off
* the decorations in a {@code Frame} or {@code Dialog} object by using the
* {@code setUndecorated} method.
* <p>
* When returning to windowed mode from an exclusive full-screen window,
* any display changes made by calling {@code setDisplayMode} are
* automatically restored to their original state.
*
* @param w a window to use as the full-screen window; {@code null}
* if returning to windowed mode. Some platforms expect the
* fullscreen window to be a top-level component (i.e., a {@code Frame});
* therefore it is preferable to use a {@code Frame} here rather than a
* {@code Window}.
*
* @see #isFullScreenSupported
* @see #getFullScreenWindow
* @see #setDisplayMode
* @see Component#enableInputMethods
* @see Component#setVisible
* @see Frame#setUndecorated
* @see Dialog#setUndecorated
*
* @since 1.4
*/
public void setFullScreenWindow(Window w) {
if (w != null) {
if (w.getShape() != null) {
w.setShape(null);
}
if (w.getOpacity() < 1.0f) {
w.setOpacity(1.0f);
}
if (!w.isOpaque()) {
Color bgColor = w.getBackground();
bgColor = new Color(bgColor.getRed(), bgColor.getGreen(),
bgColor.getBlue(), 255);
w.setBackground(bgColor);
}
// Check if this window is in fullscreen mode on another device.
final GraphicsConfiguration gc = w.getGraphicsConfiguration();
if (gc != null && gc.getDevice() != this
&& gc.getDevice().getFullScreenWindow() == w) {
gc.getDevice().setFullScreenWindow(null);
}
}
if (fullScreenWindow != null && windowedModeBounds != null) {
// if the window went into fs mode before it was realized it may
// have (0,0) dimensions
if (windowedModeBounds.width == 0) windowedModeBounds.width = 1;
if (windowedModeBounds.height == 0) windowedModeBounds.height = 1;
fullScreenWindow.setBounds(windowedModeBounds);
}
// Set the full screen window
synchronized (fsAppContextLock) {
// Associate fullscreen window with current AppContext
if (w == null) {
fullScreenAppContext = null;
} else {
fullScreenAppContext = AppContext.getAppContext();
}
fullScreenWindow = w;
}
if (fullScreenWindow != null) {
windowedModeBounds = fullScreenWindow.getBounds();
// Note that we use the graphics configuration of the device,
// not the window's, because we're setting the fs window for
// this device.
final GraphicsConfiguration gc = getDefaultConfiguration();
final Rectangle screenBounds = gc.getBounds();
if (SunToolkit.isDispatchThreadForAppContext(fullScreenWindow)) {
// Update graphics configuration here directly and do not wait
// asynchronous notification from the peer. Note that
// setBounds() will reset a GC, if it was set incorrectly.
fullScreenWindow.setGraphicsConfiguration(gc);
}
fullScreenWindow.setBounds(screenBounds.x, screenBounds.y,
screenBounds.width, screenBounds.height);
fullScreenWindow.setVisible(true);
fullScreenWindow.toFront();
}
}
/**
* Returns the <code>Window</code> object representing the
* full-screen window if the device is in full-screen mode.
*
* @return the full-screen window, or <code>null</code> if the device is
* not in full-screen mode.
* @see #setFullScreenWindow(Window)
* @since 1.4
*/
public Window getFullScreenWindow() {
Window returnWindow = null;
synchronized (fsAppContextLock) {
// Only return a handle to the current fs window if we are in the
// same AppContext that set the fs window
if (fullScreenAppContext == AppContext.getAppContext()) {
returnWindow = fullScreenWindow;
}
}
return returnWindow;
}
/**
* Returns <code>true</code> if this <code>GraphicsDevice</code>
* supports low-level display changes.
* On some platforms low-level display changes may only be allowed in
* full-screen exclusive mode (i.e., if {@link #isFullScreenSupported()}
* returns {@code true} and the application has already entered
* full-screen mode using {@link #setFullScreenWindow}).
* @return whether low-level display changes are supported for this
* graphics device.
* @see #isFullScreenSupported
* @see #setDisplayMode
* @see #setFullScreenWindow
* @since 1.4
*/
public boolean isDisplayChangeSupported() {
return false;
}
/**
* Sets the display mode of this graphics device. This is only allowed
* if {@link #isDisplayChangeSupported()} returns {@code true} and may
* require first entering full-screen exclusive mode using
* {@link #setFullScreenWindow} providing that full-screen exclusive mode is
* supported (i.e., {@link #isFullScreenSupported()} returns
* {@code true}).
* <p>
*
* The display mode must be one of the display modes returned by
* {@link #getDisplayModes()}, with one exception: passing a display mode
* with {@link DisplayMode#REFRESH_RATE_UNKNOWN} refresh rate will result in
* selecting a display mode from the list of available display modes with
* matching width, height and bit depth.
* However, passing a display mode with {@link DisplayMode#BIT_DEPTH_MULTI}
* for bit depth is only allowed if such mode exists in the list returned by
* {@link #getDisplayModes()}.
* <p>
* Example code:
* <pre><code>
* Frame frame;
* DisplayMode newDisplayMode;
* GraphicsDevice gd;
* // create a Frame, select desired DisplayMode from the list of modes
* // returned by gd.getDisplayModes() ...
*
* if (gd.isFullScreenSupported()) {
* gd.setFullScreenWindow(frame);
* } else {
* // proceed in non-full-screen mode
* frame.setSize(...);
* frame.setLocation(...);
* frame.setVisible(true);
* }
*
* if (gd.isDisplayChangeSupported()) {
* gd.setDisplayMode(newDisplayMode);
* }
* </code></pre>
*
* @param dm The new display mode of this graphics device.
* @exception IllegalArgumentException if the <code>DisplayMode</code>
* supplied is <code>null</code>, or is not available in the array returned
* by <code>getDisplayModes</code>
* @exception UnsupportedOperationException if
* <code>isDisplayChangeSupported</code> returns <code>false</code>
* @see #getDisplayMode
* @see #getDisplayModes
* @see #isDisplayChangeSupported
* @since 1.4
*/
public void setDisplayMode(DisplayMode dm) {
throw new UnsupportedOperationException("Cannot change display mode");
}
/**
* Returns the current display mode of this
* <code>GraphicsDevice</code>.
* The returned display mode is allowed to have a refresh rate
* {@link DisplayMode#REFRESH_RATE_UNKNOWN} if it is indeterminate.
* Likewise, the returned display mode is allowed to have a bit depth
* {@link DisplayMode#BIT_DEPTH_MULTI} if it is indeterminate or if multiple
* bit depths are supported.
* @return the current display mode of this graphics device.
* @see #setDisplayMode(DisplayMode)
* @since 1.4
*/
public DisplayMode getDisplayMode() {
GraphicsConfiguration gc = getDefaultConfiguration();
Rectangle r = gc.getBounds();
ColorModel cm = gc.getColorModel();
return new DisplayMode(r.width, r.height, cm.getPixelSize(), 0);
}
/**
* Returns all display modes available for this
* <code>GraphicsDevice</code>.
* The returned display modes are allowed to have a refresh rate
* {@link DisplayMode#REFRESH_RATE_UNKNOWN} if it is indeterminate.
* Likewise, the returned display modes are allowed to have a bit depth
* {@link DisplayMode#BIT_DEPTH_MULTI} if it is indeterminate or if multiple
* bit depths are supported.
* @return all of the display modes available for this graphics device.
* @since 1.4
*/
public DisplayMode[] getDisplayModes() {
return new DisplayMode[] { getDisplayMode() };
}
/**
* This method returns the number of bytes available in
* accelerated memory on this device.
* Some images are created or cached
* in accelerated memory on a first-come,
* first-served basis. On some operating systems,
* this memory is a finite resource. Calling this method
* and scheduling the creation and flushing of images carefully may
* enable applications to make the most efficient use of
* that finite resource.
* <br>
* Note that the number returned is a snapshot of how much
* memory is available; some images may still have problems
* being allocated into that memory. For example, depending
* on operating system, driver, memory configuration, and
* thread situations, the full extent of the size reported
* may not be available for a given image. There are further
* inquiry methods on the {@link ImageCapabilities} object
* associated with a VolatileImage that can be used to determine
* whether a particular VolatileImage has been created in accelerated
* memory.
* @return number of bytes available in accelerated memory.
* A negative return value indicates that the amount of accelerated memory
* on this GraphicsDevice is indeterminate.
* @see java.awt.image.VolatileImage#flush
* @see ImageCapabilities#isAccelerated
* @since 1.4
*/
public int getAvailableAcceleratedMemory() {
return -1;
}
/**
* Returns whether the given level of translucency is supported by
* this graphics device.
*
* @param translucencyKind a kind of translucency support
* @return whether the given translucency kind is supported
*
* @since 1.7
*/
public boolean isWindowTranslucencySupported(WindowTranslucency translucencyKind) {
switch (translucencyKind) {
case PERPIXEL_TRANSPARENT:
return isWindowShapingSupported();
case TRANSLUCENT:
return isWindowOpacitySupported();
case PERPIXEL_TRANSLUCENT:
return isWindowPerpixelTranslucencySupported();
}
return false;
}
/**
* Returns whether the windowing system supports changing the shape
* of top-level windows.
* Note that this method may sometimes return true, but the native
* windowing system may still not support the concept of
* shaping (due to the bugs in the windowing system).
*/
static boolean isWindowShapingSupported() {
Toolkit curToolkit = Toolkit.getDefaultToolkit();
if (!(curToolkit instanceof SunToolkit)) {
return false;
}
return ((SunToolkit)curToolkit).isWindowShapingSupported();
}
/**
* Returns whether the windowing system supports changing the opacity
* value of top-level windows.
* Note that this method may sometimes return true, but the native
* windowing system may still not support the concept of
* translucency (due to the bugs in the windowing system).
*/
static boolean isWindowOpacitySupported() {
Toolkit curToolkit = Toolkit.getDefaultToolkit();
if (!(curToolkit instanceof SunToolkit)) {
return false;
}
return ((SunToolkit)curToolkit).isWindowOpacitySupported();
}
boolean isWindowPerpixelTranslucencySupported() {
/*
* Per-pixel alpha is supported if all the conditions are TRUE:
* 1. The toolkit is a sort of SunToolkit
* 2. The toolkit supports translucency in general
* (isWindowTranslucencySupported())
* 3. There's at least one translucency-capable
* GraphicsConfiguration
*/
Toolkit curToolkit = Toolkit.getDefaultToolkit();
if (!(curToolkit instanceof SunToolkit)) {
return false;
}
if (!((SunToolkit)curToolkit).isWindowTranslucencySupported()) {
return false;
}
// TODO: cache translucency capable GC
return getTranslucencyCapableGC() != null;
}
GraphicsConfiguration getTranslucencyCapableGC() {
// If the default GC supports translucency return true.
// It is important to optimize the verification this way,
// see CR 6661196 for more details.
GraphicsConfiguration defaultGC = getDefaultConfiguration();
if (defaultGC.isTranslucencyCapable()) {
return defaultGC;
}
// ... otherwise iterate through all the GCs.
GraphicsConfiguration[] configs = getConfigurations();
for (int j = 0; j < configs.length; j++) {
if (configs[j].isTranslucencyCapable()) {
return configs[j];
}
}
return null;
}
}

View File

@@ -0,0 +1,459 @@
/*
* 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 java.awt;
import java.awt.image.BufferedImage;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Locale;
import sun.font.FontManager;
import sun.font.FontManagerFactory;
import sun.java2d.HeadlessGraphicsEnvironment;
import sun.java2d.SunGraphicsEnvironment;
import sun.security.action.GetPropertyAction;
/**
*
* The <code>GraphicsEnvironment</code> class describes the collection
* of {@link GraphicsDevice} objects and {@link java.awt.Font} objects
* available to a Java(tm) application on a particular platform.
* The resources in this <code>GraphicsEnvironment</code> might be local
* or on a remote machine. <code>GraphicsDevice</code> objects can be
* screens, printers or image buffers and are the destination of
* {@link Graphics2D} drawing methods. Each <code>GraphicsDevice</code>
* has a number of {@link GraphicsConfiguration} objects associated with
* it. These objects specify the different configurations in which the
* <code>GraphicsDevice</code> can be used.
* @see GraphicsDevice
* @see GraphicsConfiguration
*/
public abstract class GraphicsEnvironment {
private static GraphicsEnvironment localEnv;
/**
* The headless state of the Toolkit and GraphicsEnvironment
*/
private static Boolean headless;
/**
* The headless state assumed by default
*/
private static Boolean defaultHeadless;
/**
* This is an abstract class and cannot be instantiated directly.
* Instances must be obtained from a suitable factory or query method.
*/
protected GraphicsEnvironment() {
}
/**
* Returns the local <code>GraphicsEnvironment</code>.
* @return the local <code>GraphicsEnvironment</code>
*/
public static synchronized GraphicsEnvironment getLocalGraphicsEnvironment() {
if (localEnv == null) {
localEnv = createGE();
}
return localEnv;
}
/**
* Creates and returns the GraphicsEnvironment, according to the
* system property 'java.awt.graphicsenv'.
*
* @return the graphics environment
*/
private static GraphicsEnvironment createGE() {
GraphicsEnvironment ge;
String nm = AccessController.doPrivileged(new GetPropertyAction("java.awt.graphicsenv", null));
try {
// long t0 = System.currentTimeMillis();
Class<GraphicsEnvironment> geCls;
try {
// First we try if the bootclassloader finds the requested
// class. This way we can avoid to run in a privileged block.
geCls = (Class<GraphicsEnvironment>)Class.forName(nm);
} catch (ClassNotFoundException ex) {
// If the bootclassloader fails, we try again with the
// application classloader.
ClassLoader cl = ClassLoader.getSystemClassLoader();
geCls = (Class<GraphicsEnvironment>)Class.forName(nm, true, cl);
}
ge = geCls.newInstance();
// long t1 = System.currentTimeMillis();
// System.out.println("GE creation took " + (t1-t0)+ "ms.");
if (isHeadless()) {
ge = new HeadlessGraphicsEnvironment(ge);
}
} catch (ClassNotFoundException e) {
throw new Error("Could not find class: "+nm);
} catch (InstantiationException e) {
throw new Error("Could not instantiate Graphics Environment: "
+ nm);
} catch (IllegalAccessException e) {
throw new Error ("Could not access Graphics Environment: "
+ nm);
}
return ge;
}
/**
* Tests whether or not a display, keyboard, and mouse can be
* supported in this environment. If this method returns true,
* a HeadlessException is thrown from areas of the Toolkit
* and GraphicsEnvironment that are dependent on a display,
* keyboard, or mouse.
* @return <code>true</code> if this environment cannot support
* a display, keyboard, and mouse; <code>false</code>
* otherwise
* @see java.awt.HeadlessException
* @since 1.4
*/
public static boolean isHeadless() {
return getHeadlessProperty();
}
/**
* @return warning message if headless state is assumed by default;
* null otherwise
* @since 1.5
*/
static String getHeadlessMessage() {
if (headless == null) {
getHeadlessProperty(); // initialize the values
}
return defaultHeadless != Boolean.TRUE ? null :
"\nNo X11 DISPLAY variable was set, " +
"but this program performed an operation which requires it.";
}
/**
* @return the value of the property "java.awt.headless"
* @since 1.4
*/
private static boolean getHeadlessProperty() {
if (headless == null) {
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
String nm = System.getProperty("java.awt.headless");
if (nm == null) {
/* No need to ask for DISPLAY when run in a browser */
if (System.getProperty("javaplugin.version") != null) {
headless = defaultHeadless = Boolean.FALSE;
} else {
String osName = System.getProperty("os.name");
if (osName.contains("OS X") && "sun.awt.HToolkit".equals(
System.getProperty("awt.toolkit")))
{
headless = defaultHeadless = Boolean.TRUE;
} else {
final String display = System.getenv("DISPLAY");
headless = defaultHeadless =
("Linux".equals(osName) ||
"SunOS".equals(osName) ||
"FreeBSD".equals(osName) ||
"NetBSD".equals(osName) ||
"OpenBSD".equals(osName) ||
"AIX".equals(osName)) &&
(display == null || display.trim().isEmpty());
}
}
} else {
headless = Boolean.valueOf(nm);
}
return null;
});
}
return headless;
}
/**
* Check for headless state and throw HeadlessException if headless
* @since 1.4
*/
static void checkHeadless() throws HeadlessException {
if (isHeadless()) {
throw new HeadlessException();
}
}
/**
* Returns whether or not a display, keyboard, and mouse can be
* supported in this graphics environment. If this returns true,
* <code>HeadlessException</code> will be thrown from areas of the
* graphics environment that are dependent on a display, keyboard, or
* mouse.
* @return <code>true</code> if a display, keyboard, and mouse
* can be supported in this environment; <code>false</code>
* otherwise
* @see java.awt.HeadlessException
* @see #isHeadless
* @since 1.4
*/
public boolean isHeadlessInstance() {
// By default (local graphics environment), simply check the
// headless property.
return getHeadlessProperty();
}
/**
* Returns an array of all of the screen <code>GraphicsDevice</code>
* objects.
* @return an array containing all the <code>GraphicsDevice</code>
* objects that represent screen devices
* @exception HeadlessException if isHeadless() returns true
* @see #isHeadless()
*/
public abstract GraphicsDevice[] getScreenDevices()
throws HeadlessException;
/**
* Returns the default screen <code>GraphicsDevice</code>.
* @return the <code>GraphicsDevice</code> that represents the
* default screen device
* @exception HeadlessException if isHeadless() returns true
* @see #isHeadless()
*/
public abstract GraphicsDevice getDefaultScreenDevice()
throws HeadlessException;
/**
* Returns a <code>Graphics2D</code> object for rendering into the
* specified {@link BufferedImage}.
* @param img the specified <code>BufferedImage</code>
* @return a <code>Graphics2D</code> to be used for rendering into
* the specified <code>BufferedImage</code>
* @throws NullPointerException if <code>img</code> is null
*/
public abstract Graphics2D createGraphics(BufferedImage img);
/**
* Returns an array containing a one-point size instance of all fonts
* available in this <code>GraphicsEnvironment</code>. Typical usage
* would be to allow a user to select a particular font. Then, the
* application can size the font and set various font attributes by
* calling the <code>deriveFont</code> method on the chosen instance.
* <p>
* This method provides for the application the most precise control
* over which <code>Font</code> instance is used to render text.
* If a font in this <code>GraphicsEnvironment</code> has multiple
* programmable variations, only one
* instance of that <code>Font</code> is returned in the array, and
* other variations must be derived by the application.
* <p>
* If a font in this environment has multiple programmable variations,
* such as Multiple-Master fonts, only one instance of that font is
* returned in the <code>Font</code> array. The other variations
* must be derived by the application.
*
* @return an array of <code>Font</code> objects
* @see #getAvailableFontFamilyNames
* @see java.awt.Font
* @see java.awt.Font#deriveFont
* @see java.awt.Font#getFontName
* @since 1.2
*/
public abstract Font[] getAllFonts();
/**
* Returns an array containing the names of all font families in this
* <code>GraphicsEnvironment</code> localized for the default locale,
* as returned by <code>Locale.getDefault()</code>.
* <p>
* Typical usage would be for presentation to a user for selection of
* a particular family name. An application can then specify this name
* when creating a font, in conjunction with a style, such as bold or
* italic, giving the font system flexibility in choosing its own best
* match among multiple fonts in the same font family.
*
* @return an array of <code>String</code> containing font family names
* localized for the default locale, or a suitable alternative
* name if no name exists for this locale.
* @see #getAllFonts
* @see java.awt.Font
* @see java.awt.Font#getFamily
* @since 1.2
*/
public abstract String[] getAvailableFontFamilyNames();
/**
* Returns an array containing the names of all font families in this
* <code>GraphicsEnvironment</code> localized for the specified locale.
* <p>
* Typical usage would be for presentation to a user for selection of
* a particular family name. An application can then specify this name
* when creating a font, in conjunction with a style, such as bold or
* italic, giving the font system flexibility in choosing its own best
* match among multiple fonts in the same font family.
*
* @param l a {@link Locale} object that represents a
* particular geographical, political, or cultural region.
* Specifying <code>null</code> is equivalent to
* specifying <code>Locale.getDefault()</code>.
* @return an array of <code>String</code> containing font family names
* localized for the specified <code>Locale</code>, or a
* suitable alternative name if no name exists for the specified locale.
* @see #getAllFonts
* @see java.awt.Font
* @see java.awt.Font#getFamily
* @since 1.2
*/
public abstract String[] getAvailableFontFamilyNames(Locale l);
/**
* Registers a <i>created</i> <code>Font</code>in this
* <code>GraphicsEnvironment</code>.
* A created font is one that was returned from calling
* {@link Font#createFont}, or derived from a created font by
* calling {@link Font#deriveFont}.
* After calling this method for such a font, it is available to
* be used in constructing new <code>Font</code>s by name or family name,
* and is enumerated by {@link #getAvailableFontFamilyNames} and
* {@link #getAllFonts} within the execution context of this
* application or applet. This means applets cannot register fonts in
* a way that they are visible to other applets.
* <p>
* Reasons that this method might not register the font and therefore
* return <code>false</code> are:
* <ul>
* <li>The font is not a <i>created</i> <code>Font</code>.
* <li>The font conflicts with a non-created <code>Font</code> already
* in this <code>GraphicsEnvironment</code>. For example if the name
* is that of a system font, or a logical font as described in the
* documentation of the {@link Font} class. It is implementation dependent
* whether a font may also conflict if it has the same family name
* as a system font.
* <p>Notice that an application can supersede the registration
* of an earlier created font with a new one.
* </ul>
* @return true if the <code>font</code> is successfully
* registered in this <code>GraphicsEnvironment</code>.
* @throws NullPointerException if <code>font</code> is null
* @since 1.6
*/
public boolean registerFont(Font font) {
if (font == null) {
throw new NullPointerException("font cannot be null.");
}
FontManager fm = FontManagerFactory.getInstance();
return fm.registerFont(font);
}
/**
* Indicates a preference for locale-specific fonts in the mapping of
* logical fonts to physical fonts. Calling this method indicates that font
* rendering should primarily use fonts specific to the primary writing
* system (the one indicated by the default encoding and the initial
* default locale). For example, if the primary writing system is
* Japanese, then characters should be rendered using a Japanese font
* if possible, and other fonts should only be used for characters for
* which the Japanese font doesn't have glyphs.
* <p>
* The actual change in font rendering behavior resulting from a call
* to this method is implementation dependent; it may have no effect at
* all, or the requested behavior may already match the default behavior.
* The behavior may differ between font rendering in lightweight
* and peered components. Since calling this method requests a
* different font, clients should expect different metrics, and may need
* to recalculate window sizes and layout. Therefore this method should
* be called before user interface initialisation.
* @since 1.5
*/
public void preferLocaleFonts() {
FontManager fm = FontManagerFactory.getInstance();
fm.preferLocaleFonts();
}
/**
* Indicates a preference for proportional over non-proportional (e.g.
* dual-spaced CJK fonts) fonts in the mapping of logical fonts to
* physical fonts. If the default mapping contains fonts for which
* proportional and non-proportional variants exist, then calling
* this method indicates the mapping should use a proportional variant.
* <p>
* The actual change in font rendering behavior resulting from a call to
* this method is implementation dependent; it may have no effect at all.
* The behavior may differ between font rendering in lightweight and
* peered components. Since calling this method requests a
* different font, clients should expect different metrics, and may need
* to recalculate window sizes and layout. Therefore this method should
* be called before user interface initialisation.
* @since 1.5
*/
public void preferProportionalFonts() {
FontManager fm = FontManagerFactory.getInstance();
fm.preferProportionalFonts();
}
/**
* Returns the Point where Windows should be centered.
* It is recommended that centered Windows be checked to ensure they fit
* within the available display area using getMaximumWindowBounds().
* @return the point where Windows should be centered
*
* @exception HeadlessException if isHeadless() returns true
* @see #getMaximumWindowBounds
* @since 1.4
*/
public Point getCenterPoint() throws HeadlessException {
// Default implementation: return the center of the usable bounds of the
// default screen device.
Rectangle usableBounds =
SunGraphicsEnvironment.getUsableBounds(getDefaultScreenDevice());
return new Point((usableBounds.width / 2) + usableBounds.x,
(usableBounds.height / 2) + usableBounds.y);
}
/**
* Returns the maximum bounds for centered Windows.
* These bounds account for objects in the native windowing system such as
* task bars and menu bars. The returned bounds will reside on a single
* display with one exception: on multi-screen systems where Windows should
* be centered across all displays, this method returns the bounds of the
* entire display area.
* <p>
* To get the usable bounds of a single display, use
* <code>GraphicsConfiguration.getBounds()</code> and
* <code>Toolkit.getScreenInsets()</code>.
* @return the maximum bounds for centered Windows
*
* @exception HeadlessException if isHeadless() returns true
* @see #getCenterPoint
* @see GraphicsConfiguration#getBounds
* @see Toolkit#getScreenInsets
* @since 1.4
*/
public Rectangle getMaximumWindowBounds() throws HeadlessException {
// Default implementation: return the usable bounds of the default screen
// device. This is correct for Microsoft Windows and non-Xinerama X11.
return SunGraphicsEnvironment.getUsableBounds(getDefaultScreenDevice());
}
}

View File

@@ -0,0 +1,663 @@
/*
* Copyright (c) 1995, 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 java.awt;
/**
* The <code>GridBagConstraints</code> class specifies constraints
* for components that are laid out using the
* <code>GridBagLayout</code> class.
*
* @author Doug Stein
* @author Bill Spitzak (orignial NeWS &amp; OLIT implementation)
* @see java.awt.GridBagLayout
* @since JDK1.0
*/
public class GridBagConstraints implements Cloneable, java.io.Serializable {
/**
* Specifies that this component is the next-to-last component in its
* column or row (<code>gridwidth</code>, <code>gridheight</code>),
* or that this component be placed next to the previously added
* component (<code>gridx</code>, <code>gridy</code>).
* @see java.awt.GridBagConstraints#gridwidth
* @see java.awt.GridBagConstraints#gridheight
* @see java.awt.GridBagConstraints#gridx
* @see java.awt.GridBagConstraints#gridy
*/
public static final int RELATIVE = -1;
/**
* Specifies that this component is the
* last component in its column or row.
*/
public static final int REMAINDER = 0;
/**
* Do not resize the component.
*/
public static final int NONE = 0;
/**
* Resize the component both horizontally and vertically.
*/
public static final int BOTH = 1;
/**
* Resize the component horizontally but not vertically.
*/
public static final int HORIZONTAL = 2;
/**
* Resize the component vertically but not horizontally.
*/
public static final int VERTICAL = 3;
/**
* Put the component in the center of its display area.
*/
public static final int CENTER = 10;
/**
* Put the component at the top of its display area,
* centered horizontally.
*/
public static final int NORTH = 11;
/**
* Put the component at the top-right corner of its display area.
*/
public static final int NORTHEAST = 12;
/**
* Put the component on the right side of its display area,
* centered vertically.
*/
public static final int EAST = 13;
/**
* Put the component at the bottom-right corner of its display area.
*/
public static final int SOUTHEAST = 14;
/**
* Put the component at the bottom of its display area, centered
* horizontally.
*/
public static final int SOUTH = 15;
/**
* Put the component at the bottom-left corner of its display area.
*/
public static final int SOUTHWEST = 16;
/**
* Put the component on the left side of its display area,
* centered vertically.
*/
public static final int WEST = 17;
/**
* Put the component at the top-left corner of its display area.
*/
public static final int NORTHWEST = 18;
/**
* Place the component centered along the edge of its display area
* associated with the start of a page for the current
* {@code ComponentOrientation}. Equal to NORTH for horizontal
* orientations.
*/
public static final int PAGE_START = 19;
/**
* Place the component centered along the edge of its display area
* associated with the end of a page for the current
* {@code ComponentOrientation}. Equal to SOUTH for horizontal
* orientations.
*/
public static final int PAGE_END = 20;
/**
* Place the component centered along the edge of its display area where
* lines of text would normally begin for the current
* {@code ComponentOrientation}. Equal to WEST for horizontal,
* left-to-right orientations and EAST for horizontal, right-to-left
* orientations.
*/
public static final int LINE_START = 21;
/**
* Place the component centered along the edge of its display area where
* lines of text would normally end for the current
* {@code ComponentOrientation}. Equal to EAST for horizontal,
* left-to-right orientations and WEST for horizontal, right-to-left
* orientations.
*/
public static final int LINE_END = 22;
/**
* Place the component in the corner of its display area where
* the first line of text on a page would normally begin for the current
* {@code ComponentOrientation}. Equal to NORTHWEST for horizontal,
* left-to-right orientations and NORTHEAST for horizontal, right-to-left
* orientations.
*/
public static final int FIRST_LINE_START = 23;
/**
* Place the component in the corner of its display area where
* the first line of text on a page would normally end for the current
* {@code ComponentOrientation}. Equal to NORTHEAST for horizontal,
* left-to-right orientations and NORTHWEST for horizontal, right-to-left
* orientations.
*/
public static final int FIRST_LINE_END = 24;
/**
* Place the component in the corner of its display area where
* the last line of text on a page would normally start for the current
* {@code ComponentOrientation}. Equal to SOUTHWEST for horizontal,
* left-to-right orientations and SOUTHEAST for horizontal, right-to-left
* orientations.
*/
public static final int LAST_LINE_START = 25;
/**
* Place the component in the corner of its display area where
* the last line of text on a page would normally end for the current
* {@code ComponentOrientation}. Equal to SOUTHEAST for horizontal,
* left-to-right orientations and SOUTHWEST for horizontal, right-to-left
* orientations.
*/
public static final int LAST_LINE_END = 26;
/**
* Possible value for the <code>anchor</code> field. Specifies
* that the component should be horizontally centered and
* vertically aligned along the baseline of the prevailing row.
* If the component does not have a baseline it will be vertically
* centered.
*
* @since 1.6
*/
public static final int BASELINE = 0x100;
/**
* Possible value for the <code>anchor</code> field. Specifies
* that the component should be horizontally placed along the
* leading edge. For components with a left-to-right orientation,
* the leading edge is the left edge. Vertically the component is
* aligned along the baseline of the prevailing row. If the
* component does not have a baseline it will be vertically
* centered.
*
* @since 1.6
*/
public static final int BASELINE_LEADING = 0x200;
/**
* Possible value for the <code>anchor</code> field. Specifies
* that the component should be horizontally placed along the
* trailing edge. For components with a left-to-right
* orientation, the trailing edge is the right edge. Vertically
* the component is aligned along the baseline of the prevailing
* row. If the component does not have a baseline it will be
* vertically centered.
*
* @since 1.6
*/
public static final int BASELINE_TRAILING = 0x300;
/**
* Possible value for the <code>anchor</code> field. Specifies
* that the component should be horizontally centered. Vertically
* the component is positioned so that its bottom edge touches
* the baseline of the starting row. If the starting row does not
* have a baseline it will be vertically centered.
*
* @since 1.6
*/
public static final int ABOVE_BASELINE = 0x400;
/**
* Possible value for the <code>anchor</code> field. Specifies
* that the component should be horizontally placed along the
* leading edge. For components with a left-to-right orientation,
* the leading edge is the left edge. Vertically the component is
* positioned so that its bottom edge touches the baseline of the
* starting row. If the starting row does not have a baseline it
* will be vertically centered.
*
* @since 1.6
*/
public static final int ABOVE_BASELINE_LEADING = 0x500;
/**
* Possible value for the <code>anchor</code> field. Specifies
* that the component should be horizontally placed along the
* trailing edge. For components with a left-to-right
* orientation, the trailing edge is the right edge. Vertically
* the component is positioned so that its bottom edge touches
* the baseline of the starting row. If the starting row does not
* have a baseline it will be vertically centered.
*
* @since 1.6
*/
public static final int ABOVE_BASELINE_TRAILING = 0x600;
/**
* Possible value for the <code>anchor</code> field. Specifies
* that the component should be horizontally centered. Vertically
* the component is positioned so that its top edge touches the
* baseline of the starting row. If the starting row does not
* have a baseline it will be vertically centered.
*
* @since 1.6
*/
public static final int BELOW_BASELINE = 0x700;
/**
* Possible value for the <code>anchor</code> field. Specifies
* that the component should be horizontally placed along the
* leading edge. For components with a left-to-right orientation,
* the leading edge is the left edge. Vertically the component is
* positioned so that its top edge touches the baseline of the
* starting row. If the starting row does not have a baseline it
* will be vertically centered.
*
* @since 1.6
*/
public static final int BELOW_BASELINE_LEADING = 0x800;
/**
* Possible value for the <code>anchor</code> field. Specifies
* that the component should be horizontally placed along the
* trailing edge. For components with a left-to-right
* orientation, the trailing edge is the right edge. Vertically
* the component is positioned so that its top edge touches the
* baseline of the starting row. If the starting row does not
* have a baseline it will be vertically centered.
*
* @since 1.6
*/
public static final int BELOW_BASELINE_TRAILING = 0x900;
/**
* Specifies the cell containing the leading edge of the component's
* display area, where the first cell in a row has <code>gridx=0</code>.
* The leading edge of a component's display area is its left edge for
* a horizontal, left-to-right container and its right edge for a
* horizontal, right-to-left container.
* The value
* <code>RELATIVE</code> specifies that the component be placed
* immediately following the component that was added to the container
* just before this component was added.
* <p>
* The default value is <code>RELATIVE</code>.
* <code>gridx</code> should be a non-negative value.
* @serial
* @see #clone()
* @see java.awt.GridBagConstraints#gridy
* @see java.awt.ComponentOrientation
*/
public int gridx;
/**
* Specifies the cell at the top of the component's display area,
* where the topmost cell has <code>gridy=0</code>. The value
* <code>RELATIVE</code> specifies that the component be placed just
* below the component that was added to the container just before
* this component was added.
* <p>
* The default value is <code>RELATIVE</code>.
* <code>gridy</code> should be a non-negative value.
* @serial
* @see #clone()
* @see java.awt.GridBagConstraints#gridx
*/
public int gridy;
/**
* Specifies the number of cells in a row for the component's
* display area.
* <p>
* Use <code>REMAINDER</code> to specify that the component's
* display area will be from <code>gridx</code> to the last
* cell in the row.
* Use <code>RELATIVE</code> to specify that the component's
* display area will be from <code>gridx</code> to the next
* to the last one in its row.
* <p>
* <code>gridwidth</code> should be non-negative and the default
* value is 1.
* @serial
* @see #clone()
* @see java.awt.GridBagConstraints#gridheight
*/
public int gridwidth;
/**
* Specifies the number of cells in a column for the component's
* display area.
* <p>
* Use <code>REMAINDER</code> to specify that the component's
* display area will be from <code>gridy</code> to the last
* cell in the column.
* Use <code>RELATIVE</code> to specify that the component's
* display area will be from <code>gridy</code> to the next
* to the last one in its column.
* <p>
* <code>gridheight</code> should be a non-negative value and the
* default value is 1.
* @serial
* @see #clone()
* @see java.awt.GridBagConstraints#gridwidth
*/
public int gridheight;
/**
* Specifies how to distribute extra horizontal space.
* <p>
* The grid bag layout manager calculates the weight of a column to
* be the maximum <code>weightx</code> of all the components in a
* column. If the resulting layout is smaller horizontally than the area
* it needs to fill, the extra space is distributed to each column in
* proportion to its weight. A column that has a weight of zero receives
* no extra space.
* <p>
* If all the weights are zero, all the extra space appears between
* the grids of the cell and the left and right edges.
* <p>
* The default value of this field is <code>0</code>.
* <code>weightx</code> should be a non-negative value.
* @serial
* @see #clone()
* @see java.awt.GridBagConstraints#weighty
*/
public double weightx;
/**
* Specifies how to distribute extra vertical space.
* <p>
* The grid bag layout manager calculates the weight of a row to be
* the maximum <code>weighty</code> of all the components in a row.
* If the resulting layout is smaller vertically than the area it
* needs to fill, the extra space is distributed to each row in
* proportion to its weight. A row that has a weight of zero receives no
* extra space.
* <p>
* If all the weights are zero, all the extra space appears between
* the grids of the cell and the top and bottom edges.
* <p>
* The default value of this field is <code>0</code>.
* <code>weighty</code> should be a non-negative value.
* @serial
* @see #clone()
* @see java.awt.GridBagConstraints#weightx
*/
public double weighty;
/**
* This field is used when the component is smaller than its
* display area. It determines where, within the display area, to
* place the component.
* <p> There are three kinds of possible values: orientation
* relative, baseline relative and absolute. Orientation relative
* values are interpreted relative to the container's component
* orientation property, baseline relative values are interpreted
* relative to the baseline and absolute values are not. The
* absolute values are:
* <code>CENTER</code>, <code>NORTH</code>, <code>NORTHEAST</code>,
* <code>EAST</code>, <code>SOUTHEAST</code>, <code>SOUTH</code>,
* <code>SOUTHWEST</code>, <code>WEST</code>, and <code>NORTHWEST</code>.
* The orientation relative values are: <code>PAGE_START</code>,
* <code>PAGE_END</code>,
* <code>LINE_START</code>, <code>LINE_END</code>,
* <code>FIRST_LINE_START</code>, <code>FIRST_LINE_END</code>,
* <code>LAST_LINE_START</code> and <code>LAST_LINE_END</code>. The
* baseline relative values are:
* <code>BASELINE</code>, <code>BASELINE_LEADING</code>,
* <code>BASELINE_TRAILING</code>,
* <code>ABOVE_BASELINE</code>, <code>ABOVE_BASELINE_LEADING</code>,
* <code>ABOVE_BASELINE_TRAILING</code>,
* <code>BELOW_BASELINE</code>, <code>BELOW_BASELINE_LEADING</code>,
* and <code>BELOW_BASELINE_TRAILING</code>.
* The default value is <code>CENTER</code>.
* @serial
* @see #clone()
* @see java.awt.ComponentOrientation
*/
public int anchor;
/**
* This field is used when the component's display area is larger
* than the component's requested size. It determines whether to
* resize the component, and if so, how.
* <p>
* The following values are valid for <code>fill</code>:
*
* <ul>
* <li>
* <code>NONE</code>: Do not resize the component.
* <li>
* <code>HORIZONTAL</code>: Make the component wide enough to fill
* its display area horizontally, but do not change its height.
* <li>
* <code>VERTICAL</code>: Make the component tall enough to fill its
* display area vertically, but do not change its width.
* <li>
* <code>BOTH</code>: Make the component fill its display area
* entirely.
* </ul>
* <p>
* The default value is <code>NONE</code>.
* @serial
* @see #clone()
*/
public int fill;
/**
* This field specifies the external padding of the component, the
* minimum amount of space between the component and the edges of its
* display area.
* <p>
* The default value is <code>new Insets(0, 0, 0, 0)</code>.
* @serial
* @see #clone()
*/
public Insets insets;
/**
* This field specifies the internal padding of the component, how much
* space to add to the minimum width of the component. The width of
* the component is at least its minimum width plus
* <code>ipadx</code> pixels.
* <p>
* The default value is <code>0</code>.
* @serial
* @see #clone()
* @see java.awt.GridBagConstraints#ipady
*/
public int ipadx;
/**
* This field specifies the internal padding, that is, how much
* space to add to the minimum height of the component. The height of
* the component is at least its minimum height plus
* <code>ipady</code> pixels.
* <p>
* The default value is 0.
* @serial
* @see #clone()
* @see java.awt.GridBagConstraints#ipadx
*/
public int ipady;
/**
* Temporary place holder for the x coordinate.
* @serial
*/
int tempX;
/**
* Temporary place holder for the y coordinate.
* @serial
*/
int tempY;
/**
* Temporary place holder for the Width of the component.
* @serial
*/
int tempWidth;
/**
* Temporary place holder for the Height of the component.
* @serial
*/
int tempHeight;
/**
* The minimum width of the component. It is used to calculate
* <code>ipady</code>, where the default will be 0.
* @serial
* @see #ipady
*/
int minWidth;
/**
* The minimum height of the component. It is used to calculate
* <code>ipadx</code>, where the default will be 0.
* @serial
* @see #ipadx
*/
int minHeight;
// The following fields are only used if the anchor is
// one of BASELINE, BASELINE_LEADING or BASELINE_TRAILING.
// ascent and descent include the insets and ipady values.
transient int ascent;
transient int descent;
transient Component.BaselineResizeBehavior baselineResizeBehavior;
// The folllowing two fields are used if the baseline type is
// CENTER_OFFSET.
// centerPadding is either 0 or 1 and indicates if
// the height needs to be padded by one when calculating where the
// baseline lands
transient int centerPadding;
// Where the baseline lands relative to the center of the component.
transient int centerOffset;
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = -1000070633030801713L;
/**
* Creates a <code>GridBagConstraint</code> object with
* all of its fields set to their default value.
*/
public GridBagConstraints () {
gridx = RELATIVE;
gridy = RELATIVE;
gridwidth = 1;
gridheight = 1;
weightx = 0;
weighty = 0;
anchor = CENTER;
fill = NONE;
insets = new Insets(0, 0, 0, 0);
ipadx = 0;
ipady = 0;
}
/**
* Creates a <code>GridBagConstraints</code> object with
* all of its fields set to the passed-in arguments.
*
* Note: Because the use of this constructor hinders readability
* of source code, this constructor should only be used by
* automatic source code generation tools.
*
* @param gridx The initial gridx value.
* @param gridy The initial gridy value.
* @param gridwidth The initial gridwidth value.
* @param gridheight The initial gridheight value.
* @param weightx The initial weightx value.
* @param weighty The initial weighty value.
* @param anchor The initial anchor value.
* @param fill The initial fill value.
* @param insets The initial insets value.
* @param ipadx The initial ipadx value.
* @param ipady The initial ipady value.
*
* @see java.awt.GridBagConstraints#gridx
* @see java.awt.GridBagConstraints#gridy
* @see java.awt.GridBagConstraints#gridwidth
* @see java.awt.GridBagConstraints#gridheight
* @see java.awt.GridBagConstraints#weightx
* @see java.awt.GridBagConstraints#weighty
* @see java.awt.GridBagConstraints#anchor
* @see java.awt.GridBagConstraints#fill
* @see java.awt.GridBagConstraints#insets
* @see java.awt.GridBagConstraints#ipadx
* @see java.awt.GridBagConstraints#ipady
*
* @since 1.2
*/
public GridBagConstraints(int gridx, int gridy,
int gridwidth, int gridheight,
double weightx, double weighty,
int anchor, int fill,
Insets insets, int ipadx, int ipady) {
this.gridx = gridx;
this.gridy = gridy;
this.gridwidth = gridwidth;
this.gridheight = gridheight;
this.fill = fill;
this.ipadx = ipadx;
this.ipady = ipady;
this.insets = insets;
this.anchor = anchor;
this.weightx = weightx;
this.weighty = weighty;
}
/**
* Creates a copy of this grid bag constraint.
* @return a copy of this grid bag constraint
*/
public Object clone () {
try {
GridBagConstraints c = (GridBagConstraints)super.clone();
c.insets = (Insets)insets.clone();
return c;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError(e);
}
}
boolean isVerticallyResizable() {
return (fill == BOTH || fill == VERTICAL);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,87 @@
/*
* Copyright (c) 2006, 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 java.awt;
/**
* The {@code GridBagLayoutInfo} is an utility class for
* {@code GridBagLayout} layout manager.
* It stores align, size and baseline parameters for every component within a container.
* <p>
* @see java.awt.GridBagLayout
* @see java.awt.GridBagConstraints
* @since 1.6
*/
public class GridBagLayoutInfo implements java.io.Serializable {
/*
* serialVersionUID
*/
private static final long serialVersionUID = -4899416460737170217L;
int width, height; /* number of cells: horizontal and vertical */
int startx, starty; /* starting point for layout */
int minWidth[]; /* largest minWidth in each column */
int minHeight[]; /* largest minHeight in each row */
double weightX[]; /* largest weight in each column */
double weightY[]; /* largest weight in each row */
boolean hasBaseline; /* Whether or not baseline layout has been
* requested and one of the components
* has a valid baseline. */
// These are only valid if hasBaseline is true and are indexed by
// row.
short baselineType[]; /* The type of baseline for a particular
* row. A mix of the BaselineResizeBehavior
* constants (1 << ordinal()) */
int maxAscent[]; /* Max ascent (baseline). */
int maxDescent[]; /* Max descent (height - baseline) */
/**
* Creates an instance of GridBagLayoutInfo representing {@code GridBagLayout}
* grid cells with it's own parameters.
* @param width the columns
* @param height the rows
* @since 6.0
*/
GridBagLayoutInfo(int width, int height) {
this.width = width;
this.height = height;
}
/**
* Returns true if the specified row has any component aligned on the
* baseline with a baseline resize behavior of CONSTANT_DESCENT.
*/
boolean hasConstantDescent(int row) {
return ((baselineType[row] & (1 << Component.BaselineResizeBehavior.
CONSTANT_DESCENT.ordinal())) != 0);
}
/**
* Returns true if there is a baseline for the specified row.
*/
boolean hasBaseline(int row) {
return (hasBaseline && baselineType[row] != 0);
}
}

View File

@@ -0,0 +1,481 @@
/*
* Copyright (c) 1995, 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 java.awt;
/**
* The <code>GridLayout</code> class is a layout manager that
* lays out a container's components in a rectangular grid.
* The container is divided into equal-sized rectangles,
* and one component is placed in each rectangle.
* For example, the following is an applet that lays out six buttons
* into three rows and two columns:
*
* <hr><blockquote>
* <pre>
* import java.awt.*;
* import java.applet.Applet;
* public class ButtonGrid extends Applet {
* public void init() {
* setLayout(new GridLayout(3,2));
* add(new Button("1"));
* add(new Button("2"));
* add(new Button("3"));
* add(new Button("4"));
* add(new Button("5"));
* add(new Button("6"));
* }
* }
* </pre></blockquote><hr>
* <p>
* If the container's <code>ComponentOrientation</code> property is horizontal
* and left-to-right, the above example produces the output shown in Figure 1.
* If the container's <code>ComponentOrientation</code> property is horizontal
* and right-to-left, the example produces the output shown in Figure 2.
*
* <table style="float:center" WIDTH=600 summary="layout">
* <tr ALIGN=CENTER>
* <td><img SRC="doc-files/GridLayout-1.gif"
* alt="Shows 6 buttons in rows of 2. Row 1 shows buttons 1 then 2.
* Row 2 shows buttons 3 then 4. Row 3 shows buttons 5 then 6.">
* </td>
*
* <td ALIGN=CENTER><img SRC="doc-files/GridLayout-2.gif"
* alt="Shows 6 buttons in rows of 2. Row 1 shows buttons 2 then 1.
* Row 2 shows buttons 4 then 3. Row 3 shows buttons 6 then 5.">
* </td>
* </tr>
*
* <tr ALIGN=CENTER>
* <td>Figure 1: Horizontal, Left-to-Right</td>
*
* <td>Figure 2: Horizontal, Right-to-Left</td>
* </tr>
* </table>
* <p>
* When both the number of rows and the number of columns have
* been set to non-zero values, either by a constructor or
* by the <tt>setRows</tt> and <tt>setColumns</tt> methods, the number of
* columns specified is ignored. Instead, the number of
* columns is determined from the specified number of rows
* and the total number of components in the layout. So, for
* example, if three rows and two columns have been specified
* and nine components are added to the layout, they will
* be displayed as three rows of three columns. Specifying
* the number of columns affects the layout only when the
* number of rows is set to zero.
*
* @author Arthur van Hoff
* @since JDK1.0
*/
public class GridLayout implements LayoutManager, java.io.Serializable {
/*
* serialVersionUID
*/
private static final long serialVersionUID = -7411804673224730901L;
/**
* This is the horizontal gap (in pixels) which specifies the space
* between columns. They can be changed at any time.
* This should be a non-negative integer.
*
* @serial
* @see #getHgap()
* @see #setHgap(int)
*/
int hgap;
/**
* This is the vertical gap (in pixels) which specifies the space
* between rows. They can be changed at any time.
* This should be a non negative integer.
*
* @serial
* @see #getVgap()
* @see #setVgap(int)
*/
int vgap;
/**
* This is the number of rows specified for the grid. The number
* of rows can be changed at any time.
* This should be a non negative integer, where '0' means
* 'any number' meaning that the number of Rows in that
* dimension depends on the other dimension.
*
* @serial
* @see #getRows()
* @see #setRows(int)
*/
int rows;
/**
* This is the number of columns specified for the grid. The number
* of columns can be changed at any time.
* This should be a non negative integer, where '0' means
* 'any number' meaning that the number of Columns in that
* dimension depends on the other dimension.
*
* @serial
* @see #getColumns()
* @see #setColumns(int)
*/
int cols;
/**
* Creates a grid layout with a default of one column per component,
* in a single row.
* @since JDK1.1
*/
public GridLayout() {
this(1, 0, 0, 0);
}
/**
* Creates a grid layout with the specified number of rows and
* columns. All components in the layout are given equal size.
* <p>
* One, but not both, of <code>rows</code> and <code>cols</code> can
* be zero, which means that any number of objects can be placed in a
* row or in a column.
* @param rows the rows, with the value zero meaning
* any number of rows.
* @param cols the columns, with the value zero meaning
* any number of columns.
*/
public GridLayout(int rows, int cols) {
this(rows, cols, 0, 0);
}
/**
* Creates a grid layout with the specified number of rows and
* columns. All components in the layout are given equal size.
* <p>
* In addition, the horizontal and vertical gaps are set to the
* specified values. Horizontal gaps are placed between each
* of the columns. Vertical gaps are placed between each of
* the rows.
* <p>
* One, but not both, of <code>rows</code> and <code>cols</code> can
* be zero, which means that any number of objects can be placed in a
* row or in a column.
* <p>
* All <code>GridLayout</code> constructors defer to this one.
* @param rows the rows, with the value zero meaning
* any number of rows
* @param cols the columns, with the value zero meaning
* any number of columns
* @param hgap the horizontal gap
* @param vgap the vertical gap
* @exception IllegalArgumentException if the value of both
* <code>rows</code> and <code>cols</code> is
* set to zero
*/
public GridLayout(int rows, int cols, int hgap, int vgap) {
if ((rows == 0) && (cols == 0)) {
throw new IllegalArgumentException("rows and cols cannot both be zero");
}
this.rows = rows;
this.cols = cols;
this.hgap = hgap;
this.vgap = vgap;
}
/**
* Gets the number of rows in this layout.
* @return the number of rows in this layout
* @since JDK1.1
*/
public int getRows() {
return rows;
}
/**
* Sets the number of rows in this layout to the specified value.
* @param rows the number of rows in this layout
* @exception IllegalArgumentException if the value of both
* <code>rows</code> and <code>cols</code> is set to zero
* @since JDK1.1
*/
public void setRows(int rows) {
if ((rows == 0) && (this.cols == 0)) {
throw new IllegalArgumentException("rows and cols cannot both be zero");
}
this.rows = rows;
}
/**
* Gets the number of columns in this layout.
* @return the number of columns in this layout
* @since JDK1.1
*/
public int getColumns() {
return cols;
}
/**
* Sets the number of columns in this layout to the specified value.
* Setting the number of columns has no affect on the layout
* if the number of rows specified by a constructor or by
* the <tt>setRows</tt> method is non-zero. In that case, the number
* of columns displayed in the layout is determined by the total
* number of components and the number of rows specified.
* @param cols the number of columns in this layout
* @exception IllegalArgumentException if the value of both
* <code>rows</code> and <code>cols</code> is set to zero
* @since JDK1.1
*/
public void setColumns(int cols) {
if ((cols == 0) && (this.rows == 0)) {
throw new IllegalArgumentException("rows and cols cannot both be zero");
}
this.cols = cols;
}
/**
* Gets the horizontal gap between components.
* @return the horizontal gap between components
* @since JDK1.1
*/
public int getHgap() {
return hgap;
}
/**
* Sets the horizontal gap between components to the specified value.
* @param hgap the horizontal gap between components
* @since JDK1.1
*/
public void setHgap(int hgap) {
this.hgap = hgap;
}
/**
* Gets the vertical gap between components.
* @return the vertical gap between components
* @since JDK1.1
*/
public int getVgap() {
return vgap;
}
/**
* Sets the vertical gap between components to the specified value.
* @param vgap the vertical gap between components
* @since JDK1.1
*/
public void setVgap(int vgap) {
this.vgap = vgap;
}
/**
* Adds the specified component with the specified name to the layout.
* @param name the name of the component
* @param comp the component to be added
*/
public void addLayoutComponent(String name, Component comp) {
}
/**
* Removes the specified component from the layout.
* @param comp the component to be removed
*/
public void removeLayoutComponent(Component comp) {
}
/**
* Determines the preferred size of the container argument using
* this grid layout.
* <p>
* The preferred width of a grid layout is the largest preferred
* width of all of the components in the container times the number of
* columns, plus the horizontal padding times the number of columns
* minus one, plus the left and right insets of the target container.
* <p>
* The preferred height of a grid layout is the largest preferred
* height of all of the components in the container times the number of
* rows, plus the vertical padding times the number of rows minus one,
* plus the top and bottom insets of the target container.
*
* @param parent the container in which to do the layout
* @return the preferred dimensions to lay out the
* subcomponents of the specified container
* @see java.awt.GridLayout#minimumLayoutSize
* @see java.awt.Container#getPreferredSize()
*/
public Dimension preferredLayoutSize(Container parent) {
synchronized (parent.getTreeLock()) {
Insets insets = parent.getInsets();
int ncomponents = parent.getComponentCount();
int nrows = rows;
int ncols = cols;
if (nrows > 0) {
ncols = (ncomponents + nrows - 1) / nrows;
} else {
nrows = (ncomponents + ncols - 1) / ncols;
}
int w = 0;
int h = 0;
for (int i = 0 ; i < ncomponents ; i++) {
Component comp = parent.getComponent(i);
Dimension d = comp.getPreferredSize();
if (w < d.width) {
w = d.width;
}
if (h < d.height) {
h = d.height;
}
}
return new Dimension(insets.left + insets.right + ncols*w + (ncols-1)*hgap,
insets.top + insets.bottom + nrows*h + (nrows-1)*vgap);
}
}
/**
* Determines the minimum size of the container argument using this
* grid layout.
* <p>
* The minimum width of a grid layout is the largest minimum width
* of all of the components in the container times the number of columns,
* plus the horizontal padding times the number of columns minus one,
* plus the left and right insets of the target container.
* <p>
* The minimum height of a grid layout is the largest minimum height
* of all of the components in the container times the number of rows,
* plus the vertical padding times the number of rows minus one, plus
* the top and bottom insets of the target container.
*
* @param parent the container in which to do the layout
* @return the minimum dimensions needed to lay out the
* subcomponents of the specified container
* @see java.awt.GridLayout#preferredLayoutSize
* @see java.awt.Container#doLayout
*/
public Dimension minimumLayoutSize(Container parent) {
synchronized (parent.getTreeLock()) {
Insets insets = parent.getInsets();
int ncomponents = parent.getComponentCount();
int nrows = rows;
int ncols = cols;
if (nrows > 0) {
ncols = (ncomponents + nrows - 1) / nrows;
} else {
nrows = (ncomponents + ncols - 1) / ncols;
}
int w = 0;
int h = 0;
for (int i = 0 ; i < ncomponents ; i++) {
Component comp = parent.getComponent(i);
Dimension d = comp.getMinimumSize();
if (w < d.width) {
w = d.width;
}
if (h < d.height) {
h = d.height;
}
}
return new Dimension(insets.left + insets.right + ncols*w + (ncols-1)*hgap,
insets.top + insets.bottom + nrows*h + (nrows-1)*vgap);
}
}
/**
* Lays out the specified container using this layout.
* <p>
* This method reshapes the components in the specified target
* container in order to satisfy the constraints of the
* <code>GridLayout</code> object.
* <p>
* The grid layout manager determines the size of individual
* components by dividing the free space in the container into
* equal-sized portions according to the number of rows and columns
* in the layout. The container's free space equals the container's
* size minus any insets and any specified horizontal or vertical
* gap. All components in a grid layout are given the same size.
*
* @param parent the container in which to do the layout
* @see java.awt.Container
* @see java.awt.Container#doLayout
*/
public void layoutContainer(Container parent) {
synchronized (parent.getTreeLock()) {
Insets insets = parent.getInsets();
int ncomponents = parent.getComponentCount();
int nrows = rows;
int ncols = cols;
boolean ltr = parent.getComponentOrientation().isLeftToRight();
if (ncomponents == 0) {
return;
}
if (nrows > 0) {
ncols = (ncomponents + nrows - 1) / nrows;
} else {
nrows = (ncomponents + ncols - 1) / ncols;
}
// 4370316. To position components in the center we should:
// 1. get an amount of extra space within Container
// 2. incorporate half of that value to the left/top position
// Note that we use trancating division for widthOnComponent
// The reminder goes to extraWidthAvailable
int totalGapsWidth = (ncols - 1) * hgap;
int widthWOInsets = parent.width - (insets.left + insets.right);
int widthOnComponent = (widthWOInsets - totalGapsWidth) / ncols;
int extraWidthAvailable = (widthWOInsets - (widthOnComponent * ncols + totalGapsWidth)) / 2;
int totalGapsHeight = (nrows - 1) * vgap;
int heightWOInsets = parent.height - (insets.top + insets.bottom);
int heightOnComponent = (heightWOInsets - totalGapsHeight) / nrows;
int extraHeightAvailable = (heightWOInsets - (heightOnComponent * nrows + totalGapsHeight)) / 2;
if (ltr) {
for (int c = 0, x = insets.left + extraWidthAvailable; c < ncols ; c++, x += widthOnComponent + hgap) {
for (int r = 0, y = insets.top + extraHeightAvailable; r < nrows ; r++, y += heightOnComponent + vgap) {
int i = r * ncols + c;
if (i < ncomponents) {
parent.getComponent(i).setBounds(x, y, widthOnComponent, heightOnComponent);
}
}
}
} else {
for (int c = 0, x = (parent.width - insets.right - widthOnComponent) - extraWidthAvailable; c < ncols ; c++, x -= widthOnComponent + hgap) {
for (int r = 0, y = insets.top + extraHeightAvailable; r < nrows ; r++, y += heightOnComponent + vgap) {
int i = r * ncols + c;
if (i < ncomponents) {
parent.getComponent(i).setBounds(x, y, widthOnComponent, heightOnComponent);
}
}
}
}
}
}
/**
* Returns the string representation of this grid layout's values.
* @return a string representation of this grid layout
*/
public String toString() {
return getClass().getName() + "[hgap=" + hgap + ",vgap=" + vgap +
",rows=" + rows + ",cols=" + cols + "]";
}
}

View File

@@ -0,0 +1,57 @@
/*
* Copyright (c) 2000, 2004, 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 java.awt;
/**
* Thrown when code that is dependent on a keyboard, display, or mouse
* is called in an environment that does not support a keyboard, display,
* or mouse.
*
* @since 1.4
* @author Michael Martak
*/
public class HeadlessException extends UnsupportedOperationException {
/*
* JDK 1.4 serialVersionUID
*/
private static final long serialVersionUID = 167183644944358563L;
public HeadlessException() {}
public HeadlessException(String msg) {
super(msg);
}
public String getMessage() {
String superMessage = super.getMessage();
String headlessMessage = GraphicsEnvironment.getHeadlessMessage();
if (superMessage == null) {
return headlessMessage;
} else if (headlessMessage == null) {
return superMessage;
} else {
return superMessage + headlessMessage;
}
}
}

View File

@@ -0,0 +1,57 @@
/*
* Copyright (c) 1996, 1997, 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 java.awt;
/**
* Signals that an AWT component is not in an appropriate state for
* the requested operation.
*
* @author Jonni Kanerva
*/
public class IllegalComponentStateException extends IllegalStateException {
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = -1889339587208144238L;
/**
* Constructs an IllegalComponentStateException with no detail message.
* A detail message is a String that describes this particular exception.
*/
public IllegalComponentStateException() {
super();
}
/**
* Constructs an IllegalComponentStateException with the specified detail
* message. A detail message is a String that describes this particular
* exception.
* @param s the String that contains a detailed message
*/
public IllegalComponentStateException(String s) {
super(s);
}
}

View File

@@ -0,0 +1,354 @@
/*
* Copyright (c) 1995, 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 java.awt;
import java.awt.image.ImageProducer;
import java.awt.image.ImageObserver;
import java.awt.image.ImageFilter;
import java.awt.image.FilteredImageSource;
import java.awt.image.AreaAveragingScaleFilter;
import java.awt.image.ReplicateScaleFilter;
import sun.awt.image.SurfaceManager;
/**
* The abstract class <code>Image</code> is the superclass of all
* classes that represent graphical images. The image must be
* obtained in a platform-specific manner.
*
* @author Sami Shaio
* @author Arthur van Hoff
* @since JDK1.0
*/
public abstract class Image {
/**
* convenience object; we can use this single static object for
* all images that do not create their own image caps; it holds the
* default (unaccelerated) properties.
*/
private static ImageCapabilities defaultImageCaps =
new ImageCapabilities(false);
/**
* Priority for accelerating this image. Subclasses are free to
* set different default priorities and applications are free to
* set the priority for specific images via the
* <code>setAccelerationPriority(float)</code> method.
* @since 1.5
*/
protected float accelerationPriority = .5f;
/**
* Determines the width of the image. If the width is not yet known,
* this method returns <code>-1</code> and the specified
* <code>ImageObserver</code> object is notified later.
* @param observer an object waiting for the image to be loaded.
* @return the width of this image, or <code>-1</code>
* if the width is not yet known.
* @see java.awt.Image#getHeight
* @see java.awt.image.ImageObserver
*/
public abstract int getWidth(ImageObserver observer);
/**
* Determines the height of the image. If the height is not yet known,
* this method returns <code>-1</code> and the specified
* <code>ImageObserver</code> object is notified later.
* @param observer an object waiting for the image to be loaded.
* @return the height of this image, or <code>-1</code>
* if the height is not yet known.
* @see java.awt.Image#getWidth
* @see java.awt.image.ImageObserver
*/
public abstract int getHeight(ImageObserver observer);
/**
* Gets the object that produces the pixels for the image.
* This method is called by the image filtering classes and by
* methods that perform image conversion and scaling.
* @return the image producer that produces the pixels
* for this image.
* @see java.awt.image.ImageProducer
*/
public abstract ImageProducer getSource();
/**
* Creates a graphics context for drawing to an off-screen image.
* This method can only be called for off-screen images.
* @return a graphics context to draw to the off-screen image.
* @exception UnsupportedOperationException if called for a
* non-off-screen image.
* @see java.awt.Graphics
* @see java.awt.Component#createImage(int, int)
*/
public abstract Graphics getGraphics();
/**
* Gets a property of this image by name.
* <p>
* Individual property names are defined by the various image
* formats. If a property is not defined for a particular image, this
* method returns the <code>UndefinedProperty</code> object.
* <p>
* If the properties for this image are not yet known, this method
* returns <code>null</code>, and the <code>ImageObserver</code>
* object is notified later.
* <p>
* The property name <code>"comment"</code> should be used to store
* an optional comment which can be presented to the application as a
* description of the image, its source, or its author.
* @param name a property name.
* @param observer an object waiting for this image to be loaded.
* @return the value of the named property.
* @throws NullPointerException if the property name is null.
* @see java.awt.image.ImageObserver
* @see java.awt.Image#UndefinedProperty
*/
public abstract Object getProperty(String name, ImageObserver observer);
/**
* The <code>UndefinedProperty</code> object should be returned whenever a
* property which was not defined for a particular image is fetched.
*/
public static final Object UndefinedProperty = new Object();
/**
* Creates a scaled version of this image.
* A new <code>Image</code> object is returned which will render
* the image at the specified <code>width</code> and
* <code>height</code> by default. The new <code>Image</code> object
* may be loaded asynchronously even if the original source image
* has already been loaded completely.
*
* <p>
*
* If either <code>width</code>
* or <code>height</code> is a negative number then a value is
* substituted to maintain the aspect ratio of the original image
* dimensions. If both <code>width</code> and <code>height</code>
* are negative, then the original image dimensions are used.
*
* @param width the width to which to scale the image.
* @param height the height to which to scale the image.
* @param hints flags to indicate the type of algorithm to use
* for image resampling.
* @return a scaled version of the image.
* @exception IllegalArgumentException if <code>width</code>
* or <code>height</code> is zero.
* @see java.awt.Image#SCALE_DEFAULT
* @see java.awt.Image#SCALE_FAST
* @see java.awt.Image#SCALE_SMOOTH
* @see java.awt.Image#SCALE_REPLICATE
* @see java.awt.Image#SCALE_AREA_AVERAGING
* @since JDK1.1
*/
public Image getScaledInstance(int width, int height, int hints) {
ImageFilter filter;
if ((hints & (SCALE_SMOOTH | SCALE_AREA_AVERAGING)) != 0) {
filter = new AreaAveragingScaleFilter(width, height);
} else {
filter = new ReplicateScaleFilter(width, height);
}
ImageProducer prod;
prod = new FilteredImageSource(getSource(), filter);
return Toolkit.getDefaultToolkit().createImage(prod);
}
/**
* Use the default image-scaling algorithm.
* @since JDK1.1
*/
public static final int SCALE_DEFAULT = 1;
/**
* Choose an image-scaling algorithm that gives higher priority
* to scaling speed than smoothness of the scaled image.
* @since JDK1.1
*/
public static final int SCALE_FAST = 2;
/**
* Choose an image-scaling algorithm that gives higher priority
* to image smoothness than scaling speed.
* @since JDK1.1
*/
public static final int SCALE_SMOOTH = 4;
/**
* Use the image scaling algorithm embodied in the
* <code>ReplicateScaleFilter</code> class.
* The <code>Image</code> object is free to substitute a different filter
* that performs the same algorithm yet integrates more efficiently
* into the imaging infrastructure supplied by the toolkit.
* @see java.awt.image.ReplicateScaleFilter
* @since JDK1.1
*/
public static final int SCALE_REPLICATE = 8;
/**
* Use the Area Averaging image scaling algorithm. The
* image object is free to substitute a different filter that
* performs the same algorithm yet integrates more efficiently
* into the image infrastructure supplied by the toolkit.
* @see java.awt.image.AreaAveragingScaleFilter
* @since JDK1.1
*/
public static final int SCALE_AREA_AVERAGING = 16;
/**
* Flushes all reconstructable resources being used by this Image object.
* This includes any pixel data that is being cached for rendering to
* the screen as well as any system resources that are being used
* to store data or pixels for the image if they can be recreated.
* The image is reset to a state similar to when it was first created
* so that if it is again rendered, the image data will have to be
* recreated or fetched again from its source.
* <p>
* Examples of how this method affects specific types of Image object:
* <ul>
* <li>
* BufferedImage objects leave the primary Raster which stores their
* pixels untouched, but flush any information cached about those
* pixels such as copies uploaded to the display hardware for
* accelerated blits.
* <li>
* Image objects created by the Component methods which take a
* width and height leave their primary buffer of pixels untouched,
* but have all cached information released much like is done for
* BufferedImage objects.
* <li>
* VolatileImage objects release all of their pixel resources
* including their primary copy which is typically stored on
* the display hardware where resources are scarce.
* These objects can later be restored using their
* {@link java.awt.image.VolatileImage#validate validate}
* method.
* <li>
* Image objects created by the Toolkit and Component classes which are
* loaded from files, URLs or produced by an {@link ImageProducer}
* are unloaded and all local resources are released.
* These objects can later be reloaded from their original source
* as needed when they are rendered, just as when they were first
* created.
* </ul>
*/
public void flush() {
if (surfaceManager != null) {
surfaceManager.flush();
}
}
/**
* Returns an ImageCapabilities object which can be
* inquired as to the capabilities of this
* Image on the specified GraphicsConfiguration.
* This allows programmers to find
* out more runtime information on the specific Image
* object that they have created. For example, the user
* might create a BufferedImage but the system may have
* no video memory left for creating an image of that
* size on the given GraphicsConfiguration, so although the object
* may be acceleratable in general, it
* does not have that capability on this GraphicsConfiguration.
* @param gc a <code>GraphicsConfiguration</code> object. A value of null
* for this parameter will result in getting the image capabilities
* for the default <code>GraphicsConfiguration</code>.
* @return an <code>ImageCapabilities</code> object that contains
* the capabilities of this <code>Image</code> on the specified
* GraphicsConfiguration.
* @see java.awt.image.VolatileImage#getCapabilities()
* VolatileImage.getCapabilities()
* @since 1.5
*/
public ImageCapabilities getCapabilities(GraphicsConfiguration gc) {
if (surfaceManager != null) {
return surfaceManager.getCapabilities(gc);
}
// Note: this is just a default object that gets returned in the
// absence of any more specific information from a surfaceManager.
// Subclasses of Image should either override this method or
// make sure that they always have a non-null SurfaceManager
// to return an ImageCapabilities object that is appropriate
// for their given subclass type.
return defaultImageCaps;
}
/**
* Sets a hint for this image about how important acceleration is.
* This priority hint is used to compare to the priorities of other
* Image objects when determining how to use scarce acceleration
* resources such as video memory. When and if it is possible to
* accelerate this Image, if there are not enough resources available
* to provide that acceleration but enough can be freed up by
* de-accelerating some other image of lower priority, then that other
* Image may be de-accelerated in deference to this one. Images
* that have the same priority take up resources on a first-come,
* first-served basis.
* @param priority a value between 0 and 1, inclusive, where higher
* values indicate more importance for acceleration. A value of 0
* means that this Image should never be accelerated. Other values
* are used simply to determine acceleration priority relative to other
* Images.
* @throws IllegalArgumentException if <code>priority</code> is less
* than zero or greater than 1.
* @since 1.5
*/
public void setAccelerationPriority(float priority) {
if (priority < 0 || priority > 1) {
throw new IllegalArgumentException("Priority must be a value " +
"between 0 and 1, inclusive");
}
accelerationPriority = priority;
if (surfaceManager != null) {
surfaceManager.setAccelerationPriority(accelerationPriority);
}
}
/**
* Returns the current value of the acceleration priority hint.
* @see #setAccelerationPriority(float priority) setAccelerationPriority
* @return value between 0 and 1, inclusive, which represents the current
* priority value
* @since 1.5
*/
public float getAccelerationPriority() {
return accelerationPriority;
}
SurfaceManager surfaceManager;
static {
SurfaceManager.setImageAccessor(new SurfaceManager.ImageAccessor() {
public SurfaceManager getSurfaceManager(Image img) {
return img.surfaceManager;
}
public void setSurfaceManager(Image img, SurfaceManager mgr) {
img.surfaceManager = mgr;
}
});
}
}

View File

@@ -0,0 +1,81 @@
/*
* Copyright (c) 2000, 2011, 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 java.awt;
/**
* Capabilities and properties of images.
* @author Michael Martak
* @since 1.4
*/
public class ImageCapabilities implements Cloneable {
private boolean accelerated = false;
/**
* Creates a new object for specifying image capabilities.
* @param accelerated whether or not an accelerated image is desired
*/
public ImageCapabilities(boolean accelerated) {
this.accelerated = accelerated;
}
/**
* Returns <code>true</code> if the object whose capabilities are
* encapsulated in this <code>ImageCapabilities</code> can be or is
* accelerated.
* @return whether or not an image can be, or is, accelerated. There are
* various platform-specific ways to accelerate an image, including
* pixmaps, VRAM, AGP. This is the general acceleration method (as
* opposed to residing in system memory).
*/
public boolean isAccelerated() {
return accelerated;
}
/**
* Returns <code>true</code> if the <code>VolatileImage</code>
* described by this <code>ImageCapabilities</code> can lose
* its surfaces.
* @return whether or not a volatile image is subject to losing its surfaces
* at the whim of the operating system.
*/
public boolean isTrueVolatile() {
return false;
}
/**
* @return a copy of this ImageCapabilities object.
*/
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
// Since we implement Cloneable, this should never happen
throw new InternalError(e);
}
}
}

View File

@@ -0,0 +1,188 @@
/*
* Copyright (c) 1995, 2011, 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 java.awt;
/**
* An <code>Insets</code> object is a representation of the borders
* of a container. It specifies the space that a container must leave
* at each of its edges. The space can be a border, a blank space, or
* a title.
*
* @author Arthur van Hoff
* @author Sami Shaio
* @see java.awt.LayoutManager
* @see java.awt.Container
* @since JDK1.0
*/
public class Insets implements Cloneable, java.io.Serializable {
/**
* The inset from the top.
* This value is added to the Top of the rectangle
* to yield a new location for the Top.
*
* @serial
* @see #clone()
*/
public int top;
/**
* The inset from the left.
* This value is added to the Left of the rectangle
* to yield a new location for the Left edge.
*
* @serial
* @see #clone()
*/
public int left;
/**
* The inset from the bottom.
* This value is subtracted from the Bottom of the rectangle
* to yield a new location for the Bottom.
*
* @serial
* @see #clone()
*/
public int bottom;
/**
* The inset from the right.
* This value is subtracted from the Right of the rectangle
* to yield a new location for the Right edge.
*
* @serial
* @see #clone()
*/
public int right;
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = -2272572637695466749L;
static {
/* ensure that the necessary native libraries are loaded */
Toolkit.loadLibraries();
if (!GraphicsEnvironment.isHeadless()) {
initIDs();
}
}
/**
* Creates and initializes a new <code>Insets</code> object with the
* specified top, left, bottom, and right insets.
* @param top the inset from the top.
* @param left the inset from the left.
* @param bottom the inset from the bottom.
* @param right the inset from the right.
*/
public Insets(int top, int left, int bottom, int right) {
this.top = top;
this.left = left;
this.bottom = bottom;
this.right = right;
}
/**
* Set top, left, bottom, and right to the specified values
*
* @param top the inset from the top.
* @param left the inset from the left.
* @param bottom the inset from the bottom.
* @param right the inset from the right.
* @since 1.5
*/
public void set(int top, int left, int bottom, int right) {
this.top = top;
this.left = left;
this.bottom = bottom;
this.right = right;
}
/**
* Checks whether two insets objects are equal. Two instances
* of <code>Insets</code> are equal if the four integer values
* of the fields <code>top</code>, <code>left</code>,
* <code>bottom</code>, and <code>right</code> are all equal.
* @return <code>true</code> if the two insets are equal;
* otherwise <code>false</code>.
* @since JDK1.1
*/
public boolean equals(Object obj) {
if (obj instanceof Insets) {
Insets insets = (Insets)obj;
return ((top == insets.top) && (left == insets.left) &&
(bottom == insets.bottom) && (right == insets.right));
}
return false;
}
/**
* Returns the hash code for this Insets.
*
* @return a hash code for this Insets.
*/
public int hashCode() {
int sum1 = left + bottom;
int sum2 = right + top;
int val1 = sum1 * (sum1 + 1)/2 + left;
int val2 = sum2 * (sum2 + 1)/2 + top;
int sum3 = val1 + val2;
return sum3 * (sum3 + 1)/2 + val2;
}
/**
* Returns a string representation of this <code>Insets</code> object.
* This method is intended to be used only for debugging purposes, and
* the content and format of the returned string may vary between
* implementations. The returned string may be empty but may not be
* <code>null</code>.
*
* @return a string representation of this <code>Insets</code> object.
*/
public String toString() {
return getClass().getName() + "[top=" + top + ",left=" + left + ",bottom=" + bottom + ",right=" + right + "]";
}
/**
* Create a copy of this object.
* @return a copy of this <code>Insets</code> object.
*/
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError(e);
}
}
/**
* Initialize JNI field and method IDs
*/
private static native void initIDs();
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright (c) 1996, 2000, 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 java.awt;
import java.awt.event.*;
/**
* The interface for objects which contain a set of items for
* which zero or more can be selected.
*
* @author Amy Fowler
*/
public interface ItemSelectable {
/**
* Returns the selected items or <code>null</code> if no
* items are selected.
*/
public Object[] getSelectedObjects();
/**
* Adds a listener to receive item events when the state of an item is
* changed by the user. Item events are not sent when an item's
* state is set programmatically. If <code>l</code> is
* <code>null</code>, no exception is thrown and no action is performed.
*
* @param l the listener to receive events
* @see ItemEvent
*/
public void addItemListener(ItemListener l);
/**
* Removes an item listener.
* If <code>l</code> is <code>null</code>,
* no exception is thrown and no action is performed.
*
* @param l the listener being removed
* @see ItemEvent
*/
public void removeItemListener(ItemListener l);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,91 @@
/*
* Copyright (c) 2000, 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 java.awt;
import java.awt.event.KeyEvent;
/**
* A KeyEventDispatcher cooperates with the current KeyboardFocusManager in the
* targeting and dispatching of all KeyEvents. KeyEventDispatchers registered
* with the current KeyboardFocusManager will receive KeyEvents before they are
* dispatched to their targets, allowing each KeyEventDispatcher to retarget
* the event, consume it, dispatch the event itself, or make other changes.
* <p>
* Note that KeyboardFocusManager itself implements KeyEventDispatcher. By
* default, the current KeyboardFocusManager will be the sink for all KeyEvents
* not dispatched by the registered KeyEventDispatchers. The current
* KeyboardFocusManager cannot be completely deregistered as a
* KeyEventDispatcher. However, if a KeyEventDispatcher reports that it
* dispatched the KeyEvent, regardless of whether it actually did so, the
* KeyboardFocusManager will take no further action with regard to the
* KeyEvent. (While it is possible for client code to register the current
* KeyboardFocusManager as a KeyEventDispatcher one or more times, this is
* usually unnecessary and not recommended.)
*
* @author David Mendenhall
*
* @see KeyboardFocusManager#addKeyEventDispatcher
* @see KeyboardFocusManager#removeKeyEventDispatcher
* @since 1.4
*/
@FunctionalInterface
public interface KeyEventDispatcher {
/**
* This method is called by the current KeyboardFocusManager requesting
* that this KeyEventDispatcher dispatch the specified event on its behalf.
* This KeyEventDispatcher is free to retarget the event, consume it,
* dispatch it itself, or make other changes. This capability is typically
* used to deliver KeyEvents to Components other than the focus owner. This
* can be useful when navigating children of non-focusable Windows in an
* accessible environment, for example. Note that if a KeyEventDispatcher
* dispatches the KeyEvent itself, it must use <code>redispatchEvent</code>
* to prevent the current KeyboardFocusManager from recursively requesting
* that this KeyEventDispatcher dispatch the event again.
* <p>
* If an implementation of this method returns <code>false</code>, then
* the KeyEvent is passed to the next KeyEventDispatcher in the chain,
* ending with the current KeyboardFocusManager. If an implementation
* returns <code>true</code>, the KeyEvent is assumed to have been
* dispatched (although this need not be the case), and the current
* KeyboardFocusManager will take no further action with regard to the
* KeyEvent. In such a case,
* <code>KeyboardFocusManager.dispatchEvent</code> should return
* <code>true</code> as well. If an implementation consumes the KeyEvent,
* but returns <code>false</code>, the consumed event will still be passed
* to the next KeyEventDispatcher in the chain. It is important for
* developers to check whether the KeyEvent has been consumed before
* dispatching it to a target. By default, the current KeyboardFocusManager
* will not dispatch a consumed KeyEvent.
*
* @param e the KeyEvent to dispatch
* @return <code>true</code> if the KeyboardFocusManager should take no
* further action with regard to the KeyEvent; <code>false</code>
* otherwise
* @see KeyboardFocusManager#redispatchEvent
*/
boolean dispatchKeyEvent(KeyEvent e);
}

View File

@@ -0,0 +1,94 @@
/*
* Copyright (c) 2001, 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 java.awt;
import java.awt.event.KeyEvent;
/**
* A KeyEventPostProcessor cooperates with the current KeyboardFocusManager
* in the final resolution of all unconsumed KeyEvents. KeyEventPostProcessors
* registered with the current KeyboardFocusManager will receive KeyEvents
* after the KeyEvents have been dispatched to and handled by their targets.
* KeyEvents that would have been otherwise discarded because no Component in
* the application currently owns the focus will also be forwarded to
* registered KeyEventPostProcessors. This will allow applications to implement
* features that require global KeyEvent post-handling, such as menu shortcuts.
* <p>
* Note that the KeyboardFocusManager itself implements KeyEventPostProcessor.
* By default, the current KeyboardFocusManager will be the final
* KeyEventPostProcessor in the chain. The current KeyboardFocusManager cannot
* be completely deregistered as a KeyEventPostProcessor. However, if a
* KeyEventPostProcessor reports that no further post-processing of the
* KeyEvent should take place, the AWT will consider the event fully handled
* and will take no additional action with regard to the event. (While it is
* possible for client code to register the current KeyboardFocusManager as
* a KeyEventPostProcessor one or more times, this is usually unnecessary and
* not recommended.)
*
* @author David Mendenhall
*
* @see KeyboardFocusManager#addKeyEventPostProcessor
* @see KeyboardFocusManager#removeKeyEventPostProcessor
* @since 1.4
*/
@FunctionalInterface
public interface KeyEventPostProcessor {
/**
* This method is called by the current KeyboardFocusManager, requesting
* that this KeyEventPostProcessor perform any necessary post-processing
* which should be part of the KeyEvent's final resolution. At the time
* this method is invoked, typically the KeyEvent has already been
* dispatched to and handled by its target. However, if no Component in
* the application currently owns the focus, then the KeyEvent has not
* been dispatched to any Component. Typically, KeyEvent post-processing
* will be used to implement features which require global KeyEvent
* post-handling, such as menu shortcuts. Note that if a
* KeyEventPostProcessor wishes to dispatch the KeyEvent, it must use
* <code>redispatchEvent</code> to prevent the AWT from recursively
* requesting that this KeyEventPostProcessor perform post-processing
* of the event again.
* <p>
* If an implementation of this method returns <code>false</code>, then the
* KeyEvent is passed to the next KeyEventPostProcessor in the chain,
* ending with the current KeyboardFocusManager. If an implementation
* returns <code>true</code>, the KeyEvent is assumed to have been fully
* handled (although this need not be the case), and the AWT will take no
* further action with regard to the KeyEvent. If an implementation
* consumes the KeyEvent but returns <code>false</code>, the consumed
* event will still be passed to the next KeyEventPostProcessor in the
* chain. It is important for developers to check whether the KeyEvent has
* been consumed before performing any post-processing of the KeyEvent. By
* default, the current KeyboardFocusManager will perform no post-
* processing in response to a consumed KeyEvent.
*
* @param e the KeyEvent to post-process
* @return <code>true</code> if the AWT should take no further action with
* regard to the KeyEvent; <code>false</code> otherwise
* @see KeyboardFocusManager#redispatchEvent
*/
boolean postProcessKeyEvent(KeyEvent e);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,360 @@
/*
* Copyright (c) 1995, 2014, 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 java.awt;
import java.awt.peer.LabelPeer;
import java.io.IOException;
import java.io.ObjectInputStream;
import javax.accessibility.*;
/**
* A <code>Label</code> object is a component for placing text in a
* container. A label displays a single line of read-only text.
* The text can be changed by the application, but a user cannot edit it
* directly.
* <p>
* For example, the code&nbsp;.&nbsp;.&nbsp;.
*
* <hr><blockquote><pre>
* setLayout(new FlowLayout(FlowLayout.CENTER, 10, 10));
* add(new Label("Hi There!"));
* add(new Label("Another Label"));
* </pre></blockquote><hr>
* <p>
* produces the following labels:
* <p>
* <img src="doc-files/Label-1.gif" alt="Two labels: 'Hi There!' and 'Another label'"
* style="float:center; margin: 7px 10px;">
*
* @author Sami Shaio
* @since JDK1.0
*/
public class Label extends Component implements Accessible {
static {
/* ensure that the necessary native libraries are loaded */
Toolkit.loadLibraries();
if (!GraphicsEnvironment.isHeadless()) {
initIDs();
}
}
/**
* Indicates that the label should be left justified.
*/
public static final int LEFT = 0;
/**
* Indicates that the label should be centered.
*/
public static final int CENTER = 1;
/**
* Indicates that the label should be right justified.
* @since JDK1.0t.
*/
public static final int RIGHT = 2;
/**
* The text of this label.
* This text can be modified by the program
* but never by the user.
*
* @serial
* @see #getText()
* @see #setText(String)
*/
String text;
/**
* The label's alignment. The default alignment is set
* to be left justified.
*
* @serial
* @see #getAlignment()
* @see #setAlignment(int)
*/
int alignment = LEFT;
private static final String base = "label";
private static int nameCounter = 0;
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = 3094126758329070636L;
/**
* Constructs an empty label.
* The text of the label is the empty string <code>""</code>.
* @exception HeadlessException if GraphicsEnvironment.isHeadless()
* returns true.
* @see java.awt.GraphicsEnvironment#isHeadless
*/
public Label() throws HeadlessException {
this("", LEFT);
}
/**
* Constructs a new label with the specified string of text,
* left justified.
* @param text the string that the label presents.
* A <code>null</code> value
* will be accepted without causing a NullPointerException
* to be thrown.
* @exception HeadlessException if GraphicsEnvironment.isHeadless()
* returns true.
* @see java.awt.GraphicsEnvironment#isHeadless
*/
public Label(String text) throws HeadlessException {
this(text, LEFT);
}
/**
* Constructs a new label that presents the specified string of
* text with the specified alignment.
* Possible values for <code>alignment</code> are <code>Label.LEFT</code>,
* <code>Label.RIGHT</code>, and <code>Label.CENTER</code>.
* @param text the string that the label presents.
* A <code>null</code> value
* will be accepted without causing a NullPointerException
* to be thrown.
* @param alignment the alignment value.
* @exception HeadlessException if GraphicsEnvironment.isHeadless()
* returns true.
* @see java.awt.GraphicsEnvironment#isHeadless
*/
public Label(String text, int alignment) throws HeadlessException {
GraphicsEnvironment.checkHeadless();
this.text = text;
setAlignment(alignment);
}
/**
* Read a label from an object input stream.
* @exception HeadlessException if
* <code>GraphicsEnvironment.isHeadless()</code> returns
* <code>true</code>
* @serial
* @since 1.4
* @see java.awt.GraphicsEnvironment#isHeadless
*/
private void readObject(ObjectInputStream s)
throws ClassNotFoundException, IOException, HeadlessException {
GraphicsEnvironment.checkHeadless();
s.defaultReadObject();
}
/**
* Construct a name for this component. Called by getName() when the
* name is <code>null</code>.
*/
String constructComponentName() {
synchronized (Label.class) {
return base + nameCounter++;
}
}
/**
* Creates the peer for this label. The peer allows us to
* modify the appearance of the label without changing its
* functionality.
*/
public void addNotify() {
synchronized (getTreeLock()) {
if (peer == null)
peer = getToolkit().createLabel(this);
super.addNotify();
}
}
/**
* Gets the current alignment of this label. Possible values are
* <code>Label.LEFT</code>, <code>Label.RIGHT</code>, and
* <code>Label.CENTER</code>.
* @see java.awt.Label#setAlignment
*/
public int getAlignment() {
return alignment;
}
/**
* Sets the alignment for this label to the specified alignment.
* Possible values are <code>Label.LEFT</code>,
* <code>Label.RIGHT</code>, and <code>Label.CENTER</code>.
* @param alignment the alignment to be set.
* @exception IllegalArgumentException if an improper value for
* <code>alignment</code> is given.
* @see java.awt.Label#getAlignment
*/
public synchronized void setAlignment(int alignment) {
switch (alignment) {
case LEFT:
case CENTER:
case RIGHT:
this.alignment = alignment;
LabelPeer peer = (LabelPeer)this.peer;
if (peer != null) {
peer.setAlignment(alignment);
}
return;
}
throw new IllegalArgumentException("improper alignment: " + alignment);
}
/**
* Gets the text of this label.
* @return the text of this label, or <code>null</code> if
* the text has been set to <code>null</code>.
* @see java.awt.Label#setText
*/
public String getText() {
return text;
}
/**
* Sets the text for this label to the specified text.
* @param text the text that this label displays. If
* <code>text</code> is <code>null</code>, it is
* treated for display purposes like an empty
* string <code>""</code>.
* @see java.awt.Label#getText
*/
public void setText(String text) {
boolean testvalid = false;
synchronized (this) {
if (text != this.text && (this.text == null ||
!this.text.equals(text))) {
this.text = text;
LabelPeer peer = (LabelPeer)this.peer;
if (peer != null) {
peer.setText(text);
}
testvalid = true;
}
}
// This could change the preferred size of the Component.
if (testvalid) {
invalidateIfValid();
}
}
/**
* Returns a string representing the state of this <code>Label</code>.
* This method is intended to be used only for debugging purposes, and the
* content and format of the returned string may vary between
* implementations. The returned string may be empty but may not be
* <code>null</code>.
*
* @return the parameter string of this label
*/
protected String paramString() {
String align = "";
switch (alignment) {
case LEFT: align = "left"; break;
case CENTER: align = "center"; break;
case RIGHT: align = "right"; break;
}
return super.paramString() + ",align=" + align + ",text=" + text;
}
/**
* Initialize JNI field and method IDs
*/
private static native void initIDs();
/////////////////
// Accessibility support
////////////////
/**
* Gets the AccessibleContext associated with this Label.
* For labels, the AccessibleContext takes the form of an
* AccessibleAWTLabel.
* A new AccessibleAWTLabel instance is created if necessary.
*
* @return an AccessibleAWTLabel that serves as the
* AccessibleContext of this Label
* @since 1.3
*/
public AccessibleContext getAccessibleContext() {
if (accessibleContext == null) {
accessibleContext = new AccessibleAWTLabel();
}
return accessibleContext;
}
/**
* This class implements accessibility support for the
* <code>Label</code> class. It provides an implementation of the
* Java Accessibility API appropriate to label user-interface elements.
* @since 1.3
*/
protected class AccessibleAWTLabel extends AccessibleAWTComponent
{
/*
* JDK 1.3 serialVersionUID
*/
private static final long serialVersionUID = -3568967560160480438L;
public AccessibleAWTLabel() {
super();
}
/**
* Get the accessible name of this object.
*
* @return the localized name of the object -- can be null if this
* object does not have a name
* @see AccessibleContext#setAccessibleName
*/
public String getAccessibleName() {
if (accessibleName != null) {
return accessibleName;
} else {
if (getText() == null) {
return super.getAccessibleName();
} else {
return getText();
}
}
}
/**
* Get the role of this object.
*
* @return an instance of AccessibleRole describing the role of the object
* @see AccessibleRole
*/
public AccessibleRole getAccessibleRole() {
return AccessibleRole.LABEL;
}
} // inner class AccessibleAWTLabel
}

View File

@@ -0,0 +1,83 @@
/*
* Copyright (c) 1995, 2005, 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 java.awt;
/**
* Defines the interface for classes that know how to lay out
* <code>Container</code>s.
* <p>
* Swing's painting architecture assumes the children of a
* <code>JComponent</code> do not overlap. If a
* <code>JComponent</code>'s <code>LayoutManager</code> allows
* children to overlap, the <code>JComponent</code> must override
* <code>isOptimizedDrawingEnabled</code> to return false.
*
* @see Container
* @see javax.swing.JComponent#isOptimizedDrawingEnabled
*
* @author Sami Shaio
* @author Arthur van Hoff
*/
public interface LayoutManager {
/**
* If the layout manager uses a per-component string,
* adds the component <code>comp</code> to the layout,
* associating it
* with the string specified by <code>name</code>.
*
* @param name the string to be associated with the component
* @param comp the component to be added
*/
void addLayoutComponent(String name, Component comp);
/**
* Removes the specified component from the layout.
* @param comp the component to be removed
*/
void removeLayoutComponent(Component comp);
/**
* Calculates the preferred size dimensions for the specified
* container, given the components it contains.
* @param parent the container to be laid out
*
* @see #minimumLayoutSize
*/
Dimension preferredLayoutSize(Container parent);
/**
* Calculates the minimum size dimensions for the specified
* container, given the components it contains.
* @param parent the component to be laid out
* @see #preferredLayoutSize
*/
Dimension minimumLayoutSize(Container parent);
/**
* Lays out the specified container.
* @param parent the container to be laid out
*/
void layoutContainer(Container parent);
}

View File

@@ -0,0 +1,87 @@
/*
* Copyright (c) 1996, 2001, 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 java.awt;
/**
* Defines an interface for classes that know how to layout Containers
* based on a layout constraints object.
*
* This interface extends the LayoutManager interface to deal with layouts
* explicitly in terms of constraint objects that specify how and where
* components should be added to the layout.
* <p>
* This minimal extension to LayoutManager is intended for tool
* providers who wish to the creation of constraint-based layouts.
* It does not yet provide full, general support for custom
* constraint-based layout managers.
*
* @see LayoutManager
* @see Container
*
* @author Jonni Kanerva
*/
public interface LayoutManager2 extends LayoutManager {
/**
* Adds the specified component to the layout, using the specified
* constraint object.
* @param comp the component to be added
* @param constraints where/how the component is added to the layout.
*/
void addLayoutComponent(Component comp, Object constraints);
/**
* Calculates the maximum size dimensions for the specified container,
* given the components it contains.
* @see java.awt.Component#getMaximumSize
* @see LayoutManager
*/
public Dimension maximumLayoutSize(Container target);
/**
* Returns the alignment along the x axis. This specifies how
* the component would like to be aligned relative to other
* components. The value should be a number between 0 and 1
* where 0 represents alignment along the origin, 1 is aligned
* the furthest away from the origin, 0.5 is centered, etc.
*/
public float getLayoutAlignmentX(Container target);
/**
* Returns the alignment along the y axis. This specifies how
* the component would like to be aligned relative to other
* components. The value should be a number between 0 and 1
* where 0 represents alignment along the origin, 1 is aligned
* the furthest away from the origin, 0.5 is centered, etc.
*/
public float getLayoutAlignmentY(Container target);
/**
* Invalidates the layout, indicating that if the layout manager
* has cached information it should be discarded.
*/
public void invalidateLayout(Container target);
}

View File

@@ -0,0 +1,383 @@
/*
* Copyright (c) 2006, 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 java.awt;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.ColorModel;
import java.beans.ConstructorProperties;
/**
* The {@code LinearGradientPaint} class provides a way to fill
* a {@link java.awt.Shape} with a linear color gradient pattern. The user
* may specify two or more gradient colors, and this paint will provide an
* interpolation between each color. The user also specifies start and end
* points which define where in user space the color gradient should begin
* and end.
* <p>
* The user must provide an array of floats specifying how to distribute the
* colors along the gradient. These values should range from 0.0 to 1.0 and
* act like keyframes along the gradient (they mark where the gradient should
* be exactly a particular color).
* <p>
* In the event that the user does not set the first keyframe value equal
* to 0 and/or the last keyframe value equal to 1, keyframes will be created
* at these positions and the first and last colors will be replicated there.
* So, if a user specifies the following arrays to construct a gradient:<br>
* <pre>
* {Color.BLUE, Color.RED}, {.3f, .7f}
* </pre>
* this will be converted to a gradient with the following keyframes:<br>
* <pre>
* {Color.BLUE, Color.BLUE, Color.RED, Color.RED}, {0f, .3f, .7f, 1f}
* </pre>
*
* <p>
* The user may also select what action the {@code LinearGradientPaint} object
* takes when it is filling the space outside the start and end points by
* setting {@code CycleMethod} to either {@code REFLECTION} or {@code REPEAT}.
* The distances between any two colors in any of the reflected or repeated
* copies of the gradient are the same as the distance between those same two
* colors between the start and end points.
* Note that some minor variations in distances may occur due to sampling at
* the granularity of a pixel.
* If no cycle method is specified, {@code NO_CYCLE} will be chosen by
* default, which means the endpoint colors will be used to fill the
* remaining area.
* <p>
* The colorSpace parameter allows the user to specify in which colorspace
* the interpolation should be performed, default sRGB or linearized RGB.
*
* <p>
* The following code demonstrates typical usage of
* {@code LinearGradientPaint}:
* <pre>
* Point2D start = new Point2D.Float(0, 0);
* Point2D end = new Point2D.Float(50, 50);
* float[] dist = {0.0f, 0.2f, 1.0f};
* Color[] colors = {Color.RED, Color.WHITE, Color.BLUE};
* LinearGradientPaint p =
* new LinearGradientPaint(start, end, dist, colors);
* </pre>
* <p>
* This code will create a {@code LinearGradientPaint} which interpolates
* between red and white for the first 20% of the gradient and between white
* and blue for the remaining 80%.
*
* <p>
* This image demonstrates the example code above for each
* of the three cycle methods:
* <center>
* <img src = "doc-files/LinearGradientPaint.png"
* alt="image showing the output of the example code">
* </center>
*
* @see java.awt.Paint
* @see java.awt.Graphics2D#setPaint
* @author Nicholas Talian, Vincent Hardy, Jim Graham, Jerry Evans
* @since 1.6
*/
public final class LinearGradientPaint extends MultipleGradientPaint {
/** Gradient start and end points. */
private final Point2D start, end;
/**
* Constructs a {@code LinearGradientPaint} with a default
* {@code NO_CYCLE} repeating method and {@code SRGB} color space.
*
* @param startX the X coordinate of the gradient axis start point
* in user space
* @param startY the Y coordinate of the gradient axis start point
* in user space
* @param endX the X coordinate of the gradient axis end point
* in user space
* @param endY the Y coordinate of the gradient axis end point
* in user space
* @param fractions numbers ranging from 0.0 to 1.0 specifying the
* distribution of colors along the gradient
* @param colors array of colors corresponding to each fractional value
*
* @throws NullPointerException
* if {@code fractions} array is null,
* or {@code colors} array is null,
* @throws IllegalArgumentException
* if start and end points are the same points,
* or {@code fractions.length != colors.length},
* or {@code colors} is less than 2 in size,
* or a {@code fractions} value is less than 0.0 or greater than 1.0,
* or the {@code fractions} are not provided in strictly increasing order
*/
public LinearGradientPaint(float startX, float startY,
float endX, float endY,
float[] fractions, Color[] colors)
{
this(new Point2D.Float(startX, startY),
new Point2D.Float(endX, endY),
fractions,
colors,
CycleMethod.NO_CYCLE);
}
/**
* Constructs a {@code LinearGradientPaint} with a default {@code SRGB}
* color space.
*
* @param startX the X coordinate of the gradient axis start point
* in user space
* @param startY the Y coordinate of the gradient axis start point
* in user space
* @param endX the X coordinate of the gradient axis end point
* in user space
* @param endY the Y coordinate of the gradient axis end point
* in user space
* @param fractions numbers ranging from 0.0 to 1.0 specifying the
* distribution of colors along the gradient
* @param colors array of colors corresponding to each fractional value
* @param cycleMethod either {@code NO_CYCLE}, {@code REFLECT},
* or {@code REPEAT}
*
* @throws NullPointerException
* if {@code fractions} array is null,
* or {@code colors} array is null,
* or {@code cycleMethod} is null
* @throws IllegalArgumentException
* if start and end points are the same points,
* or {@code fractions.length != colors.length},
* or {@code colors} is less than 2 in size,
* or a {@code fractions} value is less than 0.0 or greater than 1.0,
* or the {@code fractions} are not provided in strictly increasing order
*/
public LinearGradientPaint(float startX, float startY,
float endX, float endY,
float[] fractions, Color[] colors,
CycleMethod cycleMethod)
{
this(new Point2D.Float(startX, startY),
new Point2D.Float(endX, endY),
fractions,
colors,
cycleMethod);
}
/**
* Constructs a {@code LinearGradientPaint} with a default
* {@code NO_CYCLE} repeating method and {@code SRGB} color space.
*
* @param start the gradient axis start {@code Point2D} in user space
* @param end the gradient axis end {@code Point2D} in user space
* @param fractions numbers ranging from 0.0 to 1.0 specifying the
* distribution of colors along the gradient
* @param colors array of colors corresponding to each fractional value
*
* @throws NullPointerException
* if one of the points is null,
* or {@code fractions} array is null,
* or {@code colors} array is null
* @throws IllegalArgumentException
* if start and end points are the same points,
* or {@code fractions.length != colors.length},
* or {@code colors} is less than 2 in size,
* or a {@code fractions} value is less than 0.0 or greater than 1.0,
* or the {@code fractions} are not provided in strictly increasing order
*/
public LinearGradientPaint(Point2D start, Point2D end,
float[] fractions, Color[] colors)
{
this(start, end,
fractions, colors,
CycleMethod.NO_CYCLE);
}
/**
* Constructs a {@code LinearGradientPaint} with a default {@code SRGB}
* color space.
*
* @param start the gradient axis start {@code Point2D} in user space
* @param end the gradient axis end {@code Point2D} in user space
* @param fractions numbers ranging from 0.0 to 1.0 specifying the
* distribution of colors along the gradient
* @param colors array of colors corresponding to each fractional value
* @param cycleMethod either {@code NO_CYCLE}, {@code REFLECT},
* or {@code REPEAT}
*
* @throws NullPointerException
* if one of the points is null,
* or {@code fractions} array is null,
* or {@code colors} array is null,
* or {@code cycleMethod} is null
* @throws IllegalArgumentException
* if start and end points are the same points,
* or {@code fractions.length != colors.length},
* or {@code colors} is less than 2 in size,
* or a {@code fractions} value is less than 0.0 or greater than 1.0,
* or the {@code fractions} are not provided in strictly increasing order
*/
public LinearGradientPaint(Point2D start, Point2D end,
float[] fractions, Color[] colors,
CycleMethod cycleMethod)
{
this(start, end,
fractions, colors,
cycleMethod,
ColorSpaceType.SRGB,
new AffineTransform());
}
/**
* Constructs a {@code LinearGradientPaint}.
*
* @param start the gradient axis start {@code Point2D} in user space
* @param end the gradient axis end {@code Point2D} in user space
* @param fractions numbers ranging from 0.0 to 1.0 specifying the
* distribution of colors along the gradient
* @param colors array of colors corresponding to each fractional value
* @param cycleMethod either {@code NO_CYCLE}, {@code REFLECT},
* or {@code REPEAT}
* @param colorSpace which color space to use for interpolation,
* either {@code SRGB} or {@code LINEAR_RGB}
* @param gradientTransform transform to apply to the gradient
*
* @throws NullPointerException
* if one of the points is null,
* or {@code fractions} array is null,
* or {@code colors} array is null,
* or {@code cycleMethod} is null,
* or {@code colorSpace} is null,
* or {@code gradientTransform} is null
* @throws IllegalArgumentException
* if start and end points are the same points,
* or {@code fractions.length != colors.length},
* or {@code colors} is less than 2 in size,
* or a {@code fractions} value is less than 0.0 or greater than 1.0,
* or the {@code fractions} are not provided in strictly increasing order
*/
@ConstructorProperties({ "startPoint", "endPoint", "fractions", "colors", "cycleMethod", "colorSpace", "transform" })
public LinearGradientPaint(Point2D start, Point2D end,
float[] fractions, Color[] colors,
CycleMethod cycleMethod,
ColorSpaceType colorSpace,
AffineTransform gradientTransform)
{
super(fractions, colors, cycleMethod, colorSpace, gradientTransform);
// check input parameters
if (start == null || end == null) {
throw new NullPointerException("Start and end points must be" +
"non-null");
}
if (start.equals(end)) {
throw new IllegalArgumentException("Start point cannot equal" +
"endpoint");
}
// copy the points...
this.start = new Point2D.Double(start.getX(), start.getY());
this.end = new Point2D.Double(end.getX(), end.getY());
}
/**
* Creates and returns a {@link PaintContext} used to
* generate a linear color gradient pattern.
* See the {@link Paint#createContext specification} of the
* method in the {@link Paint} interface for information
* on null parameter handling.
*
* @param cm the preferred {@link ColorModel} which represents the most convenient
* format for the caller to receive the pixel data, or {@code null}
* if there is no preference.
* @param deviceBounds the device space bounding box
* of the graphics primitive being rendered.
* @param userBounds the user space bounding box
* of the graphics primitive being rendered.
* @param transform the {@link AffineTransform} from user
* space into device space.
* @param hints the set of hints that the context object can use to
* choose between rendering alternatives.
* @return the {@code PaintContext} for
* generating color patterns.
* @see Paint
* @see PaintContext
* @see ColorModel
* @see Rectangle
* @see Rectangle2D
* @see AffineTransform
* @see RenderingHints
*/
public PaintContext createContext(ColorModel cm,
Rectangle deviceBounds,
Rectangle2D userBounds,
AffineTransform transform,
RenderingHints hints)
{
// avoid modifying the user's transform...
transform = new AffineTransform(transform);
// incorporate the gradient transform
transform.concatenate(gradientTransform);
if ((fractions.length == 2) &&
(cycleMethod != CycleMethod.REPEAT) &&
(colorSpace == ColorSpaceType.SRGB))
{
// faster to use the basic GradientPaintContext for this
// common case
boolean cyclic = (cycleMethod != CycleMethod.NO_CYCLE);
return new GradientPaintContext(cm, start, end,
transform,
colors[0], colors[1],
cyclic);
} else {
return new LinearGradientPaintContext(this, cm,
deviceBounds, userBounds,
transform, hints,
start, end,
fractions, colors,
cycleMethod, colorSpace);
}
}
/**
* Returns a copy of the start point of the gradient axis.
*
* @return a {@code Point2D} object that is a copy of the point
* that anchors the first color of this {@code LinearGradientPaint}
*/
public Point2D getStartPoint() {
return new Point2D.Double(start.getX(), start.getY());
}
/**
* Returns a copy of the end point of the gradient axis.
*
* @return a {@code Point2D} object that is a copy of the point
* that anchors the last color of this {@code LinearGradientPaint}
*/
public Point2D getEndPoint() {
return new Point2D.Double(end.getX(), end.getY());
}
}

View File

@@ -0,0 +1,165 @@
/*
* Copyright (c) 2006, 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 java.awt;
import java.awt.MultipleGradientPaint.CycleMethod;
import java.awt.MultipleGradientPaint.ColorSpaceType;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.ColorModel;
/**
* Provides the actual implementation for the LinearGradientPaint.
* This is where the pixel processing is done.
*
* @see java.awt.LinearGradientPaint
* @see java.awt.PaintContext
* @see java.awt.Paint
* @author Nicholas Talian, Vincent Hardy, Jim Graham, Jerry Evans
*/
final class LinearGradientPaintContext extends MultipleGradientPaintContext {
/**
* The following invariants are used to process the gradient value from
* a device space coordinate, (X, Y):
* g(X, Y) = dgdX*X + dgdY*Y + gc
*/
private float dgdX, dgdY, gc;
/**
* Constructor for LinearGradientPaintContext.
*
* @param paint the {@code LinearGradientPaint} from which this context
* is created
* @param cm {@code ColorModel} that receives
* the <code>Paint</code> data. This is used only as a hint.
* @param deviceBounds the device space bounding box of the
* graphics primitive being rendered
* @param userBounds the user space bounding box of the
* graphics primitive being rendered
* @param t the {@code AffineTransform} from user
* space into device space (gradientTransform should be
* concatenated with this)
* @param hints the hints that the context object uses to choose
* between rendering alternatives
* @param start gradient start point, in user space
* @param end gradient end point, in user space
* @param fractions the fractions specifying the gradient distribution
* @param colors the gradient colors
* @param cycleMethod either NO_CYCLE, REFLECT, or REPEAT
* @param colorSpace which colorspace to use for interpolation,
* either SRGB or LINEAR_RGB
*/
LinearGradientPaintContext(LinearGradientPaint paint,
ColorModel cm,
Rectangle deviceBounds,
Rectangle2D userBounds,
AffineTransform t,
RenderingHints hints,
Point2D start,
Point2D end,
float[] fractions,
Color[] colors,
CycleMethod cycleMethod,
ColorSpaceType colorSpace)
{
super(paint, cm, deviceBounds, userBounds, t, hints, fractions,
colors, cycleMethod, colorSpace);
// A given point in the raster should take on the same color as its
// projection onto the gradient vector.
// Thus, we want the projection of the current position vector
// onto the gradient vector, then normalized with respect to the
// length of the gradient vector, giving a value which can be mapped
// into the range 0-1.
// projection =
// currentVector dot gradientVector / length(gradientVector)
// normalized = projection / length(gradientVector)
float startx = (float)start.getX();
float starty = (float)start.getY();
float endx = (float)end.getX();
float endy = (float)end.getY();
float dx = endx - startx; // change in x from start to end
float dy = endy - starty; // change in y from start to end
float dSq = dx*dx + dy*dy; // total distance squared
// avoid repeated calculations by doing these divides once
float constX = dx/dSq;
float constY = dy/dSq;
// incremental change along gradient for +x
dgdX = a00*constX + a10*constY;
// incremental change along gradient for +y
dgdY = a01*constX + a11*constY;
// constant, incorporates the translation components from the matrix
gc = (a02-startx)*constX + (a12-starty)*constY;
}
/**
* Return a Raster containing the colors generated for the graphics
* operation. This is where the area is filled with colors distributed
* linearly.
*
* @param x,y,w,h the area in device space for which colors are
* generated.
*/
protected void fillRaster(int[] pixels, int off, int adjust,
int x, int y, int w, int h)
{
// current value for row gradients
float g = 0;
// used to end iteration on rows
int rowLimit = off + w;
// constant which can be pulled out of the inner loop
float initConst = (dgdX*x) + gc;
for (int i = 0; i < h; i++) { // for every row
// initialize current value to be start
g = initConst + dgdY*(y+i);
while (off < rowLimit) { // for every pixel in this row
// get the color
pixels[off++] = indexIntoGradientsArrays(g);
// incremental change in g
g += dgdX;
}
// change in off from row to row
off += adjust;
//rowlimit is width + offset
rowLimit = off + w;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,992 @@
/*
* Copyright (c) 1995, 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 java.awt;
import java.awt.Component;
import java.awt.Image;
import java.awt.image.ImageObserver;
import sun.awt.image.MultiResolutionToolkitImage;
/**
* The <code>MediaTracker</code> class is a utility class to track
* the status of a number of media objects. Media objects could
* include audio clips as well as images, though currently only
* images are supported.
* <p>
* To use a media tracker, create an instance of
* <code>MediaTracker</code> and call its <code>addImage</code>
* method for each image to be tracked. In addition, each image can
* be assigned a unique identifier. This identifier controls the
* priority order in which the images are fetched. It can also be used
* to identify unique subsets of the images that can be waited on
* independently. Images with a lower ID are loaded in preference to
* those with a higher ID number.
*
* <p>
*
* Tracking an animated image
* might not always be useful
* due to the multi-part nature of animated image
* loading and painting,
* but it is supported.
* <code>MediaTracker</code> treats an animated image
* as completely loaded
* when the first frame is completely loaded.
* At that point, the <code>MediaTracker</code>
* signals any waiters
* that the image is completely loaded.
* If no <code>ImageObserver</code>s are observing the image
* when the first frame has finished loading,
* the image might flush itself
* to conserve resources
* (see {@link Image#flush()}).
*
* <p>
* Here is an example of using <code>MediaTracker</code>:
* <p>
* <hr><blockquote><pre>{@code
* import java.applet.Applet;
* import java.awt.Color;
* import java.awt.Image;
* import java.awt.Graphics;
* import java.awt.MediaTracker;
*
* public class ImageBlaster extends Applet implements Runnable {
* MediaTracker tracker;
* Image bg;
* Image anim[] = new Image[5];
* int index;
* Thread animator;
*
* // Get the images for the background (id == 0)
* // and the animation frames (id == 1)
* // and add them to the MediaTracker
* public void init() {
* tracker = new MediaTracker(this);
* bg = getImage(getDocumentBase(),
* "images/background.gif");
* tracker.addImage(bg, 0);
* for (int i = 0; i < 5; i++) {
* anim[i] = getImage(getDocumentBase(),
* "images/anim"+i+".gif");
* tracker.addImage(anim[i], 1);
* }
* }
*
* // Start the animation thread.
* public void start() {
* animator = new Thread(this);
* animator.start();
* }
*
* // Stop the animation thread.
* public void stop() {
* animator = null;
* }
*
* // Run the animation thread.
* // First wait for the background image to fully load
* // and paint. Then wait for all of the animation
* // frames to finish loading. Finally, loop and
* // increment the animation frame index.
* public void run() {
* try {
* tracker.waitForID(0);
* tracker.waitForID(1);
* } catch (InterruptedException e) {
* return;
* }
* Thread me = Thread.currentThread();
* while (animator == me) {
* try {
* Thread.sleep(100);
* } catch (InterruptedException e) {
* break;
* }
* synchronized (this) {
* index++;
* if (index >= anim.length) {
* index = 0;
* }
* }
* repaint();
* }
* }
*
* // The background image fills the frame so we
* // don't need to clear the applet on repaints.
* // Just call the paint method.
* public void update(Graphics g) {
* paint(g);
* }
*
* // Paint a large red rectangle if there are any errors
* // loading the images. Otherwise always paint the
* // background so that it appears incrementally as it
* // is loading. Finally, only paint the current animation
* // frame if all of the frames (id == 1) are done loading,
* // so that we don't get partial animations.
* public void paint(Graphics g) {
* if ((tracker.statusAll(false) & MediaTracker.ERRORED) != 0) {
* g.setColor(Color.red);
* g.fillRect(0, 0, size().width, size().height);
* return;
* }
* g.drawImage(bg, 0, 0, this);
* if (tracker.statusID(1, false) == MediaTracker.COMPLETE) {
* g.drawImage(anim[index], 10, 10, this);
* }
* }
* }
* } </pre></blockquote><hr>
*
* @author Jim Graham
* @since JDK1.0
*/
public class MediaTracker implements java.io.Serializable {
/**
* A given <code>Component</code> that will be
* tracked by a media tracker where the image will
* eventually be drawn.
*
* @serial
* @see #MediaTracker(Component)
*/
Component target;
/**
* The head of the list of <code>Images</code> that is being
* tracked by the <code>MediaTracker</code>.
*
* @serial
* @see #addImage(Image, int)
* @see #removeImage(Image)
*/
MediaEntry head;
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = -483174189758638095L;
/**
* Creates a media tracker to track images for a given component.
* @param comp the component on which the images
* will eventually be drawn
*/
public MediaTracker(Component comp) {
target = comp;
}
/**
* Adds an image to the list of images being tracked by this media
* tracker. The image will eventually be rendered at its default
* (unscaled) size.
* @param image the image to be tracked
* @param id an identifier used to track this image
*/
public void addImage(Image image, int id) {
addImage(image, id, -1, -1);
}
/**
* Adds a scaled image to the list of images being tracked
* by this media tracker. The image will eventually be
* rendered at the indicated width and height.
*
* @param image the image to be tracked
* @param id an identifier that can be used to track this image
* @param w the width at which the image is rendered
* @param h the height at which the image is rendered
*/
public synchronized void addImage(Image image, int id, int w, int h) {
addImageImpl(image, id, w, h);
Image rvImage = getResolutionVariant(image);
if (rvImage != null) {
addImageImpl(rvImage, id,
w == -1 ? -1 : 2 * w,
h == -1 ? -1 : 2 * h);
}
}
private void addImageImpl(Image image, int id, int w, int h) {
head = MediaEntry.insert(head,
new ImageMediaEntry(this, image, id, w, h));
}
/**
* Flag indicating that media is currently being loaded.
* @see java.awt.MediaTracker#statusAll
* @see java.awt.MediaTracker#statusID
*/
public static final int LOADING = 1;
/**
* Flag indicating that the downloading of media was aborted.
* @see java.awt.MediaTracker#statusAll
* @see java.awt.MediaTracker#statusID
*/
public static final int ABORTED = 2;
/**
* Flag indicating that the downloading of media encountered
* an error.
* @see java.awt.MediaTracker#statusAll
* @see java.awt.MediaTracker#statusID
*/
public static final int ERRORED = 4;
/**
* Flag indicating that the downloading of media was completed
* successfully.
* @see java.awt.MediaTracker#statusAll
* @see java.awt.MediaTracker#statusID
*/
public static final int COMPLETE = 8;
static final int DONE = (ABORTED | ERRORED | COMPLETE);
/**
* Checks to see if all images being tracked by this media tracker
* have finished loading.
* <p>
* This method does not start loading the images if they are not
* already loading.
* <p>
* If there is an error while loading or scaling an image, then that
* image is considered to have finished loading. Use the
* <code>isErrorAny</code> or <code>isErrorID</code> methods to
* check for errors.
* @return <code>true</code> if all images have finished loading,
* have been aborted, or have encountered
* an error; <code>false</code> otherwise
* @see java.awt.MediaTracker#checkAll(boolean)
* @see java.awt.MediaTracker#checkID
* @see java.awt.MediaTracker#isErrorAny
* @see java.awt.MediaTracker#isErrorID
*/
public boolean checkAll() {
return checkAll(false, true);
}
/**
* Checks to see if all images being tracked by this media tracker
* have finished loading.
* <p>
* If the value of the <code>load</code> flag is <code>true</code>,
* then this method starts loading any images that are not yet
* being loaded.
* <p>
* If there is an error while loading or scaling an image, that
* image is considered to have finished loading. Use the
* <code>isErrorAny</code> and <code>isErrorID</code> methods to
* check for errors.
* @param load if <code>true</code>, start loading any
* images that are not yet being loaded
* @return <code>true</code> if all images have finished loading,
* have been aborted, or have encountered
* an error; <code>false</code> otherwise
* @see java.awt.MediaTracker#checkID
* @see java.awt.MediaTracker#checkAll()
* @see java.awt.MediaTracker#isErrorAny()
* @see java.awt.MediaTracker#isErrorID(int)
*/
public boolean checkAll(boolean load) {
return checkAll(load, true);
}
private synchronized boolean checkAll(boolean load, boolean verify) {
MediaEntry cur = head;
boolean done = true;
while (cur != null) {
if ((cur.getStatus(load, verify) & DONE) == 0) {
done = false;
}
cur = cur.next;
}
return done;
}
/**
* Checks the error status of all of the images.
* @return <code>true</code> if any of the images tracked
* by this media tracker had an error during
* loading; <code>false</code> otherwise
* @see java.awt.MediaTracker#isErrorID
* @see java.awt.MediaTracker#getErrorsAny
*/
public synchronized boolean isErrorAny() {
MediaEntry cur = head;
while (cur != null) {
if ((cur.getStatus(false, true) & ERRORED) != 0) {
return true;
}
cur = cur.next;
}
return false;
}
/**
* Returns a list of all media that have encountered an error.
* @return an array of media objects tracked by this
* media tracker that have encountered
* an error, or <code>null</code> if
* there are none with errors
* @see java.awt.MediaTracker#isErrorAny
* @see java.awt.MediaTracker#getErrorsID
*/
public synchronized Object[] getErrorsAny() {
MediaEntry cur = head;
int numerrors = 0;
while (cur != null) {
if ((cur.getStatus(false, true) & ERRORED) != 0) {
numerrors++;
}
cur = cur.next;
}
if (numerrors == 0) {
return null;
}
Object errors[] = new Object[numerrors];
cur = head;
numerrors = 0;
while (cur != null) {
if ((cur.getStatus(false, false) & ERRORED) != 0) {
errors[numerrors++] = cur.getMedia();
}
cur = cur.next;
}
return errors;
}
/**
* Starts loading all images tracked by this media tracker. This
* method waits until all the images being tracked have finished
* loading.
* <p>
* If there is an error while loading or scaling an image, then that
* image is considered to have finished loading. Use the
* <code>isErrorAny</code> or <code>isErrorID</code> methods to
* check for errors.
* @see java.awt.MediaTracker#waitForID(int)
* @see java.awt.MediaTracker#waitForAll(long)
* @see java.awt.MediaTracker#isErrorAny
* @see java.awt.MediaTracker#isErrorID
* @exception InterruptedException if any thread has
* interrupted this thread
*/
public void waitForAll() throws InterruptedException {
waitForAll(0);
}
/**
* Starts loading all images tracked by this media tracker. This
* method waits until all the images being tracked have finished
* loading, or until the length of time specified in milliseconds
* by the <code>ms</code> argument has passed.
* <p>
* If there is an error while loading or scaling an image, then
* that image is considered to have finished loading. Use the
* <code>isErrorAny</code> or <code>isErrorID</code> methods to
* check for errors.
* @param ms the number of milliseconds to wait
* for the loading to complete
* @return <code>true</code> if all images were successfully
* loaded; <code>false</code> otherwise
* @see java.awt.MediaTracker#waitForID(int)
* @see java.awt.MediaTracker#waitForAll(long)
* @see java.awt.MediaTracker#isErrorAny
* @see java.awt.MediaTracker#isErrorID
* @exception InterruptedException if any thread has
* interrupted this thread.
*/
public synchronized boolean waitForAll(long ms)
throws InterruptedException
{
long end = System.currentTimeMillis() + ms;
boolean first = true;
while (true) {
int status = statusAll(first, first);
if ((status & LOADING) == 0) {
return (status == COMPLETE);
}
first = false;
long timeout;
if (ms == 0) {
timeout = 0;
} else {
timeout = end - System.currentTimeMillis();
if (timeout <= 0) {
return false;
}
}
wait(timeout);
}
}
/**
* Calculates and returns the bitwise inclusive <b>OR</b> of the
* status of all media that are tracked by this media tracker.
* <p>
* Possible flags defined by the
* <code>MediaTracker</code> class are <code>LOADING</code>,
* <code>ABORTED</code>, <code>ERRORED</code>, and
* <code>COMPLETE</code>. An image that hasn't started
* loading has zero as its status.
* <p>
* If the value of <code>load</code> is <code>true</code>, then
* this method starts loading any images that are not yet being loaded.
*
* @param load if <code>true</code>, start loading
* any images that are not yet being loaded
* @return the bitwise inclusive <b>OR</b> of the status of
* all of the media being tracked
* @see java.awt.MediaTracker#statusID(int, boolean)
* @see java.awt.MediaTracker#LOADING
* @see java.awt.MediaTracker#ABORTED
* @see java.awt.MediaTracker#ERRORED
* @see java.awt.MediaTracker#COMPLETE
*/
public int statusAll(boolean load) {
return statusAll(load, true);
}
private synchronized int statusAll(boolean load, boolean verify) {
MediaEntry cur = head;
int status = 0;
while (cur != null) {
status = status | cur.getStatus(load, verify);
cur = cur.next;
}
return status;
}
/**
* Checks to see if all images tracked by this media tracker that
* are tagged with the specified identifier have finished loading.
* <p>
* This method does not start loading the images if they are not
* already loading.
* <p>
* If there is an error while loading or scaling an image, then that
* image is considered to have finished loading. Use the
* <code>isErrorAny</code> or <code>isErrorID</code> methods to
* check for errors.
* @param id the identifier of the images to check
* @return <code>true</code> if all images have finished loading,
* have been aborted, or have encountered
* an error; <code>false</code> otherwise
* @see java.awt.MediaTracker#checkID(int, boolean)
* @see java.awt.MediaTracker#checkAll()
* @see java.awt.MediaTracker#isErrorAny()
* @see java.awt.MediaTracker#isErrorID(int)
*/
public boolean checkID(int id) {
return checkID(id, false, true);
}
/**
* Checks to see if all images tracked by this media tracker that
* are tagged with the specified identifier have finished loading.
* <p>
* If the value of the <code>load</code> flag is <code>true</code>,
* then this method starts loading any images that are not yet
* being loaded.
* <p>
* If there is an error while loading or scaling an image, then that
* image is considered to have finished loading. Use the
* <code>isErrorAny</code> or <code>isErrorID</code> methods to
* check for errors.
* @param id the identifier of the images to check
* @param load if <code>true</code>, start loading any
* images that are not yet being loaded
* @return <code>true</code> if all images have finished loading,
* have been aborted, or have encountered
* an error; <code>false</code> otherwise
* @see java.awt.MediaTracker#checkID(int, boolean)
* @see java.awt.MediaTracker#checkAll()
* @see java.awt.MediaTracker#isErrorAny()
* @see java.awt.MediaTracker#isErrorID(int)
*/
public boolean checkID(int id, boolean load) {
return checkID(id, load, true);
}
private synchronized boolean checkID(int id, boolean load, boolean verify)
{
MediaEntry cur = head;
boolean done = true;
while (cur != null) {
if (cur.getID() == id
&& (cur.getStatus(load, verify) & DONE) == 0)
{
done = false;
}
cur = cur.next;
}
return done;
}
/**
* Checks the error status of all of the images tracked by this
* media tracker with the specified identifier.
* @param id the identifier of the images to check
* @return <code>true</code> if any of the images with the
* specified identifier had an error during
* loading; <code>false</code> otherwise
* @see java.awt.MediaTracker#isErrorAny
* @see java.awt.MediaTracker#getErrorsID
*/
public synchronized boolean isErrorID(int id) {
MediaEntry cur = head;
while (cur != null) {
if (cur.getID() == id
&& (cur.getStatus(false, true) & ERRORED) != 0)
{
return true;
}
cur = cur.next;
}
return false;
}
/**
* Returns a list of media with the specified ID that
* have encountered an error.
* @param id the identifier of the images to check
* @return an array of media objects tracked by this media
* tracker with the specified identifier
* that have encountered an error, or
* <code>null</code> if there are none with errors
* @see java.awt.MediaTracker#isErrorID
* @see java.awt.MediaTracker#isErrorAny
* @see java.awt.MediaTracker#getErrorsAny
*/
public synchronized Object[] getErrorsID(int id) {
MediaEntry cur = head;
int numerrors = 0;
while (cur != null) {
if (cur.getID() == id
&& (cur.getStatus(false, true) & ERRORED) != 0)
{
numerrors++;
}
cur = cur.next;
}
if (numerrors == 0) {
return null;
}
Object errors[] = new Object[numerrors];
cur = head;
numerrors = 0;
while (cur != null) {
if (cur.getID() == id
&& (cur.getStatus(false, false) & ERRORED) != 0)
{
errors[numerrors++] = cur.getMedia();
}
cur = cur.next;
}
return errors;
}
/**
* Starts loading all images tracked by this media tracker with the
* specified identifier. This method waits until all the images with
* the specified identifier have finished loading.
* <p>
* If there is an error while loading or scaling an image, then that
* image is considered to have finished loading. Use the
* <code>isErrorAny</code> and <code>isErrorID</code> methods to
* check for errors.
* @param id the identifier of the images to check
* @see java.awt.MediaTracker#waitForAll
* @see java.awt.MediaTracker#isErrorAny()
* @see java.awt.MediaTracker#isErrorID(int)
* @exception InterruptedException if any thread has
* interrupted this thread.
*/
public void waitForID(int id) throws InterruptedException {
waitForID(id, 0);
}
/**
* Starts loading all images tracked by this media tracker with the
* specified identifier. This method waits until all the images with
* the specified identifier have finished loading, or until the
* length of time specified in milliseconds by the <code>ms</code>
* argument has passed.
* <p>
* If there is an error while loading or scaling an image, then that
* image is considered to have finished loading. Use the
* <code>statusID</code>, <code>isErrorID</code>, and
* <code>isErrorAny</code> methods to check for errors.
* @param id the identifier of the images to check
* @param ms the length of time, in milliseconds, to wait
* for the loading to complete
* @see java.awt.MediaTracker#waitForAll
* @see java.awt.MediaTracker#waitForID(int)
* @see java.awt.MediaTracker#statusID
* @see java.awt.MediaTracker#isErrorAny()
* @see java.awt.MediaTracker#isErrorID(int)
* @exception InterruptedException if any thread has
* interrupted this thread.
*/
public synchronized boolean waitForID(int id, long ms)
throws InterruptedException
{
long end = System.currentTimeMillis() + ms;
boolean first = true;
while (true) {
int status = statusID(id, first, first);
if ((status & LOADING) == 0) {
return (status == COMPLETE);
}
first = false;
long timeout;
if (ms == 0) {
timeout = 0;
} else {
timeout = end - System.currentTimeMillis();
if (timeout <= 0) {
return false;
}
}
wait(timeout);
}
}
/**
* Calculates and returns the bitwise inclusive <b>OR</b> of the
* status of all media with the specified identifier that are
* tracked by this media tracker.
* <p>
* Possible flags defined by the
* <code>MediaTracker</code> class are <code>LOADING</code>,
* <code>ABORTED</code>, <code>ERRORED</code>, and
* <code>COMPLETE</code>. An image that hasn't started
* loading has zero as its status.
* <p>
* If the value of <code>load</code> is <code>true</code>, then
* this method starts loading any images that are not yet being loaded.
* @param id the identifier of the images to check
* @param load if <code>true</code>, start loading
* any images that are not yet being loaded
* @return the bitwise inclusive <b>OR</b> of the status of
* all of the media with the specified
* identifier that are being tracked
* @see java.awt.MediaTracker#statusAll(boolean)
* @see java.awt.MediaTracker#LOADING
* @see java.awt.MediaTracker#ABORTED
* @see java.awt.MediaTracker#ERRORED
* @see java.awt.MediaTracker#COMPLETE
*/
public int statusID(int id, boolean load) {
return statusID(id, load, true);
}
private synchronized int statusID(int id, boolean load, boolean verify) {
MediaEntry cur = head;
int status = 0;
while (cur != null) {
if (cur.getID() == id) {
status = status | cur.getStatus(load, verify);
}
cur = cur.next;
}
return status;
}
/**
* Removes the specified image from this media tracker.
* All instances of the specified image are removed,
* regardless of scale or ID.
* @param image the image to be removed
* @see java.awt.MediaTracker#removeImage(java.awt.Image, int)
* @see java.awt.MediaTracker#removeImage(java.awt.Image, int, int, int)
* @since JDK1.1
*/
public synchronized void removeImage(Image image) {
removeImageImpl(image);
Image rvImage = getResolutionVariant(image);
if (rvImage != null) {
removeImageImpl(rvImage);
}
notifyAll(); // Notify in case remaining images are "done".
}
private void removeImageImpl(Image image) {
MediaEntry cur = head;
MediaEntry prev = null;
while (cur != null) {
MediaEntry next = cur.next;
if (cur.getMedia() == image) {
if (prev == null) {
head = next;
} else {
prev.next = next;
}
cur.cancel();
} else {
prev = cur;
}
cur = next;
}
}
/**
* Removes the specified image from the specified tracking
* ID of this media tracker.
* All instances of <code>Image</code> being tracked
* under the specified ID are removed regardless of scale.
* @param image the image to be removed
* @param id the tracking ID from which to remove the image
* @see java.awt.MediaTracker#removeImage(java.awt.Image)
* @see java.awt.MediaTracker#removeImage(java.awt.Image, int, int, int)
* @since JDK1.1
*/
public synchronized void removeImage(Image image, int id) {
removeImageImpl(image, id);
Image rvImage = getResolutionVariant(image);
if (rvImage != null) {
removeImageImpl(rvImage, id);
}
notifyAll(); // Notify in case remaining images are "done".
}
private void removeImageImpl(Image image, int id) {
MediaEntry cur = head;
MediaEntry prev = null;
while (cur != null) {
MediaEntry next = cur.next;
if (cur.getID() == id && cur.getMedia() == image) {
if (prev == null) {
head = next;
} else {
prev.next = next;
}
cur.cancel();
} else {
prev = cur;
}
cur = next;
}
}
/**
* Removes the specified image with the specified
* width, height, and ID from this media tracker.
* Only the specified instance (with any duplicates) is removed.
* @param image the image to be removed
* @param id the tracking ID from which to remove the image
* @param width the width to remove (-1 for unscaled)
* @param height the height to remove (-1 for unscaled)
* @see java.awt.MediaTracker#removeImage(java.awt.Image)
* @see java.awt.MediaTracker#removeImage(java.awt.Image, int)
* @since JDK1.1
*/
public synchronized void removeImage(Image image, int id,
int width, int height) {
removeImageImpl(image, id, width, height);
Image rvImage = getResolutionVariant(image);
if (rvImage != null) {
removeImageImpl(rvImage, id,
width == -1 ? -1 : 2 * width,
height == -1 ? -1 : 2 * height);
}
notifyAll(); // Notify in case remaining images are "done".
}
private void removeImageImpl(Image image, int id, int width, int height) {
MediaEntry cur = head;
MediaEntry prev = null;
while (cur != null) {
MediaEntry next = cur.next;
if (cur.getID() == id && cur instanceof ImageMediaEntry
&& ((ImageMediaEntry) cur).matches(image, width, height))
{
if (prev == null) {
head = next;
} else {
prev.next = next;
}
cur.cancel();
} else {
prev = cur;
}
cur = next;
}
}
synchronized void setDone() {
notifyAll();
}
private static Image getResolutionVariant(Image image) {
if (image instanceof MultiResolutionToolkitImage) {
return ((MultiResolutionToolkitImage) image).getResolutionVariant();
}
return null;
}
}
abstract class MediaEntry {
MediaTracker tracker;
int ID;
MediaEntry next;
int status;
boolean cancelled;
MediaEntry(MediaTracker mt, int id) {
tracker = mt;
ID = id;
}
abstract Object getMedia();
static MediaEntry insert(MediaEntry head, MediaEntry me) {
MediaEntry cur = head;
MediaEntry prev = null;
while (cur != null) {
if (cur.ID > me.ID) {
break;
}
prev = cur;
cur = cur.next;
}
me.next = cur;
if (prev == null) {
head = me;
} else {
prev.next = me;
}
return head;
}
int getID() {
return ID;
}
abstract void startLoad();
void cancel() {
cancelled = true;
}
static final int LOADING = MediaTracker.LOADING;
static final int ABORTED = MediaTracker.ABORTED;
static final int ERRORED = MediaTracker.ERRORED;
static final int COMPLETE = MediaTracker.COMPLETE;
static final int LOADSTARTED = (LOADING | ERRORED | COMPLETE);
static final int DONE = (ABORTED | ERRORED | COMPLETE);
synchronized int getStatus(boolean doLoad, boolean doVerify) {
if (doLoad && ((status & LOADSTARTED) == 0)) {
status = (status & ~ABORTED) | LOADING;
startLoad();
}
return status;
}
void setStatus(int flag) {
synchronized (this) {
status = flag;
}
tracker.setDone();
}
}
class ImageMediaEntry extends MediaEntry implements ImageObserver,
java.io.Serializable {
Image image;
int width;
int height;
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = 4739377000350280650L;
ImageMediaEntry(MediaTracker mt, Image img, int c, int w, int h) {
super(mt, c);
image = img;
width = w;
height = h;
}
boolean matches(Image img, int w, int h) {
return (image == img && width == w && height == h);
}
Object getMedia() {
return image;
}
synchronized int getStatus(boolean doLoad, boolean doVerify) {
if (doVerify) {
int flags = tracker.target.checkImage(image, width, height, null);
int s = parseflags(flags);
if (s == 0) {
if ((status & (ERRORED | COMPLETE)) != 0) {
setStatus(ABORTED);
}
} else if (s != status) {
setStatus(s);
}
}
return super.getStatus(doLoad, doVerify);
}
void startLoad() {
if (tracker.target.prepareImage(image, width, height, this)) {
setStatus(COMPLETE);
}
}
int parseflags(int infoflags) {
if ((infoflags & ERROR) != 0) {
return ERRORED;
} else if ((infoflags & ABORT) != 0) {
return ABORTED;
} else if ((infoflags & (ALLBITS | FRAMEBITS)) != 0) {
return COMPLETE;
}
return 0;
}
public boolean imageUpdate(Image img, int infoflags,
int x, int y, int w, int h) {
if (cancelled) {
return false;
}
int s = parseflags(infoflags);
if (s != 0 && s != status) {
setStatus(s);
}
return ((status & LOADING) != 0);
}
}

View File

@@ -0,0 +1,630 @@
/*
* Copyright (c) 1995, 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 java.awt;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Vector;
import java.util.Enumeration;
import java.awt.peer.MenuPeer;
import java.awt.event.KeyEvent;
import javax.accessibility.*;
import sun.awt.AWTAccessor;
/**
* A <code>Menu</code> object is a pull-down menu component
* that is deployed from a menu bar.
* <p>
* A menu can optionally be a <i>tear-off</i> menu. A tear-off menu
* can be opened and dragged away from its parent menu bar or menu.
* It remains on the screen after the mouse button has been released.
* The mechanism for tearing off a menu is platform dependent, since
* the look and feel of the tear-off menu is determined by its peer.
* On platforms that do not support tear-off menus, the tear-off
* property is ignored.
* <p>
* Each item in a menu must belong to the <code>MenuItem</code>
* class. It can be an instance of <code>MenuItem</code>, a submenu
* (an instance of <code>Menu</code>), or a check box (an instance of
* <code>CheckboxMenuItem</code>).
*
* @author Sami Shaio
* @see java.awt.MenuItem
* @see java.awt.CheckboxMenuItem
* @since JDK1.0
*/
public class Menu extends MenuItem implements MenuContainer, Accessible {
static {
/* ensure that the necessary native libraries are loaded */
Toolkit.loadLibraries();
if (!GraphicsEnvironment.isHeadless()) {
initIDs();
}
AWTAccessor.setMenuAccessor(
new AWTAccessor.MenuAccessor() {
public Vector<MenuComponent> getItems(Menu menu) {
return menu.items;
}
});
}
/**
* A vector of the items that will be part of the Menu.
*
* @serial
* @see #countItems()
*/
Vector<MenuComponent> items = new Vector<>();
/**
* This field indicates whether the menu has the
* tear of property or not. It will be set to
* <code>true</code> if the menu has the tear off
* property and it will be set to <code>false</code>
* if it does not.
* A torn off menu can be deleted by a user when
* it is no longer needed.
*
* @serial
* @see #isTearOff()
*/
boolean tearOff;
/**
* This field will be set to <code>true</code>
* if the Menu in question is actually a help
* menu. Otherwise it will be set to <code>
* false</code>.
*
* @serial
*/
boolean isHelpMenu;
private static final String base = "menu";
private static int nameCounter = 0;
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = -8809584163345499784L;
/**
* Constructs a new menu with an empty label. This menu is not
* a tear-off menu.
* @exception HeadlessException if GraphicsEnvironment.isHeadless()
* returns true.
* @see java.awt.GraphicsEnvironment#isHeadless
* @since JDK1.1
*/
public Menu() throws HeadlessException {
this("", false);
}
/**
* Constructs a new menu with the specified label. This menu is not
* a tear-off menu.
* @param label the menu's label in the menu bar, or in
* another menu of which this menu is a submenu.
* @exception HeadlessException if GraphicsEnvironment.isHeadless()
* returns true.
* @see java.awt.GraphicsEnvironment#isHeadless
*/
public Menu(String label) throws HeadlessException {
this(label, false);
}
/**
* Constructs a new menu with the specified label,
* indicating whether the menu can be torn off.
* <p>
* Tear-off functionality may not be supported by all
* implementations of AWT. If a particular implementation doesn't
* support tear-off menus, this value is silently ignored.
* @param label the menu's label in the menu bar, or in
* another menu of which this menu is a submenu.
* @param tearOff if <code>true</code>, the menu
* is a tear-off menu.
* @exception HeadlessException if GraphicsEnvironment.isHeadless()
* returns true.
* @see java.awt.GraphicsEnvironment#isHeadless
* @since JDK1.0.
*/
public Menu(String label, boolean tearOff) throws HeadlessException {
super(label);
this.tearOff = tearOff;
}
/**
* Construct a name for this MenuComponent. Called by getName() when
* the name is null.
*/
String constructComponentName() {
synchronized (Menu.class) {
return base + nameCounter++;
}
}
/**
* Creates the menu's peer. The peer allows us to modify the
* appearance of the menu without changing its functionality.
*/
public void addNotify() {
synchronized (getTreeLock()) {
if (peer == null)
peer = Toolkit.getDefaultToolkit().createMenu(this);
int nitems = getItemCount();
for (int i = 0 ; i < nitems ; i++) {
MenuItem mi = getItem(i);
mi.parent = this;
mi.addNotify();
}
}
}
/**
* Removes the menu's peer. The peer allows us to modify the appearance
* of the menu without changing its functionality.
*/
public void removeNotify() {
synchronized (getTreeLock()) {
int nitems = getItemCount();
for (int i = 0 ; i < nitems ; i++) {
getItem(i).removeNotify();
}
super.removeNotify();
}
}
/**
* Indicates whether this menu is a tear-off menu.
* <p>
* Tear-off functionality may not be supported by all
* implementations of AWT. If a particular implementation doesn't
* support tear-off menus, this value is silently ignored.
* @return <code>true</code> if this is a tear-off menu;
* <code>false</code> otherwise.
*/
public boolean isTearOff() {
return tearOff;
}
/**
* Get the number of items in this menu.
* @return the number of items in this menu.
* @since JDK1.1
*/
public int getItemCount() {
return countItems();
}
/**
* @deprecated As of JDK version 1.1,
* replaced by <code>getItemCount()</code>.
*/
@Deprecated
public int countItems() {
return countItemsImpl();
}
/*
* This is called by the native code, so client code can't
* be called on the toolkit thread.
*/
final int countItemsImpl() {
return items.size();
}
/**
* Gets the item located at the specified index of this menu.
* @param index the position of the item to be returned.
* @return the item located at the specified index.
*/
public MenuItem getItem(int index) {
return getItemImpl(index);
}
/*
* This is called by the native code, so client code can't
* be called on the toolkit thread.
*/
final MenuItem getItemImpl(int index) {
return (MenuItem)items.elementAt(index);
}
/**
* Adds the specified menu item to this menu. If the
* menu item has been part of another menu, removes it
* from that menu.
*
* @param mi the menu item to be added
* @return the menu item added
* @see java.awt.Menu#insert(java.lang.String, int)
* @see java.awt.Menu#insert(java.awt.MenuItem, int)
*/
public MenuItem add(MenuItem mi) {
synchronized (getTreeLock()) {
if (mi.parent != null) {
mi.parent.remove(mi);
}
items.addElement(mi);
mi.parent = this;
MenuPeer peer = (MenuPeer)this.peer;
if (peer != null) {
mi.addNotify();
peer.addItem(mi);
}
return mi;
}
}
/**
* Adds an item with the specified label to this menu.
*
* @param label the text on the item
* @see java.awt.Menu#insert(java.lang.String, int)
* @see java.awt.Menu#insert(java.awt.MenuItem, int)
*/
public void add(String label) {
add(new MenuItem(label));
}
/**
* Inserts a menu item into this menu
* at the specified position.
*
* @param menuitem the menu item to be inserted.
* @param index the position at which the menu
* item should be inserted.
* @see java.awt.Menu#add(java.lang.String)
* @see java.awt.Menu#add(java.awt.MenuItem)
* @exception IllegalArgumentException if the value of
* <code>index</code> is less than zero
* @since JDK1.1
*/
public void insert(MenuItem menuitem, int index) {
synchronized (getTreeLock()) {
if (index < 0) {
throw new IllegalArgumentException("index less than zero.");
}
int nitems = getItemCount();
Vector<MenuItem> tempItems = new Vector<>();
/* Remove the item at index, nitems-index times
storing them in a temporary vector in the
order they appear on the menu.
*/
for (int i = index ; i < nitems; i++) {
tempItems.addElement(getItem(index));
remove(index);
}
add(menuitem);
/* Add the removed items back to the menu, they are
already in the correct order in the temp vector.
*/
for (int i = 0; i < tempItems.size() ; i++) {
add(tempItems.elementAt(i));
}
}
}
/**
* Inserts a menu item with the specified label into this menu
* at the specified position. This is a convenience method for
* <code>insert(menuItem, index)</code>.
*
* @param label the text on the item
* @param index the position at which the menu item
* should be inserted
* @see java.awt.Menu#add(java.lang.String)
* @see java.awt.Menu#add(java.awt.MenuItem)
* @exception IllegalArgumentException if the value of
* <code>index</code> is less than zero
* @since JDK1.1
*/
public void insert(String label, int index) {
insert(new MenuItem(label), index);
}
/**
* Adds a separator line, or a hypen, to the menu at the current position.
* @see java.awt.Menu#insertSeparator(int)
*/
public void addSeparator() {
add("-");
}
/**
* Inserts a separator at the specified position.
* @param index the position at which the
* menu separator should be inserted.
* @exception IllegalArgumentException if the value of
* <code>index</code> is less than 0.
* @see java.awt.Menu#addSeparator
* @since JDK1.1
*/
public void insertSeparator(int index) {
synchronized (getTreeLock()) {
if (index < 0) {
throw new IllegalArgumentException("index less than zero.");
}
int nitems = getItemCount();
Vector<MenuItem> tempItems = new Vector<>();
/* Remove the item at index, nitems-index times
storing them in a temporary vector in the
order they appear on the menu.
*/
for (int i = index ; i < nitems; i++) {
tempItems.addElement(getItem(index));
remove(index);
}
addSeparator();
/* Add the removed items back to the menu, they are
already in the correct order in the temp vector.
*/
for (int i = 0; i < tempItems.size() ; i++) {
add(tempItems.elementAt(i));
}
}
}
/**
* Removes the menu item at the specified index from this menu.
* @param index the position of the item to be removed.
*/
public void remove(int index) {
synchronized (getTreeLock()) {
MenuItem mi = getItem(index);
items.removeElementAt(index);
MenuPeer peer = (MenuPeer)this.peer;
if (peer != null) {
peer.delItem(index);
mi.removeNotify();
mi.parent = null;
}
}
}
/**
* Removes the specified menu item from this menu.
* @param item the item to be removed from the menu.
* If <code>item</code> is <code>null</code>
* or is not in this menu, this method does
* nothing.
*/
public void remove(MenuComponent item) {
synchronized (getTreeLock()) {
int index = items.indexOf(item);
if (index >= 0) {
remove(index);
}
}
}
/**
* Removes all items from this menu.
* @since JDK1.0.
*/
public void removeAll() {
synchronized (getTreeLock()) {
int nitems = getItemCount();
for (int i = nitems-1 ; i >= 0 ; i--) {
remove(i);
}
}
}
/*
* Post an ActionEvent to the target of the MenuPeer
* associated with the specified keyboard event (on
* keydown). Returns true if there is an associated
* keyboard event.
*/
boolean handleShortcut(KeyEvent e) {
int nitems = getItemCount();
for (int i = 0 ; i < nitems ; i++) {
MenuItem mi = getItem(i);
if (mi.handleShortcut(e)) {
return true;
}
}
return false;
}
MenuItem getShortcutMenuItem(MenuShortcut s) {
int nitems = getItemCount();
for (int i = 0 ; i < nitems ; i++) {
MenuItem mi = getItem(i).getShortcutMenuItem(s);
if (mi != null) {
return mi;
}
}
return null;
}
synchronized Enumeration<MenuShortcut> shortcuts() {
Vector<MenuShortcut> shortcuts = new Vector<>();
int nitems = getItemCount();
for (int i = 0 ; i < nitems ; i++) {
MenuItem mi = getItem(i);
if (mi instanceof Menu) {
Enumeration<MenuShortcut> e = ((Menu)mi).shortcuts();
while (e.hasMoreElements()) {
shortcuts.addElement(e.nextElement());
}
} else {
MenuShortcut ms = mi.getShortcut();
if (ms != null) {
shortcuts.addElement(ms);
}
}
}
return shortcuts.elements();
}
void deleteShortcut(MenuShortcut s) {
int nitems = getItemCount();
for (int i = 0 ; i < nitems ; i++) {
getItem(i).deleteShortcut(s);
}
}
/* Serialization support. A MenuContainer is responsible for
* restoring the parent fields of its children.
*/
/**
* The menu serialized Data Version.
*
* @serial
*/
private int menuSerializedDataVersion = 1;
/**
* Writes default serializable fields to stream.
*
* @param s the <code>ObjectOutputStream</code> to write
* @see AWTEventMulticaster#save(ObjectOutputStream, String, EventListener)
* @see #readObject(ObjectInputStream)
*/
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException
{
s.defaultWriteObject();
}
/**
* Reads the <code>ObjectInputStream</code>.
* Unrecognized keys or values will be ignored.
*
* @param s the <code>ObjectInputStream</code> to read
* @exception HeadlessException if
* <code>GraphicsEnvironment.isHeadless</code> returns
* <code>true</code>
* @see java.awt.GraphicsEnvironment#isHeadless
* @see #writeObject(ObjectOutputStream)
*/
private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException, HeadlessException
{
// HeadlessException will be thrown from MenuComponent's readObject
s.defaultReadObject();
for(int i = 0; i < items.size(); i++) {
MenuItem item = (MenuItem)items.elementAt(i);
item.parent = this;
}
}
/**
* Returns a string representing the state of this <code>Menu</code>.
* This method is intended to be used only for debugging purposes, and the
* content and format of the returned string may vary between
* implementations. The returned string may be empty but may not be
* <code>null</code>.
*
* @return the parameter string of this menu
*/
public String paramString() {
String str = ",tearOff=" + tearOff+",isHelpMenu=" + isHelpMenu;
return super.paramString() + str;
}
/**
* Initialize JNI field and method IDs
*/
private static native void initIDs();
/////////////////
// Accessibility support
////////////////
/**
* Gets the AccessibleContext associated with this Menu.
* For menus, the AccessibleContext takes the form of an
* AccessibleAWTMenu.
* A new AccessibleAWTMenu instance is created if necessary.
*
* @return an AccessibleAWTMenu that serves as the
* AccessibleContext of this Menu
* @since 1.3
*/
public AccessibleContext getAccessibleContext() {
if (accessibleContext == null) {
accessibleContext = new AccessibleAWTMenu();
}
return accessibleContext;
}
/**
* Defined in MenuComponent. Overridden here.
*/
int getAccessibleChildIndex(MenuComponent child) {
return items.indexOf(child);
}
/**
* Inner class of Menu used to provide default support for
* accessibility. This class is not meant to be used directly by
* application developers, but is instead meant only to be
* subclassed by menu component developers.
* <p>
* This class implements accessibility support for the
* <code>Menu</code> class. It provides an implementation of the
* Java Accessibility API appropriate to menu user-interface elements.
* @since 1.3
*/
protected class AccessibleAWTMenu extends AccessibleAWTMenuItem
{
/*
* JDK 1.3 serialVersionUID
*/
private static final long serialVersionUID = 5228160894980069094L;
/**
* Get the role of this object.
*
* @return an instance of AccessibleRole describing the role of the
* object
*/
public AccessibleRole getAccessibleRole() {
return AccessibleRole.MENU;
}
} // class AccessibleAWTMenu
}

View File

@@ -0,0 +1,517 @@
/*
* Copyright (c) 1995, 2015, 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 java.awt;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Vector;
import java.util.Enumeration;
import sun.awt.AWTAccessor;
import java.awt.peer.MenuBarPeer;
import java.awt.event.KeyEvent;
import javax.accessibility.*;
/**
* The <code>MenuBar</code> class encapsulates the platform's
* concept of a menu bar bound to a frame. In order to associate
* the menu bar with a <code>Frame</code> object, call the
* frame's <code>setMenuBar</code> method.
* <p>
* <A NAME="mbexample"></A><!-- target for cross references -->
* This is what a menu bar might look like:
* <p>
* <img src="doc-files/MenuBar-1.gif"
* alt="Diagram of MenuBar containing 2 menus: Examples and Options.
* Examples menu is expanded showing items: Basic, Simple, Check, and More Examples."
* style="float:center; margin: 7px 10px;">
* <p>
* A menu bar handles keyboard shortcuts for menu items, passing them
* along to its child menus.
* (Keyboard shortcuts, which are optional, provide the user with
* an alternative to the mouse for invoking a menu item and the
* action that is associated with it.)
* Each menu item can maintain an instance of <code>MenuShortcut</code>.
* The <code>MenuBar</code> class defines several methods,
* {@link MenuBar#shortcuts} and
* {@link MenuBar#getShortcutMenuItem}
* that retrieve information about the shortcuts a given
* menu bar is managing.
*
* @author Sami Shaio
* @see java.awt.Frame
* @see java.awt.Frame#setMenuBar(java.awt.MenuBar)
* @see java.awt.Menu
* @see java.awt.MenuItem
* @see java.awt.MenuShortcut
* @since JDK1.0
*/
public class MenuBar extends MenuComponent implements MenuContainer, Accessible {
static {
/* ensure that the necessary native libraries are loaded */
Toolkit.loadLibraries();
if (!GraphicsEnvironment.isHeadless()) {
initIDs();
}
AWTAccessor.setMenuBarAccessor(
new AWTAccessor.MenuBarAccessor() {
public Menu getHelpMenu(MenuBar menuBar) {
return menuBar.helpMenu;
}
public Vector<Menu> getMenus(MenuBar menuBar) {
return menuBar.menus;
}
});
}
/**
* This field represents a vector of the
* actual menus that will be part of the MenuBar.
*
* @serial
* @see #countMenus()
*/
Vector<Menu> menus = new Vector<>();
/**
* This menu is a special menu dedicated to
* help. The one thing to note about this menu
* is that on some platforms it appears at the
* right edge of the menubar.
*
* @serial
* @see #getHelpMenu()
* @see #setHelpMenu(Menu)
*/
Menu helpMenu;
private static final String base = "menubar";
private static int nameCounter = 0;
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = -4930327919388951260L;
/**
* Creates a new menu bar.
* @exception HeadlessException if GraphicsEnvironment.isHeadless()
* returns true.
* @see java.awt.GraphicsEnvironment#isHeadless
*/
public MenuBar() throws HeadlessException {
}
/**
* Construct a name for this MenuComponent. Called by getName() when
* the name is null.
*/
String constructComponentName() {
synchronized (MenuBar.class) {
return base + nameCounter++;
}
}
/**
* Creates the menu bar's peer. The peer allows us to change the
* appearance of the menu bar without changing any of the menu bar's
* functionality.
*/
public void addNotify() {
synchronized (getTreeLock()) {
if (peer == null)
peer = Toolkit.getDefaultToolkit().createMenuBar(this);
int nmenus = getMenuCount();
for (int i = 0 ; i < nmenus ; i++) {
getMenu(i).addNotify();
}
}
}
/**
* Removes the menu bar's peer. The peer allows us to change the
* appearance of the menu bar without changing any of the menu bar's
* functionality.
*/
public void removeNotify() {
synchronized (getTreeLock()) {
int nmenus = getMenuCount();
for (int i = 0 ; i < nmenus ; i++) {
getMenu(i).removeNotify();
}
super.removeNotify();
}
}
/**
* Gets the help menu on the menu bar.
* @return the help menu on this menu bar.
*/
public Menu getHelpMenu() {
return helpMenu;
}
/**
* Sets the specified menu to be this menu bar's help menu.
* If this menu bar has an existing help menu, the old help menu is
* removed from the menu bar, and replaced with the specified menu.
* @param m the menu to be set as the help menu
*/
public void setHelpMenu(final Menu m) {
synchronized (getTreeLock()) {
if (helpMenu == m) {
return;
}
if (helpMenu != null) {
remove(helpMenu);
}
helpMenu = m;
if (m != null) {
if (m.parent != this) {
add(m);
}
m.isHelpMenu = true;
m.parent = this;
MenuBarPeer peer = (MenuBarPeer)this.peer;
if (peer != null) {
if (m.peer == null) {
m.addNotify();
}
peer.addHelpMenu(m);
}
}
}
}
/**
* Adds the specified menu to the menu bar.
* If the menu has been part of another menu bar,
* removes it from that menu bar.
*
* @param m the menu to be added
* @return the menu added
* @see java.awt.MenuBar#remove(int)
* @see java.awt.MenuBar#remove(java.awt.MenuComponent)
*/
public Menu add(Menu m) {
synchronized (getTreeLock()) {
if (m.parent != null) {
m.parent.remove(m);
}
m.parent = this;
MenuBarPeer peer = (MenuBarPeer)this.peer;
if (peer != null) {
if (m.peer == null) {
m.addNotify();
}
menus.addElement(m);
peer.addMenu(m);
} else {
menus.addElement(m);
}
return m;
}
}
/**
* Removes the menu located at the specified
* index from this menu bar.
* @param index the position of the menu to be removed.
* @see java.awt.MenuBar#add(java.awt.Menu)
*/
public void remove(final int index) {
synchronized (getTreeLock()) {
Menu m = getMenu(index);
menus.removeElementAt(index);
MenuBarPeer peer = (MenuBarPeer)this.peer;
if (peer != null) {
peer.delMenu(index);
m.removeNotify();
m.parent = null;
}
if (helpMenu == m) {
helpMenu = null;
m.isHelpMenu = false;
}
}
}
/**
* Removes the specified menu component from this menu bar.
* @param m the menu component to be removed.
* @see java.awt.MenuBar#add(java.awt.Menu)
*/
public void remove(MenuComponent m) {
synchronized (getTreeLock()) {
int index = menus.indexOf(m);
if (index >= 0) {
remove(index);
}
}
}
/**
* Gets the number of menus on the menu bar.
* @return the number of menus on the menu bar.
* @since JDK1.1
*/
public int getMenuCount() {
return countMenus();
}
/**
* @deprecated As of JDK version 1.1,
* replaced by <code>getMenuCount()</code>.
*/
@Deprecated
public int countMenus() {
return getMenuCountImpl();
}
/*
* This is called by the native code, so client code can't
* be called on the toolkit thread.
*/
final int getMenuCountImpl() {
return menus.size();
}
/**
* Gets the specified menu.
* @param i the index position of the menu to be returned.
* @return the menu at the specified index of this menu bar.
*/
public Menu getMenu(int i) {
return getMenuImpl(i);
}
/*
* This is called by the native code, so client code can't
* be called on the toolkit thread.
*/
final Menu getMenuImpl(int i) {
return menus.elementAt(i);
}
/**
* Gets an enumeration of all menu shortcuts this menu bar
* is managing.
* @return an enumeration of menu shortcuts that this
* menu bar is managing.
* @see java.awt.MenuShortcut
* @since JDK1.1
*/
public synchronized Enumeration<MenuShortcut> shortcuts() {
Vector<MenuShortcut> shortcuts = new Vector<>();
int nmenus = getMenuCount();
for (int i = 0 ; i < nmenus ; i++) {
Enumeration<MenuShortcut> e = getMenu(i).shortcuts();
while (e.hasMoreElements()) {
shortcuts.addElement(e.nextElement());
}
}
return shortcuts.elements();
}
/**
* Gets the instance of <code>MenuItem</code> associated
* with the specified <code>MenuShortcut</code> object,
* or <code>null</code> if none of the menu items being managed
* by this menu bar is associated with the specified menu
* shortcut.
* @param s the specified menu shortcut.
* @see java.awt.MenuItem
* @see java.awt.MenuShortcut
* @since JDK1.1
*/
public MenuItem getShortcutMenuItem(MenuShortcut s) {
int nmenus = getMenuCount();
for (int i = 0 ; i < nmenus ; i++) {
MenuItem mi = getMenu(i).getShortcutMenuItem(s);
if (mi != null) {
return mi;
}
}
return null; // MenuShortcut wasn't found
}
/*
* Post an ACTION_EVENT to the target of the MenuPeer
* associated with the specified keyboard event (on
* keydown). Returns true if there is an associated
* keyboard event.
*/
boolean handleShortcut(KeyEvent e) {
// Is it a key event?
int id = e.getID();
if (id != KeyEvent.KEY_PRESSED && id != KeyEvent.KEY_RELEASED) {
return false;
}
// Is the accelerator modifier key pressed?
int accelKey = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
if ((e.getModifiers() & accelKey) == 0) {
return false;
}
// Pass MenuShortcut on to child menus.
int nmenus = getMenuCount();
for (int i = 0 ; i < nmenus ; i++) {
Menu m = getMenu(i);
if (m.handleShortcut(e)) {
return true;
}
}
return false;
}
/**
* Deletes the specified menu shortcut.
* @param s the menu shortcut to delete.
* @since JDK1.1
*/
public void deleteShortcut(MenuShortcut s) {
int nmenus = getMenuCount();
for (int i = 0 ; i < nmenus ; i++) {
getMenu(i).deleteShortcut(s);
}
}
/* Serialization support. Restore the (transient) parent
* fields of Menubar menus here.
*/
/**
* The MenuBar's serialized data version.
*
* @serial
*/
private int menuBarSerializedDataVersion = 1;
/**
* Writes default serializable fields to stream.
*
* @param s the <code>ObjectOutputStream</code> to write
* @see AWTEventMulticaster#save(ObjectOutputStream, String, EventListener)
* @see #readObject(java.io.ObjectInputStream)
*/
private void writeObject(java.io.ObjectOutputStream s)
throws java.lang.ClassNotFoundException,
java.io.IOException
{
s.defaultWriteObject();
}
/**
* Reads the <code>ObjectInputStream</code>.
* Unrecognized keys or values will be ignored.
*
* @param s the <code>ObjectInputStream</code> to read
* @exception HeadlessException if
* <code>GraphicsEnvironment.isHeadless</code> returns
* <code>true</code>
* @see java.awt.GraphicsEnvironment#isHeadless
* @see #writeObject(java.io.ObjectOutputStream)
*/
private void readObject(ObjectInputStream s)
throws ClassNotFoundException, IOException, HeadlessException
{
// HeadlessException will be thrown from MenuComponent's readObject
s.defaultReadObject();
for (int i = 0; i < menus.size(); i++) {
Menu m = menus.elementAt(i);
m.parent = this;
}
}
/**
* Initialize JNI field and method IDs
*/
private static native void initIDs();
/////////////////
// Accessibility support
////////////////
/**
* Gets the AccessibleContext associated with this MenuBar.
* For menu bars, the AccessibleContext takes the form of an
* AccessibleAWTMenuBar.
* A new AccessibleAWTMenuBar instance is created if necessary.
*
* @return an AccessibleAWTMenuBar that serves as the
* AccessibleContext of this MenuBar
* @since 1.3
*/
public AccessibleContext getAccessibleContext() {
if (accessibleContext == null) {
accessibleContext = new AccessibleAWTMenuBar();
}
return accessibleContext;
}
/**
* Defined in MenuComponent. Overridden here.
*/
int getAccessibleChildIndex(MenuComponent child) {
return menus.indexOf(child);
}
/**
* Inner class of MenuBar used to provide default support for
* accessibility. This class is not meant to be used directly by
* application developers, but is instead meant only to be
* subclassed by menu component developers.
* <p>
* This class implements accessibility support for the
* <code>MenuBar</code> class. It provides an implementation of the
* Java Accessibility API appropriate to menu bar user-interface elements.
* @since 1.3
*/
protected class AccessibleAWTMenuBar extends AccessibleAWTMenuComponent
{
/*
* JDK 1.3 serialVersionUID
*/
private static final long serialVersionUID = -8577604491830083815L;
/**
* Get the role of this object.
*
* @return an instance of AccessibleRole describing the role of the
* object
* @since 1.4
*/
public AccessibleRole getAccessibleRole() {
return AccessibleRole.MENU_BAR;
}
} // class AccessibleAWTMenuBar
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,43 @@
/*
* Copyright (c) 1995, 2004, 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 java.awt;
/**
* The super class of all menu related containers.
*
* @author Arthur van Hoff
*/
public interface MenuContainer {
Font getFont();
void remove(MenuComponent comp);
/**
* @deprecated As of JDK version 1.1
* replaced by dispatchEvent(AWTEvent).
*/
@Deprecated
boolean postEvent(Event evt);
}

View File

@@ -0,0 +1,942 @@
/*
* Copyright (c) 1995, 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 java.awt;
import java.awt.peer.MenuItemPeer;
import java.awt.event.*;
import java.util.EventListener;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.IOException;
import javax.accessibility.*;
import sun.awt.AWTAccessor;
/**
* All items in a menu must belong to the class
* <code>MenuItem</code>, or one of its subclasses.
* <p>
* The default <code>MenuItem</code> object embodies
* a simple labeled menu item.
* <p>
* This picture of a menu bar shows five menu items:
* <IMG SRC="doc-files/MenuBar-1.gif" alt="The following text describes this graphic."
* style="float:center; margin: 7px 10px;">
* <br style="clear:left;">
* The first two items are simple menu items, labeled
* <code>"Basic"</code> and <code>"Simple"</code>.
* Following these two items is a separator, which is itself
* a menu item, created with the label <code>"-"</code>.
* Next is an instance of <code>CheckboxMenuItem</code>
* labeled <code>"Check"</code>. The final menu item is a
* submenu labeled <code>"More&nbsp;Examples"</code>,
* and this submenu is an instance of <code>Menu</code>.
* <p>
* When a menu item is selected, AWT sends an action event to
* the menu item. Since the event is an
* instance of <code>ActionEvent</code>, the <code>processEvent</code>
* method examines the event and passes it along to
* <code>processActionEvent</code>. The latter method redirects the
* event to any <code>ActionListener</code> objects that have
* registered an interest in action events generated by this
* menu item.
* <P>
* Note that the subclass <code>Menu</code> overrides this behavior and
* does not send any event to the frame until one of its subitems is
* selected.
*
* @author Sami Shaio
*/
public class MenuItem extends MenuComponent implements Accessible {
static {
/* ensure that the necessary native libraries are loaded */
Toolkit.loadLibraries();
if (!GraphicsEnvironment.isHeadless()) {
initIDs();
}
AWTAccessor.setMenuItemAccessor(
new AWTAccessor.MenuItemAccessor() {
public boolean isEnabled(MenuItem item) {
return item.enabled;
}
public String getLabel(MenuItem item) {
return item.label;
}
public MenuShortcut getShortcut(MenuItem item) {
return item.shortcut;
}
public String getActionCommandImpl(MenuItem item) {
return item.getActionCommandImpl();
}
public boolean isItemEnabled(MenuItem item) {
return item.isItemEnabled();
}
});
}
/**
* A value to indicate whether a menu item is enabled
* or not. If it is enabled, <code>enabled</code> will
* be set to true. Else <code>enabled</code> will
* be set to false.
*
* @serial
* @see #isEnabled()
* @see #setEnabled(boolean)
*/
boolean enabled = true;
/**
* <code>label</code> is the label of a menu item.
* It can be any string.
*
* @serial
* @see #getLabel()
* @see #setLabel(String)
*/
String label;
/**
* This field indicates the command tha has been issued
* by a particular menu item.
* By default the <code>actionCommand</code>
* is the label of the menu item, unless it has been
* set using setActionCommand.
*
* @serial
* @see #setActionCommand(String)
* @see #getActionCommand()
*/
String actionCommand;
/**
* The eventMask is ONLY set by subclasses via enableEvents.
* The mask should NOT be set when listeners are registered
* so that we can distinguish the difference between when
* listeners request events and subclasses request them.
*
* @serial
*/
long eventMask;
transient ActionListener actionListener;
/**
* A sequence of key stokes that ia associated with
* a menu item.
* Note :in 1.1.2 you must use setActionCommand()
* on a menu item in order for its shortcut to
* work.
*
* @serial
* @see #getShortcut()
* @see #setShortcut(MenuShortcut)
* @see #deleteShortcut()
*/
private MenuShortcut shortcut = null;
private static final String base = "menuitem";
private static int nameCounter = 0;
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = -21757335363267194L;
/**
* Constructs a new MenuItem with an empty label and no keyboard
* shortcut.
* @exception HeadlessException if GraphicsEnvironment.isHeadless()
* returns true.
* @see java.awt.GraphicsEnvironment#isHeadless
* @since JDK1.1
*/
public MenuItem() throws HeadlessException {
this("", null);
}
/**
* Constructs a new MenuItem with the specified label
* and no keyboard shortcut. Note that use of "-" in
* a label is reserved to indicate a separator between
* menu items. By default, all menu items except for
* separators are enabled.
* @param label the label for this menu item.
* @exception HeadlessException if GraphicsEnvironment.isHeadless()
* returns true.
* @see java.awt.GraphicsEnvironment#isHeadless
* @since JDK1.0
*/
public MenuItem(String label) throws HeadlessException {
this(label, null);
}
/**
* Create a menu item with an associated keyboard shortcut.
* Note that use of "-" in a label is reserved to indicate
* a separator between menu items. By default, all menu
* items except for separators are enabled.
* @param label the label for this menu item.
* @param s the instance of <code>MenuShortcut</code>
* associated with this menu item.
* @exception HeadlessException if GraphicsEnvironment.isHeadless()
* returns true.
* @see java.awt.GraphicsEnvironment#isHeadless
* @since JDK1.1
*/
public MenuItem(String label, MenuShortcut s) throws HeadlessException {
this.label = label;
this.shortcut = s;
}
/**
* Construct a name for this MenuComponent. Called by getName() when
* the name is null.
*/
String constructComponentName() {
synchronized (MenuItem.class) {
return base + nameCounter++;
}
}
/**
* Creates the menu item's peer. The peer allows us to modify the
* appearance of the menu item without changing its functionality.
*/
public void addNotify() {
synchronized (getTreeLock()) {
if (peer == null)
peer = Toolkit.getDefaultToolkit().createMenuItem(this);
}
}
/**
* Gets the label for this menu item.
* @return the label of this menu item, or <code>null</code>
if this menu item has no label.
* @see java.awt.MenuItem#setLabel
* @since JDK1.0
*/
public String getLabel() {
return label;
}
/**
* Sets the label for this menu item to the specified label.
* @param label the new label, or <code>null</code> for no label.
* @see java.awt.MenuItem#getLabel
* @since JDK1.0
*/
public synchronized void setLabel(String label) {
this.label = label;
MenuItemPeer peer = (MenuItemPeer)this.peer;
if (peer != null) {
peer.setLabel(label);
}
}
/**
* Checks whether this menu item is enabled.
* @see java.awt.MenuItem#setEnabled
* @since JDK1.0
*/
public boolean isEnabled() {
return enabled;
}
/**
* Sets whether or not this menu item can be chosen.
* @param b if <code>true</code>, enables this menu item;
* if <code>false</code>, disables it.
* @see java.awt.MenuItem#isEnabled
* @since JDK1.1
*/
public synchronized void setEnabled(boolean b) {
enable(b);
}
/**
* @deprecated As of JDK version 1.1,
* replaced by <code>setEnabled(boolean)</code>.
*/
@Deprecated
public synchronized void enable() {
enabled = true;
MenuItemPeer peer = (MenuItemPeer)this.peer;
if (peer != null) {
peer.setEnabled(true);
}
}
/**
* @deprecated As of JDK version 1.1,
* replaced by <code>setEnabled(boolean)</code>.
*/
@Deprecated
public void enable(boolean b) {
if (b) {
enable();
} else {
disable();
}
}
/**
* @deprecated As of JDK version 1.1,
* replaced by <code>setEnabled(boolean)</code>.
*/
@Deprecated
public synchronized void disable() {
enabled = false;
MenuItemPeer peer = (MenuItemPeer)this.peer;
if (peer != null) {
peer.setEnabled(false);
}
}
/**
* Get the <code>MenuShortcut</code> object associated with this
* menu item,
* @return the menu shortcut associated with this menu item,
* or <code>null</code> if none has been specified.
* @see java.awt.MenuItem#setShortcut
* @since JDK1.1
*/
public MenuShortcut getShortcut() {
return shortcut;
}
/**
* Set the <code>MenuShortcut</code> object associated with this
* menu item. If a menu shortcut is already associated with
* this menu item, it is replaced.
* @param s the menu shortcut to associate
* with this menu item.
* @see java.awt.MenuItem#getShortcut
* @since JDK1.1
*/
public void setShortcut(MenuShortcut s) {
shortcut = s;
MenuItemPeer peer = (MenuItemPeer)this.peer;
if (peer != null) {
peer.setLabel(label);
}
}
/**
* Delete any <code>MenuShortcut</code> object associated
* with this menu item.
* @since JDK1.1
*/
public void deleteShortcut() {
shortcut = null;
MenuItemPeer peer = (MenuItemPeer)this.peer;
if (peer != null) {
peer.setLabel(label);
}
}
/*
* Delete a matching MenuShortcut associated with this MenuItem.
* Used when iterating Menus.
*/
void deleteShortcut(MenuShortcut s) {
if (s.equals(shortcut)) {
shortcut = null;
MenuItemPeer peer = (MenuItemPeer)this.peer;
if (peer != null) {
peer.setLabel(label);
}
}
}
/*
* The main goal of this method is to post an appropriate event
* to the event queue when menu shortcut is pressed. However,
* in subclasses this method may do more than just posting
* an event.
*/
void doMenuEvent(long when, int modifiers) {
Toolkit.getEventQueue().postEvent(
new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
getActionCommand(), when, modifiers));
}
/*
* Returns true if the item and all its ancestors are
* enabled, false otherwise
*/
private final boolean isItemEnabled() {
// Fix For 6185151: Menu shortcuts of all menuitems within a menu
// should be disabled when the menu itself is disabled
if (!isEnabled()) {
return false;
}
MenuContainer container = getParent_NoClientCode();
do {
if (!(container instanceof Menu)) {
return true;
}
Menu menu = (Menu)container;
if (!menu.isEnabled()) {
return false;
}
container = menu.getParent_NoClientCode();
} while (container != null);
return true;
}
/*
* Post an ActionEvent to the target (on
* keydown) and the item is enabled.
* Returns true if there is an associated shortcut.
*/
boolean handleShortcut(KeyEvent e) {
MenuShortcut s = new MenuShortcut(e.getKeyCode(),
(e.getModifiers() & InputEvent.SHIFT_MASK) > 0);
MenuShortcut sE = new MenuShortcut(e.getExtendedKeyCode(),
(e.getModifiers() & InputEvent.SHIFT_MASK) > 0);
// Fix For 6185151: Menu shortcuts of all menuitems within a menu
// should be disabled when the menu itself is disabled
if ((s.equals(shortcut) || sE.equals(shortcut)) && isItemEnabled()) {
// MenuShortcut match -- issue an event on keydown.
if (e.getID() == KeyEvent.KEY_PRESSED) {
doMenuEvent(e.getWhen(), e.getModifiers());
} else {
// silently eat key release.
}
return true;
}
return false;
}
MenuItem getShortcutMenuItem(MenuShortcut s) {
return (s.equals(shortcut)) ? this : null;
}
/**
* Enables event delivery to this menu item for events
* to be defined by the specified event mask parameter
* <p>
* Since event types are automatically enabled when a listener for
* that type is added to the menu item, this method only needs
* to be invoked by subclasses of <code>MenuItem</code> which desire to
* have the specified event types delivered to <code>processEvent</code>
* regardless of whether a listener is registered.
*
* @param eventsToEnable the event mask defining the event types
* @see java.awt.MenuItem#processEvent
* @see java.awt.MenuItem#disableEvents
* @see java.awt.Component#enableEvents
* @since JDK1.1
*/
protected final void enableEvents(long eventsToEnable) {
eventMask |= eventsToEnable;
newEventsOnly = true;
}
/**
* Disables event delivery to this menu item for events
* defined by the specified event mask parameter.
*
* @param eventsToDisable the event mask defining the event types
* @see java.awt.MenuItem#processEvent
* @see java.awt.MenuItem#enableEvents
* @see java.awt.Component#disableEvents
* @since JDK1.1
*/
protected final void disableEvents(long eventsToDisable) {
eventMask &= ~eventsToDisable;
}
/**
* Sets the command name of the action event that is fired
* by this menu item.
* <p>
* By default, the action command is set to the label of
* the menu item.
* @param command the action command to be set
* for this menu item.
* @see java.awt.MenuItem#getActionCommand
* @since JDK1.1
*/
public void setActionCommand(String command) {
actionCommand = command;
}
/**
* Gets the command name of the action event that is fired
* by this menu item.
* @see java.awt.MenuItem#setActionCommand
* @since JDK1.1
*/
public String getActionCommand() {
return getActionCommandImpl();
}
// This is final so it can be called on the Toolkit thread.
final String getActionCommandImpl() {
return (actionCommand == null? label : actionCommand);
}
/**
* Adds the specified action listener to receive action events
* from this menu item.
* If l is null, no exception is thrown and no action is performed.
* <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
* >AWT Threading Issues</a> for details on AWT's threading model.
*
* @param l the action listener.
* @see #removeActionListener
* @see #getActionListeners
* @see java.awt.event.ActionEvent
* @see java.awt.event.ActionListener
* @since JDK1.1
*/
public synchronized void addActionListener(ActionListener l) {
if (l == null) {
return;
}
actionListener = AWTEventMulticaster.add(actionListener, l);
newEventsOnly = true;
}
/**
* Removes the specified action listener so it no longer receives
* action events from this menu item.
* If l is null, no exception is thrown and no action is performed.
* <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
* >AWT Threading Issues</a> for details on AWT's threading model.
*
* @param l the action listener.
* @see #addActionListener
* @see #getActionListeners
* @see java.awt.event.ActionEvent
* @see java.awt.event.ActionListener
* @since JDK1.1
*/
public synchronized void removeActionListener(ActionListener l) {
if (l == null) {
return;
}
actionListener = AWTEventMulticaster.remove(actionListener, l);
}
/**
* Returns an array of all the action listeners
* registered on this menu item.
*
* @return all of this menu item's <code>ActionListener</code>s
* or an empty array if no action
* listeners are currently registered
*
* @see #addActionListener
* @see #removeActionListener
* @see java.awt.event.ActionEvent
* @see java.awt.event.ActionListener
* @since 1.4
*/
public synchronized ActionListener[] getActionListeners() {
return getListeners(ActionListener.class);
}
/**
* Returns an array of all the objects currently registered
* as <code><em>Foo</em>Listener</code>s
* upon this <code>MenuItem</code>.
* <code><em>Foo</em>Listener</code>s are registered using the
* <code>add<em>Foo</em>Listener</code> method.
*
* <p>
* You can specify the <code>listenerType</code> argument
* with a class literal, such as
* <code><em>Foo</em>Listener.class</code>.
* For example, you can query a
* <code>MenuItem</code> <code>m</code>
* for its action listeners with the following code:
*
* <pre>ActionListener[] als = (ActionListener[])(m.getListeners(ActionListener.class));</pre>
*
* If no such listeners exist, this method returns an empty array.
*
* @param listenerType the type of listeners requested; this parameter
* should specify an interface that descends from
* <code>java.util.EventListener</code>
* @return an array of all objects registered as
* <code><em>Foo</em>Listener</code>s on this menu item,
* or an empty array if no such
* listeners have been added
* @exception ClassCastException if <code>listenerType</code>
* doesn't specify a class or interface that implements
* <code>java.util.EventListener</code>
*
* @see #getActionListeners
* @since 1.3
*/
public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
EventListener l = null;
if (listenerType == ActionListener.class) {
l = actionListener;
}
return AWTEventMulticaster.getListeners(l, listenerType);
}
/**
* Processes events on this menu item. If the event is an
* instance of <code>ActionEvent</code>, it invokes
* <code>processActionEvent</code>, another method
* defined by <code>MenuItem</code>.
* <p>
* Currently, menu items only support action events.
* <p>Note that if the event parameter is <code>null</code>
* the behavior is unspecified and may result in an
* exception.
*
* @param e the event
* @see java.awt.MenuItem#processActionEvent
* @since JDK1.1
*/
protected void processEvent(AWTEvent e) {
if (e instanceof ActionEvent) {
processActionEvent((ActionEvent)e);
}
}
// REMIND: remove when filtering is done at lower level
boolean eventEnabled(AWTEvent e) {
if (e.id == ActionEvent.ACTION_PERFORMED) {
if ((eventMask & AWTEvent.ACTION_EVENT_MASK) != 0 ||
actionListener != null) {
return true;
}
return false;
}
return super.eventEnabled(e);
}
/**
* Processes action events occurring on this menu item,
* by dispatching them to any registered
* <code>ActionListener</code> objects.
* This method is not called unless action events are
* enabled for this component. Action events are enabled
* when one of the following occurs:
* <ul>
* <li>An <code>ActionListener</code> object is registered
* via <code>addActionListener</code>.
* <li>Action events are enabled via <code>enableEvents</code>.
* </ul>
* <p>Note that if the event parameter is <code>null</code>
* the behavior is unspecified and may result in an
* exception.
*
* @param e the action event
* @see java.awt.event.ActionEvent
* @see java.awt.event.ActionListener
* @see java.awt.MenuItem#enableEvents
* @since JDK1.1
*/
protected void processActionEvent(ActionEvent e) {
ActionListener listener = actionListener;
if (listener != null) {
listener.actionPerformed(e);
}
}
/**
* Returns a string representing the state of this <code>MenuItem</code>.
* This method is intended to be used only for debugging purposes, and the
* content and format of the returned string may vary between
* implementations. The returned string may be empty but may not be
* <code>null</code>.
*
* @return the parameter string of this menu item
*/
public String paramString() {
String str = ",label=" + label;
if (shortcut != null) {
str += ",shortcut=" + shortcut;
}
return super.paramString() + str;
}
/* Serialization support.
*/
/**
* Menu item serialized data version.
*
* @serial
*/
private int menuItemSerializedDataVersion = 1;
/**
* Writes default serializable fields to stream. Writes
* a list of serializable <code>ActionListeners</code>
* as optional data. The non-serializable listeners are
* detected and no attempt is made to serialize them.
*
* @param s the <code>ObjectOutputStream</code> to write
* @serialData <code>null</code> terminated sequence of 0
* or more pairs; the pair consists of a <code>String</code>
* and an <code>Object</code>; the <code>String</code>
* indicates the type of object and is one of the following:
* <code>actionListenerK</code> indicating an
* <code>ActionListener</code> object
*
* @see AWTEventMulticaster#save(ObjectOutputStream, String, EventListener)
* @see #readObject(ObjectInputStream)
*/
private void writeObject(ObjectOutputStream s)
throws IOException
{
s.defaultWriteObject();
AWTEventMulticaster.save(s, actionListenerK, actionListener);
s.writeObject(null);
}
/**
* Reads the <code>ObjectInputStream</code> and if it
* isn't <code>null</code> adds a listener to receive
* action events fired by the <code>Menu</code> Item.
* Unrecognized keys or values will be ignored.
*
* @param s the <code>ObjectInputStream</code> to read
* @exception HeadlessException if
* <code>GraphicsEnvironment.isHeadless</code> returns
* <code>true</code>
* @see #removeActionListener(ActionListener)
* @see #addActionListener(ActionListener)
* @see #writeObject(ObjectOutputStream)
*/
private void readObject(ObjectInputStream s)
throws ClassNotFoundException, IOException, HeadlessException
{
// HeadlessException will be thrown from MenuComponent's readObject
s.defaultReadObject();
Object keyOrNull;
while(null != (keyOrNull = s.readObject())) {
String key = ((String)keyOrNull).intern();
if (actionListenerK == key)
addActionListener((ActionListener)(s.readObject()));
else // skip value for unrecognized key
s.readObject();
}
}
/**
* Initialize JNI field and method IDs
*/
private static native void initIDs();
/////////////////
// Accessibility support
////////////////
/**
* Gets the AccessibleContext associated with this MenuItem.
* For menu items, the AccessibleContext takes the form of an
* AccessibleAWTMenuItem.
* A new AccessibleAWTMenuItem instance is created if necessary.
*
* @return an AccessibleAWTMenuItem that serves as the
* AccessibleContext of this MenuItem
* @since 1.3
*/
public AccessibleContext getAccessibleContext() {
if (accessibleContext == null) {
accessibleContext = new AccessibleAWTMenuItem();
}
return accessibleContext;
}
/**
* Inner class of MenuItem used to provide default support for
* accessibility. This class is not meant to be used directly by
* application developers, but is instead meant only to be
* subclassed by menu component developers.
* <p>
* This class implements accessibility support for the
* <code>MenuItem</code> class. It provides an implementation of the
* Java Accessibility API appropriate to menu item user-interface elements.
* @since 1.3
*/
protected class AccessibleAWTMenuItem extends AccessibleAWTMenuComponent
implements AccessibleAction, AccessibleValue
{
/*
* JDK 1.3 serialVersionUID
*/
private static final long serialVersionUID = -217847831945965825L;
/**
* Get the accessible name of this object.
*
* @return the localized name of the object -- can be null if this
* object does not have a name
*/
public String getAccessibleName() {
if (accessibleName != null) {
return accessibleName;
} else {
if (getLabel() == null) {
return super.getAccessibleName();
} else {
return getLabel();
}
}
}
/**
* Get the role of this object.
*
* @return an instance of AccessibleRole describing the role of the
* object
*/
public AccessibleRole getAccessibleRole() {
return AccessibleRole.MENU_ITEM;
}
/**
* Get the AccessibleAction associated with this object. In the
* implementation of the Java Accessibility API for this class,
* return this object, which is responsible for implementing the
* AccessibleAction interface on behalf of itself.
*
* @return this object
*/
public AccessibleAction getAccessibleAction() {
return this;
}
/**
* Get the AccessibleValue associated with this object. In the
* implementation of the Java Accessibility API for this class,
* return this object, which is responsible for implementing the
* AccessibleValue interface on behalf of itself.
*
* @return this object
*/
public AccessibleValue getAccessibleValue() {
return this;
}
/**
* Returns the number of Actions available in this object. The
* default behavior of a menu item is to have one action.
*
* @return 1, the number of Actions in this object
*/
public int getAccessibleActionCount() {
return 1;
}
/**
* Return a description of the specified action of the object.
*
* @param i zero-based index of the actions
*/
public String getAccessibleActionDescription(int i) {
if (i == 0) {
// [[[PENDING: WDW -- need to provide a localized string]]]
return "click";
} else {
return null;
}
}
/**
* Perform the specified Action on the object
*
* @param i zero-based index of actions
* @return true if the action was performed; otherwise false.
*/
public boolean doAccessibleAction(int i) {
if (i == 0) {
// Simulate a button click
Toolkit.getEventQueue().postEvent(
new ActionEvent(MenuItem.this,
ActionEvent.ACTION_PERFORMED,
MenuItem.this.getActionCommand(),
EventQueue.getMostRecentEventTime(),
0));
return true;
} else {
return false;
}
}
/**
* Get the value of this object as a Number.
*
* @return An Integer of 0 if this isn't selected or an Integer of 1 if
* this is selected.
* @see javax.swing.AbstractButton#isSelected()
*/
public Number getCurrentAccessibleValue() {
return Integer.valueOf(0);
}
/**
* Set the value of this object as a Number.
*
* @return True if the value was set.
*/
public boolean setCurrentAccessibleValue(Number n) {
return false;
}
/**
* Get the minimum value of this object as a Number.
*
* @return An Integer of 0.
*/
public Number getMinimumAccessibleValue() {
return Integer.valueOf(0);
}
/**
* Get the maximum value of this object as a Number.
*
* @return An Integer of 0.
*/
public Number getMaximumAccessibleValue() {
return Integer.valueOf(0);
}
} // class AccessibleAWTMenuItem
}

View File

@@ -0,0 +1,208 @@
/*
* Copyright (c) 1996, 2009, 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 java.awt;
import java.awt.event.KeyEvent;
/**
* The <code>MenuShortcut</code>class represents a keyboard accelerator
* for a MenuItem.
* <p>
* Menu shortcuts are created using virtual keycodes, not characters.
* For example, a menu shortcut for Ctrl-a (assuming that Control is
* the accelerator key) would be created with code like the following:
* <p>
* <code>MenuShortcut ms = new MenuShortcut(KeyEvent.VK_A, false);</code>
* <p> or alternatively
* <p>
* <code>MenuShortcut ms = new MenuShortcut(KeyEvent.getExtendedKeyCodeForChar('A'), false);</code>
* <p>
* Menu shortcuts may also be constructed for a wider set of keycodes
* using the <code>java.awt.event.KeyEvent.getExtendedKeyCodeForChar</code> call.
* For example, a menu shortcut for "Ctrl+cyrillic ef" is created by
* <p>
* <code>MenuShortcut ms = new MenuShortcut(KeyEvent.getExtendedKeyCodeForChar('\u0444'), false);</code>
* <p>
* Note that shortcuts created with a keycode or an extended keycode defined as a constant in <code>KeyEvent</code>
* work regardless of the current keyboard layout. However, a shortcut made of
* an extended keycode not listed in <code>KeyEvent</code>
* only work if the current keyboard layout produces a corresponding letter.
* <p>
* The accelerator key is platform-dependent and may be obtained
* via {@link Toolkit#getMenuShortcutKeyMask}.
*
* @author Thomas Ball
* @since JDK1.1
*/
public class MenuShortcut implements java.io.Serializable
{
/**
* The virtual keycode for the menu shortcut.
* This is the keycode with which the menu shortcut will be created.
* Note that it is a virtual keycode, not a character,
* e.g. KeyEvent.VK_A, not 'a'.
* Note: in 1.1.x you must use setActionCommand() on a menu item
* in order for its shortcut to work, otherwise it will fire a null
* action command.
*
* @serial
* @see #getKey()
* @see #usesShiftModifier()
* @see java.awt.event.KeyEvent
* @since JDK1.1
*/
int key;
/**
* Indicates whether the shft key was pressed.
* If true, the shift key was pressed.
* If false, the shift key was not pressed
*
* @serial
* @see #usesShiftModifier()
* @since JDK1.1
*/
boolean usesShift;
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = 143448358473180225L;
/**
* Constructs a new MenuShortcut for the specified virtual keycode.
* @param key the raw keycode for this MenuShortcut, as would be returned
* in the keyCode field of a {@link java.awt.event.KeyEvent KeyEvent} if
* this key were pressed.
* @see java.awt.event.KeyEvent
**/
public MenuShortcut(int key) {
this(key, false);
}
/**
* Constructs a new MenuShortcut for the specified virtual keycode.
* @param key the raw keycode for this MenuShortcut, as would be returned
* in the keyCode field of a {@link java.awt.event.KeyEvent KeyEvent} if
* this key were pressed.
* @param useShiftModifier indicates whether this MenuShortcut is invoked
* with the SHIFT key down.
* @see java.awt.event.KeyEvent
**/
public MenuShortcut(int key, boolean useShiftModifier) {
this.key = key;
this.usesShift = useShiftModifier;
}
/**
* Returns the raw keycode of this MenuShortcut.
* @return the raw keycode of this MenuShortcut.
* @see java.awt.event.KeyEvent
* @since JDK1.1
*/
public int getKey() {
return key;
}
/**
* Returns whether this MenuShortcut must be invoked using the SHIFT key.
* @return <code>true</code> if this MenuShortcut must be invoked using the
* SHIFT key, <code>false</code> otherwise.
* @since JDK1.1
*/
public boolean usesShiftModifier() {
return usesShift;
}
/**
* Returns whether this MenuShortcut is the same as another:
* equality is defined to mean that both MenuShortcuts use the same key
* and both either use or don't use the SHIFT key.
* @param s the MenuShortcut to compare with this.
* @return <code>true</code> if this MenuShortcut is the same as another,
* <code>false</code> otherwise.
* @since JDK1.1
*/
public boolean equals(MenuShortcut s) {
return (s != null && (s.getKey() == key) &&
(s.usesShiftModifier() == usesShift));
}
/**
* Returns whether this MenuShortcut is the same as another:
* equality is defined to mean that both MenuShortcuts use the same key
* and both either use or don't use the SHIFT key.
* @param obj the Object to compare with this.
* @return <code>true</code> if this MenuShortcut is the same as another,
* <code>false</code> otherwise.
* @since 1.2
*/
public boolean equals(Object obj) {
if (obj instanceof MenuShortcut) {
return equals( (MenuShortcut) obj );
}
return false;
}
/**
* Returns the hashcode for this MenuShortcut.
* @return the hashcode for this MenuShortcut.
* @since 1.2
*/
public int hashCode() {
return (usesShift) ? (~key) : key;
}
/**
* Returns an internationalized description of the MenuShortcut.
* @return a string representation of this MenuShortcut.
* @since JDK1.1
*/
public String toString() {
int modifiers = 0;
if (!GraphicsEnvironment.isHeadless()) {
modifiers = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
}
if (usesShiftModifier()) {
modifiers |= Event.SHIFT_MASK;
}
return KeyEvent.getKeyModifiersText(modifiers) + "+" +
KeyEvent.getKeyText(key);
}
/**
* Returns the parameter string representing the state of this
* MenuShortcut. This string is useful for debugging.
* @return the parameter string of this MenuShortcut.
* @since JDK1.1
*/
protected String paramString() {
String str = "key=" + key;
if (usesShiftModifier()) {
str += ",usesShiftModifier";
}
return str;
}
}

View File

@@ -0,0 +1,216 @@
/*
* Copyright (c) 2005, 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 java.awt;
import java.awt.event.*;
import sun.awt.AppContext;
abstract class ModalEventFilter implements EventFilter {
protected Dialog modalDialog;
protected boolean disabled;
protected ModalEventFilter(Dialog modalDialog) {
this.modalDialog = modalDialog;
disabled = false;
}
Dialog getModalDialog() {
return modalDialog;
}
public FilterAction acceptEvent(AWTEvent event) {
if (disabled || !modalDialog.isVisible()) {
return FilterAction.ACCEPT;
}
int eventID = event.getID();
if ((eventID >= MouseEvent.MOUSE_FIRST &&
eventID <= MouseEvent.MOUSE_LAST) ||
(eventID >= ActionEvent.ACTION_FIRST &&
eventID <= ActionEvent.ACTION_LAST) ||
eventID == WindowEvent.WINDOW_CLOSING)
{
Object o = event.getSource();
if (o instanceof sun.awt.ModalExclude) {
// Exclude this object from modality and
// continue to pump it's events.
} else if (o instanceof Component) {
Component c = (Component)o;
while ((c != null) && !(c instanceof Window)) {
c = c.getParent_NoClientCode();
}
if (c != null) {
return acceptWindow((Window)c);
}
}
}
return FilterAction.ACCEPT;
}
protected abstract FilterAction acceptWindow(Window w);
// When a modal dialog is hidden its modal filter may not be deleted from
// EventDispatchThread event filters immediately, so we need to mark the filter
// as disabled to prevent it from working. Simple checking for visibility of
// the modalDialog is not enough, as it can be hidden and then shown again
// with a new event pump and a new filter
void disable() {
disabled = true;
}
int compareTo(ModalEventFilter another) {
Dialog anotherDialog = another.getModalDialog();
// check if modalDialog is from anotherDialog's hierarchy
// or vice versa
Component c = modalDialog;
while (c != null) {
if (c == anotherDialog) {
return 1;
}
c = c.getParent_NoClientCode();
}
c = anotherDialog;
while (c != null) {
if (c == modalDialog) {
return -1;
}
c = c.getParent_NoClientCode();
}
// check if one dialog blocks (directly or indirectly) another
Dialog blocker = modalDialog.getModalBlocker();
while (blocker != null) {
if (blocker == anotherDialog) {
return -1;
}
blocker = blocker.getModalBlocker();
}
blocker = anotherDialog.getModalBlocker();
while (blocker != null) {
if (blocker == modalDialog) {
return 1;
}
blocker = blocker.getModalBlocker();
}
// compare modality types
return modalDialog.getModalityType().compareTo(anotherDialog.getModalityType());
}
static ModalEventFilter createFilterForDialog(Dialog modalDialog) {
switch (modalDialog.getModalityType()) {
case DOCUMENT_MODAL: return new DocumentModalEventFilter(modalDialog);
case APPLICATION_MODAL: return new ApplicationModalEventFilter(modalDialog);
case TOOLKIT_MODAL: return new ToolkitModalEventFilter(modalDialog);
}
return null;
}
private static class ToolkitModalEventFilter extends ModalEventFilter {
private AppContext appContext;
ToolkitModalEventFilter(Dialog modalDialog) {
super(modalDialog);
appContext = modalDialog.appContext;
}
protected FilterAction acceptWindow(Window w) {
if (w.isModalExcluded(Dialog.ModalExclusionType.TOOLKIT_EXCLUDE)) {
return FilterAction.ACCEPT;
}
if (w.appContext != appContext) {
return FilterAction.REJECT;
}
while (w != null) {
if (w == modalDialog) {
return FilterAction.ACCEPT_IMMEDIATELY;
}
w = w.getOwner();
}
return FilterAction.REJECT;
}
}
private static class ApplicationModalEventFilter extends ModalEventFilter {
private AppContext appContext;
ApplicationModalEventFilter(Dialog modalDialog) {
super(modalDialog);
appContext = modalDialog.appContext;
}
protected FilterAction acceptWindow(Window w) {
if (w.isModalExcluded(Dialog.ModalExclusionType.APPLICATION_EXCLUDE)) {
return FilterAction.ACCEPT;
}
if (w.appContext == appContext) {
while (w != null) {
if (w == modalDialog) {
return FilterAction.ACCEPT_IMMEDIATELY;
}
w = w.getOwner();
}
return FilterAction.REJECT;
}
return FilterAction.ACCEPT;
}
}
private static class DocumentModalEventFilter extends ModalEventFilter {
private Window documentRoot;
DocumentModalEventFilter(Dialog modalDialog) {
super(modalDialog);
documentRoot = modalDialog.getDocumentRoot();
}
protected FilterAction acceptWindow(Window w) {
// application- and toolkit-excluded windows are blocked by
// document-modal dialogs from their child hierarchy
if (w.isModalExcluded(Dialog.ModalExclusionType.APPLICATION_EXCLUDE)) {
Window w1 = modalDialog.getOwner();
while (w1 != null) {
if (w1 == w) {
return FilterAction.REJECT;
}
w1 = w1.getOwner();
}
return FilterAction.ACCEPT;
}
while (w != null) {
if (w == modalDialog) {
return FilterAction.ACCEPT_IMMEDIATELY;
}
if (w == documentRoot) {
return FilterAction.REJECT;
}
w = w.getOwner();
}
return FilterAction.ACCEPT;
}
}
}

View File

@@ -0,0 +1,135 @@
/*
* Copyright (c) 2003, 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 java.awt;
import sun.security.util.SecurityConstants;
/**
* <code>MouseInfo</code> provides methods for getting information about the mouse,
* such as mouse pointer location and the number of mouse buttons.
*
* @author Roman Poborchiy
* @since 1.5
*/
public class MouseInfo {
/**
* Private constructor to prevent instantiation.
*/
private MouseInfo() {
}
/**
* Returns a <code>PointerInfo</code> instance that represents the current
* location of the mouse pointer.
* The <code>GraphicsDevice</code> stored in this <code>PointerInfo</code>
* contains the mouse pointer. The coordinate system used for the mouse position
* depends on whether or not the <code>GraphicsDevice</code> is part of a virtual
* screen device.
* For virtual screen devices, the coordinates are given in the virtual
* coordinate system, otherwise they are returned in the coordinate system
* of the <code>GraphicsDevice</code>. See {@link GraphicsConfiguration}
* for more information about the virtual screen devices.
* On systems without a mouse, returns <code>null</code>.
* <p>
* If there is a security manager, its <code>checkPermission</code> method
* is called with an <code>AWTPermission("watchMousePointer")</code>
* permission before creating and returning a <code>PointerInfo</code>
* object. This may result in a <code>SecurityException</code>.
*
* @exception HeadlessException if GraphicsEnvironment.isHeadless() returns true
* @exception SecurityException if a security manager exists and its
* <code>checkPermission</code> method doesn't allow the operation
* @see GraphicsConfiguration
* @see SecurityManager#checkPermission
* @see java.awt.AWTPermission
* @return location of the mouse pointer
* @since 1.5
*/
public static PointerInfo getPointerInfo() throws HeadlessException {
if (GraphicsEnvironment.isHeadless()) {
throw new HeadlessException();
}
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkPermission(SecurityConstants.AWT.WATCH_MOUSE_PERMISSION);
}
Point point = new Point(0, 0);
int deviceNum = Toolkit.getDefaultToolkit().getMouseInfoPeer().fillPointWithCoords(point);
GraphicsDevice[] gds = GraphicsEnvironment.getLocalGraphicsEnvironment().
getScreenDevices();
PointerInfo retval = null;
if (areScreenDevicesIndependent(gds)) {
retval = new PointerInfo(gds[deviceNum], point);
} else {
for (int i = 0; i < gds.length; i++) {
GraphicsConfiguration gc = gds[i].getDefaultConfiguration();
Rectangle bounds = gc.getBounds();
if (bounds.contains(point)) {
retval = new PointerInfo(gds[i], point);
}
}
}
return retval;
}
private static boolean areScreenDevicesIndependent(GraphicsDevice[] gds) {
for (int i = 0; i < gds.length; i++) {
Rectangle bounds = gds[i].getDefaultConfiguration().getBounds();
if (bounds.x != 0 || bounds.y != 0) {
return false;
}
}
return true;
}
/**
* Returns the number of buttons on the mouse.
* On systems without a mouse, returns <code>-1</code>.
*
* @exception HeadlessException if GraphicsEnvironment.isHeadless() returns true
* @return number of buttons on the mouse
* @since 1.5
*/
public static int getNumberOfButtons() throws HeadlessException {
if (GraphicsEnvironment.isHeadless()) {
throw new HeadlessException();
}
Object prop = Toolkit.getDefaultToolkit().
getDesktopProperty("awt.mouse.numButtons");
if (prop instanceof Integer) {
return ((Integer)prop).intValue();
}
// This should never happen.
assert false : "awt.mouse.numButtons is not an integer property";
return 0;
}
}

View File

@@ -0,0 +1,311 @@
/*
* Copyright (c) 2006, 2011, 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 java.awt;
import java.awt.geom.AffineTransform;
import java.awt.image.ColorModel;
import java.lang.ref.SoftReference;
import java.util.Arrays;
/**
* This is the superclass for Paints which use a multiple color
* gradient to fill in their raster. It provides storage for variables and
* enumerated values common to
* {@code LinearGradientPaint} and {@code RadialGradientPaint}.
*
* @author Nicholas Talian, Vincent Hardy, Jim Graham, Jerry Evans
* @since 1.6
*/
public abstract class MultipleGradientPaint implements Paint {
/** The method to use when painting outside the gradient bounds.
* @since 1.6
*/
public static enum CycleMethod {
/**
* Use the terminal colors to fill the remaining area.
*/
NO_CYCLE,
/**
* Cycle the gradient colors start-to-end, end-to-start
* to fill the remaining area.
*/
REFLECT,
/**
* Cycle the gradient colors start-to-end, start-to-end
* to fill the remaining area.
*/
REPEAT
}
/** The color space in which to perform the gradient interpolation.
* @since 1.6
*/
public static enum ColorSpaceType {
/**
* Indicates that the color interpolation should occur in sRGB space.
*/
SRGB,
/**
* Indicates that the color interpolation should occur in linearized
* RGB space.
*/
LINEAR_RGB
}
/** The transparency of this paint object. */
final int transparency;
/** Gradient keyframe values in the range 0 to 1. */
final float[] fractions;
/** Gradient colors. */
final Color[] colors;
/** Transform to apply to gradient. */
final AffineTransform gradientTransform;
/** The method to use when painting outside the gradient bounds. */
final CycleMethod cycleMethod;
/** The color space in which to perform the gradient interpolation. */
final ColorSpaceType colorSpace;
/**
* The following fields are used only by MultipleGradientPaintContext
* to cache certain values that remain constant and do not need to be
* recalculated for each context created from this paint instance.
*/
ColorModel model;
float[] normalizedIntervals;
boolean isSimpleLookup;
SoftReference<int[][]> gradients;
SoftReference<int[]> gradient;
int fastGradientArraySize;
/**
* Package-private constructor.
*
* @param fractions numbers ranging from 0.0 to 1.0 specifying the
* distribution of colors along the gradient
* @param colors array of colors corresponding to each fractional value
* @param cycleMethod either {@code NO_CYCLE}, {@code REFLECT},
* or {@code REPEAT}
* @param colorSpace which color space to use for interpolation,
* either {@code SRGB} or {@code LINEAR_RGB}
* @param gradientTransform transform to apply to the gradient
*
* @throws NullPointerException
* if {@code fractions} array is null,
* or {@code colors} array is null,
* or {@code gradientTransform} is null,
* or {@code cycleMethod} is null,
* or {@code colorSpace} is null
* @throws IllegalArgumentException
* if {@code fractions.length != colors.length},
* or {@code colors} is less than 2 in size,
* or a {@code fractions} value is less than 0.0 or greater than 1.0,
* or the {@code fractions} are not provided in strictly increasing order
*/
MultipleGradientPaint(float[] fractions,
Color[] colors,
CycleMethod cycleMethod,
ColorSpaceType colorSpace,
AffineTransform gradientTransform)
{
if (fractions == null) {
throw new NullPointerException("Fractions array cannot be null");
}
if (colors == null) {
throw new NullPointerException("Colors array cannot be null");
}
if (cycleMethod == null) {
throw new NullPointerException("Cycle method cannot be null");
}
if (colorSpace == null) {
throw new NullPointerException("Color space cannot be null");
}
if (gradientTransform == null) {
throw new NullPointerException("Gradient transform cannot be "+
"null");
}
if (fractions.length != colors.length) {
throw new IllegalArgumentException("Colors and fractions must " +
"have equal size");
}
if (colors.length < 2) {
throw new IllegalArgumentException("User must specify at least " +
"2 colors");
}
// check that values are in the proper range and progress
// in increasing order from 0 to 1
float previousFraction = -1.0f;
for (float currentFraction : fractions) {
if (currentFraction < 0f || currentFraction > 1f) {
throw new IllegalArgumentException("Fraction values must " +
"be in the range 0 to 1: " +
currentFraction);
}
if (currentFraction <= previousFraction) {
throw new IllegalArgumentException("Keyframe fractions " +
"must be increasing: " +
currentFraction);
}
previousFraction = currentFraction;
}
// We have to deal with the cases where the first gradient stop is not
// equal to 0 and/or the last gradient stop is not equal to 1.
// In both cases, create a new point and replicate the previous
// extreme point's color.
boolean fixFirst = false;
boolean fixLast = false;
int len = fractions.length;
int off = 0;
if (fractions[0] != 0f) {
// first stop is not equal to zero, fix this condition
fixFirst = true;
len++;
off++;
}
if (fractions[fractions.length-1] != 1f) {
// last stop is not equal to one, fix this condition
fixLast = true;
len++;
}
this.fractions = new float[len];
System.arraycopy(fractions, 0, this.fractions, off, fractions.length);
this.colors = new Color[len];
System.arraycopy(colors, 0, this.colors, off, colors.length);
if (fixFirst) {
this.fractions[0] = 0f;
this.colors[0] = colors[0];
}
if (fixLast) {
this.fractions[len-1] = 1f;
this.colors[len-1] = colors[colors.length - 1];
}
// copy some flags
this.colorSpace = colorSpace;
this.cycleMethod = cycleMethod;
// copy the gradient transform
this.gradientTransform = new AffineTransform(gradientTransform);
// determine transparency
boolean opaque = true;
for (int i = 0; i < colors.length; i++){
opaque = opaque && (colors[i].getAlpha() == 0xff);
}
this.transparency = opaque ? OPAQUE : TRANSLUCENT;
}
/**
* Returns a copy of the array of floats used by this gradient
* to calculate color distribution.
* The returned array always has 0 as its first value and 1 as its
* last value, with increasing values in between.
*
* @return a copy of the array of floats used by this gradient to
* calculate color distribution
*/
public final float[] getFractions() {
return Arrays.copyOf(fractions, fractions.length);
}
/**
* Returns a copy of the array of colors used by this gradient.
* The first color maps to the first value in the fractions array,
* and the last color maps to the last value in the fractions array.
*
* @return a copy of the array of colors used by this gradient
*/
public final Color[] getColors() {
return Arrays.copyOf(colors, colors.length);
}
/**
* Returns the enumerated type which specifies cycling behavior.
*
* @return the enumerated type which specifies cycling behavior
*/
public final CycleMethod getCycleMethod() {
return cycleMethod;
}
/**
* Returns the enumerated type which specifies color space for
* interpolation.
*
* @return the enumerated type which specifies color space for
* interpolation
*/
public final ColorSpaceType getColorSpace() {
return colorSpace;
}
/**
* Returns a copy of the transform applied to the gradient.
*
* <p>
* Note that if no transform is applied to the gradient
* when it is created, the identity transform is used.
*
* @return a copy of the transform applied to the gradient
*/
public final AffineTransform getTransform() {
return new AffineTransform(gradientTransform);
}
/**
* Returns the transparency mode for this {@code Paint} object.
*
* @return {@code OPAQUE} if all colors used by this
* {@code Paint} object are opaque,
* {@code TRANSLUCENT} if at least one of the
* colors used by this {@code Paint} object is not opaque.
* @see java.awt.Transparency
*/
public final int getTransparency() {
return transparency;
}
}

View File

@@ -0,0 +1,724 @@
/*
* Copyright (c) 2006, 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 java.awt;
import java.awt.MultipleGradientPaint.CycleMethod;
import java.awt.MultipleGradientPaint.ColorSpaceType;
import java.awt.color.ColorSpace;
import java.awt.geom.AffineTransform;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Rectangle2D;
import java.awt.image.ColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferInt;
import java.awt.image.DirectColorModel;
import java.awt.image.Raster;
import java.awt.image.SinglePixelPackedSampleModel;
import java.awt.image.WritableRaster;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.Arrays;
/**
* This is the superclass for all PaintContexts which use a multiple color
* gradient to fill in their raster. It provides the actual color
* interpolation functionality. Subclasses only have to deal with using
* the gradient to fill pixels in a raster.
*
* @author Nicholas Talian, Vincent Hardy, Jim Graham, Jerry Evans
*/
abstract class MultipleGradientPaintContext implements PaintContext {
/**
* The PaintContext's ColorModel. This is ARGB if colors are not all
* opaque, otherwise it is RGB.
*/
protected ColorModel model;
/** Color model used if gradient colors are all opaque. */
private static ColorModel xrgbmodel =
new DirectColorModel(24, 0x00ff0000, 0x0000ff00, 0x000000ff);
/** The cached ColorModel. */
protected static ColorModel cachedModel;
/** The cached raster, which is reusable among instances. */
protected static WeakReference<Raster> cached;
/** Raster is reused whenever possible. */
protected Raster saved;
/** The method to use when painting out of the gradient bounds. */
protected CycleMethod cycleMethod;
/** The ColorSpace in which to perform the interpolation */
protected ColorSpaceType colorSpace;
/** Elements of the inverse transform matrix. */
protected float a00, a01, a10, a11, a02, a12;
/**
* This boolean specifies whether we are in simple lookup mode, where an
* input value between 0 and 1 may be used to directly index into a single
* array of gradient colors. If this boolean value is false, then we have
* to use a 2-step process where we have to determine which gradient array
* we fall into, then determine the index into that array.
*/
protected boolean isSimpleLookup;
/**
* Size of gradients array for scaling the 0-1 index when looking up
* colors the fast way.
*/
protected int fastGradientArraySize;
/**
* Array which contains the interpolated color values for each interval,
* used by calculateSingleArrayGradient(). It is protected for possible
* direct access by subclasses.
*/
protected int[] gradient;
/**
* Array of gradient arrays, one array for each interval. Used by
* calculateMultipleArrayGradient().
*/
private int[][] gradients;
/** Normalized intervals array. */
private float[] normalizedIntervals;
/** Fractions array. */
private float[] fractions;
/** Used to determine if gradient colors are all opaque. */
private int transparencyTest;
/** Color space conversion lookup tables. */
private static final int SRGBtoLinearRGB[] = new int[256];
private static final int LinearRGBtoSRGB[] = new int[256];
static {
// build the tables
for (int k = 0; k < 256; k++) {
SRGBtoLinearRGB[k] = convertSRGBtoLinearRGB(k);
LinearRGBtoSRGB[k] = convertLinearRGBtoSRGB(k);
}
}
/**
* Constant number of max colors between any 2 arbitrary colors.
* Used for creating and indexing gradients arrays.
*/
protected static final int GRADIENT_SIZE = 256;
protected static final int GRADIENT_SIZE_INDEX = GRADIENT_SIZE -1;
/**
* Maximum length of the fast single-array. If the estimated array size
* is greater than this, switch over to the slow lookup method.
* No particular reason for choosing this number, but it seems to provide
* satisfactory performance for the common case (fast lookup).
*/
private static final int MAX_GRADIENT_ARRAY_SIZE = 5000;
/**
* Constructor for MultipleGradientPaintContext superclass.
*/
protected MultipleGradientPaintContext(MultipleGradientPaint mgp,
ColorModel cm,
Rectangle deviceBounds,
Rectangle2D userBounds,
AffineTransform t,
RenderingHints hints,
float[] fractions,
Color[] colors,
CycleMethod cycleMethod,
ColorSpaceType colorSpace)
{
if (deviceBounds == null) {
throw new NullPointerException("Device bounds cannot be null");
}
if (userBounds == null) {
throw new NullPointerException("User bounds cannot be null");
}
if (t == null) {
throw new NullPointerException("Transform cannot be null");
}
if (hints == null) {
throw new NullPointerException("RenderingHints cannot be null");
}
// The inverse transform is needed to go from device to user space.
// Get all the components of the inverse transform matrix.
AffineTransform tInv;
try {
// the following assumes that the caller has copied the incoming
// transform and is not concerned about it being modified
t.invert();
tInv = t;
} catch (NoninvertibleTransformException e) {
// just use identity transform in this case; better to show
// (incorrect) results than to throw an exception and/or no-op
tInv = new AffineTransform();
}
double m[] = new double[6];
tInv.getMatrix(m);
a00 = (float)m[0];
a10 = (float)m[1];
a01 = (float)m[2];
a11 = (float)m[3];
a02 = (float)m[4];
a12 = (float)m[5];
// copy some flags
this.cycleMethod = cycleMethod;
this.colorSpace = colorSpace;
// we can avoid copying this array since we do not modify its values
this.fractions = fractions;
// note that only one of these values can ever be non-null (we either
// store the fast gradient array or the slow one, but never both
// at the same time)
int[] gradient =
(mgp.gradient != null) ? mgp.gradient.get() : null;
int[][] gradients =
(mgp.gradients != null) ? mgp.gradients.get() : null;
if (gradient == null && gradients == null) {
// we need to (re)create the appropriate values
calculateLookupData(colors);
// now cache the calculated values in the
// MultipleGradientPaint instance for future use
mgp.model = this.model;
mgp.normalizedIntervals = this.normalizedIntervals;
mgp.isSimpleLookup = this.isSimpleLookup;
if (isSimpleLookup) {
// only cache the fast array
mgp.fastGradientArraySize = this.fastGradientArraySize;
mgp.gradient = new SoftReference<int[]>(this.gradient);
} else {
// only cache the slow array
mgp.gradients = new SoftReference<int[][]>(this.gradients);
}
} else {
// use the values cached in the MultipleGradientPaint instance
this.model = mgp.model;
this.normalizedIntervals = mgp.normalizedIntervals;
this.isSimpleLookup = mgp.isSimpleLookup;
this.gradient = gradient;
this.fastGradientArraySize = mgp.fastGradientArraySize;
this.gradients = gradients;
}
}
/**
* This function is the meat of this class. It calculates an array of
* gradient colors based on an array of fractions and color values at
* those fractions.
*/
private void calculateLookupData(Color[] colors) {
Color[] normalizedColors;
if (colorSpace == ColorSpaceType.LINEAR_RGB) {
// create a new colors array
normalizedColors = new Color[colors.length];
// convert the colors using the lookup table
for (int i = 0; i < colors.length; i++) {
int argb = colors[i].getRGB();
int a = argb >>> 24;
int r = SRGBtoLinearRGB[(argb >> 16) & 0xff];
int g = SRGBtoLinearRGB[(argb >> 8) & 0xff];
int b = SRGBtoLinearRGB[(argb ) & 0xff];
normalizedColors[i] = new Color(r, g, b, a);
}
} else {
// we can just use this array by reference since we do not
// modify its values in the case of SRGB
normalizedColors = colors;
}
// this will store the intervals (distances) between gradient stops
normalizedIntervals = new float[fractions.length-1];
// convert from fractions into intervals
for (int i = 0; i < normalizedIntervals.length; i++) {
// interval distance is equal to the difference in positions
normalizedIntervals[i] = this.fractions[i+1] - this.fractions[i];
}
// initialize to be fully opaque for ANDing with colors
transparencyTest = 0xff000000;
// array of interpolation arrays
gradients = new int[normalizedIntervals.length][];
// find smallest interval
float Imin = 1;
for (int i = 0; i < normalizedIntervals.length; i++) {
Imin = (Imin > normalizedIntervals[i]) ?
normalizedIntervals[i] : Imin;
}
// Estimate the size of the entire gradients array.
// This is to prevent a tiny interval from causing the size of array
// to explode. If the estimated size is too large, break to using
// separate arrays for each interval, and using an indexing scheme at
// look-up time.
int estimatedSize = 0;
for (int i = 0; i < normalizedIntervals.length; i++) {
estimatedSize += (normalizedIntervals[i]/Imin) * GRADIENT_SIZE;
}
if (estimatedSize > MAX_GRADIENT_ARRAY_SIZE) {
// slow method
calculateMultipleArrayGradient(normalizedColors);
} else {
// fast method
calculateSingleArrayGradient(normalizedColors, Imin);
}
// use the most "economical" model
if ((transparencyTest >>> 24) == 0xff) {
model = xrgbmodel;
} else {
model = ColorModel.getRGBdefault();
}
}
/**
* FAST LOOKUP METHOD
*
* This method calculates the gradient color values and places them in a
* single int array, gradient[]. It does this by allocating space for
* each interval based on its size relative to the smallest interval in
* the array. The smallest interval is allocated 255 interpolated values
* (the maximum number of unique in-between colors in a 24 bit color
* system), and all other intervals are allocated
* size = (255 * the ratio of their size to the smallest interval).
*
* This scheme expedites a speedy retrieval because the colors are
* distributed along the array according to their user-specified
* distribution. All that is needed is a relative index from 0 to 1.
*
* The only problem with this method is that the possibility exists for
* the array size to balloon in the case where there is a
* disproportionately small gradient interval. In this case the other
* intervals will be allocated huge space, but much of that data is
* redundant. We thus need to use the space conserving scheme below.
*
* @param Imin the size of the smallest interval
*/
private void calculateSingleArrayGradient(Color[] colors, float Imin) {
// set the flag so we know later it is a simple (fast) lookup
isSimpleLookup = true;
// 2 colors to interpolate
int rgb1, rgb2;
//the eventual size of the single array
int gradientsTot = 1;
// for every interval (transition between 2 colors)
for (int i = 0; i < gradients.length; i++) {
// create an array whose size is based on the ratio to the
// smallest interval
int nGradients = (int)((normalizedIntervals[i]/Imin)*255f);
gradientsTot += nGradients;
gradients[i] = new int[nGradients];
// the 2 colors (keyframes) to interpolate between
rgb1 = colors[i].getRGB();
rgb2 = colors[i+1].getRGB();
// fill this array with the colors in between rgb1 and rgb2
interpolate(rgb1, rgb2, gradients[i]);
// if the colors are opaque, transparency should still
// be 0xff000000
transparencyTest &= rgb1;
transparencyTest &= rgb2;
}
// put all gradients in a single array
gradient = new int[gradientsTot];
int curOffset = 0;
for (int i = 0; i < gradients.length; i++){
System.arraycopy(gradients[i], 0, gradient,
curOffset, gradients[i].length);
curOffset += gradients[i].length;
}
gradient[gradient.length-1] = colors[colors.length-1].getRGB();
// if interpolation occurred in Linear RGB space, convert the
// gradients back to sRGB using the lookup table
if (colorSpace == ColorSpaceType.LINEAR_RGB) {
for (int i = 0; i < gradient.length; i++) {
gradient[i] = convertEntireColorLinearRGBtoSRGB(gradient[i]);
}
}
fastGradientArraySize = gradient.length - 1;
}
/**
* SLOW LOOKUP METHOD
*
* This method calculates the gradient color values for each interval and
* places each into its own 255 size array. The arrays are stored in
* gradients[][]. (255 is used because this is the maximum number of
* unique colors between 2 arbitrary colors in a 24 bit color system.)
*
* This method uses the minimum amount of space (only 255 * number of
* intervals), but it aggravates the lookup procedure, because now we
* have to find out which interval to select, then calculate the index
* within that interval. This causes a significant performance hit,
* because it requires this calculation be done for every point in
* the rendering loop.
*
* For those of you who are interested, this is a classic example of the
* time-space tradeoff.
*/
private void calculateMultipleArrayGradient(Color[] colors) {
// set the flag so we know later it is a non-simple lookup
isSimpleLookup = false;
// 2 colors to interpolate
int rgb1, rgb2;
// for every interval (transition between 2 colors)
for (int i = 0; i < gradients.length; i++){
// create an array of the maximum theoretical size for
// each interval
gradients[i] = new int[GRADIENT_SIZE];
// get the the 2 colors
rgb1 = colors[i].getRGB();
rgb2 = colors[i+1].getRGB();
// fill this array with the colors in between rgb1 and rgb2
interpolate(rgb1, rgb2, gradients[i]);
// if the colors are opaque, transparency should still
// be 0xff000000
transparencyTest &= rgb1;
transparencyTest &= rgb2;
}
// if interpolation occurred in Linear RGB space, convert the
// gradients back to SRGB using the lookup table
if (colorSpace == ColorSpaceType.LINEAR_RGB) {
for (int j = 0; j < gradients.length; j++) {
for (int i = 0; i < gradients[j].length; i++) {
gradients[j][i] =
convertEntireColorLinearRGBtoSRGB(gradients[j][i]);
}
}
}
}
/**
* Yet another helper function. This one linearly interpolates between
* 2 colors, filling up the output array.
*
* @param rgb1 the start color
* @param rgb2 the end color
* @param output the output array of colors; must not be null
*/
private void interpolate(int rgb1, int rgb2, int[] output) {
// color components
int a1, r1, g1, b1, da, dr, dg, db;
// step between interpolated values
float stepSize = 1.0f / output.length;
// extract color components from packed integer
a1 = (rgb1 >> 24) & 0xff;
r1 = (rgb1 >> 16) & 0xff;
g1 = (rgb1 >> 8) & 0xff;
b1 = (rgb1 ) & 0xff;
// calculate the total change in alpha, red, green, blue
da = ((rgb2 >> 24) & 0xff) - a1;
dr = ((rgb2 >> 16) & 0xff) - r1;
dg = ((rgb2 >> 8) & 0xff) - g1;
db = ((rgb2 ) & 0xff) - b1;
// for each step in the interval calculate the in-between color by
// multiplying the normalized current position by the total color
// change (0.5 is added to prevent truncation round-off error)
for (int i = 0; i < output.length; i++) {
output[i] =
(((int) ((a1 + i * da * stepSize) + 0.5) << 24)) |
(((int) ((r1 + i * dr * stepSize) + 0.5) << 16)) |
(((int) ((g1 + i * dg * stepSize) + 0.5) << 8)) |
(((int) ((b1 + i * db * stepSize) + 0.5) ));
}
}
/**
* Yet another helper function. This one extracts the color components
* of an integer RGB triple, converts them from LinearRGB to SRGB, then
* recompacts them into an int.
*/
private int convertEntireColorLinearRGBtoSRGB(int rgb) {
// color components
int a1, r1, g1, b1;
// extract red, green, blue components
a1 = (rgb >> 24) & 0xff;
r1 = (rgb >> 16) & 0xff;
g1 = (rgb >> 8) & 0xff;
b1 = (rgb ) & 0xff;
// use the lookup table
r1 = LinearRGBtoSRGB[r1];
g1 = LinearRGBtoSRGB[g1];
b1 = LinearRGBtoSRGB[b1];
// re-compact the components
return ((a1 << 24) |
(r1 << 16) |
(g1 << 8) |
(b1 ));
}
/**
* Helper function to index into the gradients array. This is necessary
* because each interval has an array of colors with uniform size 255.
* However, the color intervals are not necessarily of uniform length, so
* a conversion is required.
*
* @param position the unmanipulated position, which will be mapped
* into the range 0 to 1
* @returns integer color to display
*/
protected final int indexIntoGradientsArrays(float position) {
// first, manipulate position value depending on the cycle method
if (cycleMethod == CycleMethod.NO_CYCLE) {
if (position > 1) {
// upper bound is 1
position = 1;
} else if (position < 0) {
// lower bound is 0
position = 0;
}
} else if (cycleMethod == CycleMethod.REPEAT) {
// get the fractional part
// (modulo behavior discards integer component)
position = position - (int)position;
//position should now be between -1 and 1
if (position < 0) {
// force it to be in the range 0-1
position = position + 1;
}
} else { // cycleMethod == CycleMethod.REFLECT
if (position < 0) {
// take absolute value
position = -position;
}
// get the integer part
int part = (int)position;
// get the fractional part
position = position - part;
if ((part & 1) == 1) {
// integer part is odd, get reflected color instead
position = 1 - position;
}
}
// now, get the color based on this 0-1 position...
if (isSimpleLookup) {
// easy to compute: just scale index by array size
return gradient[(int)(position * fastGradientArraySize)];
} else {
// more complicated computation, to save space
// for all the gradient interval arrays
for (int i = 0; i < gradients.length; i++) {
if (position < fractions[i+1]) {
// this is the array we want
float delta = position - fractions[i];
// this is the interval we want
int index = (int)((delta / normalizedIntervals[i])
* (GRADIENT_SIZE_INDEX));
return gradients[i][index];
}
}
}
return gradients[gradients.length - 1][GRADIENT_SIZE_INDEX];
}
/**
* Helper function to convert a color component in sRGB space to linear
* RGB space. Used to build a static lookup table.
*/
private static int convertSRGBtoLinearRGB(int color) {
float input, output;
input = color / 255.0f;
if (input <= 0.04045f) {
output = input / 12.92f;
} else {
output = (float)Math.pow((input + 0.055) / 1.055, 2.4);
}
return Math.round(output * 255.0f);
}
/**
* Helper function to convert a color component in linear RGB space to
* SRGB space. Used to build a static lookup table.
*/
private static int convertLinearRGBtoSRGB(int color) {
float input, output;
input = color/255.0f;
if (input <= 0.0031308) {
output = input * 12.92f;
} else {
output = (1.055f *
((float) Math.pow(input, (1.0 / 2.4)))) - 0.055f;
}
return Math.round(output * 255.0f);
}
/**
* {@inheritDoc}
*/
public final Raster getRaster(int x, int y, int w, int h) {
// If working raster is big enough, reuse it. Otherwise,
// build a large enough new one.
Raster raster = saved;
if (raster == null ||
raster.getWidth() < w || raster.getHeight() < h)
{
raster = getCachedRaster(model, w, h);
saved = raster;
}
// Access raster internal int array. Because we use a DirectColorModel,
// we know the DataBuffer is of type DataBufferInt and the SampleModel
// is SinglePixelPackedSampleModel.
// Adjust for initial offset in DataBuffer and also for the scanline
// stride.
// These calls make the DataBuffer non-acceleratable, but the
// Raster is never Stable long enough to accelerate anyway...
DataBufferInt rasterDB = (DataBufferInt)raster.getDataBuffer();
int[] pixels = rasterDB.getData(0);
int off = rasterDB.getOffset();
int scanlineStride = ((SinglePixelPackedSampleModel)
raster.getSampleModel()).getScanlineStride();
int adjust = scanlineStride - w;
fillRaster(pixels, off, adjust, x, y, w, h); // delegate to subclass
return raster;
}
protected abstract void fillRaster(int pixels[], int off, int adjust,
int x, int y, int w, int h);
/**
* Took this cacheRaster code from GradientPaint. It appears to recycle
* rasters for use by any other instance, as long as they are sufficiently
* large.
*/
private static synchronized Raster getCachedRaster(ColorModel cm,
int w, int h)
{
if (cm == cachedModel) {
if (cached != null) {
Raster ras = (Raster) cached.get();
if (ras != null &&
ras.getWidth() >= w &&
ras.getHeight() >= h)
{
cached = null;
return ras;
}
}
}
return cm.createCompatibleWritableRaster(w, h);
}
/**
* Took this cacheRaster code from GradientPaint. It appears to recycle
* rasters for use by any other instance, as long as they are sufficiently
* large.
*/
private static synchronized void putCachedRaster(ColorModel cm,
Raster ras)
{
if (cached != null) {
Raster cras = (Raster) cached.get();
if (cras != null) {
int cw = cras.getWidth();
int ch = cras.getHeight();
int iw = ras.getWidth();
int ih = ras.getHeight();
if (cw >= iw && ch >= ih) {
return;
}
if (cw * ch >= iw * ih) {
return;
}
}
}
cachedModel = cm;
cached = new WeakReference<Raster>(ras);
}
/**
* {@inheritDoc}
*/
public final void dispose() {
if (saved != null) {
putCachedRaster(model, saved);
saved = null;
}
}
/**
* {@inheritDoc}
*/
public final ColorModel getColorModel() {
return model;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,108 @@
/*
* Copyright (c) 1997, 2008, 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 java.awt;
import java.awt.image.ColorModel;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
/**
* This <code>Paint</code> interface defines how color patterns
* can be generated for {@link Graphics2D} operations. A class
* implementing the <code>Paint</code> interface is added to the
* <code>Graphics2D</code> context in order to define the color
* pattern used by the <code>draw</code> and <code>fill</code> methods.
* <p>
* Instances of classes implementing <code>Paint</code> must be
* read-only because the <code>Graphics2D</code> does not clone
* these objects when they are set as an attribute with the
* <code>setPaint</code> method or when the <code>Graphics2D</code>
* object is itself cloned.
* @see PaintContext
* @see Color
* @see GradientPaint
* @see TexturePaint
* @see Graphics2D#setPaint
* @version 1.36, 06/05/07
*/
public interface Paint extends Transparency {
/**
* Creates and returns a {@link PaintContext} used to
* generate the color pattern.
* The arguments to this method convey additional information
* about the rendering operation that may be
* used or ignored on various implementations of the {@code Paint} interface.
* A caller must pass non-{@code null} values for all of the arguments
* except for the {@code ColorModel} argument which may be {@code null} to
* indicate that no specific {@code ColorModel} type is preferred.
* Implementations of the {@code Paint} interface are allowed to use or ignore
* any of the arguments as makes sense for their function, and are
* not constrained to use the specified {@code ColorModel} for the returned
* {@code PaintContext}, even if it is not {@code null}.
* Implementations are allowed to throw {@code NullPointerException} for
* any {@code null} argument other than the {@code ColorModel} argument,
* but are not required to do so.
*
* @param cm the preferred {@link ColorModel} which represents the most convenient
* format for the caller to receive the pixel data, or {@code null}
* if there is no preference.
* @param deviceBounds the device space bounding box
* of the graphics primitive being rendered.
* Implementations of the {@code Paint} interface
* are allowed to throw {@code NullPointerException}
* for a {@code null} {@code deviceBounds}.
* @param userBounds the user space bounding box
* of the graphics primitive being rendered.
* Implementations of the {@code Paint} interface
* are allowed to throw {@code NullPointerException}
* for a {@code null} {@code userBounds}.
* @param xform the {@link AffineTransform} from user
* space into device space.
* Implementations of the {@code Paint} interface
* are allowed to throw {@code NullPointerException}
* for a {@code null} {@code xform}.
* @param hints the set of hints that the context object can use to
* choose between rendering alternatives.
* Implementations of the {@code Paint} interface
* are allowed to throw {@code NullPointerException}
* for a {@code null} {@code hints}.
* @return the {@code PaintContext} for
* generating color patterns.
* @see PaintContext
* @see ColorModel
* @see Rectangle
* @see Rectangle2D
* @see AffineTransform
* @see RenderingHints
*/
public PaintContext createContext(ColorModel cm,
Rectangle deviceBounds,
Rectangle2D userBounds,
AffineTransform xform,
RenderingHints hints);
}

View File

@@ -0,0 +1,81 @@
/*
* Copyright (c) 1997, 2007, 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 java.awt;
import java.awt.image.Raster;
import java.awt.image.ColorModel;
/**
* The <code>PaintContext</code> interface defines the encapsulated
* and optimized environment to generate color patterns in device
* space for fill or stroke operations on a
* {@link Graphics2D}. The <code>PaintContext</code> provides
* the necessary colors for <code>Graphics2D</code> operations in the
* form of a {@link Raster} associated with a {@link ColorModel}.
* The <code>PaintContext</code> maintains state for a particular paint
* operation. In a multi-threaded environment, several
* contexts can exist simultaneously for a single {@link Paint} object.
* @see Paint
*/
public interface PaintContext {
/**
* Releases the resources allocated for the operation.
*/
public void dispose();
/**
* Returns the <code>ColorModel</code> of the output. Note that
* this <code>ColorModel</code> might be different from the hint
* specified in the
* {@link Paint#createContext(ColorModel, Rectangle, Rectangle2D,
AffineTransform, RenderingHints) createContext} method of
* <code>Paint</code>. Not all <code>PaintContext</code> objects are
* capable of generating color patterns in an arbitrary
* <code>ColorModel</code>.
* @return the <code>ColorModel</code> of the output.
*/
ColorModel getColorModel();
/**
* Returns a <code>Raster</code> containing the colors generated for
* the graphics operation.
* @param x the x coordinate of the area in device space
* for which colors are generated.
* @param y the y coordinate of the area in device space
* for which colors are generated.
* @param w the width of the area in device space
* @param h the height of the area in device space
* @return a <code>Raster</code> representing the specified
* rectangular area and containing the colors generated for
* the graphics operation.
*/
Raster getRaster(int x,
int y,
int w,
int h);
}

View File

@@ -0,0 +1,133 @@
/*
* Copyright (c) 1995, 2007, 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 java.awt;
import javax.accessibility.*;
/**
* <code>Panel</code> is the simplest container class. A panel
* provides space in which an application can attach any other
* component, including other panels.
* <p>
* The default layout manager for a panel is the
* <code>FlowLayout</code> layout manager.
*
* @author Sami Shaio
* @see java.awt.FlowLayout
* @since JDK1.0
*/
public class Panel extends Container implements Accessible {
private static final String base = "panel";
private static int nameCounter = 0;
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = -2728009084054400034L;
/**
* Creates a new panel using the default layout manager.
* The default layout manager for all panels is the
* <code>FlowLayout</code> class.
*/
public Panel() {
this(new FlowLayout());
}
/**
* Creates a new panel with the specified layout manager.
* @param layout the layout manager for this panel.
* @since JDK1.1
*/
public Panel(LayoutManager layout) {
setLayout(layout);
}
/**
* Construct a name for this component. Called by getName() when the
* name is null.
*/
String constructComponentName() {
synchronized (Panel.class) {
return base + nameCounter++;
}
}
/**
* Creates the Panel's peer. The peer allows you to modify the
* appearance of the panel without changing its functionality.
*/
public void addNotify() {
synchronized (getTreeLock()) {
if (peer == null)
peer = getToolkit().createPanel(this);
super.addNotify();
}
}
/////////////////
// Accessibility support
////////////////
/**
* Gets the AccessibleContext associated with this Panel.
* For panels, the AccessibleContext takes the form of an
* AccessibleAWTPanel.
* A new AccessibleAWTPanel instance is created if necessary.
*
* @return an AccessibleAWTPanel that serves as the
* AccessibleContext of this Panel
* @since 1.3
*/
public AccessibleContext getAccessibleContext() {
if (accessibleContext == null) {
accessibleContext = new AccessibleAWTPanel();
}
return accessibleContext;
}
/**
* This class implements accessibility support for the
* <code>Panel</code> class. It provides an implementation of the
* Java Accessibility API appropriate to panel user-interface elements.
* @since 1.3
*/
protected class AccessibleAWTPanel extends AccessibleAWTContainer {
private static final long serialVersionUID = -6409552226660031050L;
/**
* Get the role of this object.
*
* @return an instance of AccessibleRole describing the role of the
* object
*/
public AccessibleRole getAccessibleRole() {
return AccessibleRole.PANEL;
}
}
}

View File

@@ -0,0 +1,234 @@
/*
* Copyright (c) 1995, 2008, 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 java.awt;
import java.awt.geom.Point2D;
import java.beans.Transient;
/**
* A point representing a location in {@code (x,y)} coordinate space,
* specified in integer precision.
*
* @author Sami Shaio
* @since 1.0
*/
public class Point extends Point2D implements java.io.Serializable {
/**
* The X coordinate of this <code>Point</code>.
* If no X coordinate is set it will default to 0.
*
* @serial
* @see #getLocation()
* @see #move(int, int)
* @since 1.0
*/
public int x;
/**
* The Y coordinate of this <code>Point</code>.
* If no Y coordinate is set it will default to 0.
*
* @serial
* @see #getLocation()
* @see #move(int, int)
* @since 1.0
*/
public int y;
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = -5276940640259749850L;
/**
* Constructs and initializes a point at the origin
* (0,&nbsp;0) of the coordinate space.
* @since 1.1
*/
public Point() {
this(0, 0);
}
/**
* Constructs and initializes a point with the same location as
* the specified <code>Point</code> object.
* @param p a point
* @since 1.1
*/
public Point(Point p) {
this(p.x, p.y);
}
/**
* Constructs and initializes a point at the specified
* {@code (x,y)} location in the coordinate space.
* @param x the X coordinate of the newly constructed <code>Point</code>
* @param y the Y coordinate of the newly constructed <code>Point</code>
* @since 1.0
*/
public Point(int x, int y) {
this.x = x;
this.y = y;
}
/**
* {@inheritDoc}
* @since 1.2
*/
public double getX() {
return x;
}
/**
* {@inheritDoc}
* @since 1.2
*/
public double getY() {
return y;
}
/**
* Returns the location of this point.
* This method is included for completeness, to parallel the
* <code>getLocation</code> method of <code>Component</code>.
* @return a copy of this point, at the same location
* @see java.awt.Component#getLocation
* @see java.awt.Point#setLocation(java.awt.Point)
* @see java.awt.Point#setLocation(int, int)
* @since 1.1
*/
@Transient
public Point getLocation() {
return new Point(x, y);
}
/**
* Sets the location of the point to the specified location.
* This method is included for completeness, to parallel the
* <code>setLocation</code> method of <code>Component</code>.
* @param p a point, the new location for this point
* @see java.awt.Component#setLocation(java.awt.Point)
* @see java.awt.Point#getLocation
* @since 1.1
*/
public void setLocation(Point p) {
setLocation(p.x, p.y);
}
/**
* Changes the point to have the specified location.
* <p>
* This method is included for completeness, to parallel the
* <code>setLocation</code> method of <code>Component</code>.
* Its behavior is identical with <code>move(int,&nbsp;int)</code>.
* @param x the X coordinate of the new location
* @param y the Y coordinate of the new location
* @see java.awt.Component#setLocation(int, int)
* @see java.awt.Point#getLocation
* @see java.awt.Point#move(int, int)
* @since 1.1
*/
public void setLocation(int x, int y) {
move(x, y);
}
/**
* Sets the location of this point to the specified double coordinates.
* The double values will be rounded to integer values.
* Any number smaller than <code>Integer.MIN_VALUE</code>
* will be reset to <code>MIN_VALUE</code>, and any number
* larger than <code>Integer.MAX_VALUE</code> will be
* reset to <code>MAX_VALUE</code>.
*
* @param x the X coordinate of the new location
* @param y the Y coordinate of the new location
* @see #getLocation
*/
public void setLocation(double x, double y) {
this.x = (int) Math.floor(x+0.5);
this.y = (int) Math.floor(y+0.5);
}
/**
* Moves this point to the specified location in the
* {@code (x,y)} coordinate plane. This method
* is identical with <code>setLocation(int,&nbsp;int)</code>.
* @param x the X coordinate of the new location
* @param y the Y coordinate of the new location
* @see java.awt.Component#setLocation(int, int)
*/
public void move(int x, int y) {
this.x = x;
this.y = y;
}
/**
* Translates this point, at location {@code (x,y)},
* by {@code dx} along the {@code x} axis and {@code dy}
* along the {@code y} axis so that it now represents the point
* {@code (x+dx,y+dy)}.
*
* @param dx the distance to move this point
* along the X axis
* @param dy the distance to move this point
* along the Y axis
*/
public void translate(int dx, int dy) {
this.x += dx;
this.y += dy;
}
/**
* Determines whether or not two points are equal. Two instances of
* <code>Point2D</code> are equal if the values of their
* <code>x</code> and <code>y</code> member fields, representing
* their position in the coordinate space, are the same.
* @param obj an object to be compared with this <code>Point2D</code>
* @return <code>true</code> if the object to be compared is
* an instance of <code>Point2D</code> and has
* the same values; <code>false</code> otherwise.
*/
public boolean equals(Object obj) {
if (obj instanceof Point) {
Point pt = (Point)obj;
return (x == pt.x) && (y == pt.y);
}
return super.equals(obj);
}
/**
* Returns a string representation of this point and its location
* in the {@code (x,y)} coordinate space. This method is
* intended to be used only for debugging purposes, and the content
* and format of the returned string may vary between implementations.
* The returned string may be empty but may not be <code>null</code>.
*
* @return a string representation of this point
*/
public String toString() {
return getClass().getName() + "[x=" + x + ",y=" + y + "]";
}
}

View File

@@ -0,0 +1,81 @@
/*
* Copyright (c) 2003, 2014, 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 java.awt;
/**
* A class that describes the pointer position.
* It provides the {@code GraphicsDevice} where the pointer is and
* the {@code Point} that represents the coordinates of the pointer.
* <p>
* Instances of this class should be obtained via
* {@link MouseInfo#getPointerInfo}.
* The {@code PointerInfo} instance is not updated dynamically as the mouse
* moves. To get the updated location, you must call
* {@link MouseInfo#getPointerInfo} again.
*
* @see MouseInfo#getPointerInfo
* @author Roman Poborchiy
* @since 1.5
*/
public class PointerInfo {
private final GraphicsDevice device;
private final Point location;
/**
* Package-private constructor to prevent instantiation.
*/
PointerInfo(final GraphicsDevice device, final Point location) {
this.device = device;
this.location = location;
}
/**
* Returns the {@code GraphicsDevice} where the mouse pointer was at the
* moment this {@code PointerInfo} was created.
*
* @return {@code GraphicsDevice} corresponding to the pointer
* @since 1.5
*/
public GraphicsDevice getDevice() {
return device;
}
/**
* Returns the {@code Point} that represents the coordinates of the pointer
* on the screen. See {@link MouseInfo#getPointerInfo} for more information
* about coordinate calculation for multiscreen systems.
*
* @return coordinates of mouse pointer
* @see MouseInfo
* @see MouseInfo#getPointerInfo
* @since 1.5
*/
public Point getLocation() {
return location;
}
}

View File

@@ -0,0 +1,677 @@
/*
* Copyright (c) 1995, 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 java.awt;
import java.awt.geom.AffineTransform;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import sun.awt.geom.Crossings;
import java.util.Arrays;
/**
* The <code>Polygon</code> class encapsulates a description of a
* closed, two-dimensional region within a coordinate space. This
* region is bounded by an arbitrary number of line segments, each of
* which is one side of the polygon. Internally, a polygon
* comprises of a list of {@code (x,y)}
* coordinate pairs, where each pair defines a <i>vertex</i> of the
* polygon, and two successive pairs are the endpoints of a
* line that is a side of the polygon. The first and final
* pairs of {@code (x,y)} points are joined by a line segment
* that closes the polygon. This <code>Polygon</code> is defined with
* an even-odd winding rule. See
* {@link java.awt.geom.PathIterator#WIND_EVEN_ODD WIND_EVEN_ODD}
* for a definition of the even-odd winding rule.
* This class's hit-testing methods, which include the
* <code>contains</code>, <code>intersects</code> and <code>inside</code>
* methods, use the <i>insideness</i> definition described in the
* {@link Shape} class comments.
*
* @author Sami Shaio
* @see Shape
* @author Herb Jellinek
* @since 1.0
*/
public class Polygon implements Shape, java.io.Serializable {
/**
* The total number of points. The value of <code>npoints</code>
* represents the number of valid points in this <code>Polygon</code>
* and might be less than the number of elements in
* {@link #xpoints xpoints} or {@link #ypoints ypoints}.
* This value can be NULL.
*
* @serial
* @see #addPoint(int, int)
* @since 1.0
*/
public int npoints;
/**
* The array of X coordinates. The number of elements in
* this array might be more than the number of X coordinates
* in this <code>Polygon</code>. The extra elements allow new points
* to be added to this <code>Polygon</code> without re-creating this
* array. The value of {@link #npoints npoints} is equal to the
* number of valid points in this <code>Polygon</code>.
*
* @serial
* @see #addPoint(int, int)
* @since 1.0
*/
public int xpoints[];
/**
* The array of Y coordinates. The number of elements in
* this array might be more than the number of Y coordinates
* in this <code>Polygon</code>. The extra elements allow new points
* to be added to this <code>Polygon</code> without re-creating this
* array. The value of <code>npoints</code> is equal to the
* number of valid points in this <code>Polygon</code>.
*
* @serial
* @see #addPoint(int, int)
* @since 1.0
*/
public int ypoints[];
/**
* The bounds of this {@code Polygon}.
* This value can be null.
*
* @serial
* @see #getBoundingBox()
* @see #getBounds()
* @since 1.0
*/
protected Rectangle bounds;
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = -6460061437900069969L;
/*
* Default length for xpoints and ypoints.
*/
private static final int MIN_LENGTH = 4;
/**
* Creates an empty polygon.
* @since 1.0
*/
public Polygon() {
xpoints = new int[MIN_LENGTH];
ypoints = new int[MIN_LENGTH];
}
/**
* Constructs and initializes a <code>Polygon</code> from the specified
* parameters.
* @param xpoints an array of X coordinates
* @param ypoints an array of Y coordinates
* @param npoints the total number of points in the
* <code>Polygon</code>
* @exception NegativeArraySizeException if the value of
* <code>npoints</code> is negative.
* @exception IndexOutOfBoundsException if <code>npoints</code> is
* greater than the length of <code>xpoints</code>
* or the length of <code>ypoints</code>.
* @exception NullPointerException if <code>xpoints</code> or
* <code>ypoints</code> is <code>null</code>.
* @since 1.0
*/
public Polygon(int xpoints[], int ypoints[], int npoints) {
// Fix 4489009: should throw IndexOutofBoundsException instead
// of OutofMemoryException if npoints is huge and > {x,y}points.length
if (npoints > xpoints.length || npoints > ypoints.length) {
throw new IndexOutOfBoundsException("npoints > xpoints.length || "+
"npoints > ypoints.length");
}
// Fix 6191114: should throw NegativeArraySizeException with
// negative npoints
if (npoints < 0) {
throw new NegativeArraySizeException("npoints < 0");
}
// Fix 6343431: Applet compatibility problems if arrays are not
// exactly npoints in length
this.npoints = npoints;
this.xpoints = Arrays.copyOf(xpoints, npoints);
this.ypoints = Arrays.copyOf(ypoints, npoints);
}
/**
* Resets this <code>Polygon</code> object to an empty polygon.
* The coordinate arrays and the data in them are left untouched
* but the number of points is reset to zero to mark the old
* vertex data as invalid and to start accumulating new vertex
* data at the beginning.
* All internally-cached data relating to the old vertices
* are discarded.
* Note that since the coordinate arrays from before the reset
* are reused, creating a new empty <code>Polygon</code> might
* be more memory efficient than resetting the current one if
* the number of vertices in the new polygon data is significantly
* smaller than the number of vertices in the data from before the
* reset.
* @see java.awt.Polygon#invalidate
* @since 1.4
*/
public void reset() {
npoints = 0;
bounds = null;
}
/**
* Invalidates or flushes any internally-cached data that depends
* on the vertex coordinates of this <code>Polygon</code>.
* This method should be called after any direct manipulation
* of the coordinates in the <code>xpoints</code> or
* <code>ypoints</code> arrays to avoid inconsistent results
* from methods such as <code>getBounds</code> or <code>contains</code>
* that might cache data from earlier computations relating to
* the vertex coordinates.
* @see java.awt.Polygon#getBounds
* @since 1.4
*/
public void invalidate() {
bounds = null;
}
/**
* Translates the vertices of the <code>Polygon</code> by
* <code>deltaX</code> along the x axis and by
* <code>deltaY</code> along the y axis.
* @param deltaX the amount to translate along the X axis
* @param deltaY the amount to translate along the Y axis
* @since 1.1
*/
public void translate(int deltaX, int deltaY) {
for (int i = 0; i < npoints; i++) {
xpoints[i] += deltaX;
ypoints[i] += deltaY;
}
if (bounds != null) {
bounds.translate(deltaX, deltaY);
}
}
/*
* Calculates the bounding box of the points passed to the constructor.
* Sets <code>bounds</code> to the result.
* @param xpoints[] array of <i>x</i> coordinates
* @param ypoints[] array of <i>y</i> coordinates
* @param npoints the total number of points
*/
void calculateBounds(int xpoints[], int ypoints[], int npoints) {
int boundsMinX = Integer.MAX_VALUE;
int boundsMinY = Integer.MAX_VALUE;
int boundsMaxX = Integer.MIN_VALUE;
int boundsMaxY = Integer.MIN_VALUE;
for (int i = 0; i < npoints; i++) {
int x = xpoints[i];
boundsMinX = Math.min(boundsMinX, x);
boundsMaxX = Math.max(boundsMaxX, x);
int y = ypoints[i];
boundsMinY = Math.min(boundsMinY, y);
boundsMaxY = Math.max(boundsMaxY, y);
}
bounds = new Rectangle(boundsMinX, boundsMinY,
boundsMaxX - boundsMinX,
boundsMaxY - boundsMinY);
}
/*
* Resizes the bounding box to accommodate the specified coordinates.
* @param x,&nbsp;y the specified coordinates
*/
void updateBounds(int x, int y) {
if (x < bounds.x) {
bounds.width = bounds.width + (bounds.x - x);
bounds.x = x;
}
else {
bounds.width = Math.max(bounds.width, x - bounds.x);
// bounds.x = bounds.x;
}
if (y < bounds.y) {
bounds.height = bounds.height + (bounds.y - y);
bounds.y = y;
}
else {
bounds.height = Math.max(bounds.height, y - bounds.y);
// bounds.y = bounds.y;
}
}
/**
* Appends the specified coordinates to this <code>Polygon</code>.
* <p>
* If an operation that calculates the bounding box of this
* <code>Polygon</code> has already been performed, such as
* <code>getBounds</code> or <code>contains</code>, then this
* method updates the bounding box.
* @param x the specified X coordinate
* @param y the specified Y coordinate
* @see java.awt.Polygon#getBounds
* @see java.awt.Polygon#contains
* @since 1.0
*/
public void addPoint(int x, int y) {
if (npoints >= xpoints.length || npoints >= ypoints.length) {
int newLength = npoints * 2;
// Make sure that newLength will be greater than MIN_LENGTH and
// aligned to the power of 2
if (newLength < MIN_LENGTH) {
newLength = MIN_LENGTH;
} else if ((newLength & (newLength - 1)) != 0) {
newLength = Integer.highestOneBit(newLength);
}
xpoints = Arrays.copyOf(xpoints, newLength);
ypoints = Arrays.copyOf(ypoints, newLength);
}
xpoints[npoints] = x;
ypoints[npoints] = y;
npoints++;
if (bounds != null) {
updateBounds(x, y);
}
}
/**
* Gets the bounding box of this <code>Polygon</code>.
* The bounding box is the smallest {@link Rectangle} whose
* sides are parallel to the x and y axes of the
* coordinate space, and can completely contain the <code>Polygon</code>.
* @return a <code>Rectangle</code> that defines the bounds of this
* <code>Polygon</code>.
* @since 1.1
*/
public Rectangle getBounds() {
return getBoundingBox();
}
/**
* Returns the bounds of this <code>Polygon</code>.
* @return the bounds of this <code>Polygon</code>.
* @deprecated As of JDK version 1.1,
* replaced by <code>getBounds()</code>.
* @since 1.0
*/
@Deprecated
public Rectangle getBoundingBox() {
if (npoints == 0) {
return new Rectangle();
}
if (bounds == null) {
calculateBounds(xpoints, ypoints, npoints);
}
return bounds.getBounds();
}
/**
* Determines whether the specified {@link Point} is inside this
* <code>Polygon</code>.
* @param p the specified <code>Point</code> to be tested
* @return <code>true</code> if the <code>Polygon</code> contains the
* <code>Point</code>; <code>false</code> otherwise.
* @see #contains(double, double)
* @since 1.0
*/
public boolean contains(Point p) {
return contains(p.x, p.y);
}
/**
* Determines whether the specified coordinates are inside this
* <code>Polygon</code>.
* <p>
* @param x the specified X coordinate to be tested
* @param y the specified Y coordinate to be tested
* @return {@code true} if this {@code Polygon} contains
* the specified coordinates {@code (x,y)};
* {@code false} otherwise.
* @see #contains(double, double)
* @since 1.1
*/
public boolean contains(int x, int y) {
return contains((double) x, (double) y);
}
/**
* Determines whether the specified coordinates are contained in this
* <code>Polygon</code>.
* @param x the specified X coordinate to be tested
* @param y the specified Y coordinate to be tested
* @return {@code true} if this {@code Polygon} contains
* the specified coordinates {@code (x,y)};
* {@code false} otherwise.
* @see #contains(double, double)
* @deprecated As of JDK version 1.1,
* replaced by <code>contains(int, int)</code>.
* @since 1.0
*/
@Deprecated
public boolean inside(int x, int y) {
return contains((double) x, (double) y);
}
/**
* {@inheritDoc}
* @since 1.2
*/
public Rectangle2D getBounds2D() {
return getBounds();
}
/**
* {@inheritDoc}
* @since 1.2
*/
public boolean contains(double x, double y) {
if (npoints <= 2 || !getBoundingBox().contains(x, y)) {
return false;
}
int hits = 0;
int lastx = xpoints[npoints - 1];
int lasty = ypoints[npoints - 1];
int curx, cury;
// Walk the edges of the polygon
for (int i = 0; i < npoints; lastx = curx, lasty = cury, i++) {
curx = xpoints[i];
cury = ypoints[i];
if (cury == lasty) {
continue;
}
int leftx;
if (curx < lastx) {
if (x >= lastx) {
continue;
}
leftx = curx;
} else {
if (x >= curx) {
continue;
}
leftx = lastx;
}
double test1, test2;
if (cury < lasty) {
if (y < cury || y >= lasty) {
continue;
}
if (x < leftx) {
hits++;
continue;
}
test1 = x - curx;
test2 = y - cury;
} else {
if (y < lasty || y >= cury) {
continue;
}
if (x < leftx) {
hits++;
continue;
}
test1 = x - lastx;
test2 = y - lasty;
}
if (test1 < (test2 / (lasty - cury) * (lastx - curx))) {
hits++;
}
}
return ((hits & 1) != 0);
}
private Crossings getCrossings(double xlo, double ylo,
double xhi, double yhi)
{
Crossings cross = new Crossings.EvenOdd(xlo, ylo, xhi, yhi);
int lastx = xpoints[npoints - 1];
int lasty = ypoints[npoints - 1];
int curx, cury;
// Walk the edges of the polygon
for (int i = 0; i < npoints; i++) {
curx = xpoints[i];
cury = ypoints[i];
if (cross.accumulateLine(lastx, lasty, curx, cury)) {
return null;
}
lastx = curx;
lasty = cury;
}
return cross;
}
/**
* {@inheritDoc}
* @since 1.2
*/
public boolean contains(Point2D p) {
return contains(p.getX(), p.getY());
}
/**
* {@inheritDoc}
* @since 1.2
*/
public boolean intersects(double x, double y, double w, double h) {
if (npoints <= 0 || !getBoundingBox().intersects(x, y, w, h)) {
return false;
}
Crossings cross = getCrossings(x, y, x+w, y+h);
return (cross == null || !cross.isEmpty());
}
/**
* {@inheritDoc}
* @since 1.2
*/
public boolean intersects(Rectangle2D r) {
return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
}
/**
* {@inheritDoc}
* @since 1.2
*/
public boolean contains(double x, double y, double w, double h) {
if (npoints <= 0 || !getBoundingBox().intersects(x, y, w, h)) {
return false;
}
Crossings cross = getCrossings(x, y, x+w, y+h);
return (cross != null && cross.covers(y, y+h));
}
/**
* {@inheritDoc}
* @since 1.2
*/
public boolean contains(Rectangle2D r) {
return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
}
/**
* Returns an iterator object that iterates along the boundary of this
* <code>Polygon</code> and provides access to the geometry
* of the outline of this <code>Polygon</code>. An optional
* {@link AffineTransform} can be specified so that the coordinates
* returned in the iteration are transformed accordingly.
* @param at an optional <code>AffineTransform</code> to be applied to the
* coordinates as they are returned in the iteration, or
* <code>null</code> if untransformed coordinates are desired
* @return a {@link PathIterator} object that provides access to the
* geometry of this <code>Polygon</code>.
* @since 1.2
*/
public PathIterator getPathIterator(AffineTransform at) {
return new PolygonPathIterator(this, at);
}
/**
* Returns an iterator object that iterates along the boundary of
* the <code>Shape</code> and provides access to the geometry of the
* outline of the <code>Shape</code>. Only SEG_MOVETO, SEG_LINETO, and
* SEG_CLOSE point types are returned by the iterator.
* Since polygons are already flat, the <code>flatness</code> parameter
* is ignored. An optional <code>AffineTransform</code> can be specified
* in which case the coordinates returned in the iteration are transformed
* accordingly.
* @param at an optional <code>AffineTransform</code> to be applied to the
* coordinates as they are returned in the iteration, or
* <code>null</code> if untransformed coordinates are desired
* @param flatness the maximum amount that the control points
* for a given curve can vary from colinear before a subdivided
* curve is replaced by a straight line connecting the
* endpoints. Since polygons are already flat the
* <code>flatness</code> parameter is ignored.
* @return a <code>PathIterator</code> object that provides access to the
* <code>Shape</code> object's geometry.
* @since 1.2
*/
public PathIterator getPathIterator(AffineTransform at, double flatness) {
return getPathIterator(at);
}
class PolygonPathIterator implements PathIterator {
Polygon poly;
AffineTransform transform;
int index;
public PolygonPathIterator(Polygon pg, AffineTransform at) {
poly = pg;
transform = at;
if (pg.npoints == 0) {
// Prevent a spurious SEG_CLOSE segment
index = 1;
}
}
/**
* Returns the winding rule for determining the interior of the
* path.
* @return an integer representing the current winding rule.
* @see PathIterator#WIND_NON_ZERO
*/
public int getWindingRule() {
return WIND_EVEN_ODD;
}
/**
* Tests if there are more points to read.
* @return <code>true</code> if there are more points to read;
* <code>false</code> otherwise.
*/
public boolean isDone() {
return index > poly.npoints;
}
/**
* Moves the iterator forwards, along the primary direction of
* traversal, to the next segment of the path when there are
* more points in that direction.
*/
public void next() {
index++;
}
/**
* Returns the coordinates and type of the current path segment in
* the iteration.
* The return value is the path segment type:
* SEG_MOVETO, SEG_LINETO, or SEG_CLOSE.
* A <code>float</code> array of length 2 must be passed in and
* can be used to store the coordinates of the point(s).
* Each point is stored as a pair of <code>float</code> x,&nbsp;y
* coordinates. SEG_MOVETO and SEG_LINETO types return one
* point, and SEG_CLOSE does not return any points.
* @param coords a <code>float</code> array that specifies the
* coordinates of the point(s)
* @return an integer representing the type and coordinates of the
* current path segment.
* @see PathIterator#SEG_MOVETO
* @see PathIterator#SEG_LINETO
* @see PathIterator#SEG_CLOSE
*/
public int currentSegment(float[] coords) {
if (index >= poly.npoints) {
return SEG_CLOSE;
}
coords[0] = poly.xpoints[index];
coords[1] = poly.ypoints[index];
if (transform != null) {
transform.transform(coords, 0, coords, 0, 1);
}
return (index == 0 ? SEG_MOVETO : SEG_LINETO);
}
/**
* Returns the coordinates and type of the current path segment in
* the iteration.
* The return value is the path segment type:
* SEG_MOVETO, SEG_LINETO, or SEG_CLOSE.
* A <code>double</code> array of length 2 must be passed in and
* can be used to store the coordinates of the point(s).
* Each point is stored as a pair of <code>double</code> x,&nbsp;y
* coordinates.
* SEG_MOVETO and SEG_LINETO types return one point,
* and SEG_CLOSE does not return any points.
* @param coords a <code>double</code> array that specifies the
* coordinates of the point(s)
* @return an integer representing the type and coordinates of the
* current path segment.
* @see PathIterator#SEG_MOVETO
* @see PathIterator#SEG_LINETO
* @see PathIterator#SEG_CLOSE
*/
public int currentSegment(double[] coords) {
if (index >= poly.npoints) {
return SEG_CLOSE;
}
coords[0] = poly.xpoints[index];
coords[1] = poly.ypoints[index];
if (transform != null) {
transform.transform(coords, 0, coords, 0, 1);
}
return (index == 0 ? SEG_MOVETO : SEG_LINETO);
}
}
}

View File

@@ -0,0 +1,241 @@
/*
* Copyright (c) 1996, 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 java.awt;
import java.awt.peer.PopupMenuPeer;
import javax.accessibility.*;
import sun.awt.AWTAccessor;
/**
* A class that implements a menu which can be dynamically popped up
* at a specified position within a component.
* <p>
* As the inheritance hierarchy implies, a <code>PopupMenu</code>
* can be used anywhere a <code>Menu</code> can be used.
* However, if you use a <code>PopupMenu</code> like a <code>Menu</code>
* (e.g., you add it to a <code>MenuBar</code>), then you <b>cannot</b>
* call <code>show</code> on that <code>PopupMenu</code>.
*
* @author Amy Fowler
*/
public class PopupMenu extends Menu {
private static final String base = "popup";
static int nameCounter = 0;
transient boolean isTrayIconPopup = false;
static {
AWTAccessor.setPopupMenuAccessor(
new AWTAccessor.PopupMenuAccessor() {
public boolean isTrayIconPopup(PopupMenu popupMenu) {
return popupMenu.isTrayIconPopup;
}
});
}
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = -4620452533522760060L;
/**
* Creates a new popup menu with an empty name.
* @exception HeadlessException if GraphicsEnvironment.isHeadless()
* returns true.
* @see java.awt.GraphicsEnvironment#isHeadless
*/
public PopupMenu() throws HeadlessException {
this("");
}
/**
* Creates a new popup menu with the specified name.
*
* @param label a non-<code>null</code> string specifying
* the popup menu's label
* @exception HeadlessException if GraphicsEnvironment.isHeadless()
* returns true.
* @see java.awt.GraphicsEnvironment#isHeadless
*/
public PopupMenu(String label) throws HeadlessException {
super(label);
}
/**
* {@inheritDoc}
*/
public MenuContainer getParent() {
if (isTrayIconPopup) {
return null;
}
return super.getParent();
}
/**
* Constructs a name for this <code>MenuComponent</code>.
* Called by <code>getName</code> when the name is <code>null</code>.
*/
String constructComponentName() {
synchronized (PopupMenu.class) {
return base + nameCounter++;
}
}
/**
* Creates the popup menu's peer.
* The peer allows us to change the appearance of the popup menu without
* changing any of the popup menu's functionality.
*/
public void addNotify() {
synchronized (getTreeLock()) {
// If our parent is not a Component, then this PopupMenu is
// really just a plain, old Menu.
if (parent != null && !(parent instanceof Component)) {
super.addNotify();
}
else {
if (peer == null)
peer = Toolkit.getDefaultToolkit().createPopupMenu(this);
int nitems = getItemCount();
for (int i = 0 ; i < nitems ; i++) {
MenuItem mi = getItem(i);
mi.parent = this;
mi.addNotify();
}
}
}
}
/**
* Shows the popup menu at the x, y position relative to an origin
* component.
* The origin component must be contained within the component
* hierarchy of the popup menu's parent. Both the origin and the parent
* must be showing on the screen for this method to be valid.
* <p>
* If this <code>PopupMenu</code> is being used as a <code>Menu</code>
* (i.e., it has a non-<code>Component</code> parent),
* then you cannot call this method on the <code>PopupMenu</code>.
*
* @param origin the component which defines the coordinate space
* @param x the x coordinate position to popup the menu
* @param y the y coordinate position to popup the menu
* @exception NullPointerException if the parent is <code>null</code>
* @exception IllegalArgumentException if this <code>PopupMenu</code>
* has a non-<code>Component</code> parent
* @exception IllegalArgumentException if the origin is not in the
* parent's hierarchy
* @exception RuntimeException if the parent is not showing on screen
*/
public void show(Component origin, int x, int y) {
// Use localParent for thread safety.
MenuContainer localParent = parent;
if (localParent == null) {
throw new NullPointerException("parent is null");
}
if (!(localParent instanceof Component)) {
throw new IllegalArgumentException(
"PopupMenus with non-Component parents cannot be shown");
}
Component compParent = (Component)localParent;
//Fixed 6278745: Incorrect exception throwing in PopupMenu.show() method
//Exception was not thrown if compParent was not equal to origin and
//was not Container
if (compParent != origin) {
if (compParent instanceof Container) {
if (!((Container)compParent).isAncestorOf(origin)) {
throw new IllegalArgumentException("origin not in parent's hierarchy");
}
} else {
throw new IllegalArgumentException("origin not in parent's hierarchy");
}
}
if (compParent.getPeer() == null || !compParent.isShowing()) {
throw new RuntimeException("parent not showing on screen");
}
if (peer == null) {
addNotify();
}
synchronized (getTreeLock()) {
if (peer != null) {
((PopupMenuPeer)peer).show(
new Event(origin, 0, Event.MOUSE_DOWN, x, y, 0, 0));
}
}
}
/////////////////
// Accessibility support
////////////////
/**
* Gets the <code>AccessibleContext</code> associated with this
* <code>PopupMenu</code>.
*
* @return the <code>AccessibleContext</code> of this
* <code>PopupMenu</code>
* @since 1.3
*/
public AccessibleContext getAccessibleContext() {
if (accessibleContext == null) {
accessibleContext = new AccessibleAWTPopupMenu();
}
return accessibleContext;
}
/**
* Inner class of PopupMenu used to provide default support for
* accessibility. This class is not meant to be used directly by
* application developers, but is instead meant only to be
* subclassed by menu component developers.
* <p>
* The class used to obtain the accessible role for this object.
* @since 1.3
*/
protected class AccessibleAWTPopupMenu extends AccessibleAWTMenu
{
/*
* JDK 1.3 serialVersionUID
*/
private static final long serialVersionUID = -4282044795947239955L;
/**
* Get the role of this object.
*
* @return an instance of AccessibleRole describing the role of the
* object
*/
public AccessibleRole getAccessibleRole() {
return AccessibleRole.POPUP_MENU;
}
} // class AccessibleAWTPopupMenu
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright (c) 1996, 1997, 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 java.awt;
/**
* An abstract class which provides a print graphics context for a page.
*
* @author Amy Fowler
*/
public interface PrintGraphics {
/**
* Returns the PrintJob object from which this PrintGraphics
* object originated.
*/
public PrintJob getPrintJob();
}

Some files were not shown because too many files have changed in this diff Show More