feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
160
jdkSrc/jdk8/sun/swing/AccumulativeRunnable.java
Normal file
160
jdkSrc/jdk8/sun/swing/AccumulativeRunnable.java
Normal 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<String> 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<Rectangle> 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;
|
||||
}
|
||||
}
|
||||
93
jdkSrc/jdk8/sun/swing/BakedArrayList.java
Normal file
93
jdkSrc/jdk8/sun/swing/BakedArrayList.java
Normal 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;
|
||||
}
|
||||
}
|
||||
293
jdkSrc/jdk8/sun/swing/BeanInfoUtils.java
Normal file
293
jdkSrc/jdk8/sun/swing/BeanInfoUtils.java
Normal 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);
|
||||
}
|
||||
}
|
||||
213
jdkSrc/jdk8/sun/swing/CachedPainter.java
Normal file
213
jdkSrc/jdk8/sun/swing/CachedPainter.java
Normal 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();
|
||||
}
|
||||
}
|
||||
259
jdkSrc/jdk8/sun/swing/DefaultLayoutStyle.java
Normal file
259
jdkSrc/jdk8/sun/swing/DefaultLayoutStyle.java
Normal 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;
|
||||
}
|
||||
}
|
||||
217
jdkSrc/jdk8/sun/swing/DefaultLookup.java
Normal file
217
jdkSrc/jdk8/sun/swing/DefaultLookup.java
Normal 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());
|
||||
}
|
||||
}
|
||||
2034
jdkSrc/jdk8/sun/swing/FilePane.java
Normal file
2034
jdkSrc/jdk8/sun/swing/FilePane.java
Normal file
File diff suppressed because it is too large
Load Diff
165
jdkSrc/jdk8/sun/swing/ImageCache.java
Normal file
165
jdkSrc/jdk8/sun/swing/ImageCache.java
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
59
jdkSrc/jdk8/sun/swing/ImageIconUIResource.java
Normal file
59
jdkSrc/jdk8/sun/swing/ImageIconUIResource.java
Normal 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);
|
||||
}
|
||||
}
|
||||
516
jdkSrc/jdk8/sun/swing/JLightweightFrame.java
Normal file
516
jdkSrc/jdk8/sun/swing/JLightweightFrame.java
Normal 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);
|
||||
}
|
||||
}
|
||||
249
jdkSrc/jdk8/sun/swing/LightweightContent.java
Normal file
249
jdkSrc/jdk8/sun/swing/LightweightContent.java
Normal 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) {}
|
||||
}
|
||||
38
jdkSrc/jdk8/sun/swing/MenuItemCheckIconFactory.java
Normal file
38
jdkSrc/jdk8/sun/swing/MenuItemCheckIconFactory.java
Normal 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);
|
||||
}
|
||||
1323
jdkSrc/jdk8/sun/swing/MenuItemLayoutHelper.java
Normal file
1323
jdkSrc/jdk8/sun/swing/MenuItemLayoutHelper.java
Normal file
File diff suppressed because it is too large
Load Diff
91
jdkSrc/jdk8/sun/swing/PrintColorUIResource.java
Normal file
91
jdkSrc/jdk8/sun/swing/PrintColorUIResource.java
Normal 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);
|
||||
}
|
||||
}
|
||||
318
jdkSrc/jdk8/sun/swing/PrintingStatus.java
Normal file
318
jdkSrc/jdk8/sun/swing/PrintingStatus.java
Normal 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;
|
||||
}
|
||||
}
|
||||
44
jdkSrc/jdk8/sun/swing/StringUIClientPropertyKey.java
Normal file
44
jdkSrc/jdk8/sun/swing/StringUIClientPropertyKey.java
Normal 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;
|
||||
}
|
||||
}
|
||||
174
jdkSrc/jdk8/sun/swing/SwingAccessor.java
Normal file
174
jdkSrc/jdk8/sun/swing/SwingAccessor.java
Normal 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);
|
||||
}
|
||||
}
|
||||
128
jdkSrc/jdk8/sun/swing/SwingLazyValue.java
Normal file
128
jdkSrc/jdk8/sun/swing/SwingLazyValue.java
Normal 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;
|
||||
}
|
||||
}
|
||||
2072
jdkSrc/jdk8/sun/swing/SwingUtilities2.java
Normal file
2072
jdkSrc/jdk8/sun/swing/SwingUtilities2.java
Normal file
File diff suppressed because it is too large
Load Diff
111
jdkSrc/jdk8/sun/swing/UIAction.java
Normal file
111
jdkSrc/jdk8/sun/swing/UIAction.java
Normal 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) {
|
||||
}
|
||||
}
|
||||
40
jdkSrc/jdk8/sun/swing/UIClientPropertyKey.java
Normal file
40
jdkSrc/jdk8/sun/swing/UIClientPropertyKey.java
Normal 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 {
|
||||
}
|
||||
191
jdkSrc/jdk8/sun/swing/WindowsPlacesBar.java
Normal file
191
jdkSrc/jdk8/sun/swing/WindowsPlacesBar.java
Normal 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;
|
||||
}
|
||||
}
|
||||
121
jdkSrc/jdk8/sun/swing/icon/SortArrowIcon.java
Normal file
121
jdkSrc/jdk8/sun/swing/icon/SortArrowIcon.java
Normal 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);
|
||||
}
|
||||
}
|
||||
741
jdkSrc/jdk8/sun/swing/plaf/GTKKeybindings.java
Normal file
741
jdkSrc/jdk8/sun/swing/plaf/GTKKeybindings.java
Normal 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);
|
||||
}
|
||||
}
|
||||
648
jdkSrc/jdk8/sun/swing/plaf/WindowsKeybindings.java
Normal file
648
jdkSrc/jdk8/sun/swing/plaf/WindowsKeybindings.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
927
jdkSrc/jdk8/sun/swing/plaf/synth/DefaultSynthStyle.java
Normal file
927
jdkSrc/jdk8/sun/swing/plaf/synth/DefaultSynthStyle.java
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
340
jdkSrc/jdk8/sun/swing/plaf/synth/Paint9Painter.java
Normal file
340
jdkSrc/jdk8/sun/swing/plaf/synth/Paint9Painter.java
Normal 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);
|
||||
}
|
||||
}
|
||||
133
jdkSrc/jdk8/sun/swing/plaf/synth/StyleAssociation.java
Normal file
133
jdkSrc/jdk8/sun/swing/plaf/synth/StyleAssociation.java
Normal 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;
|
||||
}
|
||||
}
|
||||
586
jdkSrc/jdk8/sun/swing/plaf/synth/SynthFileChooserUI.java
Normal file
586
jdkSrc/jdk8/sun/swing/plaf/synth/SynthFileChooserUI.java
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
1103
jdkSrc/jdk8/sun/swing/plaf/synth/SynthFileChooserUIImpl.java
Normal file
1103
jdkSrc/jdk8/sun/swing/plaf/synth/SynthFileChooserUIImpl.java
Normal file
File diff suppressed because it is too large
Load Diff
126
jdkSrc/jdk8/sun/swing/plaf/synth/SynthIcon.java
Normal file
126
jdkSrc/jdk8/sun/swing/plaf/synth/SynthIcon.java
Normal 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);
|
||||
}
|
||||
}
|
||||
97
jdkSrc/jdk8/sun/swing/plaf/windows/ClassicSortArrowIcon.java
Normal file
97
jdkSrc/jdk8/sun/swing/plaf/windows/ClassicSortArrowIcon.java
Normal 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;
|
||||
}
|
||||
}
|
||||
197
jdkSrc/jdk8/sun/swing/table/DefaultTableCellHeaderRenderer.java
Normal file
197
jdkSrc/jdk8/sun/swing/table/DefaultTableCellHeaderRenderer.java
Normal 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; }
|
||||
}
|
||||
}
|
||||
73
jdkSrc/jdk8/sun/swing/text/CompoundPrintable.java
Normal file
73
jdkSrc/jdk8/sun/swing/text/CompoundPrintable.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
47
jdkSrc/jdk8/sun/swing/text/CountingPrintable.java
Normal file
47
jdkSrc/jdk8/sun/swing/text/CountingPrintable.java
Normal 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();
|
||||
}
|
||||
846
jdkSrc/jdk8/sun/swing/text/TextComponentPrintable.java
Normal file
846
jdkSrc/jdk8/sun/swing/text/TextComponentPrintable.java
Normal 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 + "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
36
jdkSrc/jdk8/sun/swing/text/html/FrameEditorPaneTag.java
Normal file
36
jdkSrc/jdk8/sun/swing/text/html/FrameEditorPaneTag.java
Normal 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 {
|
||||
}
|
||||
Reference in New Issue
Block a user