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,160 @@
/*
* 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 sun.swing;
import java.util.*;
import java.lang.reflect.Array;
import javax.swing.SwingUtilities;
/**
* An abstract class to be used in the cases where we need {@code Runnable}
* to perform some actions on an appendable set of data.
* The set of data might be appended after the {@code Runnable} is
* sent for the execution. Usually such {@code Runnables} are sent to
* the EDT.
*
* <p>
* Usage example:
*
* <p>
* Say we want to implement JLabel.setText(String text) which sends
* {@code text} string to the JLabel.setTextImpl(String text) on the EDT.
* In the event JLabel.setText is called rapidly many times off the EDT
* we will get many updates on the EDT but only the last one is important.
* (Every next updates overrides the previous one.)
* We might want to implement this {@code setText} in a way that only
* the last update is delivered.
* <p>
* Here is how one can do this using {@code AccumulativeRunnable}:
* <pre>
* AccumulativeRunnable<String> doSetTextImpl =
* new AccumulativeRunnable<String>() {
* @Override
* protected void run(List&lt;String&gt; args) {
* //set to the last string being passed
* setTextImpl(args.get(args.size() - 1));
* }
* }
* void setText(String text) {
* //add text and send for the execution if needed.
* doSetTextImpl.add(text);
* }
* </pre>
*
* <p>
* Say we want want to implement addDirtyRegion(Rectangle rect)
* which sends this region to the
* handleDirtyRegions(List<Rect> regiouns) on the EDT.
* addDirtyRegions better be accumulated before handling on the EDT.
*
* <p>
* Here is how it can be implemented using AccumulativeRunnable:
* <pre>
* AccumulativeRunnable<Rectangle> doHandleDirtyRegions =
* new AccumulativeRunnable<Rectangle>() {
* @Override
* protected void run(List&lt;Rectangle&gt; args) {
* handleDirtyRegions(args);
* }
* };
* void addDirtyRegion(Rectangle rect) {
* doHandleDirtyRegions.add(rect);
* }
* </pre>
*
* @author Igor Kushnirskiy
*
* @param <T> the type this {@code Runnable} accumulates
*
* @since 1.6
*/
public abstract class AccumulativeRunnable<T> implements Runnable {
private List<T> arguments = null;
/**
* Equivalent to {@code Runnable.run} method with the
* accumulated arguments to process.
*
* @param args accumulated argumets to process.
*/
protected abstract void run(List<T> args);
/**
* {@inheritDoc}
*
* <p>
* This implementation calls {@code run(List<T> args)} mehtod
* with the list of accumulated arguments.
*/
public final void run() {
run(flush());
}
/**
* appends arguments and sends this {@cod Runnable} for the
* execution if needed.
* <p>
* This implementation uses {@see #submit} to send this
* {@code Runnable} for execution.
* @param args the arguments to accumulate
*/
@SafeVarargs
@SuppressWarnings("varargs") // Copying args is safe
public final synchronized void add(T... args) {
boolean isSubmitted = true;
if (arguments == null) {
isSubmitted = false;
arguments = new ArrayList<T>();
}
Collections.addAll(arguments, args);
if (!isSubmitted) {
submit();
}
}
/**
* Sends this {@code Runnable} for the execution
*
* <p>
* This method is to be executed only from {@code add} method.
*
* <p>
* This implementation uses {@code SwingWorker.invokeLater}.
*/
protected void submit() {
SwingUtilities.invokeLater(this);
}
/**
* Returns accumulated arguments and flashes the arguments storage.
*
* @return accumulated arguments
*/
private final synchronized List<T> flush() {
List<T> list = arguments;
arguments = null;
return list;
}
}

View File

@@ -0,0 +1,93 @@
/*
* 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 sun.swing;
import java.util.*;
/**
* <b>WARNING:</b> This class is an implementation detail and is only
* public so that it can be used by two packages. You should NOT consider
* this public API.
* <p>
* <b>WARNING 2:</b> This is not a general purpose List implementation! It
* has a specific use and will not work correctly if you use it outside of
* its use.
* <p>
* A specialized ArrayList that caches its hashCode as well as overriding
* equals to avoid creating an Iterator. This class is useful in scenarios
* where the list won't change and you want to avoid the overhead of hashCode
* iterating through the elements invoking hashCode. This also assumes you'll
* only ever compare a BakedArrayList to another BakedArrayList.
*
* @author Scott Violet
*/
public class BakedArrayList extends ArrayList {
/**
* The cached hashCode.
*/
private int _hashCode;
public BakedArrayList(int size) {
super(size);
}
public BakedArrayList(java.util.List data) {
this(data.size());
for (int counter = 0, max = data.size(); counter < max; counter++){
add(data.get(counter));
}
cacheHashCode();
}
/**
* Caches the hash code. It is assumed you won't modify the list, or that
* if you do you'll call cacheHashCode again.
*/
public void cacheHashCode() {
_hashCode = 1;
for (int counter = size() - 1; counter >= 0; counter--) {
_hashCode = 31 * _hashCode + get(counter).hashCode();
}
}
public int hashCode() {
return _hashCode;
}
public boolean equals(Object o) {
BakedArrayList list = (BakedArrayList)o;
int size = size();
if (list.size() != size) {
return false;
}
while (size-- > 0) {
if (!get(size).equals(list.get(size))) {
return false;
}
}
return true;
}
}

View File

@@ -0,0 +1,293 @@
/*
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.swing;
import java.beans.*;
import java.lang.reflect.Method;
public class BeanInfoUtils
{
/* The values of these createPropertyDescriptor() and
* createBeanDescriptor() keywords are the names of the
* properties they're used to set.
*/
public static final String BOUND = "bound";
public static final String CONSTRAINED = "constrained";
public static final String PROPERTYEDITORCLASS = "propertyEditorClass";
public static final String READMETHOD = "readMethod";
public static final String WRITEMETHOD = "writeMethod";
public static final String DISPLAYNAME = "displayName";
public static final String EXPERT = "expert";
public static final String HIDDEN = "hidden";
public static final String PREFERRED = "preferred";
public static final String SHORTDESCRIPTION = "shortDescription";
public static final String CUSTOMIZERCLASS = "customizerClass";
static private void initFeatureDescriptor(FeatureDescriptor fd, String key, Object value)
{
if (DISPLAYNAME.equals(key)) {
fd.setDisplayName((String)value);
}
if (EXPERT.equals(key)) {
fd.setExpert(((Boolean)value).booleanValue());
}
if (HIDDEN.equals(key)) {
fd.setHidden(((Boolean)value).booleanValue());
}
if (PREFERRED.equals(key)) {
fd.setPreferred(((Boolean)value).booleanValue());
}
else if (SHORTDESCRIPTION.equals(key)) {
fd.setShortDescription((String)value);
}
/* Otherwise assume that we have an arbitrary FeatureDescriptor
* "attribute".
*/
else {
fd.setValue(key, value);
}
}
/**
* Create a beans PropertyDescriptor given an of keyword/value
* arguments. The following sample call shows all of the supported
* keywords:
*<pre>
* createPropertyDescriptor("contentPane", new Object[] {
* BOUND, Boolean.TRUE,
* CONSTRAINED, Boolean.TRUE,
* PROPERTYEDITORCLASS, package.MyEditor.class,
* READMETHOD, "getContentPane",
* WRITEMETHOD, "setContentPane",
* DISPLAYNAME, "contentPane",
* EXPERT, Boolean.FALSE,
* HIDDEN, Boolean.FALSE,
* PREFERRED, Boolean.TRUE,
* SHORTDESCRIPTION, "A top level window with a window manager border",
* "random attribute","random object value"
* }
* );
* </pre>
* The keywords correspond to <code>java.beans.PropertyDescriptor</code> and
* <code>java.beans.FeatureDescriptor</code> properties, e.g. providing a value
* for displayName is comparable to <code>FeatureDescriptor.setDisplayName()</code>.
* Using createPropertyDescriptor instead of the PropertyDescriptor
* constructor and set methods is preferrable in that it regularizes
* the code in a <code>java.beans.BeanInfo.getPropertyDescriptors()</code>
* method implementation. One can use <code>createPropertyDescriptor</code>
* to set <code>FeatureDescriptor</code> attributes, as in "random attribute"
* "random object value".
* <p>
* All properties should provide a reasonable value for the
* <code>SHORTDESCRIPTION</code> keyword and should set <code>BOUND</code>
* to <code>Boolean.TRUE</code> if neccessary. The remaining keywords
* are optional. There's no need to provide values for keywords like
* READMETHOD if the correct value can be computed, i.e. if the properties
* get/is method follows the standard beans pattern.
* <p>
* The PREFERRED keyword is not supported by the JDK1.1 java.beans package.
* It's still worth setting it to true for properties that are most
* likely to be interested to the average developer, e.g. AbstractButton.title
* is a preferred property, AbstractButton.focusPainted is not.
*
* @see java.beans#BeanInfo
* @see java.beans#PropertyDescriptor
* @see java.beans#FeatureDescriptor
*/
public static PropertyDescriptor createPropertyDescriptor(Class cls, String name, Object[] args)
{
PropertyDescriptor pd = null;
try {
pd = new PropertyDescriptor(name, cls);
} catch (IntrospectionException e) {
// Try creating a read-only property, in case setter isn't defined.
try {
pd = createReadOnlyPropertyDescriptor(name, cls);
} catch (IntrospectionException ie) {
throwError(ie, "Can't create PropertyDescriptor for " + name + " ");
}
}
for(int i = 0; i < args.length; i += 2) {
String key = (String)args[i];
Object value = args[i + 1];
if (BOUND.equals(key)) {
pd.setBound(((Boolean)value).booleanValue());
}
else if (CONSTRAINED.equals(key)) {
pd.setConstrained(((Boolean)value).booleanValue());
}
else if (PROPERTYEDITORCLASS.equals(key)) {
pd.setPropertyEditorClass((Class)value);
}
else if (READMETHOD.equals(key)) {
String methodName = (String)value;
Method method;
try {
method = cls.getMethod(methodName, new Class[0]);
pd.setReadMethod(method);
}
catch(Exception e) {
throwError(e, cls + " no such method as \"" + methodName + "\"");
}
}
else if (WRITEMETHOD.equals(key)) {
String methodName = (String)value;
Method method;
try {
Class type = pd.getPropertyType();
method = cls.getMethod(methodName, new Class[]{type});
pd.setWriteMethod(method);
}
catch(Exception e) {
throwError(e, cls + " no such method as \"" + methodName + "\"");
}
}
else {
initFeatureDescriptor(pd, key, value);
}
}
return pd;
}
/**
* Create a BeanDescriptor object given an of keyword/value
* arguments. The following sample call shows all of the supported
* keywords:
*<pre>
* createBeanDescriptor(JWindow..class, new Object[] {
* CUSTOMIZERCLASS, package.MyCustomizer.class,
* DISPLAYNAME, "JFrame",
* EXPERT, Boolean.FALSE,
* HIDDEN, Boolean.FALSE,
* PREFERRED, Boolean.TRUE,
* SHORTDESCRIPTION, "A top level window with a window manager border",
* "random attribute","random object value"
* }
* );
* </pre>
* The keywords correspond to <code>java.beans.BeanDescriptor</code> and
* <code>java.beans.FeatureDescriptor</code> properties, e.g. providing a value
* for displayName is comparable to <code>FeatureDescriptor.setDisplayName()</code>.
* Using createBeanDescriptor instead of the BeanDescriptor
* constructor and set methods is preferrable in that it regularizes
* the code in a <code>java.beans.BeanInfo.getBeanDescriptor()</code>
* method implementation. One can use <code>createBeanDescriptor</code>
* to set <code>FeatureDescriptor</code> attributes, as in "random attribute"
* "random object value".
*
* @see java.beans#BeanInfo
* @see java.beans#PropertyDescriptor
*/
public static BeanDescriptor createBeanDescriptor(Class cls, Object[] args)
{
Class customizerClass = null;
/* For reasons I don't understand, customizerClass is a
* readOnly property. So we have to find it and pass it
* to the constructor here.
*/
for(int i = 0; i < args.length; i += 2) {
if (CUSTOMIZERCLASS.equals((String)args[i])) {
customizerClass = (Class)args[i + 1];
break;
}
}
BeanDescriptor bd = new BeanDescriptor(cls, customizerClass);
for(int i = 0; i < args.length; i += 2) {
String key = (String)args[i];
Object value = args[i + 1];
initFeatureDescriptor(bd, key, value);
}
return bd;
}
static private PropertyDescriptor createReadOnlyPropertyDescriptor(
String name, Class cls) throws IntrospectionException {
Method readMethod = null;
String base = capitalize(name);
Class[] parameters = new Class[0];
// Is it a boolean?
try {
readMethod = cls.getMethod("is" + base, parameters);
} catch (Exception ex) {}
if (readMethod == null) {
try {
// Try normal accessor pattern.
readMethod = cls.getMethod("get" + base, parameters);
} catch (Exception ex2) {}
}
if (readMethod != null) {
return new PropertyDescriptor(name, readMethod, null);
}
try {
// Try indexed accessor pattern.
parameters = new Class[1];
parameters[0] = int.class;
readMethod = cls.getMethod("get" + base, parameters);
} catch (NoSuchMethodException nsme) {
throw new IntrospectionException(
"cannot find accessor method for " + name + " property.");
}
return new IndexedPropertyDescriptor(name, null, null, readMethod, null);
}
// Modified methods from java.beans.Introspector
private static String capitalize(String s) {
if (s.length() == 0) {
return s;
}
char chars[] = s.toCharArray();
chars[0] = Character.toUpperCase(chars[0]);
return new String(chars);
}
/**
* Fatal errors are handled by calling this method.
*/
public static void throwError(Exception e, String s) {
throw new Error(e.toString() + " " + s);
}
}

View File

@@ -0,0 +1,213 @@
/*
* Copyright (c) 2004, 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 sun.swing;
import java.awt.*;
import java.awt.image.*;
import java.util.*;
/**
* A base class used for icons or images that are expensive to paint.
* A subclass will do the following:
* <ol>
* <li>Invoke <code>paint</code> when you want to paint the image,
* if you are implementing <code>Icon</code> you'll invoke this from
* <code>paintIcon</code>.
* The args argument is useful when additional state is needed.
* <li>Override <code>paintToImage</code> to render the image. The code that
* lives here is equivalent to what previously would go in
* <code>paintIcon</code>, for an <code>Icon</code>.
* </ol>
* The two ways to use this class are:
* <ol>
* <li>Invoke <code>paint</code> to draw the cached reprensentation at
* the specified location.
* <li>Invoke <code>getImage</code> to get the cached reprensentation and
* draw the image yourself. This is primarly useful when you are not
* using <code>VolatileImage</code>.
* </ol>
*
*
*/
public abstract class CachedPainter {
// CacheMap maps from class to ImageCache.
private static final Map<Object,ImageCache> cacheMap = new HashMap<>();
private static ImageCache getCache(Object key) {
synchronized(CachedPainter.class) {
ImageCache cache = cacheMap.get(key);
if (cache == null) {
cache = new ImageCache(1);
cacheMap.put(key, cache);
}
return cache;
}
}
/**
* Creates an instance of <code>CachedPainter</code> that will cache up
* to <code>cacheCount</code> images of this class.
*
* @param cacheCount Max number of images to cache
*/
public CachedPainter(int cacheCount) {
getCache(getClass()).setMaxCount(cacheCount);
}
/**
* Renders the cached image to the the passed in <code>Graphic</code>.
* If there is no cached image <code>paintToImage</code> will be invoked.
* <code>paintImage</code> is invoked to paint the cached image.
*
* @param c Component rendering to, this may be null.
* @param g Graphics to paint to
* @param x X-coordinate to render to
* @param y Y-coordinate to render to
* @param w Width to render in
* @param h Height to render in
* @param arg Variable arguments that will be passed to paintToImage
*/
public void paint(Component c, Graphics g, int x,
int y, int w, int h, Object... args) {
if (w <= 0 || h <= 0) {
return;
}
synchronized (CachedPainter.class) {
paint0(c, g, x, y, w, h, args);
}
}
private void paint0(Component c, Graphics g, int x,
int y, int w, int h, Object... args) {
Object key = getClass();
GraphicsConfiguration config = getGraphicsConfiguration(c);
ImageCache cache = getCache(key);
Image image = cache.getImage(key, config, w, h, args);
int attempts = 0;
do {
boolean draw = false;
if (image instanceof VolatileImage) {
// See if we need to recreate the image
switch (((VolatileImage)image).validate(config)) {
case VolatileImage.IMAGE_INCOMPATIBLE:
((VolatileImage)image).flush();
image = null;
break;
case VolatileImage.IMAGE_RESTORED:
draw = true;
break;
}
}
if (image == null) {
// Recreate the image
image = createImage(c, w, h, config, args);
cache.setImage(key, config, w, h, args, image);
draw = true;
}
if (draw) {
// Render to the Image
Graphics g2 = image.getGraphics();
paintToImage(c, image, g2, w, h, args);
g2.dispose();
}
// Render to the passed in Graphics
paintImage(c, g, x, y, w, h, image, args);
// If we did this 3 times and the contents are still lost
// assume we're painting to a VolatileImage that is bogus and
// give up. Presumably we'll be called again to paint.
} while ((image instanceof VolatileImage) &&
((VolatileImage)image).contentsLost() && ++attempts < 3);
}
/**
* Paints the representation to cache to the supplied Graphics.
*
* @param c Component painting to, may be null.
* @param image Image to paint to
* @param g Graphics to paint to, obtained from the passed in Image.
* @param w Width to paint to
* @param h Height to paint to
* @param args Arguments supplied to <code>paint</code>
*/
protected abstract void paintToImage(Component c, Image image, Graphics g,
int w, int h, Object[] args);
/**
* Paints the image to the specified location.
*
* @param c Component painting to
* @param g Graphics to paint to
* @param x X coordinate to paint to
* @param y Y coordinate to paint to
* @param w Width to paint to
* @param h Height to paint to
* @param image Image to paint
* @param args Arguments supplied to <code>paint</code>
*/
protected void paintImage(Component c, Graphics g,
int x, int y, int w, int h, Image image,
Object[] args) {
g.drawImage(image, x, y, null);
}
/**
* Creates the image to cache. This returns an opaque image, subclasses
* that require translucency or transparency will need to override this
* method.
*
* @param c Component painting to
* @param w Width of image to create
* @param h Height to image to create
* @param config GraphicsConfiguration that will be
* rendered to, this may be null.
* @param args Arguments passed to paint
*/
protected Image createImage(Component c, int w, int h,
GraphicsConfiguration config, Object[] args) {
if (config == null) {
return new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
}
return config.createCompatibleVolatileImage(w, h);
}
/**
* Clear the image cache
*/
protected void flush() {
synchronized(CachedPainter.class) {
getCache(getClass()).flush();
}
}
private GraphicsConfiguration getGraphicsConfiguration(Component c) {
if (c == null) {
return null;
}
return c.getGraphicsConfiguration();
}
}

View File

@@ -0,0 +1,259 @@
/*
* Copyright (c) 2005, 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 sun.swing;
import java.awt.Container;
import java.awt.Insets;
import javax.swing.*;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.border.Border;
import javax.swing.plaf.UIResource;
/**
* An implementation of <code>LayoutStyle</code> that returns 6 for related
* components, otherwise 12. This class also provides helper methods for
* subclasses.
*
*/
public class DefaultLayoutStyle extends LayoutStyle {
private static final DefaultLayoutStyle INSTANCE =
new DefaultLayoutStyle();
public static LayoutStyle getInstance() {
return INSTANCE;
}
@Override
public int getPreferredGap(JComponent component1, JComponent component2,
ComponentPlacement type, int position, Container parent) {
if (component1 == null || component2 == null || type == null) {
throw new NullPointerException();
}
checkPosition(position);
if (type == ComponentPlacement.INDENT &&
(position == SwingConstants.EAST ||
position == SwingConstants.WEST)) {
int indent = getIndent(component1, position);
if (indent > 0) {
return indent;
}
}
return (type == ComponentPlacement.UNRELATED) ? 12 : 6;
}
@Override
public int getContainerGap(JComponent component, int position,
Container parent) {
if (component == null) {
throw new NullPointerException();
}
checkPosition(position);
return 6;
}
/**
* Returns true if the classes identify a JLabel and a non-JLabel
* along the horizontal axis.
*/
protected boolean isLabelAndNonlabel(JComponent c1, JComponent c2,
int position) {
if (position == SwingConstants.EAST ||
position == SwingConstants.WEST) {
boolean c1Label = (c1 instanceof JLabel);
boolean c2Label = (c2 instanceof JLabel);
return ((c1Label || c2Label) && (c1Label != c2Label));
}
return false;
}
/**
* For some look and feels check boxs and radio buttons typically
* don't paint the border, yet they have padding for a border. Look
* and feel guidelines generally don't include this space. Use
* this method to subtract this space from the specified
* components.
*
* @param source First component
* @param target Second component
* @param position Position doing layout along.
* @param offset Ideal offset, not including border/margin
* @return offset - border/margin around the component.
*/
protected int getButtonGap(JComponent source, JComponent target,
int position, int offset) {
offset -= getButtonGap(source, position);
if (offset > 0) {
offset -= getButtonGap(target, flipDirection(position));
}
if (offset < 0) {
return 0;
}
return offset;
}
/**
* For some look and feels check boxs and radio buttons typically
* don't paint the border, yet they have padding for a border. Look
* and feel guidelines generally don't include this space. Use
* this method to subtract this space from the specified
* components.
*
* @param source Component
* @param position Position doing layout along.
* @param offset Ideal offset, not including border/margin
* @return offset - border/margin around the component.
*/
protected int getButtonGap(JComponent source, int position, int offset) {
offset -= getButtonGap(source, position);
return Math.max(offset, 0);
}
/**
* If <code>c</code> is a check box or radio button, and the border is
* not painted this returns the inset along the specified axis.
*/
public int getButtonGap(JComponent c, int position) {
String classID = c.getUIClassID();
if ((classID == "CheckBoxUI" || classID == "RadioButtonUI") &&
!((AbstractButton)c).isBorderPainted()) {
Border border = c.getBorder();
if (border instanceof UIResource) {
return getInset(c, position);
}
}
return 0;
}
private void checkPosition(int position) {
if (position != SwingConstants.NORTH &&
position != SwingConstants.SOUTH &&
position != SwingConstants.WEST &&
position != SwingConstants.EAST) {
throw new IllegalArgumentException();
}
}
protected int flipDirection(int position) {
switch(position) {
case SwingConstants.NORTH:
return SwingConstants.SOUTH;
case SwingConstants.SOUTH:
return SwingConstants.NORTH;
case SwingConstants.EAST:
return SwingConstants.WEST;
case SwingConstants.WEST:
return SwingConstants.EAST;
}
assert false;
return 0;
}
/**
* Returns the amount to indent the specified component if it's
* a JCheckBox or JRadioButton. If the component is not a JCheckBox or
* JRadioButton, 0 will be returned.
*/
protected int getIndent(JComponent c, int position) {
String classID = c.getUIClassID();
if (classID == "CheckBoxUI" || classID == "RadioButtonUI") {
AbstractButton button = (AbstractButton)c;
Insets insets = c.getInsets();
Icon icon = getIcon(button);
int gap = button.getIconTextGap();
if (isLeftAligned(button, position)) {
return insets.left + icon.getIconWidth() + gap;
} else if (isRightAligned(button, position)) {
return insets.right + icon.getIconWidth() + gap;
}
}
return 0;
}
private Icon getIcon(AbstractButton button) {
Icon icon = button.getIcon();
if (icon != null) {
return icon;
}
String key = null;
if (button instanceof JCheckBox) {
key = "CheckBox.icon";
} else if (button instanceof JRadioButton) {
key = "RadioButton.icon";
}
if (key != null) {
Object oIcon = UIManager.get(key);
if (oIcon instanceof Icon) {
return (Icon)oIcon;
}
}
return null;
}
private boolean isLeftAligned(AbstractButton button, int position) {
if (position == SwingConstants.WEST) {
boolean ltr = button.getComponentOrientation().isLeftToRight();
int hAlign = button.getHorizontalAlignment();
return ((ltr && (hAlign == SwingConstants.LEFT ||
hAlign == SwingConstants.LEADING)) ||
(!ltr && (hAlign == SwingConstants.TRAILING)));
}
return false;
}
private boolean isRightAligned(AbstractButton button, int position) {
if (position == SwingConstants.EAST) {
boolean ltr = button.getComponentOrientation().isLeftToRight();
int hAlign = button.getHorizontalAlignment();
return ((ltr && (hAlign == SwingConstants.RIGHT ||
hAlign == SwingConstants.TRAILING)) ||
(!ltr && (hAlign == SwingConstants.LEADING)));
}
return false;
}
private int getInset(JComponent c, int position) {
return getInset(c.getInsets(), position);
}
private int getInset(Insets insets, int position) {
if (insets == null) {
return 0;
}
switch(position) {
case SwingConstants.NORTH:
return insets.top;
case SwingConstants.SOUTH:
return insets.bottom;
case SwingConstants.EAST:
return insets.right;
case SwingConstants.WEST:
return insets.left;
}
assert false;
return 0;
}
}

View File

@@ -0,0 +1,217 @@
/*
* 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 sun.swing;
import java.awt.Color;
import java.awt.Insets;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.plaf.ComponentUI;
import sun.awt.AppContext;
/**
* DefaultLookup provides a way to customize the lookup done by the
* UIManager. The default implementation of DefaultLookup forwards
* the call to the UIManager.
* <p>
* <b>WARNING:</b> While this class is public, it should not be treated as
* public API and its API may change in incompatable ways between dot dot
* releases and even patch releases. You should not rely on this class even
* existing.
*
* @author Scott Violet
*/
public class DefaultLookup {
/**
* Key used to store DefaultLookup for AppContext.
*/
private static final Object DEFAULT_LOOKUP_KEY = new
StringBuffer("DefaultLookup");
/**
* Thread that last asked for a default.
*/
private static Thread currentDefaultThread;
/**
* DefaultLookup for last thread.
*/
private static DefaultLookup currentDefaultLookup;
/**
* If true, a custom DefaultLookup has been set.
*/
private static boolean isLookupSet;
/**
* Sets the DefaultLookup instance to use for the current
* <code>AppContext</code>. Null implies the UIManager should be
* used.
*/
public static void setDefaultLookup(DefaultLookup lookup) {
synchronized(DefaultLookup.class) {
if (!isLookupSet && lookup == null) {
// Null was passed in, and no one has invoked setDefaultLookup
// with a non-null value, we don't need to do anything.
return;
}
else if (lookup == null) {
// null was passed in, but someone has invoked setDefaultLookup
// with a non-null value, use an instance of DefautLookup
// which will fallback to UIManager.
lookup = new DefaultLookup();
}
isLookupSet = true;
AppContext.getAppContext().put(DEFAULT_LOOKUP_KEY, lookup);
currentDefaultThread = Thread.currentThread();
currentDefaultLookup = lookup;
}
}
public static Object get(JComponent c, ComponentUI ui, String key) {
boolean lookupSet;
synchronized(DefaultLookup.class) {
lookupSet = isLookupSet;
}
if (!lookupSet) {
// No one has set a valid DefaultLookup, use UIManager.
return UIManager.get(key, c.getLocale());
}
Thread thisThread = Thread.currentThread();
DefaultLookup lookup;
synchronized(DefaultLookup.class) {
// See if we've already cached the DefaultLookup for this thread,
// and use it if we have.
if (thisThread == currentDefaultThread) {
// It is cached, use it.
lookup = currentDefaultLookup;
}
else {
// Not cached, get the DefaultLookup to use from the AppContext
lookup = (DefaultLookup)AppContext.getAppContext().get(
DEFAULT_LOOKUP_KEY);
if (lookup == null) {
// Fallback to DefaultLookup, which will redirect to the
// UIManager.
lookup = new DefaultLookup();
AppContext.getAppContext().put(DEFAULT_LOOKUP_KEY, lookup);
}
// Cache the values to make the next lookup easier.
currentDefaultThread = thisThread;
currentDefaultLookup = lookup;
}
}
return lookup.getDefault(c, ui, key);
}
//
// The following are convenience method that all use getDefault.
//
public static int getInt(JComponent c, ComponentUI ui, String key,
int defaultValue) {
Object iValue = get(c, ui, key);
if (iValue == null || !(iValue instanceof Number)) {
return defaultValue;
}
return ((Number)iValue).intValue();
}
public static int getInt(JComponent c, ComponentUI ui, String key) {
return getInt(c, ui, key, -1);
}
public static Insets getInsets(JComponent c, ComponentUI ui, String key,
Insets defaultValue) {
Object iValue = get(c, ui, key);
if (iValue == null || !(iValue instanceof Insets)) {
return defaultValue;
}
return (Insets)iValue;
}
public static Insets getInsets(JComponent c, ComponentUI ui, String key) {
return getInsets(c, ui, key, null);
}
public static boolean getBoolean(JComponent c, ComponentUI ui, String key,
boolean defaultValue) {
Object iValue = get(c, ui, key);
if (iValue == null || !(iValue instanceof Boolean)) {
return defaultValue;
}
return ((Boolean)iValue).booleanValue();
}
public static boolean getBoolean(JComponent c, ComponentUI ui, String key) {
return getBoolean(c, ui, key, false);
}
public static Color getColor(JComponent c, ComponentUI ui, String key,
Color defaultValue) {
Object iValue = get(c, ui, key);
if (iValue == null || !(iValue instanceof Color)) {
return defaultValue;
}
return (Color)iValue;
}
public static Color getColor(JComponent c, ComponentUI ui, String key) {
return getColor(c, ui, key, null);
}
public static Icon getIcon(JComponent c, ComponentUI ui, String key,
Icon defaultValue) {
Object iValue = get(c, ui, key);
if (iValue == null || !(iValue instanceof Icon)) {
return defaultValue;
}
return (Icon)iValue;
}
public static Icon getIcon(JComponent c, ComponentUI ui, String key) {
return getIcon(c, ui, key, null);
}
public static Border getBorder(JComponent c, ComponentUI ui, String key,
Border defaultValue) {
Object iValue = get(c, ui, key);
if (iValue == null || !(iValue instanceof Border)) {
return defaultValue;
}
return (Border)iValue;
}
public static Border getBorder(JComponent c, ComponentUI ui, String key) {
return getBorder(c, ui, key, null);
}
public Object getDefault(JComponent c, ComponentUI ui, String key) {
// basic
return UIManager.get(key, c.getLocale());
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,165 @@
/*
* 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 sun.swing;
import java.awt.GraphicsConfiguration;
import java.awt.Image;
import java.lang.ref.SoftReference;
import java.util.Iterator;
import java.util.LinkedList;
/**
* Cache is used to cache an image based on a set of arguments.
*/
public class ImageCache {
// Maximum number of entries to cache
private int maxCount;
// The entries.
final private LinkedList<SoftReference<Entry>> entries;
public ImageCache(int maxCount) {
this.maxCount = maxCount;
entries = new LinkedList<SoftReference<Entry>>();
}
void setMaxCount(int maxCount) {
this.maxCount = maxCount;
}
public void flush() {
entries.clear();
}
private Entry getEntry(Object key, GraphicsConfiguration config,
int w, int h, Object[] args) {
Entry entry;
Iterator<SoftReference<Entry>> iter = entries.listIterator();
while (iter.hasNext()) {
SoftReference<Entry> ref = iter.next();
entry = ref.get();
if (entry == null) {
// SoftReference was invalidated, remove the entry
iter.remove();
}
else if (entry.equals(config, w, h, args)) {
// Put most recently used entries at the head
iter.remove();
entries.addFirst(ref);
return entry;
}
}
// Entry doesn't exist
entry = new Entry(config, w, h, args);
if (entries.size() >= maxCount) {
entries.removeLast();
}
entries.addFirst(new SoftReference<Entry>(entry));
return entry;
}
/**
* Returns the cached Image, or null, for the specified arguments.
*/
public Image getImage(Object key, GraphicsConfiguration config,
int w, int h, Object[] args) {
Entry entry = getEntry(key, config, w, h, args);
return entry.getImage();
}
/**
* Sets the cached image for the specified constraints.
*/
public void setImage(Object key, GraphicsConfiguration config,
int w, int h, Object[] args, Image image) {
Entry entry = getEntry(key, config, w, h, args);
entry.setImage(image);
}
/**
* Caches set of arguments and Image.
*/
private static class Entry {
final private GraphicsConfiguration config;
final private int w;
final private int h;
final private Object[] args;
private Image image;
Entry(GraphicsConfiguration config, int w, int h, Object[] args) {
this.config = config;
this.args = args;
this.w = w;
this.h = h;
}
public void setImage(Image image) {
this.image = image;
}
public Image getImage() {
return image;
}
public String toString() {
String value = super.toString() +
"[ graphicsConfig=" + config +
", image=" + image +
", w=" + w + ", h=" + h;
if (args != null) {
for (int counter = 0; counter < args.length; counter++) {
value += ", " + args[counter];
}
}
value += "]";
return value;
}
public boolean equals(GraphicsConfiguration config,
int w, int h, Object[] args) {
if (this.w == w && this.h == h &&
((this.config != null && this.config.equals(config)) ||
(this.config == null && config == null))) {
if (this.args == null && args == null) {
return true;
}
if (this.args != null && args != null &&
this.args.length == args.length) {
for (int counter = args.length - 1; counter >= 0;
counter--) {
Object a1 = this.args[counter];
Object a2 = args[counter];
if ((a1 == null && a2 != null) ||
(a1 != null && !a1.equals(a2))) {
return false;
}
}
return true;
}
}
return false;
}
}
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright (c) 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 sun.swing;
import javax.swing.ImageIcon;
import javax.swing.plaf.UIResource;
import java.awt.Image;
/**
* A subclass of <code>ImageIcon</code> that implements UIResource.
*
* @author Shannon Hickey
*
*/
public class ImageIconUIResource extends ImageIcon implements UIResource {
/**
* Calls the superclass constructor with the same parameter.
*
* @param imageData an array of pixels
* @see javax.swing.ImageIcon#ImageIcon(byte[])
*/
public ImageIconUIResource(byte[] imageData) {
super(imageData);
}
/**
* Calls the superclass constructor with the same parameter.
*
* @param image an image
* @see javax.swing.ImageIcon#ImageIcon(Image)
*/
public ImageIconUIResource(Image image) {
super(image);
}
}

View File

@@ -0,0 +1,516 @@
/*
* Copyright (c) 2013, 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 sun.swing;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Window;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragGestureRecognizer;
import java.awt.dnd.DragSource;
import java.awt.dnd.DropTarget;
import java.awt.dnd.InvalidDnDOperationException;
import java.awt.dnd.peer.DragSourceContextPeer;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.security.AccessController;
import javax.swing.JComponent;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.JRootPane;
import javax.swing.LayoutFocusTraversalPolicy;
import javax.swing.RepaintManager;
import javax.swing.RootPaneContainer;
import javax.swing.SwingUtilities;
import sun.awt.AWTAccessor;
import sun.awt.DisplayChangedListener;
import sun.awt.LightweightFrame;
import sun.awt.OverrideNativeWindowHandle;
import sun.security.action.GetPropertyAction;
import sun.swing.SwingUtilities2.RepaintListener;
/**
* The frame serves as a lightweight container which paints its content
* to an offscreen image and provides access to the image's data via the
* {@link LightweightContent} interface. Note, that it may not be shown
* as a standalone toplevel frame. Its purpose is to provide functionality
* for lightweight embedding.
*
* @author Artem Ananiev
* @author Anton Tarasov
*/
public final class JLightweightFrame extends LightweightFrame implements RootPaneContainer {
private final JRootPane rootPane = new JRootPane();
private LightweightContent content;
private Component component;
private JPanel contentPane;
private BufferedImage bbImage;
private volatile int scaleFactor = 1;
/**
* {@code copyBufferEnabled}, true by default, defines the following strategy.
* A duplicating (copy) buffer is created for the original pixel buffer.
* The copy buffer is synchronized with the original buffer every time the
* latter changes. {@code JLightweightFrame} passes the copy buffer array
* to the {@link LightweightContent#imageBufferReset} method. The code spot
* which synchronizes two buffers becomes the only critical section guarded
* by the lock (managed with the {@link LightweightContent#paintLock()},
* {@link LightweightContent#paintUnlock()} methods).
*/
private static boolean copyBufferEnabled;
private int[] copyBuffer;
private PropertyChangeListener layoutSizeListener;
private RepaintListener repaintListener;
static {
SwingAccessor.setJLightweightFrameAccessor(new SwingAccessor.JLightweightFrameAccessor() {
@Override
public void updateCursor(JLightweightFrame frame) {
frame.updateClientCursor();
}
});
copyBufferEnabled = "true".equals(AccessController.
doPrivileged(new GetPropertyAction("swing.jlf.copyBufferEnabled", "true")));
}
/**
* Constructs a new, initially invisible {@code JLightweightFrame}
* instance.
*/
public JLightweightFrame() {
super();
copyBufferEnabled = "true".equals(AccessController.
doPrivileged(new GetPropertyAction("swing.jlf.copyBufferEnabled", "true")));
add(rootPane, BorderLayout.CENTER);
setFocusTraversalPolicy(new LayoutFocusTraversalPolicy());
if (getGraphicsConfiguration().isTranslucencyCapable()) {
setBackground(new Color(0, 0, 0, 0));
}
layoutSizeListener = new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent e) {
Dimension d = (Dimension)e.getNewValue();
if ("preferredSize".equals(e.getPropertyName())) {
content.preferredSizeChanged(d.width, d.height);
} else if ("maximumSize".equals(e.getPropertyName())) {
content.maximumSizeChanged(d.width, d.height);
} else if ("minimumSize".equals(e.getPropertyName())) {
content.minimumSizeChanged(d.width, d.height);
}
}
};
repaintListener = (JComponent c, int x, int y, int w, int h) -> {
Window jlf = SwingUtilities.getWindowAncestor(c);
if (jlf != JLightweightFrame.this) {
return;
}
Point p = SwingUtilities.convertPoint(c, x, y, jlf);
Rectangle r = new Rectangle(p.x, p.y, w, h).intersection(
new Rectangle(0, 0, bbImage.getWidth() / scaleFactor,
bbImage.getHeight() / scaleFactor));
if (!r.isEmpty()) {
notifyImageUpdated(r.x, r.y, r.width, r.height);
}
};
SwingAccessor.getRepaintManagerAccessor().addRepaintListener(
RepaintManager.currentManager(this), repaintListener);
}
@Override
public void dispose() {
SwingAccessor.getRepaintManagerAccessor().removeRepaintListener(
RepaintManager.currentManager(this), repaintListener);
super.dispose();
}
/**
* Sets the {@link LightweightContent} instance for this frame.
* The {@code JComponent} object returned by the
* {@link LightweightContent#getComponent()} method is immediately
* added to the frame's content pane.
*
* @param content the {@link LightweightContent} instance
*/
public void setContent(final LightweightContent content) {
if (content == null) {
System.err.println("JLightweightFrame.setContent: content may not be null!");
return;
}
this.content = content;
this.component = content.getComponent();
Dimension d = this.component.getPreferredSize();
content.preferredSizeChanged(d.width, d.height);
d = this.component.getMaximumSize();
content.maximumSizeChanged(d.width, d.height);
d = this.component.getMinimumSize();
content.minimumSizeChanged(d.width, d.height);
initInterior();
}
@Override
public Graphics getGraphics() {
if (bbImage == null) return null;
Graphics2D g = bbImage.createGraphics();
g.setBackground(getBackground());
g.setColor(getForeground());
g.setFont(getFont());
g.scale(scaleFactor, scaleFactor);
return g;
}
/**
* {@inheritDoc}
*
* @see LightweightContent#focusGrabbed()
*/
@Override
public void grabFocus() {
if (content != null) content.focusGrabbed();
}
/**
* {@inheritDoc}
*
* @see LightweightContent#focusUngrabbed()
*/
@Override
public void ungrabFocus() {
if (content != null) content.focusUngrabbed();
}
@Override
public int getScaleFactor() {
return scaleFactor;
}
@Override
public void notifyDisplayChanged(final int scaleFactor) {
if (scaleFactor != this.scaleFactor) {
if (!copyBufferEnabled) content.paintLock();
try {
if (bbImage != null) {
resizeBuffer(getWidth(), getHeight(), scaleFactor);
}
} finally {
if (!copyBufferEnabled) content.paintUnlock();
}
this.scaleFactor = scaleFactor;
}
if (getPeer() instanceof DisplayChangedListener) {
((DisplayChangedListener)getPeer()).displayChanged();
}
repaint();
}
@Override
public void addNotify() {
super.addNotify();
if (getPeer() instanceof DisplayChangedListener) {
((DisplayChangedListener)getPeer()).displayChanged();
}
}
private void syncCopyBuffer(boolean reset, int x, int y, int w, int h, int scale) {
content.paintLock();
try {
int[] srcBuffer = ((DataBufferInt)bbImage.getRaster().getDataBuffer()).getData();
if (reset) {
copyBuffer = new int[srcBuffer.length];
}
int linestride = bbImage.getWidth();
x *= scale;
y *= scale;
w *= scale;
h *= scale;
for (int i=0; i<h; i++) {
int from = (y + i) * linestride + x;
System.arraycopy(srcBuffer, from, copyBuffer, from, w);
}
} finally {
content.paintUnlock();
}
}
private void notifyImageUpdated(int x, int y, int width, int height) {
if (copyBufferEnabled) {
syncCopyBuffer(false, x, y, width, height, scaleFactor);
}
content.imageUpdated(x, y, width, height);
}
private void initInterior() {
contentPane = new JPanel() {
@Override
public void paint(Graphics g) {
if (!copyBufferEnabled) {
content.paintLock();
}
try {
super.paint(g);
final Rectangle clip = g.getClipBounds() != null ?
g.getClipBounds() :
new Rectangle(0, 0, contentPane.getWidth(), contentPane.getHeight());
clip.x = Math.max(0, clip.x);
clip.y = Math.max(0, clip.y);
clip.width = Math.min(contentPane.getWidth(), clip.width);
clip.height = Math.min(contentPane.getHeight(), clip.height);
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
Rectangle c = contentPane.getBounds().intersection(clip);
notifyImageUpdated(c.x, c.y, c.width, c.height);
}
});
} finally {
if (!copyBufferEnabled) {
content.paintUnlock();
}
}
}
@Override
protected boolean isPaintingOrigin() {
return true;
}
};
contentPane.setLayout(new BorderLayout());
contentPane.add(component);
if ("true".equals(AccessController.
doPrivileged(new GetPropertyAction("swing.jlf.contentPaneTransparent", "false"))))
{
contentPane.setOpaque(false);
}
setContentPane(contentPane);
contentPane.addContainerListener(new ContainerListener() {
@Override
public void componentAdded(ContainerEvent e) {
Component c = JLightweightFrame.this.component;
if (e.getChild() == c) {
c.addPropertyChangeListener("preferredSize", layoutSizeListener);
c.addPropertyChangeListener("maximumSize", layoutSizeListener);
c.addPropertyChangeListener("minimumSize", layoutSizeListener);
}
}
@Override
public void componentRemoved(ContainerEvent e) {
Component c = JLightweightFrame.this.component;
if (e.getChild() == c) {
c.removePropertyChangeListener(layoutSizeListener);
}
}
});
}
@SuppressWarnings("deprecation")
@Override public void reshape(int x, int y, int width, int height) {
super.reshape(x, y, width, height);
if (width == 0 || height == 0) {
return;
}
if (!copyBufferEnabled) {
content.paintLock();
}
try {
boolean createBB = (bbImage == null);
int newW = width;
int newH = height;
if (bbImage != null) {
int imgWidth = bbImage.getWidth() / scaleFactor;
int imgHeight = bbImage.getHeight() / scaleFactor;
if (width != imgWidth || height != imgHeight) {
createBB = true;
if (bbImage != null) {
int oldW = imgWidth;
int oldH = imgHeight;
if ((oldW >= newW) && (oldH >= newH)) {
createBB = false;
} else {
if (oldW >= newW) {
newW = oldW;
} else {
newW = Math.max((int)(oldW * 1.2), width);
}
if (oldH >= newH) {
newH = oldH;
} else {
newH = Math.max((int)(oldH * 1.2), height);
}
}
}
}
}
if (createBB) {
resizeBuffer(newW, newH, scaleFactor);
return;
}
content.imageReshaped(0, 0, width, height);
} finally {
if (!copyBufferEnabled) {
content.paintUnlock();
}
}
}
private void resizeBuffer(int width, int height, int newScaleFactor) {
bbImage = new BufferedImage(width*newScaleFactor,height*newScaleFactor,
BufferedImage.TYPE_INT_ARGB_PRE);
int[] pixels= ((DataBufferInt)bbImage.getRaster().getDataBuffer()).getData();
if (copyBufferEnabled) {
syncCopyBuffer(true, 0, 0, width, height, newScaleFactor);
pixels = copyBuffer;
}
content.imageBufferReset(pixels, 0, 0, width, height,
width * newScaleFactor, newScaleFactor);
}
@Override
public JRootPane getRootPane() {
return rootPane;
}
@Override
public void setContentPane(Container contentPane) {
getRootPane().setContentPane(contentPane);
}
@Override
public Container getContentPane() {
return getRootPane().getContentPane();
}
@Override
public void setLayeredPane(JLayeredPane layeredPane) {
getRootPane().setLayeredPane(layeredPane);
}
@Override
public JLayeredPane getLayeredPane() {
return getRootPane().getLayeredPane();
}
@Override
public void setGlassPane(Component glassPane) {
getRootPane().setGlassPane(glassPane);
}
@Override
public Component getGlassPane() {
return getRootPane().getGlassPane();
}
/*
* Notifies client toolkit that it should change a cursor.
*
* Called from the peer via SwingAccessor, because the
* Component.updateCursorImmediately method is final
* and could not be overridden.
*/
private void updateClientCursor() {
Point p = MouseInfo.getPointerInfo().getLocation();
SwingUtilities.convertPointFromScreen(p, this);
Component target = SwingUtilities.getDeepestComponentAt(this, p.x, p.y);
if (target != null) {
content.setCursor(target.getCursor());
}
}
//Called by reflection by SwingNode
public void overrideNativeWindowHandle(long handle, Runnable closeWindow) {
final Object peer = AWTAccessor.getComponentAccessor().getPeer(this);
if (peer instanceof OverrideNativeWindowHandle) {
((OverrideNativeWindowHandle) peer).overrideWindowHandle(handle);
}
if (closeWindow != null) {
closeWindow.run();
}
}
public <T extends DragGestureRecognizer> T createDragGestureRecognizer(
Class<T> abstractRecognizerClass,
DragSource ds, Component c, int srcActions,
DragGestureListener dgl)
{
return content == null ? null : content.createDragGestureRecognizer(
abstractRecognizerClass, ds, c, srcActions, dgl);
}
public DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent dge) throws InvalidDnDOperationException {
return content == null ? null : content.createDragSourceContextPeer(dge);
}
public void addDropTarget(DropTarget dt) {
if (content == null) return;
content.addDropTarget(dt);
}
public void removeDropTarget(DropTarget dt) {
if (content == null) return;
content.removeDropTarget(dt);
}
}

View File

@@ -0,0 +1,249 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.swing;
import javax.swing.JComponent;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragGestureRecognizer;
import java.awt.dnd.DragSource;
import java.awt.dnd.DropTarget;
import java.awt.dnd.InvalidDnDOperationException;
import java.awt.dnd.peer.DragSourceContextPeer;
/**
* The interface by means of which the {@link JLightweightFrame} class
* communicates to its client application.
* <p>
* The client application implements this interface so it can response
* to requests and process notifications from {@code JLightweightFrame}.
* An implementation of this interface is associated with a {@code
* JLightweightFrame} instance via the {@link JLightweightFrame#setContent}
* method.
*
* A hierarchy of components contained in the {@code JComponent} instance
* returned by the {@link #getComponent} method should not contain any
* heavyweight components, otherwise {@code JLightweightFrame} may fail
* to paint it.
*
* @author Artem Ananiev
* @author Anton Tarasov
* @author Jim Graham
*/
public interface LightweightContent {
/**
* The client application overrides this method to return the {@code
* JComponent} instance which the {@code JLightweightFrame} container
* will paint as its lightweight content. A hierarchy of components
* contained in this component should not contain any heavyweight objects.
*
* @return the component to paint
*/
public JComponent getComponent();
/**
* {@code JLightweightFrame} calls this method to notify the client
* application that it acquires the paint lock. The client application
* should implement the locking mechanism in order to synchronize access
* to the content image data, shared between {@code JLightweightFrame}
* and the client application.
*
* @see #paintUnlock
*/
public void paintLock();
/**
* {@code JLightweightFrame} calls this method to notify the client
* application that it releases the paint lock. The client application
* should implement the locking mechanism in order to synchronize access
* to the content image data, shared between {@code JLightweightFrame}
* and the client application.
*
* @see #paintLock
*/
public void paintUnlock();
/**
* {@code JLightweightFrame} calls this method to notify the client
* application that a new data buffer has been set as a content pixel
* buffer. Typically this occurs when a buffer of a larger size is
* created in response to a content resize event.
* <p>
* The method reports a reference to the pixel data buffer, the content
* image bounds within the buffer and the line stride of the buffer.
* These values have the following correlation.
* The {@code width} and {@code height} matches the layout size of the content
* (the component returned from the {@link #getComponent} method). The
* {@code x} and {@code y} is the origin of the content, {@code (0, 0)}
* in the layout coordinate space of the content, appearing at
* {@code data[y * scale * linestride + x * scale]} in the buffer.
* A pixel with indices {@code (i, j)}, where {@code (0 <= i < width)} and
* {@code (0 <= j < height)}, in the layout coordinate space of the content
* is represented by a {@code scale^2} square of pixels in the physical
* coordinate space of the buffer. The top-left corner of the square has the
* following physical coordinate in the buffer:
* {@code data[(y + j) * scale * linestride + (x + i) * scale]}.
*
* @param data the content pixel data buffer of INT_ARGB_PRE type
* @param x the logical x coordinate of the image
* @param y the logical y coordinate of the image
* @param width the logical width of the image
* @param height the logical height of the image
* @param linestride the line stride of the pixel buffer
* @param scale the scale factor of the pixel buffer
*/
default public void imageBufferReset(int[] data,
int x, int y,
int width, int height,
int linestride,
int scale)
{
imageBufferReset(data, x, y, width, height, linestride);
}
/**
* The default implementation for #imageBufferReset uses a hard-coded value
* of 1 for the scale factor. Both the old and the new methods provide
* default implementations in order to allow a client application to run
* with any JDK version without breaking backward compatibility.
*/
default public void imageBufferReset(int[] data,
int x, int y,
int width, int height,
int linestride)
{
imageBufferReset(data, x, y, width, height, linestride, 1);
}
/**
* {@code JLightweightFrame} calls this method to notify the client
* application that the content image bounds have been changed within the
* image's pixel buffer.
*
* @param x the x coordinate of the image
* @param y the y coordinate of the image
* @param width the width of the image
* @param height the height of the image
*
* @see #imageBufferReset
*/
public void imageReshaped(int x, int y, int width, int height);
/**
* {@code JLightweightFrame} calls this method to notify the client
* application that a part of the content image, or the whole image has
* been updated. The method reports bounds of the rectangular dirty region.
* The {@code dirtyX} and {@code dirtyY} is the origin of the dirty
* rectangle, which is relative to the origin of the content, appearing
* at {@code data[(y + dirtyY] * linestride + (x + dirtyX)]} in the pixel
* buffer (see {@link #imageBufferReset}). All indices
* {@code data[(y + dirtyY + j) * linestride + (x + dirtyX + i)]} where
* {@code (0 <= i < dirtyWidth)} and {@code (0 <= j < dirtyHeight)}
* will represent valid pixel data, {@code (i, j)} in the coordinate space
* of the dirty rectangle.
*
* @param dirtyX the x coordinate of the dirty rectangle,
* relative to the image origin
* @param dirtyY the y coordinate of the dirty rectangle,
* relative to the image origin
* @param dirtyWidth the width of the dirty rectangle
* @param dirtyHeight the height of the dirty rectangle
*
* @see #imageBufferReset
* @see #imageReshaped
*/
public void imageUpdated(int dirtyX, int dirtyY,
int dirtyWidth, int dirtyHeight);
/**
* {@code JLightweightFrame} calls this method to notify the client
* application that the frame has grabbed focus.
*/
public void focusGrabbed();
/**
* {@code JLightweightFrame} calls this method to notify the client
* application that the frame has ungrabbed focus.
*/
public void focusUngrabbed();
/**
* {@code JLightweightFrame} calls this method to notify the client
* application that the content preferred size has changed.
*/
public void preferredSizeChanged(int width, int height);
/**
* {@code JLightweightFrame} calls this method to notify the client
* application that the content maximum size has changed.
*/
public void maximumSizeChanged(int width, int height);
/**
* {@code JLightweightFrame} calls this method to notify the client
* application that the content minimum size has changed.
*/
public void minimumSizeChanged(int width, int height);
/**
* {@code JLightweightFrame} calls this method to notify the client
* application that in needs to set a cursor
* @param cursor a cursor to set
*/
default public void setCursor(Cursor cursor) { }
/**
* Create a drag gesture recognizer for the lightweight frame.
*/
default public <T extends DragGestureRecognizer> T createDragGestureRecognizer(
Class<T> abstractRecognizerClass,
DragSource ds, Component c, int srcActions,
DragGestureListener dgl)
{
return null;
}
/**
* Create a drag source context peer for the lightweight frame.
*/
default public DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent dge) throws InvalidDnDOperationException
{
return null;
}
/**
* Adds a drop target to the lightweight frame.
*/
default public void addDropTarget(DropTarget dt) {}
/**
* Removes a drop target from the lightweight frame.
*/
default public void removeDropTarget(DropTarget dt) {}
}

View File

@@ -0,0 +1,38 @@
/*
* 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 sun.swing;
import javax.swing.Icon;
import javax.swing.JMenuItem;
/**
*
* @author Igor Kushnirskiy
*/
public interface MenuItemCheckIconFactory {
Icon getIcon(JMenuItem component);
boolean isCompatible(Object icon, String prefix);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,91 @@
/*
* Copyright (c) 2004, 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 sun.swing;
import java.awt.Color;
import javax.swing.plaf.ColorUIResource;
/**
* A subclass of ColorUIResource that wraps an alternate color
* for use during printing. Useful to replace color values that
* may look poor in printed output.
*
* @author Shannon Hickey
*
*/
public class PrintColorUIResource extends ColorUIResource {
/** The color to use during printing */
private Color printColor;
/**
* Construct an instance for the given RGB value and
* alternate color to use during printing.
*
* @param rgb the color rgb value
* @param printColor the alternate color for printing
*/
public PrintColorUIResource(int rgb, Color printColor) {
super(rgb);
this.printColor = printColor;
}
/**
* Return the color to use during printing. If no alternate
* color was specified on construction, this method will
* return <code>this</code>.
*
* @return the color to use during printing
*/
public Color getPrintColor() {
return ((printColor != null) ? printColor : this);
}
/**
* Replaces this object with a plain {@code ColorUIResource} during
* serialization. Since {@code PrintColorUIResource} resides in the
* sun.swing package, access can be disallowed to it by a security
* manager. When access is disallowed, deserialization of any object
* with reference to a {@code PrintColorUIResource} fails.
* <p>
* Since {@code PrintColorUIResource) is used only by Swing's look
* and feels, and we know that UI supplied colors are replaced after
* deserialization when the UI is re-installed, the only important
* aspect of the {@code PrintColorUIResource} that needs to be
* persisted is the fact that it is a {@code ColorUIResource}. As
* such, we can avoid the problem outlined above by replacing
* the problematic {@code PrintColorUIResource} with a plain
* {@code ColorUIResource}.
* <p>
* Note: As a result of this method, it is not possible to write
* a {@code PrintColorUIResource} to a stream and then read
* back a {@code PrintColorUIResource}. This is acceptable since we
* don't have a requirement for that in Swing.
*/
private Object writeReplace() {
return new ColorUIResource(this);
}
}

View File

@@ -0,0 +1,318 @@
/*
* 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 sun.swing;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.text.MessageFormat;
import java.util.concurrent.atomic.AtomicBoolean;
import java.lang.reflect.InvocationTargetException;
/**
* The {@code PrintingStatus} provides a dialog that displays progress
* of the printing job and provides a way to abort it
* <p/>
* Methods of these class are thread safe, although most Swing methods
* are not. Please see
* <A HREF="https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
* in Swing</A> for more information.
*
* @author Alexander Potochkin
* @since 1.6
*/
public class PrintingStatus {
private final PrinterJob job;
private final Component parent;
private JDialog abortDialog;
private JButton abortButton;
private JLabel statusLabel;
private MessageFormat statusFormat;
private final AtomicBoolean isAborted = new AtomicBoolean(false);
// the action that will abort printing
private final Action abortAction = new AbstractAction() {
public void actionPerformed(ActionEvent ae) {
if (!isAborted.get()) {
isAborted.set(true);
// update the status abortDialog to indicate aborting
abortButton.setEnabled(false);
abortDialog.setTitle(
UIManager.getString("PrintingDialog.titleAbortingText"));
statusLabel.setText(
UIManager.getString("PrintingDialog.contentAbortingText"));
// cancel the PrinterJob
job.cancel();
}
}
};
private final WindowAdapter closeListener = new WindowAdapter() {
public void windowClosing(WindowEvent we) {
abortAction.actionPerformed(null);
}
};
/**
* Creates PrintingStatus instance
*
* @param parent a <code>Component</code> object to be used
* as parent component for PrintingStatus dialog
* @param job a <code>PrinterJob</code> object to be cancelled
* using this <code>PrintingStatus</code> dialog
* @return a <code>PrintingStatus</code> object
*/
public static PrintingStatus
createPrintingStatus(Component parent, PrinterJob job) {
return new PrintingStatus(parent, job);
}
protected PrintingStatus(Component parent, PrinterJob job) {
this.job = job;
this.parent = parent;
}
private void init() {
// prepare the status JOptionPane
String progressTitle =
UIManager.getString("PrintingDialog.titleProgressText");
String dialogInitialContent =
UIManager.getString("PrintingDialog.contentInitialText");
// this one's a MessageFormat since it must include the page
// number in its text
statusFormat = new MessageFormat(
UIManager.getString("PrintingDialog.contentProgressText"));
String abortText =
UIManager.getString("PrintingDialog.abortButtonText");
String abortTooltip =
UIManager.getString("PrintingDialog.abortButtonToolTipText");
int abortMnemonic =
getInt("PrintingDialog.abortButtonMnemonic", -1);
int abortMnemonicIndex =
getInt("PrintingDialog.abortButtonDisplayedMnemonicIndex", -1);
abortButton = new JButton(abortText);
abortButton.addActionListener(abortAction);
abortButton.setToolTipText(abortTooltip);
if (abortMnemonic != -1) {
abortButton.setMnemonic(abortMnemonic);
}
if (abortMnemonicIndex != -1) {
abortButton.setDisplayedMnemonicIndex(abortMnemonicIndex);
}
statusLabel = new JLabel(dialogInitialContent);
JOptionPane abortPane = new JOptionPane(statusLabel,
JOptionPane.INFORMATION_MESSAGE,
JOptionPane.DEFAULT_OPTION,
null, new Object[]{abortButton},
abortButton);
abortPane.getActionMap().put("close", abortAction);
// The dialog should be centered over the viewport if the table is in one
if (parent != null && parent.getParent() instanceof JViewport) {
abortDialog =
abortPane.createDialog(parent.getParent(), progressTitle);
} else {
abortDialog = abortPane.createDialog(parent, progressTitle);
}
// clicking the X button should not hide the dialog
abortDialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
abortDialog.addWindowListener(closeListener);
}
/**
* Shows PrintingStatus dialog.
* if dialog is modal this method returns only
* after <code>dispose()</code> was called otherwise returns immediately
*
* @param isModal <code>true</code> this dialog should be modal;
* <code>false</code> otherwise.
* @see #dispose
*/
public void showModal(final boolean isModal) {
if (SwingUtilities.isEventDispatchThread()) {
showModalOnEDT(isModal);
} else {
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
showModalOnEDT(isModal);
}
});
} catch(InterruptedException e) {
throw new RuntimeException(e);
} catch(InvocationTargetException e) {
Throwable cause = e.getCause();
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof Error) {
throw (Error) cause;
} else {
throw new RuntimeException(cause);
}
}
}
}
/**
* The EDT part of the showModal method.
*
* This method is to be called on the EDT only.
*/
private void showModalOnEDT(boolean isModal) {
assert SwingUtilities.isEventDispatchThread();
init();
abortDialog.setModal(isModal);
abortDialog.setVisible(true);
}
/**
* Disposes modal PrintingStatus dialog
*
* @see #showModal(boolean)
*/
public void dispose() {
if (SwingUtilities.isEventDispatchThread()) {
disposeOnEDT();
} else {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
disposeOnEDT();
}
});
}
}
/**
* The EDT part of the dispose method.
*
* This method is to be called on the EDT only.
*/
private void disposeOnEDT() {
assert SwingUtilities.isEventDispatchThread();
if (abortDialog != null) {
abortDialog.removeWindowListener(closeListener);
abortDialog.dispose();
abortDialog = null;
}
}
/**
* Returns whether the printng was aborted using this PrintingStatus
*
* @return whether the printng was aborted using this PrintingStatus
*/
public boolean isAborted() {
return isAborted.get();
}
/**
* Returns printable which is used to track the current page being
* printed in this PrintingStatus
*
* @param printable to be used to create notification printable
* @return printable which is used to track the current page being
* printed in this PrintingStatus
* @throws NullPointerException if <code>printable</code> is <code>null</code>
*/
public Printable createNotificationPrintable(Printable printable) {
return new NotificationPrintable(printable);
}
private class NotificationPrintable implements Printable {
private final Printable printDelegatee;
public NotificationPrintable(Printable delegatee) {
if (delegatee == null) {
throw new NullPointerException("Printable is null");
}
this.printDelegatee = delegatee;
}
public int print(final Graphics graphics,
final PageFormat pageFormat, final int pageIndex)
throws PrinterException {
final int retVal =
printDelegatee.print(graphics, pageFormat, pageIndex);
if (retVal != NO_SUCH_PAGE && !isAborted()) {
if (SwingUtilities.isEventDispatchThread()) {
updateStatusOnEDT(pageIndex);
} else {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
updateStatusOnEDT(pageIndex);
}
});
}
}
return retVal;
}
/**
* The EDT part of the print method.
*
* This method is to be called on the EDT only.
*/
private void updateStatusOnEDT(int pageIndex) {
assert SwingUtilities.isEventDispatchThread();
Object[] pageNumber = new Object[]{
new Integer(pageIndex + 1)};
statusLabel.setText(statusFormat.format(pageNumber));
}
}
/**
* Duplicated from UIManager to make it visible
*/
static int getInt(Object key, int defaultValue) {
Object value = UIManager.get(key);
if (value instanceof Integer) {
return ((Integer) value).intValue();
}
if (value instanceof String) {
try {
return Integer.parseInt((String) value);
} catch(NumberFormatException nfe) {
}
}
return defaultValue;
}
}

View File

@@ -0,0 +1,44 @@
/*
* 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 sun.swing;
/**
* An implementation of {@code UIClientPropertyKey} that wraps a {@code String}.
*
* @author Shannon Hickey
*/
public class StringUIClientPropertyKey implements UIClientPropertyKey {
private final String key;
public StringUIClientPropertyKey(String key) {
this.key = key;
}
public String toString() {
return key;
}
}

View File

@@ -0,0 +1,174 @@
/*
* Copyright (c) 2009, 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 sun.swing;
import sun.misc.Unsafe;
import java.awt.Point;
import javax.swing.RepaintManager;
import javax.swing.text.JTextComponent;
import javax.swing.TransferHandler;
/**
* The SwingAccessor utility class.
* The main purpose of this class is to enable accessing
* private and package-private fields of classes from
* different classes/packages. See sun.misc.SharedSecretes
* for another example.
*/
public final class SwingAccessor {
private static final Unsafe unsafe = Unsafe.getUnsafe();
/**
* We don't need any objects of this class.
* It's rather a collection of static methods
* and interfaces.
*/
private SwingAccessor() {
}
/**
* An accessor for the JTextComponent class.
* Note that we intentionally introduce the JTextComponentAccessor,
* and not the JComponentAccessor because the needed methods
* aren't override methods.
*/
public interface JTextComponentAccessor {
/**
* Calculates a custom drop location for the text component,
* representing where a drop at the given point should insert data.
*/
TransferHandler.DropLocation dropLocationForPoint(JTextComponent textComp, Point p);
/**
* Called to set or clear the drop location during a DnD operation.
*/
Object setDropLocation(JTextComponent textComp, TransferHandler.DropLocation location,
Object state, boolean forDrop);
}
/**
* An accessor for the JLightweightFrame class.
*/
public interface JLightweightFrameAccessor {
/**
* Notifies the JLightweight frame that it needs to update a cursor
*/
void updateCursor(JLightweightFrame frame);
}
/**
* An accessor for the RepaintManager class.
*/
public interface RepaintManagerAccessor {
void addRepaintListener(RepaintManager rm, SwingUtilities2.RepaintListener l);
void removeRepaintListener(RepaintManager rm, SwingUtilities2.RepaintListener l);
}
/**
* The javax.swing.text.JTextComponent class accessor object.
*/
private static JTextComponentAccessor jtextComponentAccessor;
/**
* Set an accessor object for the javax.swing.text.JTextComponent class.
*/
public static void setJTextComponentAccessor(JTextComponentAccessor jtca) {
jtextComponentAccessor = jtca;
}
/**
* Retrieve the accessor object for the javax.swing.text.JTextComponent class.
*/
public static JTextComponentAccessor getJTextComponentAccessor() {
if (jtextComponentAccessor == null) {
unsafe.ensureClassInitialized(JTextComponent.class);
}
return jtextComponentAccessor;
}
/**
* The JLightweightFrame class accessor object
*/
private static JLightweightFrameAccessor jLightweightFrameAccessor;
/**
* Set an accessor object for the JLightweightFrame class.
*/
public static void setJLightweightFrameAccessor(JLightweightFrameAccessor accessor) {
jLightweightFrameAccessor = accessor;
}
/**
* Retrieve the accessor object for the JLightweightFrame class
*/
public static JLightweightFrameAccessor getJLightweightFrameAccessor() {
if (jLightweightFrameAccessor == null) {
unsafe.ensureClassInitialized(JLightweightFrame.class);
}
return jLightweightFrameAccessor;
}
/**
* The RepaintManager class accessor object.
*/
private static RepaintManagerAccessor repaintManagerAccessor;
/**
* Set an accessor object for the RepaintManager class.
*/
public static void setRepaintManagerAccessor(RepaintManagerAccessor accessor) {
repaintManagerAccessor = accessor;
}
/**
* Retrieve the accessor object for the RepaintManager class.
*/
public static RepaintManagerAccessor getRepaintManagerAccessor() {
if (repaintManagerAccessor == null) {
unsafe.ensureClassInitialized(RepaintManager.class);
}
return repaintManagerAccessor;
}
private static ThreadLocal<Boolean> tlObj = new ThreadLocal<Boolean>();
public static Boolean getAllowHTMLObject() {
Boolean b = tlObj.get();
if (b == null) {
return Boolean.TRUE;
} else {
return b;
}
}
public static void setAllowHTMLObject(Boolean val) {
tlObj.set(val);
}
}

View File

@@ -0,0 +1,128 @@
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.swing;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.AccessibleObject;
import java.security.AccessController;
import java.security.PrivilegedAction;
import javax.swing.UIDefaults;
import sun.reflect.misc.ReflectUtil;
/**
* SwingLazyValue is a copy of ProxyLazyValue that does not snapshot the
* AccessControlContext or use a doPrivileged to resolve the class name.
* It's intented for use in places in Swing where we need ProxyLazyValue, this
* should never be used in a place where the developer could supply the
* arguments.
*
*/
public class SwingLazyValue implements UIDefaults.LazyValue {
private String className;
private String methodName;
private Object[] args;
public SwingLazyValue(String c) {
this(c, (String)null);
}
public SwingLazyValue(String c, String m) {
this(c, m, null);
}
public SwingLazyValue(String c, Object[] o) {
this(c, null, o);
}
public SwingLazyValue(String c, String m, Object[] o) {
className = c;
methodName = m;
if (o != null) {
args = o.clone();
}
}
public Object createValue(final UIDefaults table) {
try {
ReflectUtil.checkPackageAccess(className);
Class<?> c = Class.forName(className, true, null);
if (methodName != null) {
Class[] types = getClassArray(args);
Method m = c.getMethod(methodName, types);
makeAccessible(m);
return m.invoke(c, args);
} else {
Class[] types = getClassArray(args);
Constructor constructor = c.getConstructor(types);
makeAccessible(constructor);
return constructor.newInstance(args);
}
} catch (Exception e) {
// Ideally we would throw an exception, unfortunately
// often times there are errors as an initial look and
// feel is loaded before one can be switched. Perhaps a
// flag should be added for debugging, so that if true
// the exception would be thrown.
}
return null;
}
private void makeAccessible(final AccessibleObject object) {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
object.setAccessible(true);
return null;
}
});
}
private Class[] getClassArray(Object[] args) {
Class[] types = null;
if (args!=null) {
types = new Class[args.length];
for (int i = 0; i< args.length; i++) {
/* PENDING(ges): At present only the primitive types
used are handled correctly; this should eventually
handle all primitive types */
if (args[i] instanceof java.lang.Integer) {
types[i]=Integer.TYPE;
} else if (args[i] instanceof java.lang.Boolean) {
types[i]=Boolean.TYPE;
} else if (args[i] instanceof javax.swing.plaf.ColorUIResource) {
/* PENDING(ges) Currently the Reflection APIs do not
search superclasses of parameters supplied for
constructor/method lookup. Since we only have
one case where this is needed, we substitute
directly instead of adding a massive amount
of mechanism for this. Eventually this will
probably need to handle the general case as well.
*/
types[i]=java.awt.Color.class;
} else {
types[i]=args[i].getClass();
}
}
}
return types;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,111 @@
/*
* 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 sun.swing;
import java.beans.PropertyChangeListener;
import javax.swing.Action;
/**
* UIAction is the basis of all of basic's action classes that are used in
* an ActionMap. Subclasses need to override <code>actionPerformed</code>.
* <p>
* A typical subclass will look like:
* <pre>
* private static class Actions extends UIAction {
* Actions(String name) {
* super(name);
* }
*
* public void actionPerformed(ActionEvent ae) {
* if (getName() == "selectAll") {
* selectAll();
* }
* else if (getName() == "cancelEditing") {
* cancelEditing();
* }
* }
* }
* </pre>
* <p>
* Subclasses that wish to conditionalize the enabled state should override
* <code>isEnabled(Component)</code>, and be aware that the passed in
* <code>Component</code> may be null.
*
* @see com.sun.java.swing.ExtendedAction
* @see javax.swing.Action
* @author Scott Violet
*/
public abstract class UIAction implements Action {
private String name;
public UIAction(String name) {
this.name = name;
}
public final String getName() {
return name;
}
public Object getValue(String key) {
if (key == NAME) {
return name;
}
return null;
}
// UIAction is not mutable, this does nothing.
public void putValue(String key, Object value) {
}
// UIAction is not mutable, this does nothing.
public void setEnabled(boolean b) {
}
/**
* Cover method for <code>isEnabled(null)</code>.
*/
public final boolean isEnabled() {
return isEnabled(null);
}
/**
* Subclasses that need to conditionalize the enabled state should
* override this. Be aware that <code>sender</code> may be null.
*
* @param sender Widget enabled state is being asked for, may be null.
*/
public boolean isEnabled(Object sender) {
return true;
}
// UIAction is not mutable, this does nothing.
public void addPropertyChangeListener(PropertyChangeListener listener) {
}
// UIAction is not mutable, this does nothing.
public void removePropertyChangeListener(PropertyChangeListener listener) {
}
}

View File

@@ -0,0 +1,40 @@
/*
* 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 sun.swing;
/**
* This interface is used only for tagging keys for client properties
* for {@code JComponent} set by UI which needs to be cleared on L&F
* change and serialization.
*
* All such keys are removed from client properties in {@code
* JComponent.setUI()} method after uninstalling old UI and before
* intalling the new one. They are also removed prior to serialization.
*
* @author Igor Kushnirskiy
*/
public interface UIClientPropertyKey {
}

View File

@@ -0,0 +1,191 @@
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.swing;
import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.filechooser.*;
import sun.awt.shell.*;
import sun.awt.OSInfo;
/**
* <b>WARNING:</b> This class is an implementation detail and is only
* public so that it can be used by two packages. You should NOT consider
* this public API.
* <p>
*
* @author Leif Samuelsson
*/
public class WindowsPlacesBar extends JToolBar
implements ActionListener, PropertyChangeListener {
JFileChooser fc;
JToggleButton[] buttons;
ButtonGroup buttonGroup;
File[] files;
final Dimension buttonSize;
public WindowsPlacesBar(JFileChooser fc, boolean isXPStyle) {
super(JToolBar.VERTICAL);
this.fc = fc;
setFloatable(false);
putClientProperty("JToolBar.isRollover", Boolean.TRUE);
boolean isXPPlatform = (OSInfo.getOSType() == OSInfo.OSType.WINDOWS &&
OSInfo.getWindowsVersion().compareTo(OSInfo.WINDOWS_XP) >= 0);
if (isXPStyle) {
buttonSize = new Dimension(83, 69);
putClientProperty("XPStyle.subAppName", "placesbar");
setBorder(new EmptyBorder(1, 1, 1, 1));
} else {
// The button size almost matches the XP style when in Classic style on XP
buttonSize = new Dimension(83, isXPPlatform ? 65 : 54);
setBorder(new BevelBorder(BevelBorder.LOWERED,
UIManager.getColor("ToolBar.highlight"),
UIManager.getColor("ToolBar.background"),
UIManager.getColor("ToolBar.darkShadow"),
UIManager.getColor("ToolBar.shadow")));
}
Color bgColor = new Color(UIManager.getColor("ToolBar.shadow").getRGB());
setBackground(bgColor);
FileSystemView fsv = fc.getFileSystemView();
files = (File[]) ShellFolder.get("fileChooserShortcutPanelFolders");
buttons = new JToggleButton[files.length];
buttonGroup = new ButtonGroup();
for (int i = 0; i < files.length; i++) {
if (fsv.isFileSystemRoot(files[i])) {
// Create special File wrapper for drive path
files[i] = fsv.createFileObject(files[i].getAbsolutePath());
}
String folderName = fsv.getSystemDisplayName(files[i]);
int index = folderName.lastIndexOf(File.separatorChar);
if (index >= 0 && index < folderName.length() - 1) {
folderName = folderName.substring(index + 1);
}
Icon icon;
if (files[i] instanceof ShellFolder) {
// We want a large icon, fsv only gives us a small.
ShellFolder sf = (ShellFolder)files[i];
Image image = sf.getIcon(true);
if (image == null) {
// Get default image
image = (Image) ShellFolder.get("shell32LargeIcon 1");
}
icon = image == null ? null : new ImageIcon(image, sf.getFolderType());
} else {
icon = fsv.getSystemIcon(files[i]);
}
buttons[i] = new JToggleButton(folderName, icon);
if (isXPStyle) {
buttons[i].putClientProperty("XPStyle.subAppName", "placesbar");
} else {
Color fgColor = new Color(UIManager.getColor("List.selectionForeground").getRGB());
buttons[i].setContentAreaFilled(false);
buttons[i].setForeground(fgColor);
}
buttons[i].setMargin(new Insets(3, 2, 1, 2));
buttons[i].setFocusPainted(false);
buttons[i].setIconTextGap(0);
buttons[i].setHorizontalTextPosition(JToggleButton.CENTER);
buttons[i].setVerticalTextPosition(JToggleButton.BOTTOM);
buttons[i].setAlignmentX(JComponent.CENTER_ALIGNMENT);
buttons[i].setPreferredSize(buttonSize);
buttons[i].setMaximumSize(buttonSize);
buttons[i].addActionListener(this);
add(buttons[i]);
if (i < files.length-1 && isXPStyle) {
add(Box.createRigidArea(new Dimension(1, 1)));
}
buttonGroup.add(buttons[i]);
}
doDirectoryChanged(fc.getCurrentDirectory());
}
protected void doDirectoryChanged(File f) {
for (int i=0; i<buttons.length; i++) {
JToggleButton b = buttons[i];
if (files[i].equals(f)) {
b.setSelected(true);
break;
} else if (b.isSelected()) {
// Remove temporarily from group because it doesn't
// allow for no button to be selected.
buttonGroup.remove(b);
b.setSelected(false);
buttonGroup.add(b);
}
}
}
public void propertyChange(PropertyChangeEvent e) {
String prop = e.getPropertyName();
if (prop == JFileChooser.DIRECTORY_CHANGED_PROPERTY) {
doDirectoryChanged(fc.getCurrentDirectory());
}
}
public void actionPerformed(ActionEvent e) {
JToggleButton b = (JToggleButton)e.getSource();
for (int i=0; i<buttons.length; i++) {
if (b == buttons[i]) {
fc.setCurrentDirectory(files[i]);
break;
}
}
}
public Dimension getPreferredSize() {
Dimension min = super.getMinimumSize();
Dimension pref = super.getPreferredSize();
int h = min.height;
if (buttons != null && buttons.length > 0 && buttons.length < 5) {
JToggleButton b = buttons[0];
if (b != null) {
int bh = 5 * (b.getPreferredSize().height + 1);
if (bh > h) {
h = bh;
}
}
}
if (h > pref.height) {
pref = new Dimension(pref.width, h);
}
return pref;
}
}

View File

@@ -0,0 +1,121 @@
/*
* 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 sun.swing.icon;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.io.Serializable;
import javax.swing.Icon;
import javax.swing.UIManager;
import javax.swing.plaf.UIResource;
/**
* Sorting icon.
*
*/
public class SortArrowIcon implements Icon, UIResource, Serializable {
// Height of the arrow, the width is ARROW_HEIGHT
private static final int ARROW_HEIGHT = 5;
// Amount of pad to left of arrow
private static final int X_PADDING = 7;
// Sort direction
private boolean ascending;
// The Color to use, may be null indicating colorKey should be used
private Color color;
// If non-null indicates the color should come from the UIManager with
// this key.
private String colorKey;
/**
* Creates a <code>SortArrowIcon</code>.
*
* @param ascending if true, icon respresenting ascending sort, otherwise
* descending
* @param color the color to render the icon
*/
public SortArrowIcon(boolean ascending, Color color) {
this.ascending = ascending;
this.color = color;
if (color == null) {
throw new IllegalArgumentException();
}
}
/**
* Creates a <code>SortArrowIcon</code>.
*
* @param ascending if true, icon respresenting ascending sort, otherwise
* descending
* @param colorKey the key used to find color in UIManager
*/
public SortArrowIcon(boolean ascending, String colorKey) {
this.ascending = ascending;
this.colorKey = colorKey;
if (colorKey == null) {
throw new IllegalArgumentException();
}
}
public void paintIcon(Component c, Graphics g, int x, int y) {
g.setColor(getColor());
int startX = X_PADDING + x + ARROW_HEIGHT / 2;
if (ascending) {
int startY = y;
g.fillRect(startX, startY, 1, 1);
for (int line = 1; line < ARROW_HEIGHT; line++) {
g.fillRect(startX - line, startY + line,
line + line + 1, 1);
}
}
else {
int startY = y + ARROW_HEIGHT - 1;
g.fillRect(startX, startY, 1, 1);
for (int line = 1; line < ARROW_HEIGHT; line++) {
g.fillRect(startX - line, startY - line,
line + line + 1, 1);
}
}
}
public int getIconWidth() {
return X_PADDING + ARROW_HEIGHT * 2;
}
public int getIconHeight() {
return ARROW_HEIGHT + 2;
}
private Color getColor() {
if (color != null) {
return color;
}
return UIManager.getColor(colorKey);
}
}

View File

@@ -0,0 +1,741 @@
/*
* Copyright (c) 2002, 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 sun.swing.plaf;
import javax.swing.JTextField;
import javax.swing.UIDefaults;
import javax.swing.text.DefaultEditorKit;
/**
* GTKKeybindings - The standard set of keymaps for the GTK Platform
*
* @author Jasper Potts
*/
public class GTKKeybindings {
/**
* Install all GTK keybindings into the provided UIDefaults table
*
* @param table The UiDefaults table to install into
*/
public static void installKeybindings(UIDefaults table) {
Object fieldInputMap = new UIDefaults.LazyInputMap(new Object[]{
"ctrl C", DefaultEditorKit.copyAction,
"ctrl V", DefaultEditorKit.pasteAction,
"ctrl X", DefaultEditorKit.cutAction,
"COPY", DefaultEditorKit.copyAction,
"PASTE", DefaultEditorKit.pasteAction,
"CUT", DefaultEditorKit.cutAction,
"control INSERT", DefaultEditorKit.copyAction,
"shift INSERT", DefaultEditorKit.pasteAction,
"shift DELETE", DefaultEditorKit.cutAction,
"shift LEFT", DefaultEditorKit.selectionBackwardAction,
"shift KP_LEFT", DefaultEditorKit.selectionBackwardAction,
"shift RIGHT", DefaultEditorKit.selectionForwardAction,
"shift KP_RIGHT", DefaultEditorKit.selectionForwardAction,
"ctrl LEFT", DefaultEditorKit.previousWordAction,
"ctrl KP_LEFT", DefaultEditorKit.previousWordAction,
"ctrl RIGHT", DefaultEditorKit.nextWordAction,
"ctrl KP_RIGHT", DefaultEditorKit.nextWordAction,
"ctrl shift LEFT", DefaultEditorKit.selectionPreviousWordAction,
"ctrl shift KP_LEFT", DefaultEditorKit.selectionPreviousWordAction,
"ctrl shift RIGHT", DefaultEditorKit.selectionNextWordAction,
"ctrl shift KP_RIGHT", DefaultEditorKit.selectionNextWordAction,
"ctrl A", DefaultEditorKit.selectAllAction,
"HOME", DefaultEditorKit.beginLineAction,
"END", DefaultEditorKit.endLineAction,
"shift HOME", DefaultEditorKit.selectionBeginLineAction,
"shift END", DefaultEditorKit.selectionEndLineAction,
"BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
"shift BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
"ctrl H", DefaultEditorKit.deletePrevCharAction,
"DELETE", DefaultEditorKit.deleteNextCharAction,
"ctrl DELETE", DefaultEditorKit.deleteNextWordAction,
"ctrl BACK_SPACE", DefaultEditorKit.deletePrevWordAction,
"RIGHT", DefaultEditorKit.forwardAction,
"LEFT", DefaultEditorKit.backwardAction,
"KP_RIGHT", DefaultEditorKit.forwardAction,
"KP_LEFT", DefaultEditorKit.backwardAction,
"ENTER", JTextField.notifyAction,
"ctrl BACK_SLASH", "unselect"/*DefaultEditorKit.unselectAction*/,
"control shift O", "toggle-componentOrientation"/*DefaultEditorKit.toggleComponentOrientation*/
});
Object passwordInputMap = new UIDefaults.LazyInputMap(new Object[]{
"ctrl C", DefaultEditorKit.copyAction,
"ctrl V", DefaultEditorKit.pasteAction,
"ctrl X", DefaultEditorKit.cutAction,
"COPY", DefaultEditorKit.copyAction,
"PASTE", DefaultEditorKit.pasteAction,
"CUT", DefaultEditorKit.cutAction,
"control INSERT", DefaultEditorKit.copyAction,
"shift INSERT", DefaultEditorKit.pasteAction,
"shift DELETE", DefaultEditorKit.cutAction,
"shift LEFT", DefaultEditorKit.selectionBackwardAction,
"shift KP_LEFT", DefaultEditorKit.selectionBackwardAction,
"shift RIGHT", DefaultEditorKit.selectionForwardAction,
"shift KP_RIGHT", DefaultEditorKit.selectionForwardAction,
"ctrl LEFT", DefaultEditorKit.beginLineAction,
"ctrl KP_LEFT", DefaultEditorKit.beginLineAction,
"ctrl RIGHT", DefaultEditorKit.endLineAction,
"ctrl KP_RIGHT", DefaultEditorKit.endLineAction,
"ctrl shift LEFT", DefaultEditorKit.selectionBeginLineAction,
"ctrl shift KP_LEFT", DefaultEditorKit.selectionBeginLineAction,
"ctrl shift RIGHT", DefaultEditorKit.selectionEndLineAction,
"ctrl shift KP_RIGHT", DefaultEditorKit.selectionEndLineAction,
"ctrl A", DefaultEditorKit.selectAllAction,
"HOME", DefaultEditorKit.beginLineAction,
"END", DefaultEditorKit.endLineAction,
"shift HOME", DefaultEditorKit.selectionBeginLineAction,
"shift END", DefaultEditorKit.selectionEndLineAction,
"BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
"shift BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
"ctrl H", DefaultEditorKit.deletePrevCharAction,
"DELETE", DefaultEditorKit.deleteNextCharAction,
"RIGHT", DefaultEditorKit.forwardAction,
"LEFT", DefaultEditorKit.backwardAction,
"KP_RIGHT", DefaultEditorKit.forwardAction,
"KP_LEFT", DefaultEditorKit.backwardAction,
"ENTER", JTextField.notifyAction,
"ctrl BACK_SLASH", "unselect"/*DefaultEditorKit.unselectAction*/,
"control shift O", "toggle-componentOrientation"/*DefaultEditorKit.toggleComponentOrientation*/
});
Object multilineInputMap = new UIDefaults.LazyInputMap(new Object[]{
"ctrl C", DefaultEditorKit.copyAction,
"ctrl V", DefaultEditorKit.pasteAction,
"ctrl X", DefaultEditorKit.cutAction,
"COPY", DefaultEditorKit.copyAction,
"PASTE", DefaultEditorKit.pasteAction,
"CUT", DefaultEditorKit.cutAction,
"control INSERT", DefaultEditorKit.copyAction,
"shift INSERT", DefaultEditorKit.pasteAction,
"shift DELETE", DefaultEditorKit.cutAction,
"shift LEFT", DefaultEditorKit.selectionBackwardAction,
"shift KP_LEFT", DefaultEditorKit.selectionBackwardAction,
"shift RIGHT", DefaultEditorKit.selectionForwardAction,
"shift KP_RIGHT", DefaultEditorKit.selectionForwardAction,
"ctrl LEFT", DefaultEditorKit.previousWordAction,
"ctrl KP_LEFT", DefaultEditorKit.previousWordAction,
"ctrl RIGHT", DefaultEditorKit.nextWordAction,
"ctrl KP_RIGHT", DefaultEditorKit.nextWordAction,
"ctrl shift LEFT", DefaultEditorKit.selectionPreviousWordAction,
"ctrl shift KP_LEFT", DefaultEditorKit.selectionPreviousWordAction,
"ctrl shift RIGHT", DefaultEditorKit.selectionNextWordAction,
"ctrl shift KP_RIGHT", DefaultEditorKit.selectionNextWordAction,
"ctrl A", DefaultEditorKit.selectAllAction,
"HOME", DefaultEditorKit.beginLineAction,
"END", DefaultEditorKit.endLineAction,
"shift HOME", DefaultEditorKit.selectionBeginLineAction,
"shift END", DefaultEditorKit.selectionEndLineAction,
"UP", DefaultEditorKit.upAction,
"KP_UP", DefaultEditorKit.upAction,
"DOWN", DefaultEditorKit.downAction,
"KP_DOWN", DefaultEditorKit.downAction,
"PAGE_UP", DefaultEditorKit.pageUpAction,
"PAGE_DOWN", DefaultEditorKit.pageDownAction,
"shift PAGE_UP", "selection-page-up",
"shift PAGE_DOWN", "selection-page-down",
"ctrl shift PAGE_UP", "selection-page-left",
"ctrl shift PAGE_DOWN", "selection-page-right",
"shift UP", DefaultEditorKit.selectionUpAction,
"shift KP_UP", DefaultEditorKit.selectionUpAction,
"shift DOWN", DefaultEditorKit.selectionDownAction,
"shift KP_DOWN", DefaultEditorKit.selectionDownAction,
"ENTER", DefaultEditorKit.insertBreakAction,
"BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
"shift BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
"ctrl H", DefaultEditorKit.deletePrevCharAction,
"DELETE", DefaultEditorKit.deleteNextCharAction,
"ctrl DELETE", DefaultEditorKit.deleteNextWordAction,
"ctrl BACK_SPACE", DefaultEditorKit.deletePrevWordAction,
"RIGHT", DefaultEditorKit.forwardAction,
"LEFT", DefaultEditorKit.backwardAction,
"KP_RIGHT", DefaultEditorKit.forwardAction,
"KP_LEFT", DefaultEditorKit.backwardAction,
"TAB", DefaultEditorKit.insertTabAction,
"ctrl BACK_SLASH", "unselect"/*DefaultEditorKit.unselectAction*/,
"ctrl HOME", DefaultEditorKit.beginAction,
"ctrl END", DefaultEditorKit.endAction,
"ctrl shift HOME", DefaultEditorKit.selectionBeginAction,
"ctrl shift END", DefaultEditorKit.selectionEndAction,
"ctrl T", "next-link-action",
"ctrl shift T", "previous-link-action",
"ctrl SPACE", "activate-link-action",
"control shift O", "toggle-componentOrientation"/*DefaultEditorKit.toggleComponentOrientation*/
});
Object[] defaults = new Object[]{
"Button.focusInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"SPACE", "pressed",
"released SPACE", "released",
"ENTER", "pressed",
"released ENTER", "released"
}),
"CheckBox.focusInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"SPACE", "pressed",
"released SPACE", "released"
}),
"ComboBox.ancestorInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"ESCAPE", "hidePopup",
"PAGE_UP", "pageUpPassThrough",
"PAGE_DOWN", "pageDownPassThrough",
"HOME", "homePassThrough",
"END", "endPassThrough",
"DOWN", "selectNext",
"KP_DOWN", "selectNext",
"alt DOWN", "togglePopup",
"alt KP_DOWN", "togglePopup",
"alt UP", "togglePopup",
"alt KP_UP", "togglePopup",
"SPACE", "spacePopup",
"ENTER", "enterPressed",
"UP", "selectPrevious",
"KP_UP", "selectPrevious"
}),
"EditorPane.focusInputMap", multilineInputMap,
"FileChooser.ancestorInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"ESCAPE", "cancelSelection",
"F2", "editFileName",
"F5", "refresh",
"BACK_SPACE", "Go Up",
"ENTER", "approveSelection",
"ctrl ENTER", "approveSelection"
}),
"FormattedTextField.focusInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"ctrl C", DefaultEditorKit.copyAction,
"ctrl V", DefaultEditorKit.pasteAction,
"ctrl X", DefaultEditorKit.cutAction,
"COPY", DefaultEditorKit.copyAction,
"PASTE", DefaultEditorKit.pasteAction,
"CUT", DefaultEditorKit.cutAction,
"control INSERT", DefaultEditorKit.copyAction,
"shift INSERT", DefaultEditorKit.pasteAction,
"shift DELETE", DefaultEditorKit.cutAction,
"shift LEFT", DefaultEditorKit.selectionBackwardAction,
"shift KP_LEFT", DefaultEditorKit.selectionBackwardAction,
"shift RIGHT", DefaultEditorKit.selectionForwardAction,
"shift KP_RIGHT", DefaultEditorKit.selectionForwardAction,
"ctrl LEFT", DefaultEditorKit.previousWordAction,
"ctrl KP_LEFT", DefaultEditorKit.previousWordAction,
"ctrl RIGHT", DefaultEditorKit.nextWordAction,
"ctrl KP_RIGHT", DefaultEditorKit.nextWordAction,
"ctrl shift LEFT", DefaultEditorKit.selectionPreviousWordAction,
"ctrl shift KP_LEFT", DefaultEditorKit.selectionPreviousWordAction,
"ctrl shift RIGHT", DefaultEditorKit.selectionNextWordAction,
"ctrl shift KP_RIGHT", DefaultEditorKit.selectionNextWordAction,
"ctrl A", DefaultEditorKit.selectAllAction,
"HOME", DefaultEditorKit.beginLineAction,
"END", DefaultEditorKit.endLineAction,
"shift HOME", DefaultEditorKit.selectionBeginLineAction,
"shift END", DefaultEditorKit.selectionEndLineAction,
"BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
"shift BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
"ctrl H", DefaultEditorKit.deletePrevCharAction,
"DELETE", DefaultEditorKit.deleteNextCharAction,
"ctrl DELETE", DefaultEditorKit.deleteNextWordAction,
"ctrl BACK_SPACE", DefaultEditorKit.deletePrevWordAction,
"RIGHT", DefaultEditorKit.forwardAction,
"LEFT", DefaultEditorKit.backwardAction,
"KP_RIGHT", DefaultEditorKit.forwardAction,
"KP_LEFT", DefaultEditorKit.backwardAction,
"ENTER", JTextField.notifyAction,
"ctrl BACK_SLASH", "unselect",
"control shift O", "toggle-componentOrientation",
"ESCAPE", "reset-field-edit",
"UP", "increment",
"KP_UP", "increment",
"DOWN", "decrement",
"KP_DOWN", "decrement",
}),
"InternalFrame.windowBindings",
new Object[]{
"shift ESCAPE", "showSystemMenu",
"ctrl SPACE", "showSystemMenu",
"ESCAPE", "hideSystemMenu"
},
"List.focusInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"ctrl C", "copy",
"ctrl V", "paste",
"ctrl X", "cut",
"COPY", "copy",
"PASTE", "paste",
"CUT", "cut",
"control INSERT", "copy",
"shift INSERT", "paste",
"shift DELETE", "cut",
"UP", "selectPreviousRow",
"KP_UP", "selectPreviousRow",
"shift UP", "selectPreviousRowExtendSelection",
"shift KP_UP", "selectPreviousRowExtendSelection",
"ctrl shift UP", "selectPreviousRowExtendSelection",
"ctrl shift KP_UP", "selectPreviousRowExtendSelection",
"ctrl UP", "selectPreviousRowChangeLead",
"ctrl KP_UP", "selectPreviousRowChangeLead",
"DOWN", "selectNextRow",
"KP_DOWN", "selectNextRow",
"shift DOWN", "selectNextRowExtendSelection",
"shift KP_DOWN", "selectNextRowExtendSelection",
"ctrl shift DOWN", "selectNextRowExtendSelection",
"ctrl shift KP_DOWN", "selectNextRowExtendSelection",
"ctrl DOWN", "selectNextRowChangeLead",
"ctrl KP_DOWN", "selectNextRowChangeLead",
"LEFT", "selectPreviousColumn",
"KP_LEFT", "selectPreviousColumn",
"shift LEFT", "selectPreviousColumnExtendSelection",
"shift KP_LEFT", "selectPreviousColumnExtendSelection",
"ctrl shift LEFT", "selectPreviousColumnExtendSelection",
"ctrl shift KP_LEFT", "selectPreviousColumnExtendSelection",
"ctrl LEFT", "selectPreviousColumnChangeLead",
"ctrl KP_LEFT", "selectPreviousColumnChangeLead",
"RIGHT", "selectNextColumn",
"KP_RIGHT", "selectNextColumn",
"shift RIGHT", "selectNextColumnExtendSelection",
"shift KP_RIGHT", "selectNextColumnExtendSelection",
"ctrl shift RIGHT", "selectNextColumnExtendSelection",
"ctrl shift KP_RIGHT", "selectNextColumnExtendSelection",
"ctrl RIGHT", "selectNextColumnChangeLead",
"ctrl KP_RIGHT", "selectNextColumnChangeLead",
"HOME", "selectFirstRow",
"shift HOME", "selectFirstRowExtendSelection",
"ctrl shift HOME", "selectFirstRowExtendSelection",
"ctrl HOME", "selectFirstRowChangeLead",
"END", "selectLastRow",
"shift END", "selectLastRowExtendSelection",
"ctrl shift END", "selectLastRowExtendSelection",
"ctrl END", "selectLastRowChangeLead",
"PAGE_UP", "scrollUp",
"shift PAGE_UP", "scrollUpExtendSelection",
"ctrl shift PAGE_UP", "scrollUpExtendSelection",
"ctrl PAGE_UP", "scrollUpChangeLead",
"PAGE_DOWN", "scrollDown",
"shift PAGE_DOWN", "scrollDownExtendSelection",
"ctrl shift PAGE_DOWN", "scrollDownExtendSelection",
"ctrl PAGE_DOWN", "scrollDownChangeLead",
"ctrl A", "selectAll",
"ctrl SLASH", "selectAll",
"ctrl BACK_SLASH", "clearSelection",
"SPACE", "addToSelection",
"ctrl SPACE", "toggleAndAnchor",
"shift SPACE", "extendTo",
"ctrl shift SPACE", "moveSelectionTo"
}),
"List.focusInputMap.RightToLeft",
new UIDefaults.LazyInputMap(new Object[]{
"LEFT", "selectNextColumn",
"KP_LEFT", "selectNextColumn",
"shift LEFT", "selectNextColumnExtendSelection",
"shift KP_LEFT", "selectNextColumnExtendSelection",
"ctrl shift LEFT", "selectNextColumnExtendSelection",
"ctrl shift KP_LEFT", "selectNextColumnExtendSelection",
"ctrl LEFT", "selectNextColumnChangeLead",
"ctrl KP_LEFT", "selectNextColumnChangeLead",
"RIGHT", "selectPreviousColumn",
"KP_RIGHT", "selectPreviousColumn",
"shift RIGHT", "selectPreviousColumnExtendSelection",
"shift KP_RIGHT", "selectPreviousColumnExtendSelection",
"ctrl shift RIGHT", "selectPreviousColumnExtendSelection",
"ctrl shift KP_RIGHT", "selectPreviousColumnExtendSelection",
"ctrl RIGHT", "selectPreviousColumnChangeLead",
"ctrl KP_RIGHT", "selectPreviousColumnChangeLead",
}),
"MenuBar.windowBindings", new Object[]{
"F10", "takeFocus"
},
"OptionPane.windowBindings", new Object[]{
"ESCAPE", "close"
},
"PasswordField.focusInputMap", passwordInputMap,
"PopupMenu.selectedWindowInputMapBindings",
new Object[]{
"ESCAPE", "cancel",
"DOWN", "selectNext",
"KP_DOWN", "selectNext",
"UP", "selectPrevious",
"KP_UP", "selectPrevious",
"LEFT", "selectParent",
"KP_LEFT", "selectParent",
"RIGHT", "selectChild",
"KP_RIGHT", "selectChild",
"ENTER", "return",
"SPACE", "return"
},
"PopupMenu.selectedWindowInputMapBindings.RightToLeft",
new Object[]{
"LEFT", "selectChild",
"KP_LEFT", "selectChild",
"RIGHT", "selectParent",
"KP_RIGHT", "selectParent",
},
"RadioButton.focusInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"SPACE", "pressed",
"released SPACE", "released",
"RETURN", "pressed"
}),
"RootPane.ancestorInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"shift F10", "postPopup",
"CONTEXT_MENU", "postPopup"
}),
// These bindings are only enabled when there is a default
// button set on the rootpane.
"RootPane.defaultButtonWindowKeyBindings", new Object[]{
"ENTER", "press",
"released ENTER", "release",
"ctrl ENTER", "press",
"ctrl released ENTER", "release"
},
"ScrollBar.ancestorInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"RIGHT", "positiveUnitIncrement",
"KP_RIGHT", "positiveUnitIncrement",
"DOWN", "positiveUnitIncrement",
"KP_DOWN", "positiveUnitIncrement",
"PAGE_DOWN", "positiveBlockIncrement",
"LEFT", "negativeUnitIncrement",
"KP_LEFT", "negativeUnitIncrement",
"UP", "negativeUnitIncrement",
"KP_UP", "negativeUnitIncrement",
"PAGE_UP", "negativeBlockIncrement",
"HOME", "minScroll",
"END", "maxScroll"
}),
"ScrollBar.ancestorInputMap.RightToLeft",
new UIDefaults.LazyInputMap(new Object[]{
"RIGHT", "negativeUnitIncrement",
"KP_RIGHT", "negativeUnitIncrement",
"LEFT", "positiveUnitIncrement",
"KP_LEFT", "positiveUnitIncrement",
}),
"ScrollPane.ancestorInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"RIGHT", "unitScrollRight",
"KP_RIGHT", "unitScrollRight",
"DOWN", "unitScrollDown",
"KP_DOWN", "unitScrollDown",
"LEFT", "unitScrollLeft",
"KP_LEFT", "unitScrollLeft",
"UP", "unitScrollUp",
"KP_UP", "unitScrollUp",
"PAGE_UP", "scrollUp",
"PAGE_DOWN", "scrollDown",
"ctrl PAGE_UP", "scrollLeft",
"ctrl PAGE_DOWN", "scrollRight",
"ctrl HOME", "scrollHome",
"ctrl END", "scrollEnd"
}),
"ScrollPane.ancestorInputMap.RightToLeft",
new UIDefaults.LazyInputMap(new Object[]{
"ctrl PAGE_UP", "scrollRight",
"ctrl PAGE_DOWN", "scrollLeft",
}),
"Slider.focusInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"RIGHT", "positiveUnitIncrement",
"KP_RIGHT", "positiveUnitIncrement",
"DOWN", "negativeUnitIncrement",
"KP_DOWN", "negativeUnitIncrement",
"PAGE_DOWN", "negativeBlockIncrement",
"LEFT", "negativeUnitIncrement",
"KP_LEFT", "negativeUnitIncrement",
"UP", "positiveUnitIncrement",
"KP_UP", "positiveUnitIncrement",
"PAGE_UP", "positiveBlockIncrement",
"HOME", "minScroll",
"END", "maxScroll"
}),
"Slider.focusInputMap.RightToLeft",
new UIDefaults.LazyInputMap(new Object[]{
"RIGHT", "negativeUnitIncrement",
"KP_RIGHT", "negativeUnitIncrement",
"LEFT", "positiveUnitIncrement",
"KP_LEFT", "positiveUnitIncrement",
}),
"Spinner.ancestorInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"UP", "increment",
"KP_UP", "increment",
"DOWN", "decrement",
"KP_DOWN", "decrement",
}),
"SplitPane.ancestorInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"UP", "negativeIncrement",
"DOWN", "positiveIncrement",
"LEFT", "negativeIncrement",
"RIGHT", "positiveIncrement",
"KP_UP", "negativeIncrement",
"KP_DOWN", "positiveIncrement",
"KP_LEFT", "negativeIncrement",
"KP_RIGHT", "positiveIncrement",
"HOME", "selectMin",
"END", "selectMax",
"F8", "startResize",
"F6", "toggleFocus",
"ctrl TAB", "focusOutForward",
"ctrl shift TAB", "focusOutBackward"
}),
"TabbedPane.focusInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"RIGHT", "navigateRight",
"KP_RIGHT", "navigateRight",
"LEFT", "navigateLeft",
"KP_LEFT", "navigateLeft",
"UP", "navigateUp",
"KP_UP", "navigateUp",
"DOWN", "navigateDown",
"KP_DOWN", "navigateDown",
"ctrl DOWN", "requestFocusForVisibleComponent",
"ctrl KP_DOWN", "requestFocusForVisibleComponent",
"SPACE", "selectTabWithFocus"
}),
"TabbedPane.ancestorInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"ctrl TAB", "navigateNext",
"ctrl shift TAB", "navigatePrevious",
"ctrl PAGE_DOWN", "navigatePageDown",
"ctrl PAGE_UP", "navigatePageUp",
"ctrl UP", "requestFocus",
"ctrl KP_UP", "requestFocus",
}),
"TableHeader.ancestorInputMap",
new UIDefaults.LazyInputMap(new Object[] {
"SPACE", "toggleSortOrder",
"LEFT", "selectColumnToLeft",
"KP_LEFT", "selectColumnToLeft",
"RIGHT", "selectColumnToRight",
"KP_RIGHT", "selectColumnToRight",
"alt LEFT", "moveColumnLeft",
"alt KP_LEFT", "moveColumnLeft",
"alt RIGHT", "moveColumnRight",
"alt KP_RIGHT", "moveColumnRight",
"alt shift LEFT", "resizeLeft",
"alt shift KP_LEFT", "resizeLeft",
"alt shift RIGHT", "resizeRight",
"alt shift KP_RIGHT", "resizeRight",
"ESCAPE", "focusTable",
}),
"Table.ancestorInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"ctrl C", "copy",
"ctrl V", "paste",
"ctrl X", "cut",
"COPY", "copy",
"PASTE", "paste",
"CUT", "cut",
"control INSERT", "copy",
"shift INSERT", "paste",
"shift DELETE", "cut",
"RIGHT", "selectNextColumn",
"KP_RIGHT", "selectNextColumn",
"shift RIGHT", "selectNextColumnExtendSelection",
"shift KP_RIGHT", "selectNextColumnExtendSelection",
"ctrl shift RIGHT", "selectNextColumnExtendSelection",
"ctrl shift KP_RIGHT", "selectNextColumnExtendSelection",
"ctrl RIGHT", "selectNextColumnChangeLead",
"ctrl KP_RIGHT", "selectNextColumnChangeLead",
"LEFT", "selectPreviousColumn",
"KP_LEFT", "selectPreviousColumn",
"shift LEFT", "selectPreviousColumnExtendSelection",
"shift KP_LEFT", "selectPreviousColumnExtendSelection",
"ctrl shift LEFT", "selectPreviousColumnExtendSelection",
"ctrl shift KP_LEFT", "selectPreviousColumnExtendSelection",
"ctrl LEFT", "selectPreviousColumnChangeLead",
"ctrl KP_LEFT", "selectPreviousColumnChangeLead",
"DOWN", "selectNextRow",
"KP_DOWN", "selectNextRow",
"shift DOWN", "selectNextRowExtendSelection",
"shift KP_DOWN", "selectNextRowExtendSelection",
"ctrl shift DOWN", "selectNextRowExtendSelection",
"ctrl shift KP_DOWN", "selectNextRowExtendSelection",
"ctrl DOWN", "selectNextRowChangeLead",
"ctrl KP_DOWN", "selectNextRowChangeLead",
"UP", "selectPreviousRow",
"KP_UP", "selectPreviousRow",
"shift UP", "selectPreviousRowExtendSelection",
"shift KP_UP", "selectPreviousRowExtendSelection",
"ctrl shift UP", "selectPreviousRowExtendSelection",
"ctrl shift KP_UP", "selectPreviousRowExtendSelection",
"ctrl UP", "selectPreviousRowChangeLead",
"ctrl KP_UP", "selectPreviousRowChangeLead",
"HOME", "selectFirstColumn",
"shift HOME", "selectFirstColumnExtendSelection",
"ctrl shift HOME", "selectFirstRowExtendSelection",
"ctrl HOME", "selectFirstRow",
"END", "selectLastColumn",
"shift END", "selectLastColumnExtendSelection",
"ctrl shift END", "selectLastRowExtendSelection",
"ctrl END", "selectLastRow",
"PAGE_UP", "scrollUpChangeSelection",
"shift PAGE_UP", "scrollUpExtendSelection",
"ctrl shift PAGE_UP", "scrollLeftExtendSelection",
"ctrl PAGE_UP", "scrollLeftChangeSelection",
"PAGE_DOWN", "scrollDownChangeSelection",
"shift PAGE_DOWN", "scrollDownExtendSelection",
"ctrl shift PAGE_DOWN", "scrollRightExtendSelection",
"ctrl PAGE_DOWN", "scrollRightChangeSelection",
"TAB", "selectNextColumnCell",
"shift TAB", "selectPreviousColumnCell",
"ENTER", "selectNextRowCell",
"shift ENTER", "selectPreviousRowCell",
"ctrl A", "selectAll",
"ctrl SLASH", "selectAll",
"ctrl BACK_SLASH", "clearSelection",
"ESCAPE", "cancel",
"F2", "startEditing",
"SPACE", "addToSelection",
"ctrl SPACE", "toggleAndAnchor",
"shift SPACE", "extendTo",
"ctrl shift SPACE", "moveSelectionTo",
"F8", "focusHeader"
}),
"Table.ancestorInputMap.RightToLeft",
new UIDefaults.LazyInputMap(new Object[]{
"RIGHT", "selectPreviousColumn",
"KP_RIGHT", "selectPreviousColumn",
"shift RIGHT", "selectPreviousColumnExtendSelection",
"shift KP_RIGHT", "selectPreviousColumnExtendSelection",
"ctrl shift RIGHT", "selectPreviousColumnExtendSelection",
"ctrl shift KP_RIGHT", "selectPreviousColumnExtendSelection",
"shift RIGHT", "selectPreviousColumnChangeLead",
"shift KP_RIGHT", "selectPreviousColumnChangeLead",
"LEFT", "selectNextColumn",
"KP_LEFT", "selectNextColumn",
"shift LEFT", "selectNextColumnExtendSelection",
"shift KP_LEFT", "selectNextColumnExtendSelection",
"ctrl shift LEFT", "selectNextColumnExtendSelection",
"ctrl shift KP_LEFT", "selectNextColumnExtendSelection",
"ctrl LEFT", "selectNextColumnChangeLead",
"ctrl KP_LEFT", "selectNextColumnChangeLead",
"ctrl PAGE_UP", "scrollRightChangeSelection",
"ctrl PAGE_DOWN", "scrollLeftChangeSelection",
"ctrl shift PAGE_UP", "scrollRightExtendSelection",
"ctrl shift PAGE_DOWN", "scrollLeftExtendSelection",
}),
"TextArea.focusInputMap", multilineInputMap,
"TextField.focusInputMap", fieldInputMap,
"TextPane.focusInputMap", multilineInputMap,
"ToggleButton.focusInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"SPACE", "pressed",
"released SPACE", "released"
}),
"ToolBar.ancestorInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"UP", "navigateUp",
"KP_UP", "navigateUp",
"DOWN", "navigateDown",
"KP_DOWN", "navigateDown",
"LEFT", "navigateLeft",
"KP_LEFT", "navigateLeft",
"RIGHT", "navigateRight",
"KP_RIGHT", "navigateRight"
}),
"Tree.focusInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"ctrl C", "copy",
"ctrl V", "paste",
"ctrl X", "cut",
"COPY", "copy",
"PASTE", "paste",
"CUT", "cut",
"control INSERT", "copy",
"shift INSERT", "paste",
"shift DELETE", "cut",
"UP", "selectPrevious",
"KP_UP", "selectPrevious",
"shift UP", "selectPreviousExtendSelection",
"shift KP_UP", "selectPreviousExtendSelection",
"ctrl shift UP", "selectPreviousExtendSelection",
"ctrl shift KP_UP", "selectPreviousExtendSelection",
"ctrl UP", "selectPreviousChangeLead",
"ctrl KP_UP", "selectPreviousChangeLead",
"DOWN", "selectNext",
"KP_DOWN", "selectNext",
"shift DOWN", "selectNextExtendSelection",
"shift KP_DOWN", "selectNextExtendSelection",
"ctrl shift DOWN", "selectNextExtendSelection",
"ctrl shift KP_DOWN", "selectNextExtendSelection",
"ctrl DOWN", "selectNextChangeLead",
"ctrl KP_DOWN", "selectNextChangeLead",
"RIGHT", "selectChild",
"KP_RIGHT", "selectChild",
"LEFT", "selectParent",
"KP_LEFT", "selectParent",
"typed +", "expand",
"typed -", "collapse",
"BACK_SPACE", "moveSelectionToParent",
"PAGE_UP", "scrollUpChangeSelection",
"shift PAGE_UP", "scrollUpExtendSelection",
"ctrl shift PAGE_UP", "scrollUpExtendSelection",
"ctrl PAGE_UP", "scrollUpChangeLead",
"PAGE_DOWN", "scrollDownChangeSelection",
"shift PAGE_DOWN", "scrollDownExtendSelection",
"ctrl shift PAGE_DOWN", "scrollDownExtendSelection",
"ctrl PAGE_DOWN", "scrollDownChangeLead",
"HOME", "selectFirst",
"shift HOME", "selectFirstExtendSelection",
"ctrl shift HOME", "selectFirstExtendSelection",
"ctrl HOME", "selectFirstChangeLead",
"END", "selectLast",
"shift END", "selectLastExtendSelection",
"ctrl shift END", "selectLastExtendSelection",
"ctrl END", "selectLastChangeLead",
"F2", "startEditing",
"ctrl A", "selectAll",
"ctrl SLASH", "selectAll",
"ctrl BACK_SLASH", "clearSelection",
"ctrl LEFT", "scrollLeft",
"ctrl KP_LEFT", "scrollLeft",
"ctrl RIGHT", "scrollRight",
"ctrl KP_RIGHT", "scrollRight",
"SPACE", "addToSelection",
"ctrl SPACE", "toggleAndAnchor",
"shift SPACE", "extendTo",
"ctrl shift SPACE", "moveSelectionTo"
}),
"Tree.focusInputMap.RightToLeft",
new UIDefaults.LazyInputMap(new Object[]{
"RIGHT", "selectParent",
"KP_RIGHT", "selectParent",
"LEFT", "selectChild",
"KP_LEFT", "selectChild",
}),
"Tree.ancestorInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"ESCAPE", "cancel"
}),
};
table.putDefaults(defaults);
}
}

View File

@@ -0,0 +1,648 @@
/*
* Copyright (c) 2002, 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 sun.swing.plaf;
import javax.swing.JTextField;
import javax.swing.UIDefaults;
import javax.swing.text.DefaultEditorKit;
/**
* WindowsKeybindings - The standard set of keymaps for the Windows Platform
*
* @author Jasper Potts
*/
public class WindowsKeybindings {
/**
* Install all Windows keybindings into the provided UIDefaults table
*
* @param table The UiDefaults table to install into
*/
public static void installKeybindings(UIDefaults table) {
// *** Text
Object fieldInputMap = new UIDefaults.LazyInputMap(new Object[]{
"control C", DefaultEditorKit.copyAction,
"control V", DefaultEditorKit.pasteAction,
"control X", DefaultEditorKit.cutAction,
"COPY", DefaultEditorKit.copyAction,
"PASTE", DefaultEditorKit.pasteAction,
"CUT", DefaultEditorKit.cutAction,
"control INSERT", DefaultEditorKit.copyAction,
"shift INSERT", DefaultEditorKit.pasteAction,
"shift DELETE", DefaultEditorKit.cutAction,
"control A", DefaultEditorKit.selectAllAction,
"control BACK_SLASH", "unselect"/*DefaultEditorKit.unselectAction*/,
"shift LEFT", DefaultEditorKit.selectionBackwardAction,
"shift RIGHT", DefaultEditorKit.selectionForwardAction,
"control LEFT", DefaultEditorKit.previousWordAction,
"control RIGHT", DefaultEditorKit.nextWordAction,
"control shift LEFT", DefaultEditorKit.selectionPreviousWordAction,
"control shift RIGHT", DefaultEditorKit.selectionNextWordAction,
"HOME", DefaultEditorKit.beginLineAction,
"END", DefaultEditorKit.endLineAction,
"shift HOME", DefaultEditorKit.selectionBeginLineAction,
"shift END", DefaultEditorKit.selectionEndLineAction,
"BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
"shift BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
"ctrl H", DefaultEditorKit.deletePrevCharAction,
"DELETE", DefaultEditorKit.deleteNextCharAction,
"ctrl DELETE", DefaultEditorKit.deleteNextWordAction,
"ctrl BACK_SPACE", DefaultEditorKit.deletePrevWordAction,
"RIGHT", DefaultEditorKit.forwardAction,
"LEFT", DefaultEditorKit.backwardAction,
"KP_RIGHT", DefaultEditorKit.forwardAction,
"KP_LEFT", DefaultEditorKit.backwardAction,
"ENTER", JTextField.notifyAction,
"control shift O", "toggle-componentOrientation"/*DefaultEditorKit.toggleComponentOrientation*/
});
Object passwordInputMap = new UIDefaults.LazyInputMap(new Object[]{
"control C", DefaultEditorKit.copyAction,
"control V", DefaultEditorKit.pasteAction,
"control X", DefaultEditorKit.cutAction,
"COPY", DefaultEditorKit.copyAction,
"PASTE", DefaultEditorKit.pasteAction,
"CUT", DefaultEditorKit.cutAction,
"control INSERT", DefaultEditorKit.copyAction,
"shift INSERT", DefaultEditorKit.pasteAction,
"shift DELETE", DefaultEditorKit.cutAction,
"control A", DefaultEditorKit.selectAllAction,
"control BACK_SLASH", "unselect"/*DefaultEditorKit.unselectAction*/,
"shift LEFT", DefaultEditorKit.selectionBackwardAction,
"shift RIGHT", DefaultEditorKit.selectionForwardAction,
"control LEFT", DefaultEditorKit.beginLineAction,
"control RIGHT", DefaultEditorKit.endLineAction,
"control shift LEFT", DefaultEditorKit.selectionBeginLineAction,
"control shift RIGHT", DefaultEditorKit.selectionEndLineAction,
"HOME", DefaultEditorKit.beginLineAction,
"END", DefaultEditorKit.endLineAction,
"shift HOME", DefaultEditorKit.selectionBeginLineAction,
"shift END", DefaultEditorKit.selectionEndLineAction,
"BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
"shift BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
"ctrl H", DefaultEditorKit.deletePrevCharAction,
"DELETE", DefaultEditorKit.deleteNextCharAction,
"RIGHT", DefaultEditorKit.forwardAction,
"LEFT", DefaultEditorKit.backwardAction,
"KP_RIGHT", DefaultEditorKit.forwardAction,
"KP_LEFT", DefaultEditorKit.backwardAction,
"ENTER", JTextField.notifyAction,
"control shift O", "toggle-componentOrientation"/*DefaultEditorKit.toggleComponentOrientation*/
});
Object multilineInputMap = new UIDefaults.LazyInputMap(new Object[]{
"control C", DefaultEditorKit.copyAction,
"control V", DefaultEditorKit.pasteAction,
"control X", DefaultEditorKit.cutAction,
"COPY", DefaultEditorKit.copyAction,
"PASTE", DefaultEditorKit.pasteAction,
"CUT", DefaultEditorKit.cutAction,
"control INSERT", DefaultEditorKit.copyAction,
"shift INSERT", DefaultEditorKit.pasteAction,
"shift DELETE", DefaultEditorKit.cutAction,
"shift LEFT", DefaultEditorKit.selectionBackwardAction,
"shift RIGHT", DefaultEditorKit.selectionForwardAction,
"control LEFT", DefaultEditorKit.previousWordAction,
"control RIGHT", DefaultEditorKit.nextWordAction,
"control shift LEFT", DefaultEditorKit.selectionPreviousWordAction,
"control shift RIGHT", DefaultEditorKit.selectionNextWordAction,
"control A", DefaultEditorKit.selectAllAction,
"control BACK_SLASH", "unselect"/*DefaultEditorKit.unselectAction*/,
"HOME", DefaultEditorKit.beginLineAction,
"END", DefaultEditorKit.endLineAction,
"shift HOME", DefaultEditorKit.selectionBeginLineAction,
"shift END", DefaultEditorKit.selectionEndLineAction,
"control HOME", DefaultEditorKit.beginAction,
"control END", DefaultEditorKit.endAction,
"control shift HOME", DefaultEditorKit.selectionBeginAction,
"control shift END", DefaultEditorKit.selectionEndAction,
"UP", DefaultEditorKit.upAction,
"DOWN", DefaultEditorKit.downAction,
"BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
"shift BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
"ctrl H", DefaultEditorKit.deletePrevCharAction,
"DELETE", DefaultEditorKit.deleteNextCharAction,
"ctrl DELETE", DefaultEditorKit.deleteNextWordAction,
"ctrl BACK_SPACE", DefaultEditorKit.deletePrevWordAction,
"RIGHT", DefaultEditorKit.forwardAction,
"LEFT", DefaultEditorKit.backwardAction,
"KP_RIGHT", DefaultEditorKit.forwardAction,
"KP_LEFT", DefaultEditorKit.backwardAction,
"PAGE_UP", DefaultEditorKit.pageUpAction,
"PAGE_DOWN", DefaultEditorKit.pageDownAction,
"shift PAGE_UP", "selection-page-up",
"shift PAGE_DOWN", "selection-page-down",
"ctrl shift PAGE_UP", "selection-page-left",
"ctrl shift PAGE_DOWN", "selection-page-right",
"shift UP", DefaultEditorKit.selectionUpAction,
"shift DOWN", DefaultEditorKit.selectionDownAction,
"ENTER", DefaultEditorKit.insertBreakAction,
"TAB", DefaultEditorKit.insertTabAction,
"control T", "next-link-action",
"control shift T", "previous-link-action",
"control SPACE", "activate-link-action",
"control shift O", "toggle-componentOrientation"/*DefaultEditorKit.toggleComponentOrientation*/
});
Object[] defaults = {
"TextField.focusInputMap", fieldInputMap,
"PasswordField.focusInputMap", passwordInputMap,
"TextArea.focusInputMap", multilineInputMap,
"TextPane.focusInputMap", multilineInputMap,
"EditorPane.focusInputMap", multilineInputMap,
"Button.focusInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"SPACE", "pressed",
"released SPACE", "released"
}),
"CheckBox.focusInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"SPACE", "pressed",
"released SPACE", "released"
}),
"ComboBox.ancestorInputMap", new UIDefaults.LazyInputMap(new Object[]{
"ESCAPE", "hidePopup",
"PAGE_UP", "pageUpPassThrough",
"PAGE_DOWN", "pageDownPassThrough",
"HOME", "homePassThrough",
"END", "endPassThrough",
"DOWN", "selectNext2",
"KP_DOWN", "selectNext2",
"UP", "selectPrevious2",
"KP_UP", "selectPrevious2",
"ENTER", "enterPressed",
"F4", "togglePopup",
"alt DOWN", "togglePopup",
"alt KP_DOWN", "togglePopup",
"alt UP", "togglePopup",
"alt KP_UP", "togglePopup"
}),
"Desktop.ancestorInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"ctrl F5", "restore",
"ctrl F4", "close",
"ctrl F7", "move",
"ctrl F8", "resize",
"RIGHT", "right",
"KP_RIGHT", "right",
"LEFT", "left",
"KP_LEFT", "left",
"UP", "up",
"KP_UP", "up",
"DOWN", "down",
"KP_DOWN", "down",
"ESCAPE", "escape",
"ctrl F9", "minimize",
"ctrl F10", "maximize",
"ctrl F6", "selectNextFrame",
"ctrl TAB", "selectNextFrame",
"ctrl alt F6", "selectNextFrame",
"shift ctrl alt F6", "selectPreviousFrame",
"ctrl F12", "navigateNext",
"shift ctrl F12", "navigatePrevious"
}),
"FileChooser.ancestorInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"ESCAPE", "cancelSelection",
"F2", "editFileName",
"F5", "refresh",
"BACK_SPACE", "Go Up",
"ENTER", "approveSelection",
"ctrl ENTER", "approveSelection"
}),
"InternalFrame.windowBindings", new Object[]{
"shift ESCAPE", "showSystemMenu",
"ctrl SPACE", "showSystemMenu",
"ESCAPE", "hideSystemMenu"
},
"List.focusInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"ctrl C", "copy",
"ctrl V", "paste",
"ctrl X", "cut",
"COPY", "copy",
"PASTE", "paste",
"CUT", "cut",
"control INSERT", "copy",
"shift INSERT", "paste",
"shift DELETE", "cut",
"UP", "selectPreviousRow",
"KP_UP", "selectPreviousRow",
"shift UP", "selectPreviousRowExtendSelection",
"shift KP_UP", "selectPreviousRowExtendSelection",
"ctrl shift UP", "selectPreviousRowExtendSelection",
"ctrl shift KP_UP", "selectPreviousRowExtendSelection",
"ctrl UP", "selectPreviousRowChangeLead",
"ctrl KP_UP", "selectPreviousRowChangeLead",
"DOWN", "selectNextRow",
"KP_DOWN", "selectNextRow",
"shift DOWN", "selectNextRowExtendSelection",
"shift KP_DOWN", "selectNextRowExtendSelection",
"ctrl shift DOWN", "selectNextRowExtendSelection",
"ctrl shift KP_DOWN", "selectNextRowExtendSelection",
"ctrl DOWN", "selectNextRowChangeLead",
"ctrl KP_DOWN", "selectNextRowChangeLead",
"LEFT", "selectPreviousColumn",
"KP_LEFT", "selectPreviousColumn",
"shift LEFT", "selectPreviousColumnExtendSelection",
"shift KP_LEFT", "selectPreviousColumnExtendSelection",
"ctrl shift LEFT", "selectPreviousColumnExtendSelection",
"ctrl shift KP_LEFT", "selectPreviousColumnExtendSelection",
"ctrl LEFT", "selectPreviousColumnChangeLead",
"ctrl KP_LEFT", "selectPreviousColumnChangeLead",
"RIGHT", "selectNextColumn",
"KP_RIGHT", "selectNextColumn",
"shift RIGHT", "selectNextColumnExtendSelection",
"shift KP_RIGHT", "selectNextColumnExtendSelection",
"ctrl shift RIGHT", "selectNextColumnExtendSelection",
"ctrl shift KP_RIGHT", "selectNextColumnExtendSelection",
"ctrl RIGHT", "selectNextColumnChangeLead",
"ctrl KP_RIGHT", "selectNextColumnChangeLead",
"HOME", "selectFirstRow",
"shift HOME", "selectFirstRowExtendSelection",
"ctrl shift HOME", "selectFirstRowExtendSelection",
"ctrl HOME", "selectFirstRowChangeLead",
"END", "selectLastRow",
"shift END", "selectLastRowExtendSelection",
"ctrl shift END", "selectLastRowExtendSelection",
"ctrl END", "selectLastRowChangeLead",
"PAGE_UP", "scrollUp",
"shift PAGE_UP", "scrollUpExtendSelection",
"ctrl shift PAGE_UP", "scrollUpExtendSelection",
"ctrl PAGE_UP", "scrollUpChangeLead",
"PAGE_DOWN", "scrollDown",
"shift PAGE_DOWN", "scrollDownExtendSelection",
"ctrl shift PAGE_DOWN", "scrollDownExtendSelection",
"ctrl PAGE_DOWN", "scrollDownChangeLead",
"ctrl A", "selectAll",
"ctrl SLASH", "selectAll",
"ctrl BACK_SLASH", "clearSelection",
"SPACE", "addToSelection",
"ctrl SPACE", "toggleAndAnchor",
"shift SPACE", "extendTo",
"ctrl shift SPACE", "moveSelectionTo"
}),
"MenuBar.windowBindings", new Object[]{
"F10", "takeFocus"
},
"RadioButton.focusInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"SPACE", "pressed",
"released SPACE", "released"
}),
"OptionPane.windowBindings", new Object[]{
"ESCAPE", "close"
},
"FormattedTextField.focusInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"ctrl C", DefaultEditorKit.copyAction,
"ctrl V", DefaultEditorKit.pasteAction,
"ctrl X", DefaultEditorKit.cutAction,
"COPY", DefaultEditorKit.copyAction,
"PASTE", DefaultEditorKit.pasteAction,
"CUT", DefaultEditorKit.cutAction,
"control INSERT", DefaultEditorKit.copyAction,
"shift INSERT", DefaultEditorKit.pasteAction,
"shift DELETE", DefaultEditorKit.cutAction,
"shift LEFT", DefaultEditorKit.selectionBackwardAction,
"shift KP_LEFT", DefaultEditorKit.selectionBackwardAction,
"shift RIGHT", DefaultEditorKit.selectionForwardAction,
"shift KP_RIGHT", DefaultEditorKit.selectionForwardAction,
"ctrl LEFT", DefaultEditorKit.previousWordAction,
"ctrl KP_LEFT", DefaultEditorKit.previousWordAction,
"ctrl RIGHT", DefaultEditorKit.nextWordAction,
"ctrl KP_RIGHT", DefaultEditorKit.nextWordAction,
"ctrl shift LEFT", DefaultEditorKit.selectionPreviousWordAction,
"ctrl shift KP_LEFT", DefaultEditorKit.selectionPreviousWordAction,
"ctrl shift RIGHT", DefaultEditorKit.selectionNextWordAction,
"ctrl shift KP_RIGHT", DefaultEditorKit.selectionNextWordAction,
"ctrl A", DefaultEditorKit.selectAllAction,
"HOME", DefaultEditorKit.beginLineAction,
"END", DefaultEditorKit.endLineAction,
"shift HOME", DefaultEditorKit.selectionBeginLineAction,
"shift END", DefaultEditorKit.selectionEndLineAction,
"BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
"shift BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
"ctrl H", DefaultEditorKit.deletePrevCharAction,
"DELETE", DefaultEditorKit.deleteNextCharAction,
"ctrl DELETE", DefaultEditorKit.deleteNextWordAction,
"ctrl BACK_SPACE", DefaultEditorKit.deletePrevWordAction,
"RIGHT", DefaultEditorKit.forwardAction,
"LEFT", DefaultEditorKit.backwardAction,
"KP_RIGHT", DefaultEditorKit.forwardAction,
"KP_LEFT", DefaultEditorKit.backwardAction,
"ENTER", JTextField.notifyAction,
"ctrl BACK_SLASH", "unselect",
"control shift O", "toggle-componentOrientation",
"ESCAPE", "reset-field-edit",
"UP", "increment",
"KP_UP", "increment",
"DOWN", "decrement",
"KP_DOWN", "decrement",
}),
"RootPane.ancestorInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"shift F10", "postPopup",
"CONTEXT_MENU", "postPopup"
}),
// These bindings are only enabled when there is a default
// button set on the rootpane.
"RootPane.defaultButtonWindowKeyBindings", new Object[]{
"ENTER", "press",
"released ENTER", "release",
"ctrl ENTER", "press",
"ctrl released ENTER", "release"
},
"ScrollBar.ancestorInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"RIGHT", "positiveUnitIncrement",
"KP_RIGHT", "positiveUnitIncrement",
"DOWN", "positiveUnitIncrement",
"KP_DOWN", "positiveUnitIncrement",
"PAGE_DOWN", "positiveBlockIncrement",
"ctrl PAGE_DOWN", "positiveBlockIncrement",
"LEFT", "negativeUnitIncrement",
"KP_LEFT", "negativeUnitIncrement",
"UP", "negativeUnitIncrement",
"KP_UP", "negativeUnitIncrement",
"PAGE_UP", "negativeBlockIncrement",
"ctrl PAGE_UP", "negativeBlockIncrement",
"HOME", "minScroll",
"END", "maxScroll"
}),
"ScrollPane.ancestorInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"RIGHT", "unitScrollRight",
"KP_RIGHT", "unitScrollRight",
"DOWN", "unitScrollDown",
"KP_DOWN", "unitScrollDown",
"LEFT", "unitScrollLeft",
"KP_LEFT", "unitScrollLeft",
"UP", "unitScrollUp",
"KP_UP", "unitScrollUp",
"PAGE_UP", "scrollUp",
"PAGE_DOWN", "scrollDown",
"ctrl PAGE_UP", "scrollLeft",
"ctrl PAGE_DOWN", "scrollRight",
"ctrl HOME", "scrollHome",
"ctrl END", "scrollEnd"
}),
"Slider.focusInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"RIGHT", "positiveUnitIncrement",
"KP_RIGHT", "positiveUnitIncrement",
"DOWN", "negativeUnitIncrement",
"KP_DOWN", "negativeUnitIncrement",
"PAGE_DOWN", "negativeBlockIncrement",
"LEFT", "negativeUnitIncrement",
"KP_LEFT", "negativeUnitIncrement",
"UP", "positiveUnitIncrement",
"KP_UP", "positiveUnitIncrement",
"PAGE_UP", "positiveBlockIncrement",
"HOME", "minScroll",
"END", "maxScroll"
}),
"Spinner.ancestorInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"UP", "increment",
"KP_UP", "increment",
"DOWN", "decrement",
"KP_DOWN", "decrement",
}),
"SplitPane.ancestorInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"UP", "negativeIncrement",
"DOWN", "positiveIncrement",
"LEFT", "negativeIncrement",
"RIGHT", "positiveIncrement",
"KP_UP", "negativeIncrement",
"KP_DOWN", "positiveIncrement",
"KP_LEFT", "negativeIncrement",
"KP_RIGHT", "positiveIncrement",
"HOME", "selectMin",
"END", "selectMax",
"F8", "startResize",
"F6", "toggleFocus",
"ctrl TAB", "focusOutForward",
"ctrl shift TAB", "focusOutBackward"
}),
"TabbedPane.focusInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"RIGHT", "navigateRight",
"KP_RIGHT", "navigateRight",
"LEFT", "navigateLeft",
"KP_LEFT", "navigateLeft",
"UP", "navigateUp",
"KP_UP", "navigateUp",
"DOWN", "navigateDown",
"KP_DOWN", "navigateDown",
"ctrl DOWN", "requestFocusForVisibleComponent",
"ctrl KP_DOWN", "requestFocusForVisibleComponent",
}),
"TabbedPane.ancestorInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"ctrl TAB", "navigateNext",
"ctrl shift TAB", "navigatePrevious",
"ctrl PAGE_DOWN", "navigatePageDown",
"ctrl PAGE_UP", "navigatePageUp",
"ctrl UP", "requestFocus",
"ctrl KP_UP", "requestFocus",
}),
"TableHeader.ancestorInputMap",
new UIDefaults.LazyInputMap(new Object[] {
"SPACE", "toggleSortOrder",
"LEFT", "selectColumnToLeft",
"KP_LEFT", "selectColumnToLeft",
"RIGHT", "selectColumnToRight",
"KP_RIGHT", "selectColumnToRight",
"alt LEFT", "moveColumnLeft",
"alt KP_LEFT", "moveColumnLeft",
"alt RIGHT", "moveColumnRight",
"alt KP_RIGHT", "moveColumnRight",
"alt shift LEFT", "resizeLeft",
"alt shift KP_LEFT", "resizeLeft",
"alt shift RIGHT", "resizeRight",
"alt shift KP_RIGHT", "resizeRight",
"ESCAPE", "focusTable",
}),
"Table.ancestorInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"ctrl C", "copy",
"ctrl V", "paste",
"ctrl X", "cut",
"COPY", "copy",
"PASTE", "paste",
"CUT", "cut",
"control INSERT", "copy",
"shift INSERT", "paste",
"shift DELETE", "cut",
"RIGHT", "selectNextColumn",
"KP_RIGHT", "selectNextColumn",
"shift RIGHT", "selectNextColumnExtendSelection",
"shift KP_RIGHT", "selectNextColumnExtendSelection",
"ctrl shift RIGHT", "selectNextColumnExtendSelection",
"ctrl shift KP_RIGHT", "selectNextColumnExtendSelection",
"ctrl RIGHT", "selectNextColumnChangeLead",
"ctrl KP_RIGHT", "selectNextColumnChangeLead",
"LEFT", "selectPreviousColumn",
"KP_LEFT", "selectPreviousColumn",
"shift LEFT", "selectPreviousColumnExtendSelection",
"shift KP_LEFT", "selectPreviousColumnExtendSelection",
"ctrl shift LEFT", "selectPreviousColumnExtendSelection",
"ctrl shift KP_LEFT", "selectPreviousColumnExtendSelection",
"ctrl LEFT", "selectPreviousColumnChangeLead",
"ctrl KP_LEFT", "selectPreviousColumnChangeLead",
"DOWN", "selectNextRow",
"KP_DOWN", "selectNextRow",
"shift DOWN", "selectNextRowExtendSelection",
"shift KP_DOWN", "selectNextRowExtendSelection",
"ctrl shift DOWN", "selectNextRowExtendSelection",
"ctrl shift KP_DOWN", "selectNextRowExtendSelection",
"ctrl DOWN", "selectNextRowChangeLead",
"ctrl KP_DOWN", "selectNextRowChangeLead",
"UP", "selectPreviousRow",
"KP_UP", "selectPreviousRow",
"shift UP", "selectPreviousRowExtendSelection",
"shift KP_UP", "selectPreviousRowExtendSelection",
"ctrl shift UP", "selectPreviousRowExtendSelection",
"ctrl shift KP_UP", "selectPreviousRowExtendSelection",
"ctrl UP", "selectPreviousRowChangeLead",
"ctrl KP_UP", "selectPreviousRowChangeLead",
"HOME", "selectFirstColumn",
"shift HOME", "selectFirstColumnExtendSelection",
"ctrl shift HOME", "selectFirstRowExtendSelection",
"ctrl HOME", "selectFirstRow",
"END", "selectLastColumn",
"shift END", "selectLastColumnExtendSelection",
"ctrl shift END", "selectLastRowExtendSelection",
"ctrl END", "selectLastRow",
"PAGE_UP", "scrollUpChangeSelection",
"shift PAGE_UP", "scrollUpExtendSelection",
"ctrl shift PAGE_UP", "scrollLeftExtendSelection",
"ctrl PAGE_UP", "scrollLeftChangeSelection",
"PAGE_DOWN", "scrollDownChangeSelection",
"shift PAGE_DOWN", "scrollDownExtendSelection",
"ctrl shift PAGE_DOWN", "scrollRightExtendSelection",
"ctrl PAGE_DOWN", "scrollRightChangeSelection",
"TAB", "selectNextColumnCell",
"shift TAB", "selectPreviousColumnCell",
"ENTER", "selectNextRowCell",
"shift ENTER", "selectPreviousRowCell",
"ctrl A", "selectAll",
"ctrl SLASH", "selectAll",
"ctrl BACK_SLASH", "clearSelection",
"ESCAPE", "cancel",
"F2", "startEditing",
"SPACE", "addToSelection",
"ctrl SPACE", "toggleAndAnchor",
"shift SPACE", "extendTo",
"ctrl shift SPACE", "moveSelectionTo",
"F8", "focusHeader"
}),
"ToggleButton.focusInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"SPACE", "pressed",
"released SPACE", "released"
}),
"ToolBar.ancestorInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"UP", "navigateUp",
"KP_UP", "navigateUp",
"DOWN", "navigateDown",
"KP_DOWN", "navigateDown",
"LEFT", "navigateLeft",
"KP_LEFT", "navigateLeft",
"RIGHT", "navigateRight",
"KP_RIGHT", "navigateRight"
}),
"Tree.focusInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"ADD", "expand",
"SUBTRACT", "collapse",
"ctrl C", "copy",
"ctrl V", "paste",
"ctrl X", "cut",
"COPY", "copy",
"PASTE", "paste",
"CUT", "cut",
"control INSERT", "copy",
"shift INSERT", "paste",
"shift DELETE", "cut",
"UP", "selectPrevious",
"KP_UP", "selectPrevious",
"shift UP", "selectPreviousExtendSelection",
"shift KP_UP", "selectPreviousExtendSelection",
"ctrl shift UP", "selectPreviousExtendSelection",
"ctrl shift KP_UP", "selectPreviousExtendSelection",
"ctrl UP", "selectPreviousChangeLead",
"ctrl KP_UP", "selectPreviousChangeLead",
"DOWN", "selectNext",
"KP_DOWN", "selectNext",
"shift DOWN", "selectNextExtendSelection",
"shift KP_DOWN", "selectNextExtendSelection",
"ctrl shift DOWN", "selectNextExtendSelection",
"ctrl shift KP_DOWN", "selectNextExtendSelection",
"ctrl DOWN", "selectNextChangeLead",
"ctrl KP_DOWN", "selectNextChangeLead",
"RIGHT", "selectChild",
"KP_RIGHT", "selectChild",
"LEFT", "selectParent",
"KP_LEFT", "selectParent",
"PAGE_UP", "scrollUpChangeSelection",
"shift PAGE_UP", "scrollUpExtendSelection",
"ctrl shift PAGE_UP", "scrollUpExtendSelection",
"ctrl PAGE_UP", "scrollUpChangeLead",
"PAGE_DOWN", "scrollDownChangeSelection",
"shift PAGE_DOWN", "scrollDownExtendSelection",
"ctrl shift PAGE_DOWN", "scrollDownExtendSelection",
"ctrl PAGE_DOWN", "scrollDownChangeLead",
"HOME", "selectFirst",
"shift HOME", "selectFirstExtendSelection",
"ctrl shift HOME", "selectFirstExtendSelection",
"ctrl HOME", "selectFirstChangeLead",
"END", "selectLast",
"shift END", "selectLastExtendSelection",
"ctrl shift END", "selectLastExtendSelection",
"ctrl END", "selectLastChangeLead",
"F2", "startEditing",
"ctrl A", "selectAll",
"ctrl SLASH", "selectAll",
"ctrl BACK_SLASH", "clearSelection",
"ctrl LEFT", "scrollLeft",
"ctrl KP_LEFT", "scrollLeft",
"ctrl RIGHT", "scrollRight",
"ctrl KP_RIGHT", "scrollRight",
"SPACE", "addToSelection",
"ctrl SPACE", "toggleAndAnchor",
"shift SPACE", "extendTo",
"ctrl shift SPACE", "moveSelectionTo"
}),
"Tree.ancestorInputMap",
new UIDefaults.LazyInputMap(new Object[]{
"ESCAPE", "cancel"
}),
};
table.putDefaults(defaults);
}
}

View File

@@ -0,0 +1,927 @@
/*
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.swing.plaf.synth;
import javax.swing.plaf.synth.*;
import java.awt.*;
import java.util.*;
import javax.swing.*;
import javax.swing.plaf.*;
/**
* Default implementation of SynthStyle. Has setters for the various
* SynthStyle methods. Many of the properties can be specified for all states,
* using SynthStyle directly, or a specific state using one of the StateInfo
* methods.
* <p>
* Beyond the constructor a subclass should override the <code>addTo</code>
* and <code>clone</code> methods, these are used when the Styles are being
* merged into a resulting style.
*
* @author Scott Violet
*/
public class DefaultSynthStyle extends SynthStyle implements Cloneable {
private static final Object PENDING = new Object();
/**
* Should the component be opaque?
*/
private boolean opaque;
/**
* Insets.
*/
private Insets insets;
/**
* Information specific to ComponentState.
*/
private StateInfo[] states;
/**
* User specific data.
*/
private Map data;
/**
* Font to use if there is no matching StateInfo, or the StateInfo doesn't
* define one.
*/
private Font font;
/**
* SynthGraphics, may be null.
*/
private SynthGraphicsUtils synthGraphics;
/**
* Painter to use if the StateInfo doesn't have one.
*/
private SynthPainter painter;
/**
* Nullary constructor, intended for subclassers.
*/
public DefaultSynthStyle() {
}
/**
* Creates a new DefaultSynthStyle that is a copy of the passed in
* style. Any StateInfo's of the passed in style are clonsed as well.
*
* @param style Style to duplicate
*/
public DefaultSynthStyle(DefaultSynthStyle style) {
opaque = style.opaque;
if (style.insets != null) {
insets = new Insets(style.insets.top, style.insets.left,
style.insets.bottom, style.insets.right);
}
if (style.states != null) {
states = new StateInfo[style.states.length];
for (int counter = style.states.length - 1; counter >= 0;
counter--) {
states[counter] = (StateInfo)style.states[counter].clone();
}
}
if (style.data != null) {
data = new HashMap();
data.putAll(style.data);
}
font = style.font;
synthGraphics = style.synthGraphics;
painter = style.painter;
}
/**
* Creates a new DefaultSynthStyle.
*
* @param insets Insets for the Style
* @param opaque Whether or not the background is completely painted in
* an opaque color
* @param states StateInfos describing properties per state
* @param data Style specific data.
*/
public DefaultSynthStyle(Insets insets, boolean opaque,
StateInfo[] states, Map data) {
this.insets = insets;
this.opaque = opaque;
this.states = states;
this.data = data;
}
public Color getColor(SynthContext context, ColorType type) {
return getColor(context.getComponent(), context.getRegion(),
context.getComponentState(), type);
}
public Color getColor(JComponent c, Region id, int state,
ColorType type) {
// For the enabled state, prefer the widget's colors
if (!id.isSubregion() && state == SynthConstants.ENABLED) {
if (type == ColorType.BACKGROUND) {
return c.getBackground();
}
else if (type == ColorType.FOREGROUND) {
return c.getForeground();
}
else if (type == ColorType.TEXT_FOREGROUND) {
// If getForeground returns a non-UIResource it means the
// developer has explicitly set the foreground, use it over
// that of TEXT_FOREGROUND as that is typically the expected
// behavior.
Color color = c.getForeground();
if (!(color instanceof UIResource)) {
return color;
}
}
}
// Then use what we've locally defined
Color color = getColorForState(c, id, state, type);
if (color == null) {
// No color, fallback to that of the widget.
if (type == ColorType.BACKGROUND ||
type == ColorType.TEXT_BACKGROUND) {
return c.getBackground();
}
else if (type == ColorType.FOREGROUND ||
type == ColorType.TEXT_FOREGROUND) {
return c.getForeground();
}
}
return color;
}
protected Color getColorForState(SynthContext context, ColorType type) {
return getColorForState(context.getComponent(), context.getRegion(),
context.getComponentState(), type);
}
/**
* Returns the color for the specified state.
*
* @param c JComponent the style is associated with
* @param id Region identifier
* @param state State of the region.
* @param type Type of color being requested.
* @return Color to render with
*/
protected Color getColorForState(JComponent c, Region id, int state,
ColorType type) {
// Use the best state.
StateInfo si = getStateInfo(state);
Color color;
if (si != null && (color = si.getColor(type)) != null) {
return color;
}
if (si == null || si.getComponentState() != 0) {
si = getStateInfo(0);
if (si != null) {
return si.getColor(type);
}
}
return null;
}
/**
* Sets the font that is used if there is no matching StateInfo, or
* it does not define a font.
*
* @param font Font to use for rendering
*/
public void setFont(Font font) {
this.font = font;
}
public Font getFont(SynthContext state) {
return getFont(state.getComponent(), state.getRegion(),
state.getComponentState());
}
public Font getFont(JComponent c, Region id, int state) {
if (!id.isSubregion() && state == SynthConstants.ENABLED) {
return c.getFont();
}
Font cFont = c.getFont();
if (cFont != null && !(cFont instanceof UIResource)) {
return cFont;
}
return getFontForState(c, id, state);
}
/**
* Returns the font for the specified state. This should NOT callback
* to the JComponent.
*
* @param c JComponent the style is associated with
* @param id Region identifier
* @param state State of the region.
* @return Font to render with
*/
protected Font getFontForState(JComponent c, Region id, int state) {
if (c == null) {
return this.font;
}
// First pass, look for the best match
StateInfo si = getStateInfo(state);
Font font;
if (si != null && (font = si.getFont()) != null) {
return font;
}
if (si == null || si.getComponentState() != 0) {
si = getStateInfo(0);
if (si != null && (font = si.getFont()) != null) {
return font;
}
}
// Fallback font.
return this.font;
}
protected Font getFontForState(SynthContext context) {
return getFontForState(context.getComponent(), context.getRegion(),
context.getComponentState());
}
/**
* Sets the SynthGraphicsUtils that will be used for rendering.
*
* @param graphics SynthGraphics
*/
public void setGraphicsUtils(SynthGraphicsUtils graphics) {
this.synthGraphics = graphics;
}
/**
* Returns a SynthGraphicsUtils.
*
* @param context SynthContext identifying requestor
* @return SynthGraphicsUtils
*/
public SynthGraphicsUtils getGraphicsUtils(SynthContext context) {
if (synthGraphics == null) {
return super.getGraphicsUtils(context);
}
return synthGraphics;
}
/**
* Sets the insets.
*
* @param Insets.
*/
public void setInsets(Insets insets) {
this.insets = insets;
}
/**
* Returns the Insets. If <code>to</code> is non-null the resulting
* insets will be placed in it, otherwise a new Insets object will be
* created and returned.
*
* @param context SynthContext identifying requestor
* @param to Where to place Insets
* @return Insets.
*/
public Insets getInsets(SynthContext state, Insets to) {
if (to == null) {
to = new Insets(0, 0, 0, 0);
}
if (insets != null) {
to.left = insets.left;
to.right = insets.right;
to.top = insets.top;
to.bottom = insets.bottom;
}
else {
to.left = to.right = to.top = to.bottom = 0;
}
return to;
}
/**
* Sets the Painter to use for the border.
*
* @param painter Painter for the Border.
*/
public void setPainter(SynthPainter painter) {
this.painter = painter;
}
/**
* Returns the Painter for the passed in Component. This may return null.
*
* @param ss SynthContext identifying requestor
* @return Painter for the border
*/
public SynthPainter getPainter(SynthContext ss) {
return painter;
}
/**
* Sets whether or not the JComponent should be opaque.
*
* @param opaque Whether or not the JComponent should be opaque.
*/
public void setOpaque(boolean opaque) {
this.opaque = opaque;
}
/**
* Returns the value to initialize the opacity property of the Component
* to. A Style should NOT assume the opacity will remain this value, the
* developer may reset it or override it.
*
* @param ss SynthContext identifying requestor
* @return opaque Whether or not the JComponent is opaque.
*/
public boolean isOpaque(SynthContext ss) {
return opaque;
}
/**
* Sets style specific values. This does NOT copy the data, it
* assigns it directly to this Style.
*
* @param data Style specific values
*/
public void setData(Map data) {
this.data = data;
}
/**
* Returns the style specific data.
*
* @return Style specific data.
*/
public Map getData() {
return data;
}
/**
* Getter for a region specific style property.
*
* @param state SynthContext identifying requestor
* @param key Property being requested.
* @return Value of the named property
*/
public Object get(SynthContext state, Object key) {
// Look for the best match
StateInfo si = getStateInfo(state.getComponentState());
if (si != null && si.getData() != null && getKeyFromData(si.getData(), key) != null) {
return getKeyFromData(si.getData(), key);
}
si = getStateInfo(0);
if (si != null && si.getData() != null && getKeyFromData(si.getData(), key) != null) {
return getKeyFromData(si.getData(), key);
}
if(getKeyFromData(data, key) != null)
return getKeyFromData(data, key);
return getDefaultValue(state, key);
}
private Object getKeyFromData(Map stateData, Object key) {
Object value = null;
if (stateData != null) {
synchronized(stateData) {
value = stateData.get(key);
}
while (value == PENDING) {
synchronized(stateData) {
try {
stateData.wait();
} catch (InterruptedException ie) {}
value = stateData.get(key);
}
}
if (value instanceof UIDefaults.LazyValue) {
synchronized(stateData) {
stateData.put(key, PENDING);
}
value = ((UIDefaults.LazyValue)value).createValue(null);
synchronized(stateData) {
stateData.put(key, value);
stateData.notifyAll();
}
}
}
return value;
}
/**
* Returns the default value for a particular property. This is only
* invoked if this style doesn't define a property for <code>key</code>.
*
* @param state SynthContext identifying requestor
* @param key Property being requested.
* @return Value of the named property
*/
public Object getDefaultValue(SynthContext context, Object key) {
return super.get(context, key);
}
/**
* Creates a clone of this style.
*
* @return Clone of this style
*/
public Object clone() {
DefaultSynthStyle style;
try {
style = (DefaultSynthStyle)super.clone();
} catch (CloneNotSupportedException cnse) {
return null;
}
if (states != null) {
style.states = new StateInfo[states.length];
for (int counter = states.length - 1; counter >= 0; counter--) {
style.states[counter] = (StateInfo)states[counter].clone();
}
}
if (data != null) {
style.data = new HashMap();
style.data.putAll(data);
}
return style;
}
/**
* Merges the contents of this Style with that of the passed in Style,
* returning the resulting merged syle. Properties of this
* <code>DefaultSynthStyle</code> will take precedence over those of the
* passed in <code>DefaultSynthStyle</code>. For example, if this
* style specifics a non-null font, the returned style will have its
* font so to that regardless of the <code>style</code>'s font.
*
* @param style Style to add our styles to
* @return Merged style.
*/
public DefaultSynthStyle addTo(DefaultSynthStyle style) {
if (insets != null) {
style.insets = this.insets;
}
if (font != null) {
style.font = this.font;
}
if (painter != null) {
style.painter = this.painter;
}
if (synthGraphics != null) {
style.synthGraphics = this.synthGraphics;
}
style.opaque = opaque;
if (states != null) {
if (style.states == null) {
style.states = new StateInfo[states.length];
for (int counter = states.length - 1; counter >= 0; counter--){
if (states[counter] != null) {
style.states[counter] = (StateInfo)states[counter].
clone();
}
}
}
else {
// Find the number of new states in unique, merging any
// matching states as we go. Also, move any merge styles
// to the end to give them precedence.
int unique = 0;
// Number of StateInfos that match.
int matchCount = 0;
int maxOStyles = style.states.length;
for (int thisCounter = states.length - 1; thisCounter >= 0;
thisCounter--) {
int state = states[thisCounter].getComponentState();
boolean found = false;
for (int oCounter = maxOStyles - 1 - matchCount;
oCounter >= 0; oCounter--) {
if (state == style.states[oCounter].
getComponentState()) {
style.states[oCounter] = states[thisCounter].
addTo(style.states[oCounter]);
// Move StateInfo to end, giving it precedence.
StateInfo tmp = style.states[maxOStyles - 1 -
matchCount];
style.states[maxOStyles - 1 - matchCount] =
style.states[oCounter];
style.states[oCounter] = tmp;
matchCount++;
found = true;
break;
}
}
if (!found) {
unique++;
}
}
if (unique != 0) {
// There are states that exist in this Style that
// don't exist in the other style, recreate the array
// and add them.
StateInfo[] newStates = new StateInfo[
unique + maxOStyles];
int newIndex = maxOStyles;
System.arraycopy(style.states, 0, newStates, 0,maxOStyles);
for (int thisCounter = states.length - 1; thisCounter >= 0;
thisCounter--) {
int state = states[thisCounter].getComponentState();
boolean found = false;
for (int oCounter = maxOStyles - 1; oCounter >= 0;
oCounter--) {
if (state == style.states[oCounter].
getComponentState()) {
found = true;
break;
}
}
if (!found) {
newStates[newIndex++] = (StateInfo)states[
thisCounter].clone();
}
}
style.states = newStates;
}
}
}
if (data != null) {
if (style.data == null) {
style.data = new HashMap();
}
style.data.putAll(data);
}
return style;
}
/**
* Sets the array of StateInfo's which are used to specify properties
* specific to a particular style.
*
* @param states StateInfos
*/
public void setStateInfo(StateInfo[] states) {
this.states = states;
}
/**
* Returns the array of StateInfo's that that are used to specify
* properties specific to a particular style.
*
* @return Array of StateInfos.
*/
public StateInfo[] getStateInfo() {
return states;
}
/**
* Returns the best matching StateInfo for a particular state.
*
* @param state Component state.
* @return Best matching StateInfo, or null
*/
public StateInfo getStateInfo(int state) {
// Use the StateInfo with the most bits that matches that of state.
// If there is none, than fallback to
// the StateInfo with a state of 0, indicating it'll match anything.
// Consider if we have 3 StateInfos a, b and c with states:
// SELECTED, SELECTED | ENABLED, 0
//
// Input Return Value
// ----- ------------
// SELECTED a
// SELECTED | ENABLED b
// MOUSE_OVER c
// SELECTED | ENABLED | FOCUSED b
// ENABLED c
if (states != null) {
int bestCount = 0;
int bestIndex = -1;
int wildIndex = -1;
if (state == 0) {
for (int counter = states.length - 1; counter >= 0;counter--) {
if (states[counter].getComponentState() == 0) {
return states[counter];
}
}
return null;
}
for (int counter = states.length - 1; counter >= 0; counter--) {
int oState = states[counter].getComponentState();
if (oState == 0) {
if (wildIndex == -1) {
wildIndex = counter;
}
}
else if ((state & oState) == oState) {
// This is key, we need to make sure all bits of the
// StateInfo match, otherwise a StateInfo with
// SELECTED | ENABLED would match ENABLED, which we
// don't want.
// This comes from BigInteger.bitCnt
int bitCount = oState;
bitCount -= (0xaaaaaaaa & bitCount) >>> 1;
bitCount = (bitCount & 0x33333333) + ((bitCount >>> 2) &
0x33333333);
bitCount = bitCount + (bitCount >>> 4) & 0x0f0f0f0f;
bitCount += bitCount >>> 8;
bitCount += bitCount >>> 16;
bitCount = bitCount & 0xff;
if (bitCount > bestCount) {
bestIndex = counter;
bestCount = bitCount;
}
}
}
if (bestIndex != -1) {
return states[bestIndex];
}
if (wildIndex != -1) {
return states[wildIndex];
}
}
return null;
}
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append(super.toString()).append(',');
buf.append("data=").append(data).append(',');
buf.append("font=").append(font).append(',');
buf.append("insets=").append(insets).append(',');
buf.append("synthGraphics=").append(synthGraphics).append(',');
buf.append("painter=").append(painter).append(',');
StateInfo[] states = getStateInfo();
if (states != null) {
buf.append("states[");
for (StateInfo state : states) {
buf.append(state.toString()).append(',');
}
buf.append(']').append(',');
}
// remove last newline
buf.deleteCharAt(buf.length() - 1);
return buf.toString();
}
/**
* StateInfo represents Style information specific to the state of
* a component.
*/
public static class StateInfo {
private Map data;
private Font font;
private Color[] colors;
private int state;
/**
* Creates a new StateInfo.
*/
public StateInfo() {
}
/**
* Creates a new StateInfo with the specified properties
*
* @param state Component state(s) that this StateInfo should be used
* for
* @param painter Painter responsible for rendering
* @param bgPainter Painter responsible for rendering the background
* @param font Font for this state
* @param colors Colors for this state
*/
public StateInfo(int state, Font font, Color[] colors) {
this.state = state;
this.font = font;
this.colors = colors;
}
/**
* Creates a new StateInfo that is a copy of the passed in
* StateInfo.
*
* @param info StateInfo to copy.
*/
public StateInfo(StateInfo info) {
this.state = info.state;
this.font = info.font;
if(info.data != null) {
if(data == null) {
data = new HashMap();
}
data.putAll(info.data);
}
if (info.colors != null) {
this.colors = new Color[info.colors.length];
System.arraycopy(info.colors, 0, colors, 0,info.colors.length);
}
}
public Map getData() {
return data;
}
public void setData(Map data) {
this.data = data;
}
/**
* Sets the font for this state.
*
* @param font Font to use for rendering
*/
public void setFont(Font font) {
this.font = font;
}
/**
* Returns the font for this state.
*
* @return Returns the font to use for rendering this state
*/
public Font getFont() {
return font;
}
/**
* Sets the array of colors to use for rendering this state. This
* is indexed by <code>ColorType.getID()</code>.
*
* @param colors Array of colors
*/
public void setColors(Color[] colors) {
this.colors = colors;
}
/**
* Returns the array of colors to use for rendering this state. This
* is indexed by <code>ColorType.getID()</code>.
*
* @return Array of colors
*/
public Color[] getColors() {
return colors;
}
/**
* Returns the Color to used for the specified ColorType.
*
* @return Color.
*/
public Color getColor(ColorType type) {
if (colors != null) {
int id = type.getID();
if (id < colors.length) {
return colors[id];
}
}
return null;
}
/**
* Merges the contents of this StateInfo with that of the passed in
* StateInfo, returning the resulting merged StateInfo. Properties of
* this <code>StateInfo</code> will take precedence over those of the
* passed in <code>StateInfo</code>. For example, if this
* StateInfo specifics a non-null font, the returned StateInfo will
* have its font so to that regardless of the <code>StateInfo</code>'s
* font.
*
* @param info StateInfo to add our styles to
* @return Merged StateInfo.
*/
public StateInfo addTo(StateInfo info) {
if (font != null) {
info.font = font;
}
if(data != null) {
if(info.data == null) {
info.data = new HashMap();
}
info.data.putAll(data);
}
if (colors != null) {
if (info.colors == null) {
info.colors = new Color[colors.length];
System.arraycopy(colors, 0, info.colors, 0,
colors.length);
}
else {
if (info.colors.length < colors.length) {
Color[] old = info.colors;
info.colors = new Color[colors.length];
System.arraycopy(old, 0, info.colors, 0, old.length);
}
for (int counter = colors.length - 1; counter >= 0;
counter--) {
if (colors[counter] != null) {
info.colors[counter] = colors[counter];
}
}
}
}
return info;
}
/**
* Sets the state this StateInfo corresponds to.
*
* @see SynthConstants
* @param state info.
*/
public void setComponentState(int state) {
this.state = state;
}
/**
* Returns the state this StateInfo corresponds to.
*
* @see SynthConstants
* @return state info.
*/
public int getComponentState() {
return state;
}
/**
* Returns the number of states that are similar between the
* ComponentState this StateInfo represents and val.
*/
private int getMatchCount(int val) {
// This comes from BigInteger.bitCnt
val &= state;
val -= (0xaaaaaaaa & val) >>> 1;
val = (val & 0x33333333) + ((val >>> 2) & 0x33333333);
val = val + (val >>> 4) & 0x0f0f0f0f;
val += val >>> 8;
val += val >>> 16;
return val & 0xff;
}
/**
* Creates and returns a copy of this StateInfo.
*
* @return Copy of this StateInfo.
*/
public Object clone() {
return new StateInfo(this);
}
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append(super.toString()).append(',');
buf.append("state=").append(Integer.toString(state)).append(',');
buf.append("font=").append(font).append(',');
if (colors != null) {
buf.append("colors=").append(Arrays.asList(colors)).
append(',');
}
return buf.toString();
}
}
}

View File

@@ -0,0 +1,340 @@
/*
* Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.swing.plaf.synth;
import java.awt.*;
import java.awt.image.BufferedImage;
import sun.swing.CachedPainter;
/**
* Paint9Painter is used for painting images for both Synth and GTK's
* pixmap/blueprint engines.
*
*/
public class Paint9Painter extends CachedPainter {
/**
* Enumeration for the types of painting this class can handle.
*/
public enum PaintType {
/**
* Painting type indicating the image should be centered in
* the space provided. When used the <code>mask</code> is ignored.
*/
CENTER,
/**
* Painting type indicating the image should be tiled across the
* specified width and height. When used the <code>mask</code> is
* ignored.
*/
TILE,
/**
* Painting type indicating the image should be split into nine
* regions with the top, left, bottom and right areas stretched.
*/
PAINT9_STRETCH,
/**
* Painting type indicating the image should be split into nine
* regions with the top, left, bottom and right areas tiled.
*/
PAINT9_TILE
};
private static final Insets EMPTY_INSETS = new Insets(0, 0, 0, 0);
public static final int PAINT_TOP_LEFT = 1;
public static final int PAINT_TOP = 2;
public static final int PAINT_TOP_RIGHT = 4;
public static final int PAINT_LEFT = 8;
public static final int PAINT_CENTER = 16;
public static final int PAINT_RIGHT = 32;
public static final int PAINT_BOTTOM_RIGHT = 64;
public static final int PAINT_BOTTOM = 128;
public static final int PAINT_BOTTOM_LEFT = 256;
/**
* Specifies that all regions should be painted. If this is set any
* other regions specified will not be painted. For example
* PAINT_ALL | PAINT_CENTER will paint all but the center.
*/
public static final int PAINT_ALL = 512;
/**
* Convenience method for testing the validity of an image.
*
* @param image Image to check.
* @return true if <code>image</code> is non-null and has a positive
* size.
*/
public static boolean validImage(Image image) {
return (image != null && image.getWidth(null) > 0 &&
image.getHeight(null) > 0);
}
public Paint9Painter(int cacheCount) {
super(cacheCount);
}
/**
* Paints using the algorightm specified by <code>paintType</code>.
* NOTE that this just invokes super.paint(...) with the same
* argument ordering as this method.
*
* @param c Component rendering to
* @param g Graphics to render to
* @param x X-coordinate
* @param y Y-coordinate
* @param w Width to render to
* @param h Height to render to
* @param source Image to render from, if <code>null</code> this method
* will do nothing
* @param sInsets Insets specifying the portion of the image that
* will be stretched or tiled, if <code>null</code> empty
* <code>Insets</code> will be used.
* @param dInsets Destination insets specifying the portion of the image
* will be stretched or tiled, if <code>null</code> empty
* <code>Insets</code> will be used.
* @param paintType Specifies what type of algorithm to use in painting
* @param mask Specifies portion of image to render, if
* <code>PAINT_ALL</code> is specified, any other regions
* specified will not be painted, for example
* PAINT_ALL | PAINT_CENTER paints everything but the center.
*/
public void paint(Component c, Graphics g, int x,
int y, int w, int h, Image source, Insets sInsets,
Insets dInsets,
PaintType type, int mask) {
if (source == null) {
return;
}
super.paint(c, g, x, y, w, h, source, sInsets, dInsets, type, mask);
}
protected void paintToImage(Component c, Image destImage, Graphics g,
int w, int h, Object[] args) {
int argIndex = 0;
while (argIndex < args.length) {
Image image = (Image)args[argIndex++];
Insets sInsets = (Insets)args[argIndex++];
Insets dInsets = (Insets)args[argIndex++];
PaintType type = (PaintType)args[argIndex++];
int mask = (Integer)args[argIndex++];
paint9(g, 0, 0, w, h, image, sInsets, dInsets, type, mask);
}
}
protected void paint9(Graphics g, int x, int y, int w, int h,
Image image, Insets sInsets,
Insets dInsets, PaintType type, int componentMask) {
if (!validImage(image)) {
return;
}
if (sInsets == null) {
sInsets = EMPTY_INSETS;
}
if (dInsets == null) {
dInsets = EMPTY_INSETS;
}
int iw = image.getWidth(null);
int ih = image.getHeight(null);
if (type == PaintType.CENTER) {
// Center the image
g.drawImage(image, x + (w - iw) / 2,
y + (h - ih) / 2, null);
}
else if (type == PaintType.TILE) {
// Tile the image
int lastIY = 0;
for (int yCounter = y, maxY = y + h; yCounter < maxY;
yCounter += (ih - lastIY), lastIY = 0) {
int lastIX = 0;
for (int xCounter = x, maxX = x + w; xCounter < maxX;
xCounter += (iw - lastIX), lastIX = 0) {
int dx2 = Math.min(maxX, xCounter + iw - lastIX);
int dy2 = Math.min(maxY, yCounter + ih - lastIY);
g.drawImage(image, xCounter, yCounter, dx2, dy2,
lastIX, lastIY, lastIX + dx2 - xCounter,
lastIY + dy2 - yCounter, null);
}
}
}
else {
int st = sInsets.top;
int sl = sInsets.left;
int sb = sInsets.bottom;
int sr = sInsets.right;
int dt = dInsets.top;
int dl = dInsets.left;
int db = dInsets.bottom;
int dr = dInsets.right;
// Constrain the insets to the size of the image
if (st + sb > ih) {
db = dt = sb = st = Math.max(0, ih / 2);
}
if (sl + sr > iw) {
dl = dr = sl = sr = Math.max(0, iw / 2);
}
// Constrain the insets to the size of the region we're painting
// in.
if (dt + db > h) {
dt = db = Math.max(0, h / 2 - 1);
}
if (dl + dr > w) {
dl = dr = Math.max(0, w / 2 - 1);
}
boolean stretch = (type == PaintType.PAINT9_STRETCH);
if ((componentMask & PAINT_ALL) != 0) {
componentMask = (PAINT_ALL - 1) & ~componentMask;
}
if ((componentMask & PAINT_LEFT) != 0) {
drawChunk(image, g, stretch, x, y + dt, x + dl, y + h - db,
0, st, sl, ih - sb, false);
}
if ((componentMask & PAINT_TOP_LEFT) != 0) {
drawImage(image, g, x, y, x + dl, y + dt,
0, 0, sl, st);
}
if ((componentMask & PAINT_TOP) != 0) {
drawChunk(image, g, stretch, x + dl, y, x + w - dr, y + dt,
sl, 0, iw - sr, st, true);
}
if ((componentMask & PAINT_TOP_RIGHT) != 0) {
drawImage(image, g, x + w - dr, y, x + w, y + dt,
iw - sr, 0, iw, st);
}
if ((componentMask & PAINT_RIGHT) != 0) {
drawChunk(image, g, stretch,
x + w - dr, y + dt, x + w, y + h - db,
iw - sr, st, iw, ih - sb, false);
}
if ((componentMask & PAINT_BOTTOM_RIGHT) != 0) {
drawImage(image, g, x + w - dr, y + h - db, x + w, y + h,
iw - sr, ih - sb, iw, ih);
}
if ((componentMask & PAINT_BOTTOM) != 0) {
drawChunk(image, g, stretch,
x + dl, y + h - db, x + w - dr, y + h,
sl, ih - sb, iw - sr, ih, true);
}
if ((componentMask & PAINT_BOTTOM_LEFT) != 0) {
drawImage(image, g, x, y + h - db, x + dl, y + h,
0, ih - sb, sl, ih);
}
if ((componentMask & PAINT_CENTER) != 0) {
drawImage(image, g, x + dl, y + dt, x + w - dr, y + h - db,
sl, st, iw - sr, ih - sb);
}
}
}
private void drawImage(Image image, Graphics g,
int dx1, int dy1, int dx2, int dy2, int sx1,
int sy1, int sx2, int sy2) {
// PENDING: is this necessary, will G2D do it for me?
if (dx2 - dx1 <= 0 || dy2 - dy1 <= 0 || sx2 - sx1 <= 0 ||
sy2 - sy1 <= 0) {
// Bogus location, nothing to paint
return;
}
g.drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null);
}
/**
* Draws a portion of an image, stretched or tiled.
*
* @param image Image to render.
* @param g Graphics to render to
* @param stretch Whether the image should be stretched or timed in the
* provided space.
* @param dx1 X origin to draw to
* @param dy1 Y origin to draw to
* @param dx2 End x location to draw to
* @param dy2 End y location to draw to
* @param sx1 X origin to draw from
* @param sy1 Y origin to draw from
* @param sx2 Max x location to draw from
* @param sy2 Max y location to draw from
* @param xDirection Used if the image is not stretched. If true it
* indicates the image should be tiled along the x axis.
*/
private void drawChunk(Image image, Graphics g, boolean stretch,
int dx1, int dy1, int dx2, int dy2, int sx1,
int sy1, int sx2, int sy2,
boolean xDirection) {
if (dx2 - dx1 <= 0 || dy2 - dy1 <= 0 || sx2 - sx1 <= 0 ||
sy2 - sy1 <= 0) {
// Bogus location, nothing to paint
return;
}
if (stretch) {
g.drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null);
}
else {
int xSize = sx2 - sx1;
int ySize = sy2 - sy1;
int deltaX;
int deltaY;
if (xDirection) {
deltaX = xSize;
deltaY = 0;
}
else {
deltaX = 0;
deltaY = ySize;
}
while (dx1 < dx2 && dy1 < dy2) {
int newDX2 = Math.min(dx2, dx1 + xSize);
int newDY2 = Math.min(dy2, dy1 + ySize);
g.drawImage(image, dx1, dy1, newDX2, newDY2,
sx1, sy1, sx1 + newDX2 - dx1,
sy1 + newDY2 - dy1, null);
dx1 += deltaX;
dy1 += deltaY;
}
}
}
/**
* Subclassed to always create a translucent image.
*/
protected Image createImage(Component c, int w, int h,
GraphicsConfiguration config,
Object[] args) {
if (config == null) {
return new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
}
return config.createCompatibleImage(w, h, Transparency.TRANSLUCENT);
}
}

View File

@@ -0,0 +1,133 @@
/*
* Copyright (c) 2003, 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 sun.swing.plaf.synth;
import javax.swing.plaf.synth.*;
import java.util.*;
import java.util.regex.*;
/**
* <b>WARNING:</b> This class is an implementation detail and is only
* public so that it can be used by two packages. You should NOT consider
* this public API.
* <p>
* StyleAssociation is used to lookup a style for a particular
* component (or region).
*
* @author Scott Violet
*/
public class StyleAssociation {
/**
* The style
*/
private SynthStyle _style;
/**
* Pattern used for matching.
*/
private Pattern _pattern;
/**
* Matcher used for testing if path matches that of pattern.
*/
private Matcher _matcher;
/**
* Identifier for this association.
*/
private int _id;
/**
* Returns a StyleAssociation that can be used to determine if
* a particular string matches the returned association.
*/
public static StyleAssociation createStyleAssociation(
String text, SynthStyle style)
throws PatternSyntaxException {
return createStyleAssociation(text, style, 0);
}
/**
* Returns a StyleAssociation that can be used to determine if
* a particular string matches the returned association.
*/
public static StyleAssociation createStyleAssociation(
String text, SynthStyle style, int id)
throws PatternSyntaxException {
return new StyleAssociation(text, style, id);
}
private StyleAssociation(String text, SynthStyle style, int id)
throws PatternSyntaxException {
_style = style;
_pattern = Pattern.compile(text);
_id = id;
}
/**
* Returns the developer specified identifier for this association, will
* be <code>0</code> if an identifier was not specified when this
* <code>StyleAssociation</code> was created.
*/
public int getID() {
return _id;
}
/**
* Returns true if this <code>StyleAssociation</code> matches the
* passed in CharSequence.
*
* @return true if this <code>StyleAssociation</code> matches the
* passed in CharSequence.if this StyleAssociation.
*/
public synchronized boolean matches(CharSequence path) {
if (_matcher == null) {
_matcher = _pattern.matcher(path);
}
else {
_matcher.reset(path);
}
return _matcher.matches();
}
/**
* Returns the text used in matching the string.
*
* @return the text used in matching the string.
*/
public String getText() {
return _pattern.pattern();
}
/**
* Returns the style this association is mapped to.
*
* @return the style this association is mapped to.
*/
public SynthStyle getStyle() {
return _style;
}
}

View File

@@ -0,0 +1,586 @@
/*
* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.swing.plaf.synth;
import javax.swing.plaf.synth.*;
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import java.io.File;
import java.util.regex.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.filechooser.*;
import javax.swing.plaf.*;
import javax.swing.plaf.basic.BasicFileChooserUI;
/**
* Synth FileChooserUI.
*
* Note: This class is abstract. It does not actually create the file chooser GUI.
* <p>
* Note that the classes in the com.sun.java.swing.plaf.synth
* package are not
* part of the core Java APIs. They are a part of Sun's JDK and JRE
* distributions. Although other licensees may choose to distribute
* these classes, developers cannot depend on their availability in
* non-Sun implementations. Additionally this API may change in
* incompatible ways between releases. While this class is public, it
* shoud be considered an implementation detail, and subject to change.
*
* @author Leif Samuelsson
* @author Jeff Dinkins
*/
public abstract class SynthFileChooserUI extends BasicFileChooserUI implements
SynthUI {
private JButton approveButton, cancelButton;
private SynthStyle style;
// Some generic FileChooser functions
private Action fileNameCompletionAction = new FileNameCompletionAction();
private FileFilter actualFileFilter = null;
private GlobFilter globFilter = null;
public static ComponentUI createUI(JComponent c) {
return new SynthFileChooserUIImpl((JFileChooser)c);
}
public SynthFileChooserUI(JFileChooser b) {
super(b);
}
public SynthContext getContext(JComponent c) {
return new SynthContext(c, Region.FILE_CHOOSER, style,
getComponentState(c));
}
protected SynthContext getContext(JComponent c, int state) {
Region region = SynthLookAndFeel.getRegion(c);
return new SynthContext(c, Region.FILE_CHOOSER, style, state);
}
private Region getRegion(JComponent c) {
return SynthLookAndFeel.getRegion(c);
}
private int getComponentState(JComponent c) {
if (c.isEnabled()) {
if (c.isFocusOwner()) {
return ENABLED | FOCUSED;
}
return ENABLED;
}
return DISABLED;
}
private void updateStyle(JComponent c) {
SynthStyle newStyle = SynthLookAndFeel.getStyleFactory().getStyle(c,
Region.FILE_CHOOSER);
if (newStyle != style) {
if (style != null) {
style.uninstallDefaults(getContext(c, ENABLED));
}
style = newStyle;
SynthContext context = getContext(c, ENABLED);
style.installDefaults(context);
Border border = c.getBorder();
if (border == null || border instanceof UIResource) {
c.setBorder(new UIBorder(style.getInsets(context, null)));
}
directoryIcon = style.getIcon(context, "FileView.directoryIcon");
fileIcon = style.getIcon(context, "FileView.fileIcon");
computerIcon = style.getIcon(context, "FileView.computerIcon");
hardDriveIcon = style.getIcon(context, "FileView.hardDriveIcon");
floppyDriveIcon = style.getIcon(context, "FileView.floppyDriveIcon");
newFolderIcon = style.getIcon(context, "FileChooser.newFolderIcon");
upFolderIcon = style.getIcon(context, "FileChooser.upFolderIcon");
homeFolderIcon = style.getIcon(context, "FileChooser.homeFolderIcon");
detailsViewIcon = style.getIcon(context, "FileChooser.detailsViewIcon");
listViewIcon = style.getIcon(context, "FileChooser.listViewIcon");
}
}
public void installUI(JComponent c) {
super.installUI(c);
SwingUtilities.replaceUIActionMap(c, createActionMap());
}
public void installComponents(JFileChooser fc) {
SynthContext context = getContext(fc, ENABLED);
cancelButton = new JButton(cancelButtonText);
cancelButton.setName("SynthFileChooser.cancelButton");
cancelButton.setIcon(context.getStyle().getIcon(context, "FileChooser.cancelIcon"));
cancelButton.setMnemonic(cancelButtonMnemonic);
cancelButton.setToolTipText(cancelButtonToolTipText);
cancelButton.addActionListener(getCancelSelectionAction());
approveButton = new JButton(getApproveButtonText(fc));
approveButton.setName("SynthFileChooser.approveButton");
approveButton.setIcon(context.getStyle().getIcon(context, "FileChooser.okIcon"));
approveButton.setMnemonic(getApproveButtonMnemonic(fc));
approveButton.setToolTipText(getApproveButtonToolTipText(fc));
approveButton.addActionListener(getApproveSelectionAction());
}
public void uninstallComponents(JFileChooser fc) {
fc.removeAll();
}
protected void installListeners(JFileChooser fc) {
super.installListeners(fc);
getModel().addListDataListener(new ListDataListener() {
public void contentsChanged(ListDataEvent e) {
// Update the selection after JList has been updated
new DelayedSelectionUpdater();
}
public void intervalAdded(ListDataEvent e) {
new DelayedSelectionUpdater();
}
public void intervalRemoved(ListDataEvent e) {
}
});
}
private class DelayedSelectionUpdater implements Runnable {
DelayedSelectionUpdater() {
SwingUtilities.invokeLater(this);
}
public void run() {
updateFileNameCompletion();
}
}
protected abstract ActionMap createActionMap();
protected void installDefaults(JFileChooser fc) {
super.installDefaults(fc);
updateStyle(fc);
}
protected void uninstallDefaults(JFileChooser fc) {
super.uninstallDefaults(fc);
SynthContext context = getContext(getFileChooser(), ENABLED);
style.uninstallDefaults(context);
style = null;
}
protected void installIcons(JFileChooser fc) {
// The icons are installed in updateStyle, not here
}
public void update(Graphics g, JComponent c) {
SynthContext context = getContext(c);
if (c.isOpaque()) {
g.setColor(style.getColor(context, ColorType.BACKGROUND));
g.fillRect(0, 0, c.getWidth(), c.getHeight());
}
style.getPainter(context).paintFileChooserBackground(context,
g, 0, 0, c.getWidth(), c.getHeight());
paint(context, g);
}
public void paintBorder(SynthContext context, Graphics g, int x, int y, int w, int h) {
}
public void paint(Graphics g, JComponent c) {
SynthContext context = getContext(c);
paint(context, g);
}
protected void paint(SynthContext context, Graphics g) {
}
abstract public void setFileName(String fileName);
abstract public String getFileName();
protected void doSelectedFileChanged(PropertyChangeEvent e) {
}
protected void doSelectedFilesChanged(PropertyChangeEvent e) {
}
protected void doDirectoryChanged(PropertyChangeEvent e) {
}
protected void doAccessoryChanged(PropertyChangeEvent e) {
}
protected void doFileSelectionModeChanged(PropertyChangeEvent e) {
}
protected void doMultiSelectionChanged(PropertyChangeEvent e) {
if (!getFileChooser().isMultiSelectionEnabled()) {
getFileChooser().setSelectedFiles(null);
}
}
protected void doControlButtonsChanged(PropertyChangeEvent e) {
if (getFileChooser().getControlButtonsAreShown()) {
approveButton.setText(getApproveButtonText(getFileChooser()));
approveButton.setToolTipText(getApproveButtonToolTipText(getFileChooser()));
approveButton.setMnemonic(getApproveButtonMnemonic(getFileChooser()));
}
}
protected void doAncestorChanged(PropertyChangeEvent e) {
}
public PropertyChangeListener createPropertyChangeListener(JFileChooser fc) {
return new SynthFCPropertyChangeListener();
}
private class SynthFCPropertyChangeListener implements PropertyChangeListener {
public void propertyChange(PropertyChangeEvent e) {
String prop = e.getPropertyName();
if (prop.equals(JFileChooser.FILE_SELECTION_MODE_CHANGED_PROPERTY)) {
doFileSelectionModeChanged(e);
} else if (prop.equals(JFileChooser.SELECTED_FILE_CHANGED_PROPERTY)) {
doSelectedFileChanged(e);
} else if (prop.equals(JFileChooser.SELECTED_FILES_CHANGED_PROPERTY)) {
doSelectedFilesChanged(e);
} else if (prop.equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY)) {
doDirectoryChanged(e);
} else if (prop == JFileChooser.MULTI_SELECTION_ENABLED_CHANGED_PROPERTY) {
doMultiSelectionChanged(e);
} else if (prop == JFileChooser.ACCESSORY_CHANGED_PROPERTY) {
doAccessoryChanged(e);
} else if (prop == JFileChooser.APPROVE_BUTTON_TEXT_CHANGED_PROPERTY ||
prop == JFileChooser.APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY ||
prop == JFileChooser.DIALOG_TYPE_CHANGED_PROPERTY ||
prop == JFileChooser.CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY) {
doControlButtonsChanged(e);
} else if (prop.equals("componentOrientation")) {
ComponentOrientation o = (ComponentOrientation)e.getNewValue();
JFileChooser cc = (JFileChooser)e.getSource();
if (o != (ComponentOrientation)e.getOldValue()) {
cc.applyComponentOrientation(o);
}
} else if (prop.equals("ancestor")) {
doAncestorChanged(e);
}
}
}
/**
* Responds to a File Name completion request (e.g. Tab)
*/
private class FileNameCompletionAction extends AbstractAction {
protected FileNameCompletionAction() {
super("fileNameCompletion");
}
public void actionPerformed(ActionEvent e) {
JFileChooser chooser = getFileChooser();
String fileName = getFileName();
if (fileName != null) {
// Remove whitespace from beginning and end of filename
fileName = fileName.trim();
}
resetGlobFilter();
if (fileName == null || fileName.equals("") ||
(chooser.isMultiSelectionEnabled() && fileName.startsWith("\""))) {
return;
}
FileFilter currentFilter = chooser.getFileFilter();
if (globFilter == null) {
globFilter = new GlobFilter();
}
try {
globFilter.setPattern(!isGlobPattern(fileName) ? fileName + "*" : fileName);
if (!(currentFilter instanceof GlobFilter)) {
actualFileFilter = currentFilter;
}
chooser.setFileFilter(null);
chooser.setFileFilter(globFilter);
fileNameCompletionString = fileName;
} catch (PatternSyntaxException pse) {
// Not a valid glob pattern. Abandon filter.
}
}
}
private String fileNameCompletionString;
private void updateFileNameCompletion() {
if (fileNameCompletionString != null) {
if (fileNameCompletionString.equals(getFileName())) {
File[] files = getModel().getFiles().toArray(new File[0]);
String str = getCommonStartString(files);
if (str != null && str.startsWith(fileNameCompletionString)) {
setFileName(str);
}
fileNameCompletionString = null;
}
}
}
private String getCommonStartString(File[] files) {
String str = null;
String str2 = null;
int i = 0;
if (files.length == 0) {
return null;
}
while (true) {
for (int f = 0; f < files.length; f++) {
String name = files[f].getName();
if (f == 0) {
if (name.length() == i) {
return str;
}
str2 = name.substring(0, i+1);
}
if (!name.startsWith(str2)) {
return str;
}
}
str = str2;
i++;
}
}
private void resetGlobFilter() {
if (actualFileFilter != null) {
JFileChooser chooser = getFileChooser();
FileFilter currentFilter = chooser.getFileFilter();
if (currentFilter != null && currentFilter.equals(globFilter)) {
chooser.setFileFilter(actualFileFilter);
chooser.removeChoosableFileFilter(globFilter);
}
actualFileFilter = null;
}
}
private static boolean isGlobPattern(String fileName) {
return ((File.separatorChar == '\\' && fileName.indexOf('*') >= 0)
|| (File.separatorChar == '/' && (fileName.indexOf('*') >= 0
|| fileName.indexOf('?') >= 0
|| fileName.indexOf('[') >= 0)));
}
/* A file filter which accepts file patterns containing
* the special wildcard '*' on windows, plus '?', and '[ ]' on Unix.
*/
class GlobFilter extends FileFilter {
Pattern pattern;
String globPattern;
public void setPattern(String globPattern) {
char[] gPat = globPattern.toCharArray();
char[] rPat = new char[gPat.length * 2];
boolean isWin32 = (File.separatorChar == '\\');
boolean inBrackets = false;
int j = 0;
this.globPattern = globPattern;
if (isWin32) {
// On windows, a pattern ending with *.* is equal to ending with *
int len = gPat.length;
if (globPattern.endsWith("*.*")) {
len -= 2;
}
for (int i = 0; i < len; i++) {
if (gPat[i] == '*') {
rPat[j++] = '.';
}
rPat[j++] = gPat[i];
}
} else {
for (int i = 0; i < gPat.length; i++) {
switch(gPat[i]) {
case '*':
if (!inBrackets) {
rPat[j++] = '.';
}
rPat[j++] = '*';
break;
case '?':
rPat[j++] = inBrackets ? '?' : '.';
break;
case '[':
inBrackets = true;
rPat[j++] = gPat[i];
if (i < gPat.length - 1) {
switch (gPat[i+1]) {
case '!':
case '^':
rPat[j++] = '^';
i++;
break;
case ']':
rPat[j++] = gPat[++i];
break;
}
}
break;
case ']':
rPat[j++] = gPat[i];
inBrackets = false;
break;
case '\\':
if (i == 0 && gPat.length > 1 && gPat[1] == '~') {
rPat[j++] = gPat[++i];
} else {
rPat[j++] = '\\';
if (i < gPat.length - 1 && "*?[]".indexOf(gPat[i+1]) >= 0) {
rPat[j++] = gPat[++i];
} else {
rPat[j++] = '\\';
}
}
break;
default:
//if ("+()|^$.{}<>".indexOf(gPat[i]) >= 0) {
if (!Character.isLetterOrDigit(gPat[i])) {
rPat[j++] = '\\';
}
rPat[j++] = gPat[i];
break;
}
}
}
this.pattern = Pattern.compile(new String(rPat, 0, j), Pattern.CASE_INSENSITIVE);
}
public boolean accept(File f) {
if (f == null) {
return false;
}
if (f.isDirectory()) {
return true;
}
return pattern.matcher(f.getName()).matches();
}
public String getDescription() {
return globPattern;
}
}
// *******************************************************
// ************ FileChooser UI PLAF methods **************
// *******************************************************
// *****************************
// ***** Directory Actions *****
// *****************************
public Action getFileNameCompletionAction() {
return fileNameCompletionAction;
}
protected JButton getApproveButton(JFileChooser fc) {
return approveButton;
}
protected JButton getCancelButton(JFileChooser fc) {
return cancelButton;
}
// Overload to do nothing. We don't have and icon cache.
public void clearIconCache() { }
// Copied as SynthBorder is package private in synth
private class UIBorder extends AbstractBorder implements UIResource {
private Insets _insets;
UIBorder(Insets insets) {
if (insets != null) {
_insets = new Insets(insets.top, insets.left, insets.bottom,
insets.right);
}
else {
_insets = null;
}
}
public void paintBorder(Component c, Graphics g, int x, int y,
int width, int height) {
if (!(c instanceof JComponent)) {
return;
}
JComponent jc = (JComponent)c;
SynthContext context = getContext(jc);
SynthStyle style = context.getStyle();
if (style != null) {
style.getPainter(context).paintFileChooserBorder(
context, g, x, y, width, height);
}
}
public Insets getBorderInsets(Component c, Insets insets) {
if (insets == null) {
insets = new Insets(0, 0, 0, 0);
}
if (_insets != null) {
insets.top = _insets.top;
insets.bottom = _insets.bottom;
insets.left = _insets.left;
insets.right = _insets.right;
}
else {
insets.top = insets.bottom = insets.right = insets.left = 0;
}
return insets;
}
public boolean isBorderOpaque() {
return false;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,126 @@
/*
* Copyright (c) 2002, 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 sun.swing.plaf.synth;
import javax.swing.plaf.synth.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.plaf.UIResource;
/**
* An icon that is passed a SynthContext. Subclasses need only implement
* the variants that take a SynthContext, but must be prepared for the
* SynthContext to be null.
*
* @author Scott Violet
*/
public abstract class SynthIcon implements Icon {
public static int getIconWidth(Icon icon, SynthContext context) {
if (icon == null) {
return 0;
}
if (icon instanceof SynthIcon) {
return ((SynthIcon)icon).getIconWidth(context);
}
return icon.getIconWidth();
}
public static int getIconHeight(Icon icon, SynthContext context) {
if (icon == null) {
return 0;
}
if (icon instanceof SynthIcon) {
return ((SynthIcon)icon).getIconHeight(context);
}
return icon.getIconHeight();
}
public static void paintIcon(Icon icon, SynthContext context, Graphics g,
int x, int y, int w, int h) {
if (icon instanceof SynthIcon) {
((SynthIcon)icon).paintIcon(context, g, x, y, w, h);
}
else if (icon != null) {
icon.paintIcon(context.getComponent(), g, x, y);
}
}
/**
* Paints the icon at the specified location.
*
* @param context Identifies hosting region, may be null.
* @param x x location to paint to
* @param y y location to paint to
* @param w Width of the region to paint to, may be 0
* @param h Height of the region to paint to, may be 0
*/
public abstract void paintIcon(SynthContext context, Graphics g, int x,
int y, int w, int h);
/**
* Returns the desired width of the Icon.
*
* @param context SynthContext requesting the Icon, may be null.
* @return Desired width of the icon.
*/
public abstract int getIconWidth(SynthContext context);
/**
* Returns the desired height of the Icon.
*
* @param context SynthContext requesting the Icon, may be null.
* @return Desired height of the icon.
*/
public abstract int getIconHeight(SynthContext context);
/**
* Paints the icon. This is a cover method for
* <code>paintIcon(null, g, x, y, 0, 0)</code>
*/
public void paintIcon(Component c, Graphics g, int x, int y) {
paintIcon(null, g, x, y, 0, 0);
}
/**
* Returns the icon's width. This is a cover methods for
* <code>getIconWidth(null)</code>.
*
* @return an int specifying the fixed width of the icon.
*/
public int getIconWidth() {
return getIconWidth(null);
}
/**
* Returns the icon's height. This is a cover method for
* <code>getIconHeight(null)</code>.
*
* @return an int specifying the fixed height of the icon.
*/
public int getIconHeight() {
return getIconHeight(null);
}
}

View File

@@ -0,0 +1,97 @@
/*
* 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 sun.swing.plaf.windows;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.io.Serializable;
import javax.swing.Icon;
import javax.swing.UIManager;
import javax.swing.plaf.UIResource;
/**
* Classic sort icons.
*
*/
public class ClassicSortArrowIcon implements Icon, UIResource, Serializable{
private static final int X_OFFSET = 9;
private boolean ascending;
public ClassicSortArrowIcon(boolean ascending) {
this.ascending = ascending;
}
public void paintIcon(Component c, Graphics g, int x, int y) {
x += X_OFFSET;
if (ascending) {
g.setColor(UIManager.getColor("Table.sortIconHighlight"));
drawSide(g, x + 3, y, -1);
g.setColor(UIManager.getColor("Table.sortIconLight"));
drawSide(g, x + 4, y, 1);
g.fillRect(x + 1, y + 6, 6, 1);
}
else {
g.setColor(UIManager.getColor("Table.sortIconHighlight"));
drawSide(g, x + 3, y + 6, -1);
g.fillRect(x + 1, y, 6, 1);
g.setColor(UIManager.getColor("Table.sortIconLight"));
drawSide(g, x + 4, y + 6, 1);
}
}
private void drawSide(Graphics g, int x, int y, int xIncrement) {
int yIncrement = 2;
if (ascending) {
g.fillRect(x, y, 1, 2);
y++;
}
else {
g.fillRect(x, --y, 1, 2);
yIncrement = -2;
y -= 2;
}
x += xIncrement;
for (int i = 0; i < 2; i++) {
g.fillRect(x, y, 1, 3);
x += xIncrement;
y += yIncrement;
}
if (!ascending) {
y++;
}
g.fillRect(x, y, 1, 2);
}
public int getIconWidth() {
return X_OFFSET + 8;
}
public int getIconHeight() {
return 9;
}
}

View File

@@ -0,0 +1,197 @@
/*
* Copyright (c) 2005, 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 sun.swing.table;
import sun.swing.DefaultLookup;
import java.awt.Component;
import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.io.Serializable;
import javax.swing.*;
import javax.swing.plaf.UIResource;
import javax.swing.border.Border;
import javax.swing.table.*;
public class DefaultTableCellHeaderRenderer extends DefaultTableCellRenderer
implements UIResource {
private boolean horizontalTextPositionSet;
private Icon sortArrow;
private EmptyIcon emptyIcon = new EmptyIcon();
public DefaultTableCellHeaderRenderer() {
setHorizontalAlignment(JLabel.CENTER);
}
public void setHorizontalTextPosition(int textPosition) {
horizontalTextPositionSet = true;
super.setHorizontalTextPosition(textPosition);
}
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
Icon sortIcon = null;
boolean isPaintingForPrint = false;
if (table != null) {
JTableHeader header = table.getTableHeader();
if (header != null) {
Color fgColor = null;
Color bgColor = null;
if (hasFocus) {
fgColor = DefaultLookup.getColor(this, ui, "TableHeader.focusCellForeground");
bgColor = DefaultLookup.getColor(this, ui, "TableHeader.focusCellBackground");
}
if (fgColor == null) {
fgColor = header.getForeground();
}
if (bgColor == null) {
bgColor = header.getBackground();
}
setForeground(fgColor);
setBackground(bgColor);
setFont(header.getFont());
isPaintingForPrint = header.isPaintingForPrint();
}
if (!isPaintingForPrint && table.getRowSorter() != null) {
if (!horizontalTextPositionSet) {
// There is a row sorter, and the developer hasn't
// set a text position, change to leading.
setHorizontalTextPosition(JLabel.LEADING);
}
SortOrder sortOrder = getColumnSortOrder(table, column);
if (sortOrder != null) {
switch(sortOrder) {
case ASCENDING:
sortIcon = DefaultLookup.getIcon(
this, ui, "Table.ascendingSortIcon");
break;
case DESCENDING:
sortIcon = DefaultLookup.getIcon(
this, ui, "Table.descendingSortIcon");
break;
case UNSORTED:
sortIcon = DefaultLookup.getIcon(
this, ui, "Table.naturalSortIcon");
break;
}
}
}
}
setText(value == null ? "" : value.toString());
setIcon(sortIcon);
sortArrow = sortIcon;
Border border = null;
if (hasFocus) {
border = DefaultLookup.getBorder(this, ui, "TableHeader.focusCellBorder");
}
if (border == null) {
border = DefaultLookup.getBorder(this, ui, "TableHeader.cellBorder");
}
setBorder(border);
return this;
}
public static SortOrder getColumnSortOrder(JTable table, int column) {
SortOrder rv = null;
if (table == null || table.getRowSorter() == null) {
return rv;
}
java.util.List<? extends RowSorter.SortKey> sortKeys =
table.getRowSorter().getSortKeys();
if (sortKeys.size() > 0 && sortKeys.get(0).getColumn() ==
table.convertColumnIndexToModel(column)) {
rv = sortKeys.get(0).getSortOrder();
}
return rv;
}
@Override
public void paintComponent(Graphics g) {
boolean b = DefaultLookup.getBoolean(this, ui,
"TableHeader.rightAlignSortArrow", false);
if (b && sortArrow != null) {
//emptyIcon is used so that if the text in the header is right
//aligned, or if the column is too narrow, then the text will
//be sized appropriately to make room for the icon that is about
//to be painted manually here.
emptyIcon.width = sortArrow.getIconWidth();
emptyIcon.height = sortArrow.getIconHeight();
setIcon(emptyIcon);
super.paintComponent(g);
Point position = computeIconPosition(g);
sortArrow.paintIcon(this, g, position.x, position.y);
} else {
super.paintComponent(g);
}
}
private Point computeIconPosition(Graphics g) {
FontMetrics fontMetrics = g.getFontMetrics();
Rectangle viewR = new Rectangle();
Rectangle textR = new Rectangle();
Rectangle iconR = new Rectangle();
Insets i = getInsets();
viewR.x = i.left;
viewR.y = i.top;
viewR.width = getWidth() - (i.left + i.right);
viewR.height = getHeight() - (i.top + i.bottom);
SwingUtilities.layoutCompoundLabel(
this,
fontMetrics,
getText(),
sortArrow,
getVerticalAlignment(),
getHorizontalAlignment(),
getVerticalTextPosition(),
getHorizontalTextPosition(),
viewR,
iconR,
textR,
getIconTextGap());
int x = getWidth() - i.right - sortArrow.getIconWidth();
int y = iconR.y;
return new Point(x, y);
}
private class EmptyIcon implements Icon, Serializable {
int width = 0;
int height = 0;
public void paintIcon(Component c, Graphics g, int x, int y) {}
public int getIconWidth() { return width; }
public int getIconHeight() { return height; }
}
}

View File

@@ -0,0 +1,73 @@
/*
* 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 sun.swing.text;
import java.util.*;
import java.awt.Graphics;
import java.awt.print.*;
/**
* Printable to merge multiple printables into one.
*
* @author Igor Kushnirskiy
*
* @since 1.6
*/
class CompoundPrintable implements CountingPrintable {
private final Queue<CountingPrintable> printables;
private int offset = 0;
public CompoundPrintable(List<CountingPrintable> printables) {
this.printables = new LinkedList<CountingPrintable>(printables);
}
public int print(final Graphics graphics,
final PageFormat pf,
final int pageIndex) throws PrinterException {
int ret = NO_SUCH_PAGE;
while (printables.peek() != null) {
ret = printables.peek().print(graphics, pf, pageIndex - offset);
if (ret == PAGE_EXISTS) {
break;
} else {
offset += printables.poll().getNumberOfPages();
}
}
return ret;
}
/**
* Returns the number of pages in this printable.
* <p>
* This number is defined only after {@code print} returns NO_SUCH_PAGE.
*
* @return the number of pages.
*/
public int getNumberOfPages() {
return offset;
}
}

View File

@@ -0,0 +1,47 @@
/*
* 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 sun.swing.text;
import java.awt.print.*;
/**
* Printable which counts the number of pages.
*
* @author Igor Kushnirskiy
*
* @since 1.6
*/
public interface CountingPrintable extends Printable {
/**
* Returns the number of pages in this printable.
* <p>
* This number is defined only after {@code print} returns NO_SUCH_PAGE.
*
* @return the number of pages.
*/
int getNumberOfPages();
}

View File

@@ -0,0 +1,846 @@
/*
* Copyright (c) 2005, 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 sun.swing.text;
import java.awt.ComponentOrientation;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.Component;
import java.awt.Container;
import java.awt.font.FontRenderContext;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.atomic.AtomicReference;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
import javax.swing.text.BadLocationException;
import javax.swing.text.JTextComponent;
import javax.swing.text.Document;
import javax.swing.text.EditorKit;
import javax.swing.text.AbstractDocument;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTML;
import sun.font.FontDesignMetrics;
import sun.swing.text.html.FrameEditorPaneTag;
/**
* An implementation of {@code Printable} to print {@code JTextComponent} with
* the header and footer.
*
* <h1>
* WARNING: this class is to be used in
* javax.swing.text.JTextComponent only.
* </h1>
*
* <p>
* The implementation creates a new {@code JTextComponent} ({@code printShell})
* to print the content using the {@code Document}, {@code EditorKit} and
* rendering-affecting properties from the original {@code JTextComponent}.
*
* <p>
* {@code printShell} is laid out on the first {@code print} invocation.
*
* <p>
* This class can be used on any thread. Part of the implementation is executed
* on the EDT though.
*
* @author Igor Kushnirskiy
*
* @since 1.6
*/
public class TextComponentPrintable implements CountingPrintable {
private static final int LIST_SIZE = 1000;
private boolean isLayouted = false;
/*
* The text component to print.
*/
private final JTextComponent textComponentToPrint;
/*
* The FontRenderContext to layout and print with
*/
private final AtomicReference<FontRenderContext> frc =
new AtomicReference<FontRenderContext>(null);
/**
* Special text component used to print to the printer.
*/
private final JTextComponent printShell;
private final MessageFormat headerFormat;
private final MessageFormat footerFormat;
private static final float HEADER_FONT_SIZE = 18.0f;
private static final float FOOTER_FONT_SIZE = 12.0f;
private final Font headerFont;
private final Font footerFont;
/**
* stores metrics for the unhandled rows. The only metrics we need are
* yStart and yEnd when row is handled by updatePagesMetrics it is removed
* from the list. Thus the head of the list is the fist row to handle.
*
* sorted
*/
private final List<IntegerSegment> rowsMetrics;
/**
* thread-safe list for storing pages metrics. The only metrics we need are
* yStart and yEnd.
* It has to be thread-safe since metrics are calculated on
* the printing thread and accessed on the EDT thread.
*
* sorted
*/
private final List<IntegerSegment> pagesMetrics;
/**
* Returns {@code TextComponentPrintable} to print {@code textComponent}.
*
* @param textComponent {@code JTextComponent} to print
* @param headerFormat the page header, or {@code null} for none
* @param footerFormat the page footer, or {@code null} for none
* @return {@code TextComponentPrintable} to print {@code textComponent}
*/
public static Printable getPrintable(final JTextComponent textComponent,
final MessageFormat headerFormat,
final MessageFormat footerFormat) {
if (textComponent instanceof JEditorPane
&& isFrameSetDocument(textComponent.getDocument())) {
//for document with frames we create one printable per
//frame and merge them with the CompoundPrintable.
List<JEditorPane> frames = getFrames((JEditorPane) textComponent);
List<CountingPrintable> printables =
new ArrayList<CountingPrintable>();
for (JEditorPane frame : frames) {
printables.add((CountingPrintable)
getPrintable(frame, headerFormat, footerFormat));
}
return new CompoundPrintable(printables);
} else {
return new TextComponentPrintable(textComponent,
headerFormat, footerFormat);
}
}
/**
* Checks whether the document has frames. Only HTMLDocument might
* have frames.
*
* @param document the {@code Document} to check
* @return {@code true} if the {@code document} has frames
*/
private static boolean isFrameSetDocument(final Document document) {
boolean ret = false;
if (document instanceof HTMLDocument) {
HTMLDocument htmlDocument = (HTMLDocument)document;
if (htmlDocument.getIterator(HTML.Tag.FRAME).isValid()) {
ret = true;
}
}
return ret;
}
/**
* Returns frames under the {@code editor}.
* The frames are created if necessary.
*
* @param editor the {@JEditorPane} to find the frames for
* @return list of all frames
*/
private static List<JEditorPane> getFrames(final JEditorPane editor) {
List<JEditorPane> list = new ArrayList<JEditorPane>();
getFrames(editor, list);
if (list.size() == 0) {
//the frames have not been created yet.
//let's trigger the frames creation.
createFrames(editor);
getFrames(editor, list);
}
return list;
}
/**
* Adds all {@code JEditorPanes} under {@code container} tagged by {@code
* FrameEditorPaneTag} to the {@code list}. It adds only top
* level {@code JEditorPanes}. For instance if there is a frame
* inside the frame it will return the top frame only.
*
* @param c the container to find all frames under
* @param list {@code List} to append the results too
*/
private static void getFrames(final Container container, List<JEditorPane> list) {
for (Component c : container.getComponents()) {
if (c instanceof FrameEditorPaneTag
&& c instanceof JEditorPane ) { //it should be always JEditorPane
list.add((JEditorPane) c);
} else {
if (c instanceof Container) {
getFrames((Container) c, list);
}
}
}
}
/**
* Triggers the frames creation for {@code JEditorPane}
*
* @param editor the {@code JEditorPane} to create frames for
*/
private static void createFrames(final JEditorPane editor) {
Runnable doCreateFrames =
new Runnable() {
public void run() {
final int WIDTH = 500;
final int HEIGHT = 500;
CellRendererPane rendererPane = new CellRendererPane();
rendererPane.add(editor);
//the values do not matter
//we only need to get frames created
rendererPane.setSize(WIDTH, HEIGHT);
};
};
if (SwingUtilities.isEventDispatchThread()) {
doCreateFrames.run();
} else {
try {
SwingUtilities.invokeAndWait(doCreateFrames);
} catch (Exception e) {
if (e instanceof RuntimeException) {
throw (RuntimeException) e;
} else {
throw new RuntimeException(e);
}
}
}
}
/**
* Constructs {@code TextComponentPrintable} to print {@code JTextComponent}
* {@code textComponent} with {@code headerFormat} and {@code footerFormat}.
*
* @param textComponent {@code JTextComponent} to print
* @param headerFormat the page header or {@code null} for none
* @param footerFormat the page footer or {@code null} for none
*/
private TextComponentPrintable(JTextComponent textComponent,
MessageFormat headerFormat,
MessageFormat footerFormat) {
this.textComponentToPrint = textComponent;
this.headerFormat = headerFormat;
this.footerFormat = footerFormat;
headerFont = textComponent.getFont().deriveFont(Font.BOLD,
HEADER_FONT_SIZE);
footerFont = textComponent.getFont().deriveFont(Font.PLAIN,
FOOTER_FONT_SIZE);
this.pagesMetrics =
Collections.synchronizedList(new ArrayList<IntegerSegment>());
this.rowsMetrics = new ArrayList<IntegerSegment>(LIST_SIZE);
this.printShell = createPrintShell(textComponent);
}
/**
* creates a printShell.
* It creates closest text component to {@code textComponent}
* which uses {@code frc} from the {@code TextComponentPrintable}
* for the {@code getFontMetrics} method.
*
* @param textComponent {@code JTextComponent} to create a
* printShell for
* @return the print shell
*/
private JTextComponent createPrintShell(final JTextComponent textComponent) {
if (SwingUtilities.isEventDispatchThread()) {
return createPrintShellOnEDT(textComponent);
} else {
FutureTask<JTextComponent> futureCreateShell =
new FutureTask<JTextComponent>(
new Callable<JTextComponent>() {
public JTextComponent call() throws Exception {
return createPrintShellOnEDT(textComponent);
}
});
SwingUtilities.invokeLater(futureCreateShell);
try {
return futureCreateShell.get();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (ExecutionException e) {
Throwable cause = e.getCause();
if (cause instanceof Error) {
throw (Error) cause;
}
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
}
throw new AssertionError(cause);
}
}
}
private JTextComponent createPrintShellOnEDT(final JTextComponent textComponent) {
assert SwingUtilities.isEventDispatchThread();
JTextComponent ret = null;
if (textComponent instanceof JPasswordField) {
ret =
new JPasswordField() {
{
setEchoChar(((JPasswordField) textComponent).getEchoChar());
setHorizontalAlignment(
((JTextField) textComponent).getHorizontalAlignment());
}
@Override
public FontMetrics getFontMetrics(Font font) {
return (frc.get() == null)
? super.getFontMetrics(font)
: FontDesignMetrics.getMetrics(font, frc.get());
}
};
} else if (textComponent instanceof JTextField) {
ret =
new JTextField() {
{
setHorizontalAlignment(
((JTextField) textComponent).getHorizontalAlignment());
}
@Override
public FontMetrics getFontMetrics(Font font) {
return (frc.get() == null)
? super.getFontMetrics(font)
: FontDesignMetrics.getMetrics(font, frc.get());
}
};
} else if (textComponent instanceof JTextArea) {
ret =
new JTextArea() {
{
JTextArea textArea = (JTextArea) textComponent;
setLineWrap(textArea.getLineWrap());
setWrapStyleWord(textArea.getWrapStyleWord());
setTabSize(textArea.getTabSize());
}
@Override
public FontMetrics getFontMetrics(Font font) {
return (frc.get() == null)
? super.getFontMetrics(font)
: FontDesignMetrics.getMetrics(font, frc.get());
}
};
} else if (textComponent instanceof JTextPane) {
ret =
new JTextPane() {
@Override
public FontMetrics getFontMetrics(Font font) {
return (frc.get() == null)
? super.getFontMetrics(font)
: FontDesignMetrics.getMetrics(font, frc.get());
}
@Override
public EditorKit getEditorKit() {
if (getDocument() == textComponent.getDocument()) {
return ((JTextPane) textComponent).getEditorKit();
} else {
return super.getEditorKit();
}
}
};
} else if (textComponent instanceof JEditorPane) {
ret =
new JEditorPane() {
@Override
public FontMetrics getFontMetrics(Font font) {
return (frc.get() == null)
? super.getFontMetrics(font)
: FontDesignMetrics.getMetrics(font, frc.get());
}
@Override
public EditorKit getEditorKit() {
if (getDocument() == textComponent.getDocument()) {
return ((JEditorPane) textComponent).getEditorKit();
} else {
return super.getEditorKit();
}
}
};
}
//want to occupy the whole width and height by text
ret.setBorder(null);
//set properties from the component to print
ret.setOpaque(textComponent.isOpaque());
ret.setEditable(textComponent.isEditable());
ret.setEnabled(textComponent.isEnabled());
ret.setFont(textComponent.getFont());
ret.setBackground(textComponent.getBackground());
ret.setForeground(textComponent.getForeground());
ret.setComponentOrientation(
textComponent.getComponentOrientation());
if (ret instanceof JEditorPane) {
ret.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES,
textComponent.getClientProperty(
JEditorPane.HONOR_DISPLAY_PROPERTIES));
ret.putClientProperty(JEditorPane.W3C_LENGTH_UNITS,
textComponent.getClientProperty(JEditorPane.W3C_LENGTH_UNITS));
ret.putClientProperty("charset",
textComponent.getClientProperty("charset"));
}
ret.setDocument(textComponent.getDocument());
return ret;
}
/**
* Returns the number of pages in this printable.
* <p>
* This number is defined only after {@code print} returns NO_SUCH_PAGE.
*
* @return the number of pages.
*/
public int getNumberOfPages() {
return pagesMetrics.size();
}
/**
* See Printable.print for the API description.
*
* There are two parts in the implementation.
* First part (print) is to be called on the printing thread.
* Second part (printOnEDT) is to be called on the EDT only.
*
* print triggers printOnEDT
*/
public int print(final Graphics graphics,
final PageFormat pf,
final int pageIndex) throws PrinterException {
if (!isLayouted) {
if (graphics instanceof Graphics2D) {
frc.set(((Graphics2D)graphics).getFontRenderContext());
}
layout((int)Math.floor(pf.getImageableWidth()));
calculateRowsMetrics();
}
int ret;
if (!SwingUtilities.isEventDispatchThread()) {
Callable<Integer> doPrintOnEDT = new Callable<Integer>() {
public Integer call() throws Exception {
return printOnEDT(graphics, pf, pageIndex);
}
};
FutureTask<Integer> futurePrintOnEDT =
new FutureTask<Integer>(doPrintOnEDT);
SwingUtilities.invokeLater(futurePrintOnEDT);
try {
ret = futurePrintOnEDT.get();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (ExecutionException e) {
Throwable cause = e.getCause();
if (cause instanceof PrinterException) {
throw (PrinterException)cause;
} else if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof Error) {
throw (Error) cause;
} else {
throw new RuntimeException(cause);
}
}
} else {
ret = printOnEDT(graphics, pf, pageIndex);
}
return ret;
}
/**
* The EDT part of the print method.
*
* This method is to be called on the EDT only. Layout should be done before
* calling this method.
*/
private int printOnEDT(final Graphics graphics,
final PageFormat pf,
final int pageIndex) throws PrinterException {
assert SwingUtilities.isEventDispatchThread();
Border border = BorderFactory.createEmptyBorder();
//handle header and footer
if (headerFormat != null || footerFormat != null) {
//Printable page enumeration is 0 base. We need 1 based.
Object[] formatArg = new Object[]{Integer.valueOf(pageIndex + 1)};
if (headerFormat != null) {
border = new TitledBorder(border,
headerFormat.format(formatArg),
TitledBorder.CENTER, TitledBorder.ABOVE_TOP,
headerFont, printShell.getForeground());
}
if (footerFormat != null) {
border = new TitledBorder(border,
footerFormat.format(formatArg),
TitledBorder.CENTER, TitledBorder.BELOW_BOTTOM,
footerFont, printShell.getForeground());
}
}
Insets borderInsets = border.getBorderInsets(printShell);
updatePagesMetrics(pageIndex,
(int)Math.floor(pf.getImageableHeight()) - borderInsets.top
- borderInsets.bottom);
if (pagesMetrics.size() <= pageIndex) {
return NO_SUCH_PAGE;
}
Graphics2D g2d = (Graphics2D)graphics.create();
g2d.translate(pf.getImageableX(), pf.getImageableY());
border.paintBorder(printShell, g2d, 0, 0,
(int)Math.floor(pf.getImageableWidth()),
(int)Math.floor(pf.getImageableHeight()));
g2d.translate(0, borderInsets.top);
//want to clip only vertically
Rectangle clip = new Rectangle(0, 0,
(int) pf.getWidth(),
pagesMetrics.get(pageIndex).end
- pagesMetrics.get(pageIndex).start + 1);
g2d.clip(clip);
int xStart = 0;
if (ComponentOrientation.RIGHT_TO_LEFT ==
printShell.getComponentOrientation()) {
xStart = (int) pf.getImageableWidth() - printShell.getWidth();
}
g2d.translate(xStart, - pagesMetrics.get(pageIndex).start);
printShell.print(g2d);
g2d.dispose();
return Printable.PAGE_EXISTS;
}
private boolean needReadLock = false;
/**
* Tries to release document's readlock
*
* Note: Not to be called on the EDT.
*/
private void releaseReadLock() {
assert ! SwingUtilities.isEventDispatchThread();
Document document = textComponentToPrint.getDocument();
if (document instanceof AbstractDocument) {
try {
((AbstractDocument) document).readUnlock();
needReadLock = true;
} catch (Error ignore) {
// readUnlock() might throw StateInvariantError
}
}
}
/**
* Tries to acquire document's readLock if it was released
* in releaseReadLock() method.
*
* Note: Not to be called on the EDT.
*/
private void acquireReadLock() {
assert ! SwingUtilities.isEventDispatchThread();
if (needReadLock) {
try {
/*
* wait until all the EDT events are processed
* some of the document changes are asynchronous
* we need to make sure we get the lock after those changes
*/
SwingUtilities.invokeAndWait(
new Runnable() {
public void run() {
}
});
} catch (InterruptedException ignore) {
} catch (java.lang.reflect.InvocationTargetException ignore) {
}
Document document = textComponentToPrint.getDocument();
((AbstractDocument) document).readLock();
needReadLock = false;
}
}
/**
* Prepares {@code printShell} for printing.
*
* Sets properties from the component to print.
* Sets width and FontRenderContext.
*
* Triggers Views creation for the printShell.
*
* There are two parts in the implementation.
* First part (layout) is to be called on the printing thread.
* Second part (layoutOnEDT) is to be called on the EDT only.
*
* {@code layout} triggers {@code layoutOnEDT}.
*
* @param width width to layout the text for
*/
private void layout(final int width) {
if (!SwingUtilities.isEventDispatchThread()) {
Callable<Object> doLayoutOnEDT = new Callable<Object>() {
public Object call() throws Exception {
layoutOnEDT(width);
return null;
}
};
FutureTask<Object> futureLayoutOnEDT = new FutureTask<Object>(
doLayoutOnEDT);
/*
* We need to release document's readlock while printShell is
* initializing
*/
releaseReadLock();
SwingUtilities.invokeLater(futureLayoutOnEDT);
try {
futureLayoutOnEDT.get();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (ExecutionException e) {
Throwable cause = e.getCause();
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof Error) {
throw (Error) cause;
} else {
throw new RuntimeException(cause);
}
} finally {
acquireReadLock();
}
} else {
layoutOnEDT(width);
}
isLayouted = true;
}
/**
* The EDT part of layout method.
*
* This method is to be called on the EDT only.
*/
private void layoutOnEDT(final int width) {
assert SwingUtilities.isEventDispatchThread();
//need to have big value but smaller than MAX_VALUE otherwise
//printing goes south due to overflow somewhere
final int HUGE_INTEGER = Integer.MAX_VALUE - 1000;
CellRendererPane rendererPane = new CellRendererPane();
//need to use JViewport since text is layouted to the viewPort width
//otherwise it will be layouted to the maximum text width
JViewport viewport = new JViewport();
viewport.setBorder(null);
Dimension size = new Dimension(width, HUGE_INTEGER);
//JTextField is a special case
//it layouts text in the middle by Y
if (printShell instanceof JTextField) {
size =
new Dimension(size.width, printShell.getPreferredSize().height);
}
printShell.setSize(size);
viewport.setComponentOrientation(printShell.getComponentOrientation());
viewport.setSize(size);
viewport.add(printShell);
rendererPane.add(viewport);
}
/**
* Calculates pageMetrics for the pages up to the {@code pageIndex} using
* {@code rowsMetrics}.
* Metrics are stored in the {@code pagesMetrics}.
*
* @param pageIndex the page to update the metrics for
* @param pageHeight the page height
*/
private void updatePagesMetrics(final int pageIndex, final int pageHeight) {
while (pageIndex >= pagesMetrics.size() && !rowsMetrics.isEmpty()) {
// add one page to the pageMetrics
int lastPage = pagesMetrics.size() - 1;
int pageStart = (lastPage >= 0)
? pagesMetrics.get(lastPage).end + 1
: 0;
int rowIndex;
for (rowIndex = 0;
rowIndex < rowsMetrics.size()
&& (rowsMetrics.get(rowIndex).end - pageStart + 1)
<= pageHeight;
rowIndex++) {
}
if (rowIndex == 0) {
// can not fit a single row
// need to split
pagesMetrics.add(
new IntegerSegment(pageStart, pageStart + pageHeight - 1));
} else {
rowIndex--;
pagesMetrics.add(new IntegerSegment(pageStart,
rowsMetrics.get(rowIndex).end));
for (int i = 0; i <= rowIndex; i++) {
rowsMetrics.remove(0);
}
}
}
}
/**
* Calculates rowsMetrics for the document. The result is stored
* in the {@code rowsMetrics}.
*
* Two steps process.
* First step is to find yStart and yEnd for the every document position.
* Second step is to merge all intersected segments ( [yStart, yEnd] ).
*/
private void calculateRowsMetrics() {
final int documentLength = printShell.getDocument().getLength();
List<IntegerSegment> documentMetrics = new ArrayList<IntegerSegment>(LIST_SIZE);
Rectangle rect;
for (int i = 0, previousY = -1, previousHeight = -1; i < documentLength;
i++) {
try {
rect = printShell.modelToView(i);
if (rect != null) {
int y = (int) rect.getY();
int height = (int) rect.getHeight();
if (height != 0
&& (y != previousY || height != previousHeight)) {
/*
* we do not store the same value as previous. in our
* documents it is often for consequent positons to have
* the same modelToView y and height.
*/
previousY = y;
previousHeight = height;
documentMetrics.add(new IntegerSegment(y, y + height - 1));
}
}
} catch (BadLocationException e) {
assert false;
}
}
/*
* Merge all intersected segments.
*/
Collections.sort(documentMetrics);
int yStart = Integer.MIN_VALUE;
int yEnd = Integer.MIN_VALUE;
for (IntegerSegment segment : documentMetrics) {
if (yEnd < segment.start) {
if (yEnd != Integer.MIN_VALUE) {
rowsMetrics.add(new IntegerSegment(yStart, yEnd));
}
yStart = segment.start;
yEnd = segment.end;
} else {
yEnd = segment.end;
}
}
if (yEnd != Integer.MIN_VALUE) {
rowsMetrics.add(new IntegerSegment(yStart, yEnd));
}
}
/**
* Class to represent segment of integers.
* we do not call it Segment to avoid confusion with
* javax.swing.text.Segment
*/
private static class IntegerSegment implements Comparable<IntegerSegment> {
final int start;
final int end;
IntegerSegment(int start, int end) {
this.start = start;
this.end = end;
}
public int compareTo(IntegerSegment object) {
int startsDelta = start - object.start;
return (startsDelta != 0) ? startsDelta : end - object.end;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof IntegerSegment) {
return compareTo((IntegerSegment) obj) == 0;
} else {
return false;
}
}
@Override
public int hashCode() {
// from the "Effective Java: Programming Language Guide"
int result = 17;
result = 37 * result + start;
result = 37 * result + end;
return result;
}
@Override
public String toString() {
return "IntegerSegment [" + start + ", " + end + "]";
}
}
}

View File

@@ -0,0 +1,36 @@
/*
* 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 sun.swing.text.html;
/**
* This interface is used only for tagging
* FrameEditorPane in javax.swing.text.html.FrameView.
*/
public interface FrameEditorPaneTag {
}