diff options
Diffstat (limited to 'libjava/classpath/javax')
182 files changed, 17587 insertions, 3289 deletions
diff --git a/libjava/classpath/javax/crypto/CipherInputStream.java b/libjava/classpath/javax/crypto/CipherInputStream.java index 01c9976..dff7edc 100644 --- a/libjava/classpath/javax/crypto/CipherInputStream.java +++ b/libjava/classpath/javax/crypto/CipherInputStream.java @@ -38,10 +38,16 @@ exception statement from your version. */ package javax.crypto; +import gnu.classpath.Configuration; +import gnu.classpath.debug.Component; +import gnu.classpath.debug.SystemLogger; + import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; +import java.util.logging.Logger; + /** * This is an {@link java.io.InputStream} that filters its data * through a {@link Cipher} before returning it. The <code>Cipher</code> @@ -56,10 +62,12 @@ public class CipherInputStream extends FilterInputStream // Constants and variables. // ------------------------------------------------------------------------ + private static final Logger logger = SystemLogger.SYSTEM; + /** * The underlying {@link Cipher} instance. */ - private Cipher cipher; + private final Cipher cipher; /** * Data that has been transformed but not read. @@ -72,32 +80,15 @@ public class CipherInputStream extends FilterInputStream private int outOffset; /** - * The number of valid bytes in the {@link #outBuffer}. - */ - private int outLength; - - /** - * Byte buffer that is filled with raw data from the underlying input - * stream. - */ - private byte[][] inBuffer; - - /** - * The amount of bytes in inBuffer[0] that may be input to the cipher. - */ - private int inLength; - - /** * We set this when the cipher block size is 1, meaning that we can * transform any amount of data. */ - private boolean isStream; + private final boolean isStream; - private static final int VIRGIN = 0; // I am born. - private static final int LIVING = 1; // I am nailed to the hull. - private static final int DYING = 2; // I am eaten by sharks. - private static final int DEAD = 3; - private int state; + /** + * Whether or not we've reached the end of the stream. + */ + private boolean eof; // Constructors. // ------------------------------------------------------------------------ @@ -110,18 +101,14 @@ public class CipherInputStream extends FilterInputStream */ public CipherInputStream(InputStream in, Cipher cipher) { - this(in); + super (in); this.cipher = cipher; - if (!(isStream = cipher.getBlockSize() == 1)) - { - inBuffer = new byte[2][]; - inBuffer[0] = new byte[cipher.getBlockSize()]; - inBuffer[1] = new byte[cipher.getBlockSize()]; - inLength = 0; - outBuffer = new byte[cipher.getBlockSize()]; - outOffset = outLength = 0; - state = VIRGIN; - } + isStream = cipher.getBlockSize () == 1; + eof = false; + if (Configuration.DEBUG) + logger.log (Component.CRYPTO, "I am born; cipher: {0}, stream? {1}", + new Object[] { cipher.getAlgorithm (), + Boolean.valueOf (isStream) }); } /** @@ -133,7 +120,7 @@ public class CipherInputStream extends FilterInputStream */ protected CipherInputStream(InputStream in) { - super(in); + this (in, new NullCipher ()); } // Instance methods overriding java.io.FilterInputStream. @@ -141,8 +128,8 @@ public class CipherInputStream extends FilterInputStream /** * Returns the number of bytes available without blocking. The value - * returned by this method is never greater than the underlying - * cipher's block size. + * returned is the number of bytes that have been processed by the + * cipher, and which are currently buffered by this class. * * @return The number of bytes immediately available. * @throws java.io.IOException If an I/O exception occurs. @@ -151,7 +138,9 @@ public class CipherInputStream extends FilterInputStream { if (isStream) return super.available(); - return outLength - outOffset; + if (outBuffer == null || outOffset >= outBuffer.length) + nextBlock (); + return outBuffer.length - outOffset; } /** @@ -160,7 +149,7 @@ public class CipherInputStream extends FilterInputStream * * @throws java.io.IOException If an I/O exception occurs. */ - public void close() throws IOException + public synchronized void close() throws IOException { super.close(); } @@ -172,7 +161,7 @@ public class CipherInputStream extends FilterInputStream * @return The byte read, or -1 if there are no more bytes. * @throws java.io.IOExcpetion If an I/O exception occurs. */ - public int read() throws IOException + public synchronized int read() throws IOException { if (isStream) { @@ -191,10 +180,14 @@ public class CipherInputStream extends FilterInputStream } return buf[0] & 0xFF; } - if (state == DEAD) return -1; - if (available() == 0) nextBlock(); - if (state == DEAD) return -1; - return outBuffer[outOffset++] & 0xFF; + + if (outBuffer == null || outOffset == outBuffer.length) + { + if (eof) + return -1; + nextBlock (); + } + return outBuffer [outOffset++] & 0xFF; } /** @@ -207,18 +200,29 @@ public class CipherInputStream extends FilterInputStream * @return The number of bytes read, or -1 on the end-of-file. * @throws java.io.IOException If an I/O exception occurs. */ - public int read(byte[] buf, int off, int len) throws IOException + public synchronized int read(byte[] buf, int off, int len) + throws IOException { + // CipherInputStream has this wierd implementation where if + // the buffer is null, this call is the same as `skip'. + if (buf == null) + return (int) skip (len); + if (isStream) { len = super.read(buf, off, len); - try - { - cipher.update(buf, off, len, buf, off); - } - catch (ShortBufferException shouldNotHappen) + if (len > 0) { - throw new IOException(shouldNotHappen.getMessage()); + try + { + cipher.update(buf, off, len, buf, off); + } + catch (ShortBufferException shouldNotHappen) + { + IOException ioe = new IOException ("Short buffer for stream cipher -- this should not happen"); + ioe.initCause (shouldNotHappen); + throw ioe; + } } return len; } @@ -226,17 +230,20 @@ public class CipherInputStream extends FilterInputStream int count = 0; while (count < len) { - if (available() == 0) - nextBlock(); - if (state == DEAD) + if (outBuffer == null || outOffset >= outBuffer.length) { - if (count > 0) return count; - else return -1; + if (eof) + { + if (count == 0) + count = -1; + break; + } + nextBlock(); } - int l = Math.min(available(), len - count); - System.arraycopy(outBuffer, outOffset, buf, count+off, l); + int l = Math.min (outBuffer.length - outOffset, len - count); + System.arraycopy (outBuffer, outOffset, buf, count+off, l); count += l; - outOffset = outLength = 0; + outOffset += l; } return count; } @@ -269,10 +276,10 @@ public class CipherInputStream extends FilterInputStream return super.skip(bytes); } long ret = 0; - if (bytes > 0 && available() > 0) + if (bytes > 0 && outBuffer != null && outOffset >= outBuffer.length) { - ret = available(); - outOffset = outLength = 0; + ret = outBuffer.length - outOffset; + outOffset = outBuffer.length; } return ret; } @@ -309,75 +316,53 @@ public class CipherInputStream extends FilterInputStream // Own methods. // ------------------------------------------------------------------------- + // FIXME: I don't fully understand how this class is supposed to work. + private void nextBlock() throws IOException { - byte[] temp = inBuffer[0]; - inBuffer[0] = inBuffer[1]; - inBuffer[1] = temp; - int count = 0; - boolean eof = false; + byte[] buf = new byte[cipher.getBlockSize ()]; + if (Configuration.DEBUG) + logger.log (Component.CRYPTO, "getting a new data block"); - if (state == VIRGIN || state == LIVING) + try { - do + outBuffer = null; + outOffset = 0; + while (outBuffer == null) { - int l = in.read(inBuffer[1], count, inBuffer[1].length - count); + int l = in.read (buf); + if (Configuration.DEBUG) + logger.log (Component.CRYPTO, "we read {0} bytes", + Integer.valueOf (l)); if (l == -1) { + outBuffer = cipher.doFinal (); eof = true; - break; + return; } - count += l; - } - while (count < inBuffer[1].length); - } - try - { - switch (state) - { - case VIRGIN: - state = LIVING; - nextBlock(); - break; - case LIVING: - if (eof) - { - if (count > 0) - { - outOffset = cipher.update(inBuffer[0], 0, inLength, outBuffer, 0); - state = DYING; - } - else - { - outOffset = cipher.doFinal(inBuffer[0], 0, inLength, outBuffer, 0); - state = DEAD; - } - } - else - { - outOffset = cipher.update(inBuffer[0], 0, inLength, outBuffer, 0); - } - break; - case DYING: - outOffset = cipher.doFinal(inBuffer[0], 0, inLength, outBuffer, 0); - state = DEAD; - break; - case DEAD: + outOffset = 0; + outBuffer = cipher.update (buf, 0, l); } } - catch (ShortBufferException sbe) - { - throw new IOException(sbe.toString()); - } catch (BadPaddingException bpe) { - throw new IOException(bpe.toString()); + IOException ioe = new IOException ("bad padding"); + ioe.initCause (bpe); + throw ioe; } catch (IllegalBlockSizeException ibse) { - throw new IOException(ibse.toString()); + IOException ioe = new IOException ("illegal block size"); + ioe.initCause (ibse); + throw ioe; + } + finally + { + if (Configuration.DEBUG) + logger.log (Component.CRYPTO, + "decrypted {0} bytes for reading", + Integer.valueOf (outBuffer.length)); } - inLength = count; } } diff --git a/libjava/classpath/javax/management/Attribute.java b/libjava/classpath/javax/management/Attribute.java new file mode 100644 index 0000000..5c4a65e --- /dev/null +++ b/libjava/classpath/javax/management/Attribute.java @@ -0,0 +1,138 @@ +/* Attribute.java -- + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package javax.management; + +import java.io.Serializable; + +/** + * Represents an MBean attribute, having the name and the assigned value. The + * MBean objects use this class to get and set attributes values. + * + * @since 1.5 + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class Attribute + implements Serializable +{ + /** + * The attribute name. + */ + final String m_name; + + /** + * The attribute value. + */ + final Object m_value; + + /** + * Create the attribute with the given name and value. + * + * @param name the attribute name + * @param value the attribute value + */ + public Attribute(String name, Object value) + { + m_name = name; + m_value = value; + } + + /** + * Compares the attribute with another attribute. + * + * @param other the other object to compare with + * + * @return true if both value and object are equal, false otherwise. + */ + public boolean equals(Object other) + { + if (other instanceof Attribute) + { + Attribute oa = (Attribute) other; + boolean n, v; + if (oa.m_name == null || m_name == null) + n = oa.m_name == m_name; + else + n = oa.m_name.equals(m_name); + + if (oa.m_value == null || m_value == null) + v = oa.m_value == m_value; + else + v = oa.m_value.equals(m_value); + + return n && v; + + } + else + return false; + } + + /** + * Returns the attribute name. + * + * @return the attribute name + */ + public String getName() + { + return m_name; + } + + /** + * Returns the attribute value. + * + * @return the attribute value. + */ + public Object getValue() + { + return m_value; + } + + /** + * Need to override as {@link #equals} is overridden. + * + * @return the expression, dependent of the object and name hashcodes. + */ + public int hashCode() + { + int n = m_name == null ? 0 : m_name.hashCode(); + int v = m_value == null ? 0 : m_value.hashCode(); + + return n ^ v; + } + +} diff --git a/libjava/classpath/javax/print/AttributeException.java b/libjava/classpath/javax/print/AttributeException.java index d22c5bf..1251b00 100644 --- a/libjava/classpath/javax/print/AttributeException.java +++ b/libjava/classpath/javax/print/AttributeException.java @@ -1,5 +1,5 @@ -/* CancelablePrintJob.java -- - Copyright (C) 2004 Free Software Foundation, Inc. +/* AttributeException.java -- + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -41,23 +41,36 @@ package javax.print; import javax.print.attribute.Attribute; /** + * <code>AttributeException</code> specifies two methods a specific + * subclass of {@link javax.print.PrintException} may implement to + * provide further information of printing errors if unsupported + * attribute classes or values of attributes are involved. + * <p> + * There exists no <code>PrintException</code> class implementing this + * interface. Providing these extensions in <code>PrintException</code> + * subclasses is left to the concrete print service implementation. + * </p> + * * @author Michael Koch (konqueror@gmx.de) */ public interface AttributeException { /** * Returns the unsupported printing attribute classes for a print service - * that does not support them. + * that does not support the attribute category at all. The returned + * class instances are sublcasses of the base interface {@link Attribute}. * - * @return array of unsupported attribute classes, or null + * @return The unsupported attribute classes, or <code>null</code> if there + * are no such attribute classes. */ Class[] getUnsupportedAttributes(); /** - * Returns the unsupported values of printing attributes for a print service - * that does not support them. + * Returns the unsupported attribute values of printing attributes a specific + * print service does support but not the particular provided value. * - * @return array of unsupperted attribute values, or null + * @return The unsupported attribute values, or <code>null</code> if there + * are no such attributes values. */ Attribute[] getUnsupportedValues(); } diff --git a/libjava/classpath/javax/print/FlavorException.java b/libjava/classpath/javax/print/FlavorException.java index 1de6a22..879f108 100644 --- a/libjava/classpath/javax/print/FlavorException.java +++ b/libjava/classpath/javax/print/FlavorException.java @@ -1,5 +1,5 @@ /* FlavorException.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -39,6 +39,16 @@ exception statement from your version. */ package javax.print; /** + * <code>FlavorException</code> specifies a method a specific + * subclass of {@link javax.print.PrintException} may implement to + * provide further information of printing errors if unsupported + * document flavors are involved. + * <p> + * There exists no <code>PrintException</code> class implementing this + * interface. Providing this extension in <code>PrintException</code> + * subclasses is left to the concrete print service implementation. + * </p> + * * @author Michael Koch (konqueror@gmx.de) */ public interface FlavorException @@ -46,7 +56,7 @@ public interface FlavorException /** * Returns the unsupported document flavors. * - * @return the unsupported document flavors + * @return The unsupported document flavors. */ DocFlavor[] getUnsupportedFlavors(); }
\ No newline at end of file diff --git a/libjava/classpath/javax/print/PrintException.java b/libjava/classpath/javax/print/PrintException.java index 3eef243..6fd46b5 100644 --- a/libjava/classpath/javax/print/PrintException.java +++ b/libjava/classpath/javax/print/PrintException.java @@ -1,5 +1,5 @@ /* PrintException.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -39,6 +39,20 @@ exception statement from your version. */ package javax.print; /** + * <code>PrintException</code> is used to report exceptions during the + * usage of a print service implementation. + * <p> + * This base class only provides the possibility to report a message as + * exception. A concrete print service implementation may provide + * specialised subclasses implementing one or more of the following + * exception interfaces:<br> + * <ul> + * <li>{@link javax.print.AttributeException}</li> + * <li>{@link javax.print.FlavorException}</li> + * <li>{@link javax.print.URIException}</li> + * </ul> + * </p> + * * @author Michael Koch (konqueror@gmx.de) */ public class PrintException extends Exception diff --git a/libjava/classpath/javax/print/URIException.java b/libjava/classpath/javax/print/URIException.java index 5cc4c0d..9b22bdf 100644 --- a/libjava/classpath/javax/print/URIException.java +++ b/libjava/classpath/javax/print/URIException.java @@ -1,5 +1,5 @@ /* URIException.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -41,25 +41,48 @@ package javax.print; import java.net.URI; /** + * <code>URIException</code> specifies methods a specific subclass of + * {@link javax.print.PrintException} may implement to provide further + * informations of printing errors if URI problems are involved. + * <p> + * There exists no <code>PrintException</code> class implementing this + * interface. Providing this extension in <code>PrintException</code> + * subclasses is left to the concrete print service implementation. + * </p> + * * @author Michael Koch (konqueror@gmx.de) */ public interface URIException { + /** + * Indicates that the provided <code>URI</code> is not accessible. + */ int URIInaccessible = 1; + + /** + * Indicates any other problem which is not defined by + * the other reason constants. + */ int URIOtherProblem = -1; + + /** + * Indicates that the print service does not support a specific + * uri scheme (for example the ftp scheme). + */ int URISchemeNotSupported = 2; /** - * Returns the reason for this exception. + * Returns the reason for this exception as + * predefined constants in this interface. * - * @return the reason + * @return The reason. */ int getReason(); /** - * Returns the unsupported <code>URI</code> for this exception. + * Returns the unsupported <code>URI</code> which caused this exception. * - * @return the unsupported <code>URI</code>. + * @return The unsupported <code>URI</code>. */ URI getUnsupportedURI(); } diff --git a/libjava/classpath/javax/print/attribute/ResolutionSyntax.java b/libjava/classpath/javax/print/attribute/ResolutionSyntax.java index a7878c5..aca4c01 100644 --- a/libjava/classpath/javax/print/attribute/ResolutionSyntax.java +++ b/libjava/classpath/javax/print/attribute/ResolutionSyntax.java @@ -1,5 +1,5 @@ /* ResolutionSyntax.java -- - Copyright (C) 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -40,7 +40,42 @@ package javax.print.attribute; import java.io.Serializable; /** - * @author Michael Koch + * <code>ResolutionSyntax</code> is the abstract base class of all attribute + * classes which provide a resolution as value (e.g. printer resolution). + * <p> + * A <code>ResolutionSyntax</code> instance consists of two integer values + * describing the resolution in feed and cross feed direction. The units of + * the given values is determined by two defined constants: + * <ul> + * <li>DPCM - dots per centimeter</li> + * <li>DPI - dots per inch</li> + * </ul> + * </p> + * <p> + * A resolutions attribute is constructed by two values for the resolution and + * one of the two constants defining the actual units of the given values. + * </p> + * <p> + * There are different methods provided to return the resolution values in + * either of the both units and to compare if a resolution is less than or + * equal to a given other resolution attribute. + * </p> + * <p> + * <b>Internal storage:</b><br> + * The resolutions are stored internally as dots per 100 inches (dphi). The + * values of the provided constants for dots per inch (value 100) and dots + * per centimeter (value 254) are used as conversion factors to the internal + * storage units. To get the internal dphi values a multiplication of a given + * resolution value with its units constant value is needed. Retrieving the + * resolution for specific units is done by dividing the internal stored + * value through the units constant value. Clients are therefore able to + * provide their own resolution units by supplying other conversion factors. + * Subclasses of <code>ResolutionSyntax</code> have access to the internal + * resolution values through the protected methods + * {@link #getCrossFeedResolutionDphi()} and {@link #getFeedResolutionDphi()}. + * </p> + * + * @author Michael Koch (konqueror@gmx.de) */ public abstract class ResolutionSyntax implements Cloneable, Serializable @@ -65,7 +100,7 @@ public abstract class ResolutionSyntax * * @param crossFeedResolution the cross feed resolution * @param feedResolution the feed resolution - * @param units the unit to use + * @param units the unit to use (e.g. {@link #DPCM} or {@link #DPI}) * * @exception IllegalArgumentException if preconditions fail */ @@ -82,11 +117,12 @@ public abstract class ResolutionSyntax } /** - * Tests of obj is equal to this object. + * Tests if the given object is equal to this object. * * @param obj the object to test * - * @return true if both objects are equal, false otherwise. + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. */ public boolean equals(Object obj) { @@ -100,24 +136,25 @@ public abstract class ResolutionSyntax } /** - * Returns the cross feed resolution in units. + * Returns the cross feed resolution for the given units. * - * @return the resolution + * @param units the unit to use (e.g. {@link #DPCM} or {@link #DPI}) + * @return The resolution for the given units. * - * @exception IllegalArgumentException if units < 1 + * @exception IllegalArgumentException if units < 1 */ public int getCrossFeedResolution(int units) { if (units < 1) throw new IllegalArgumentException("units may not be less then 1"); - return (crossFeedResolution + units) / units; + return crossFeedResolution / units; } /** - * Returns the raw cross feed resolution in units. + * Returns the raw cross feed resolution in dots per 100 inches. * - * @return the raw resolution + * @return The raw resolution. */ protected int getCrossFeedResolutionDphi() { @@ -125,24 +162,25 @@ public abstract class ResolutionSyntax } /** - * Returns the feed resolution in units. + * Returns the feed resolution for the given units. * - * @return the resolution + * @param units the unit to use (e.g. {@link #DPCM} or {@link #DPI}) + * @return The resolution for the given units. * - * @exception IllegalArgumentException if units < 1 + * @exception IllegalArgumentException if units < 1 */ public int getFeedResolution(int units) { if (units < 1) throw new IllegalArgumentException("units may not be less then 1"); - return (crossFeedResolution + units) / units; + return feedResolution / units; } /** - * Returns the raw feed resolution in units. + * Returns the raw feed resolution in dots per 100 inches. * - * @return the raw resolution + * @return The raw resolution. */ protected int getFeedResolutionDphi() { @@ -155,7 +193,7 @@ public abstract class ResolutionSyntax * * @param units the units to use * - * @return the array with the resolutions + * @return The array with the resolutions. */ public int[] getResolution(int units) { @@ -168,7 +206,7 @@ public abstract class ResolutionSyntax /** * Returns the hashcode for this object. * - * @return the hashcode + * @return The hashcode. */ public int hashCode() { @@ -176,11 +214,13 @@ public abstract class ResolutionSyntax } /** - * Checks of other is a lower or equal resolution. + * Checks if the given resolution attribute is a lower or equal + * to this resolution object. * * @param other the resolution to check against * - * @return true if other describes a lower or equal resolution + * @return <code>true</code> if other resolution attribute describes + * a lower or equal resolution, <code>false</code> otherwise. */ public boolean lessThanOrEquals(ResolutionSyntax other) { @@ -193,8 +233,12 @@ public abstract class ResolutionSyntax /** * Returns the string representation for this object. - * - * @return the string representation + * <p> + * The returned string is in the form "CxF dphi" with C standing + * for the cross feed and F for the feed direction resolution. + * Units used are dots per 100 inches (dphi). + * </p> + * @return The string representation. */ public String toString() { @@ -203,14 +247,23 @@ public abstract class ResolutionSyntax /** * Returns the string representation for this object. - * + * <p> + * The returned string is in the form "CxF U" with C standing + * for the cross feed and F for the feed direction resolution. + * U denotes the units name if one is supplied. + * </p> + * * @param units the units to use - * @param unitsName the name of the units + * @param unitsName the name of the units. If <code>null</code> + * it is ommitted from the string representation. * - * @return the string representation + * @return The string representation. */ public String toString(int units, String unitsName) { + if (unitsName == null) + return getCrossFeedResolution(units) + "x" + getFeedResolution(units); + return ("" + getCrossFeedResolution(units) + "x" + getFeedResolution(units) + " " + unitsName); diff --git a/libjava/classpath/javax/print/attribute/SetOfIntegerSyntax.java b/libjava/classpath/javax/print/attribute/SetOfIntegerSyntax.java index 3990b66..4c0dd2f 100644 --- a/libjava/classpath/javax/print/attribute/SetOfIntegerSyntax.java +++ b/libjava/classpath/javax/print/attribute/SetOfIntegerSyntax.java @@ -1,5 +1,5 @@ /* SetOfIntegerSyntax.java -- - Copyright (C) 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -45,7 +45,55 @@ import java.util.Arrays; import java.util.Comparator; /** - * @author Michael Koch + * <code>SetOfIntegerSyntax</code> is the abstract base class of all attribute + * classes which provide a set of non-negative integers as value (e.g. the + * page ranges to print) represented as single values or ranges of values. + * <p> + * A <code>SetOfIntegerSyntax</code> instance consists of an integer array of + * ranges. Ranges may have the same lower and upper bound representing a single + * integer value. Ranges with a lower bound greater than the upper bound are + * null ranges and discarded. Ranges may overlap in their values. In no case + * negative integers are allowed. + * </p> + * <p> + * There are several constructors available: + * <ul> + * <li><code>SetOfIntegerSyntax(int member)</code><br> + * Constructor for an instance with only one integer value. + * </li><br> + * <li><code>SetOfIntegerSyntax(int lowerBound, int upperBound)</code><br> + * Constructor for an instance with one range of integer values. + * </li><br> + * <li><code>SetOfIntegerSyntax(int[][] members)</code><br> + * Flexible constructor for an instance with several single integer values + * and/or several ranges of integer values. The allowed array form is an + * array of integer arrays of length one or two. Examples are: + * <code>int[0][]</code> for empty set of integers, <code>int[][] {{1}}</code> + * , <code>int[][] {{1,5}}</code>, <code>int[][] {{1,5},{7,9}}</code>, + * <code>int[][] {{3,7},{19}}</code>. + * </li><br> + * <li><code>SetOfIntegerSyntax(String s)</code><br> + * Flexible constructor for an instance with several single integer values + * and/or several ranges of integer values. The allowed String instance have + * to be a String with comma separated ranges of integer values or single + * values. Ranges are represented by two integer with a hypen (-) or colon (:) + * between the lower and upper bound value. Whitespace characters are ignored. + * Examples are: <code>""</code> for an empty set of integers, + * <code>"1"</code>, <code>"1-5"</code>, <code>"1-5,7-9"</code>, + * <code>"3-7,19"</code> and <code>"1:2,4"</code>. + * </li> + * </ul> + * </p> + * <p> + * <b>Internal storage:</b><br> + * The set of integers are stored internally in a normalized array form. + * In the normalized array form the set of integer ranges are represented + * in as few ranges as possible and overlapping ranges are merged. The ranges + * are always represented as an integer array of length two with ranges + * stored in {lower bound, upper bound} form. The ranges are stored in + * ascending order, without any null ranges. + * </p> + * @author Michael Koch (konqueror@gmx.de) */ public abstract class SetOfIntegerSyntax implements Cloneable, Serializable @@ -96,7 +144,7 @@ public abstract class SetOfIntegerSyntax * * @param member the member value * - * @exception IllegalArgumentException if member is < 0 + * @exception IllegalArgumentException if member is < 0 */ protected SetOfIntegerSyntax(int member) { @@ -109,7 +157,8 @@ public abstract class SetOfIntegerSyntax /** * Creates a <code>SetOfIntegerSyntax</code> object. * - * @param members the members to use in this set + * @param members the members to use in this set. If + * <code>null</code> an empty set is created. * * @exception IllegalArgumentException if any element is invalid * @exception NullPointerException if any element of members is null @@ -176,55 +225,68 @@ public abstract class SetOfIntegerSyntax return readAny; } + /** + * Creates a <code>SetOfIntegerSyntax</code> object. + * + * @param s the members to use in this set in string form. If + * <code>null</code> an empty set is created. + * + * @exception IllegalArgumentException if any element is invalid + */ protected SetOfIntegerSyntax(String s) { - ArrayList vals = new ArrayList(); - - StringCharacterIterator it = new StringCharacterIterator(s); - - while (true) - { - // Skip whitespace. - if (skipWhitespace(it)) - break; - - // Parse integer. - int index = it.getIndex(); - if (! skipNumber(it)) - throw new IllegalArgumentException(); - int[] item = new int[2]; - item[0] = Integer.parseInt(s.substring(index, it.getIndex())); - - if (! skipWhitespace(it)) + if (s == null) + this.members = normalize(new int[0][], 0); + else + { + ArrayList vals = new ArrayList(); + + StringCharacterIterator it = new StringCharacterIterator(s); + + while (true) { - char c = it.current(); - if (c == ':' || c == '-') + // Skip whitespace. + if (skipWhitespace(it)) + break; + + // Parse integer. + int index = it.getIndex(); + if (! skipNumber(it)) + throw new IllegalArgumentException(); + int[] item = new int[2]; + item[0] = Integer.parseInt(s.substring(index, it.getIndex())); + + if (! skipWhitespace(it)) { - it.next(); - if (skipWhitespace(it)) - throw new IllegalArgumentException(); - index = it.getIndex(); - if (! skipNumber(it)) - throw new IllegalArgumentException(); - item[1] = Integer.parseInt(s.substring(index, it.getIndex())); + char c = it.current(); + if (c == ':' || c == '-') + { + it.next(); + if (skipWhitespace(it)) + throw new IllegalArgumentException(); + index = it.getIndex(); + if (! skipNumber(it)) + throw new IllegalArgumentException(); + item[1] = Integer.parseInt(s.substring(index, it.getIndex())); + } + else + item[1] = item[0]; } else item[1] = item[0]; + + if (item[0] <= item[1]) + vals.add(item); + + if (skipWhitespace(it)) + break; + if (it.current() != ',') + throw new IllegalArgumentException(); + it.next(); } - else - item[1] = item[0]; - - if (item[0] <= item[1]) - vals.add(item); - if (skipWhitespace(it)) - break; - if (it.current() != ',') - throw new IllegalArgumentException(); - it.next(); + members = normalize((int[][]) vals.toArray(new int[0][]), vals.size()); } - - members = normalize((int[][]) vals.toArray(new int[0][]), vals.size()); } /** @@ -248,7 +310,7 @@ public abstract class SetOfIntegerSyntax } /** - * Checks if this set contains value. + * Checks if this set contains the given value. * * @param value the value to test for * @@ -269,7 +331,7 @@ public abstract class SetOfIntegerSyntax } /** - * Checks if this set contains value. + * Checks if this set contains the given value. * * @param value the value to test for * @@ -281,7 +343,7 @@ public abstract class SetOfIntegerSyntax } /** - * Tests of obj is equal to this object. + * Tests if the given object is equal to this object. * * @param obj the object to test * @@ -306,7 +368,7 @@ public abstract class SetOfIntegerSyntax /** * Returns an array describing the members included in this set. * - * @return the array with the members + * @return The members in normalized array form. */ public int[][] getMembers() { @@ -316,7 +378,7 @@ public abstract class SetOfIntegerSyntax /** * Returns the hashcode for this object. * - * @return the hashcode + * @return The hashcode. */ public int hashCode() { @@ -331,7 +393,8 @@ public abstract class SetOfIntegerSyntax * * @param x an integer value * - * @return the next value + * @return The next smallest integer value, or <code>-1</code> if there + * is no greater integer in the set. */ public int next(int x) { @@ -349,8 +412,10 @@ public abstract class SetOfIntegerSyntax /** * Returns the string representation for this object. + * The value is a zero length string for an empty set, or a comma seperated + * list of ranges and single values in the form <code>"1-2,5-7,10"</code>. * - * @return the string representation + * @return The string representation. */ public String toString() { diff --git a/libjava/classpath/javax/print/attribute/Size2DSyntax.java b/libjava/classpath/javax/print/attribute/Size2DSyntax.java index c8d6ec7..0b5c100 100644 --- a/libjava/classpath/javax/print/attribute/Size2DSyntax.java +++ b/libjava/classpath/javax/print/attribute/Size2DSyntax.java @@ -1,5 +1,5 @@ /* Size2DSyntax.java -- - Copyright (C) 2003 Free Software Foundation, Inc. + Copyright (C) 2003, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -40,21 +40,62 @@ package javax.print.attribute; import java.io.Serializable; /** - * @author Michael Koch + * <code>Size2DSyntax</code> is the abstract base class of all attribute + * classes which provide a two dimensional size as value (e.g. the size of + * a media like Letter or A4). + * <p> + * A <code>Size2DSyntax</code> instance consists of two integer values + * describing the size in the x and y dimension. The units of + * the given values is determined by two defined constants: + * <ul> + * <li>INCH - defines an inch</li> + * <li>MM - defines a millimeter</li> + * </ul> + * </p> + * <p> + * A size 2D attribute is constructed by two values for the size of the x and + * y dimension and the actual units of the given values as defined by the + * constants. + * </p> + * <p> + * There are different methods provided to return the size values for the + * dimensions in either of the two predefined units or with a given client + * supplied units conversion factor. + * </p> + * <p> + * <b>Internal storage:</b><br> + * The size of the x,y dimensions are stored internally in micrometers. The + * values of the provided constants for inch (value 25400) and millimeters + * (value 1000) are used as conversion factors to the internal storage units. + * To get the internal micrometers values a multiplication of a given + * size value with its units constant value is done. Retrieving the size value + * for specific units is done by dividing the internal stored value by the + * units constant value. Clients are therefore able to provide their own + * size units by supplying other conversion factors. + * Subclasses of <code>Size2DSyntax</code> have access to the internal + * size values through the protected methods + * {@link #getXMicrometers()} and {@link #getYMicrometers()}. + * </p> + * + * @author Michael Koch (konqueror@gmx.de) */ public abstract class Size2DSyntax implements Cloneable, Serializable { /** - * Constant for units of dots per mircometer to describe an inch. + * Constant for the units of inches. + * The actual value is the conversion factor to micrometers. */ public static final int INCH = 25400; /** - * Constant for units of dots per mircometer to describe a centimeter. + * Constant for the units of millimeters. + * The actual value is the conversion factor to micrometers. */ public static final int MM = 1000; + /** x size in micrometers. */ private int x; + /** y size in micrometers. */ private int y; /** @@ -64,7 +105,7 @@ public abstract class Size2DSyntax implements Cloneable, Serializable * @param y the size in y direction * @param units the units to use for the sizes * - * @exception IllegalArgumentException if preconditions fail + * @exception IllegalArgumentException if x or y < 0 or units < 1 */ protected Size2DSyntax(float x, float y, int units) { @@ -85,7 +126,7 @@ public abstract class Size2DSyntax implements Cloneable, Serializable * @param y the size in y direction * @param units the units to use for the sizes * - * @exception IllegalArgumentException if preconditions fail + * @exception IllegalArgumentException if x or y < 0 or units < 1 */ protected Size2DSyntax(int x, int y, int units) { @@ -100,11 +141,11 @@ public abstract class Size2DSyntax implements Cloneable, Serializable } /** - * Tests of obj is equal to this object. + * Tests if the given object is equal to this object. * * @param obj the object to test * - * @returns true if both objects are equal, false otherwise. + * @return <code>true</code> if both objects are equal, <code>false</code> otherwise. */ public boolean equals(Object obj) { @@ -118,15 +159,15 @@ public abstract class Size2DSyntax implements Cloneable, Serializable } /** - * Return the size described in this object as a two field array. + * Returns the size described in this object as a two field array. * Index 0 contains the size in x direction, index 1 the size in * y direction. * * @param units the units to use * - * @return the array that describes the size + * @return The array with the size dimensions. * - * @exception IllegalArgumentException if units < 1 + * @exception IllegalArgumentException if units < 1 */ public float[] getSize(int units) { @@ -137,13 +178,13 @@ public abstract class Size2DSyntax implements Cloneable, Serializable } /** - * Return the size in x direction. + * Returns the size in x direction. * * @param units the units to use * - * @return the size value + * @return The size in x direction. * - * @exception IllegalArgumentException if units < 1 + * @exception IllegalArgumentException if units < 1 */ public float getX(int units) { @@ -155,8 +196,9 @@ public abstract class Size2DSyntax implements Cloneable, Serializable /** * Returns the size in x direction in mircometers. + * To be used by sublcasses that need access to the internal storage value. * - * @return the size value + * @return The size in x direction in micrometers. */ protected int getXMicrometers() { @@ -168,9 +210,9 @@ public abstract class Size2DSyntax implements Cloneable, Serializable * * @param units the units to use * - * @return the size value + * @return The size in y direction. * - * @exception IllegalArgumentException if units < 1 + * @exception IllegalArgumentException if units < 1 */ public float getY(int units) { @@ -182,8 +224,9 @@ public abstract class Size2DSyntax implements Cloneable, Serializable /** * Returns the size in y direction in mircometers. + * To be used by sublcasses that need access to the internal storage value. * - * @return the size value + * @return The size in y direction in micrometers. */ protected int getYMicrometers() { @@ -193,7 +236,7 @@ public abstract class Size2DSyntax implements Cloneable, Serializable /** * Returns the hashcode for this object. * - * @return the hashcode + * @return The hashcode. */ public int hashCode() { @@ -202,24 +245,39 @@ public abstract class Size2DSyntax implements Cloneable, Serializable /** * Returns the string representation for this object. - * - * @return the string representation + * <p> + * The returned string is in the form "XxY um" with X standing + * for size in x and Y for the size in y direction. The used + * micrometers units is indicated by the appended "um" notation. + * </p> + * + * @return The string representation in micrometers. */ public String toString() { - return toString(1, "um"); + return getXMicrometers() + "x" + getYMicrometers() + " um"; } /** * Returns the string representation for this object. - * + * <p> + * The returned string is in the form "XxY U" with X standing + * for size in x and Y for the size in y direction. U denotes + * the units name if one is supplied. The values are given as + * floating point values. + * </p> + * * @param units the units to use - * @param unitsName the name of the units + * @param unitsName the name of the units. If <code>null</code> + * it is ommitted from the string representation. * - * @return the string representation + * @return The string representation. */ public String toString(int units, String unitsName) { - return "" + getX(units) + "x" + getY(units) + " " + unitsName; + if (unitsName == null) + return getX(units) + "x" + getY(units); + + return getX(units) + "x" + getY(units) + " " + unitsName; } } diff --git a/libjava/classpath/javax/print/attribute/TextSyntax.java b/libjava/classpath/javax/print/attribute/TextSyntax.java index 98fabdc..2daab6e 100644 --- a/libjava/classpath/javax/print/attribute/TextSyntax.java +++ b/libjava/classpath/javax/print/attribute/TextSyntax.java @@ -1,5 +1,5 @@ /* TextSyntax.java -- - Copyright (C) 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -41,7 +41,14 @@ import java.io.Serializable; import java.util.Locale; /** - * @author Michael Koch + * <code>TextSyntax</code> is the abstract base class of all attribute + * classes which provide a string as value (e.g. the location of the printer). + * <p> + * A <code>TextSyntax</code> instance consists of a string value and a + * locale which indicates the language of the locale of the string. + * </p> + * + * @author Michael Koch (konqueror@gmx.de) */ public abstract class TextSyntax implements Cloneable, Serializable { @@ -55,23 +62,24 @@ public abstract class TextSyntax implements Cloneable, Serializable * and locale. * * @param value the value for this syntax - * @param locale the locale to use + * @param locale the locale to use, if <code>null</code> the default + * locale is used. * - * @exception NullPointerException if value and/or locale is null + * @exception NullPointerException if value is null */ protected TextSyntax(String value, Locale locale) { - if (value == null || locale == null) - throw new NullPointerException("value and/or locale may not be null"); - + if (value == null) + throw new NullPointerException("value may not be null"); + this.value = value; - this.locale = locale; + this.locale = (locale == null ? Locale.getDefault() : locale); } /** * Returns the value of this syntax object. * - * @return the value + * @return The value. */ public String getValue() { @@ -81,7 +89,7 @@ public abstract class TextSyntax implements Cloneable, Serializable /** * Returns the locale of this syntax object. * - * @return the locale + * @return The locale. */ public Locale getLocale() { @@ -91,7 +99,7 @@ public abstract class TextSyntax implements Cloneable, Serializable /** * Returns the hashcode for this object. * - * @return the hashcode + * @return The hashcode. */ public int hashCode() { @@ -99,7 +107,7 @@ public abstract class TextSyntax implements Cloneable, Serializable } /** - * Tests of obj is equal to this object. + * Tests if the given object is equal to this object. * * @param obj the object to test * @@ -117,7 +125,10 @@ public abstract class TextSyntax implements Cloneable, Serializable } /** - * Returns a string representing the object. + * Returns a string representing the object. The returned + * string is the underlying text value of this object. + * + * @return The string representation. */ public String toString() { diff --git a/libjava/classpath/javax/print/attribute/standard/Chromaticity.java b/libjava/classpath/javax/print/attribute/standard/Chromaticity.java index 3d336a4..cc834f6 100644 --- a/libjava/classpath/javax/print/attribute/standard/Chromaticity.java +++ b/libjava/classpath/javax/print/attribute/standard/Chromaticity.java @@ -44,15 +44,40 @@ import javax.print.attribute.PrintJobAttribute; import javax.print.attribute.PrintRequestAttribute; /** + * The <code>Chromaticity</code> printing attribute specifies if print data + * should be printed in monochrome or color. + * <p> + * The attribute interacts with the document to be printed. If the document + * to be printed is a monochrome document it will be printed monochrome + * regardless of the value of this attribute category. However if it is a + * color document supplying the attribute value <code>MONOCHROME</code> + * will prepare the document to be printed in monochrome instead of color. + * </p> + * <p> + * This printing attribute has nothing to do with the capabilities of the + * printer device. To check if a specific printer service supports printing + * in color you have to use the attribute + * {@link javax.print.attribute.standard.ColorSupported} + * </p> + * <p> + * <b>IPP Compatibility:</b> Chromaticity is not an IPP 1.1 attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) */ public final class Chromaticity extends EnumSyntax implements DocAttribute, PrintRequestAttribute, PrintJobAttribute { private static final long serialVersionUID = 4660543931355214012L; - + + /** Specifies monochrome printing. */ public static final Chromaticity MONOCHROME = new Chromaticity(0); + + /** Specifies color printing. */ public static final Chromaticity COLOR = new Chromaticity(1); + + private static final String[] stringTable = { "monochrome", "color" }; + private static final Chromaticity[] enumValueTable = { MONOCHROME, COLOR }; /** * Creates a <code>Chromaticity</code> object. @@ -67,7 +92,7 @@ public final class Chromaticity extends EnumSyntax /** * Returns category of this class. * - * @return the class <code>Sides</code> itself + * @return The class <code>Chromaticity</code> itself. */ public Class getCategory() { @@ -77,10 +102,32 @@ public final class Chromaticity extends EnumSyntax /** * Returns the name of this attribute. * - * @return the name + * @return The name "chromaticity". */ public String getName() { return "chromaticity"; } + + /** + * Returns a table with the enumeration values represented as strings + * for this object. + * + * @return The enumeration values as strings. + */ + protected String[] getStringTable() + { + return stringTable; + } + + /** + * Returns a table with the enumeration values for this object. + * + * @return The enumeration values. + */ + protected EnumSyntax[] getEnumValueTable() + { + return enumValueTable; + } + } diff --git a/libjava/classpath/javax/print/attribute/standard/ColorSupported.java b/libjava/classpath/javax/print/attribute/standard/ColorSupported.java index fad7ced..bca932d 100644 --- a/libjava/classpath/javax/print/attribute/standard/ColorSupported.java +++ b/libjava/classpath/javax/print/attribute/standard/ColorSupported.java @@ -1,5 +1,5 @@ /* ColorSupported.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -42,6 +42,20 @@ import javax.print.attribute.PrintServiceAttribute; /** + * The <code>ColorSupported</code> printing attribute specifies if a + * printing device is capable of color printing. + * <p> + * This attributes just tells if a printer device supports color printing + * but does not specify how a specific print job is printed. Therefore the + * attribute {@link javax.print.attribute.standard.Chromaticity} exists. + * </p> + * <p> + * <b>IPP Compatibility:</b> ColorSupported is an IPP 1.1 attribute. The IPP + * specification treats ColorSupported as a boolean type which is not available + * in the Java Print Service API. The IPP boolean value true corresponds + * to <code>SUPPORTED</code> and "false" to <code>NOT_SUPPORTED</code>. + * </p> + * * @author Michael Koch (konqueror@gmx.de) */ public final class ColorSupported extends EnumSyntax @@ -49,13 +63,20 @@ public final class ColorSupported extends EnumSyntax { private static final long serialVersionUID = -2700555589688535545L; + /** The printer does not support printing in color. */ public static final ColorSupported NOT_SUPPORTED = new ColorSupported(0); + + /** The printer supports printing in color. */ public static final ColorSupported SUPPORTED = new ColorSupported(1); + private static final String[] stringTable = { "not-supported", "supported" }; + private static final ColorSupported[] enumValueTable = { NOT_SUPPORTED, + SUPPORTED }; + /** * Constructs a <code>ColorSupported</code> object. * - * @param value the value + * @param value the enum value */ protected ColorSupported(int value) { @@ -65,7 +86,7 @@ public final class ColorSupported extends EnumSyntax /** * Returns category of this class. * - * @return the class <code>ColorSupported</code> itself + * @return The class <code>ColorSupported</code> itself. */ public Class getCategory() { @@ -75,10 +96,31 @@ public final class ColorSupported extends EnumSyntax /** * Returns the name of this attribute. * - * @return the name + * @return The name "color-supported". */ public String getName() { return "color-supported"; } + + /** + * Returns a table with the enumeration values represented as strings + * for this object. + * + * @return The enumeration values as strings. + */ + protected String[] getStringTable() + { + return stringTable; + } + + /** + * Returns a table with the enumeration values for this object. + * + * @return The enumeration values. + */ + protected EnumSyntax[] getEnumValueTable() + { + return enumValueTable; + } } diff --git a/libjava/classpath/javax/print/attribute/standard/Compression.java b/libjava/classpath/javax/print/attribute/standard/Compression.java index 112202a..d29ffa0 100644 --- a/libjava/classpath/javax/print/attribute/standard/Compression.java +++ b/libjava/classpath/javax/print/attribute/standard/Compression.java @@ -1,5 +1,5 @@ /* Compression.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -42,6 +42,16 @@ import javax.print.attribute.EnumSyntax; /** + * The <code>Compression</code> printing attribute specifies if and how the + * supplied print data is compressed. + * <p> + * If this attribute is ommitted from the attributes set of the print + * data it is assumed that no compression is done. + * </p> + * <p> + * <b>IPP Compatibility:</b> Compression is an IPP 1.1 attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) */ public class Compression extends EnumSyntax @@ -49,15 +59,27 @@ public class Compression extends EnumSyntax { private static final long serialVersionUID = -5716748913324997674L; + /** The print data is not compressed. */ public static final Compression NONE = new Compression(0); + + /** The print data is ZIP compressed. */ public static final Compression DEFLATE = new Compression(1); + + /** The print data is GNU Zip compressed. */ public static final Compression GZIP = new Compression(2); + + /** The print data is UNIX compressed. */ public static final Compression COMPRESS = new Compression(3); + + private static final String[] stringTable = { "none", "deflate", + "gzip", "compress" }; + private static final Compression[] enumValueTable = { NONE, DEFLATE, + GZIP, COMPRESS }; /** * Constructs a <code>Compression</code> object. * - * @param value that value + * @param value the enum value */ protected Compression(int value) { @@ -67,7 +89,7 @@ public class Compression extends EnumSyntax /** * Returns category of this class. * - * @return the class <code>Compression</code> itself + * @return The class <code>Compression</code> itself. */ public Class getCategory() { @@ -77,10 +99,31 @@ public class Compression extends EnumSyntax /** * Returns the name of this attribute. * - * @return the name + * @return The name "compression". */ public String getName() { return "compression"; } + + /** + * Returns a table with the enumeration values represented as strings + * for this object. + * + * @return The enumeration values as strings. + */ + protected String[] getStringTable() + { + return stringTable; + } + + /** + * Returns a table with the enumeration values for this object. + * + * @return The enumeration values. + */ + protected EnumSyntax[] getEnumValueTable() + { + return enumValueTable; + } } diff --git a/libjava/classpath/javax/print/attribute/standard/Copies.java b/libjava/classpath/javax/print/attribute/standard/Copies.java index 7c5fdff..78ca6c6 100644 --- a/libjava/classpath/javax/print/attribute/standard/Copies.java +++ b/libjava/classpath/javax/print/attribute/standard/Copies.java @@ -1,5 +1,5 @@ /* Copies.java -- - Copyright (C) 2003 Free Software Foundation, Inc. + Copyright (C) 2003, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -33,7 +33,7 @@ module. An independent module is a module which is not derived from or based on this library. If you modify this library, you may extend this exception to your version of the library, but you are not obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ +exception statement from your version. */ package javax.print.attribute.standard; @@ -42,7 +42,19 @@ import javax.print.attribute.PrintJobAttribute; import javax.print.attribute.PrintRequestAttribute; /** - * @author Michael Koch + * The <code>Copies</code> printing attribute specifies the number + * of copies to be printed. + * <p> + * <b>Note:</b> The effect of this attribute on jobs with multiple documents + * is controlled by the job attribute + * {@link javax.print.attribute.standard.MultipleDocumentHandling}. + * </p> + * <p> + * <b>IPP Compatibility:</b> Copies is an IPP 1.1 attribute. + * </p> + * @see javax.print.attribute.standard.MultipleDocumentHandling + * + * @author Michael Koch (konqueror@gmx.de) */ public final class Copies extends IntegerSyntax implements PrintJobAttribute, PrintRequestAttribute @@ -54,7 +66,7 @@ public final class Copies extends IntegerSyntax * * @param value the number of copies * - * @exception IllegalArgumentException if value < 1 + * @exception IllegalArgumentException if value < 1 */ public Copies(int value) { @@ -65,11 +77,12 @@ public final class Copies extends IntegerSyntax } /** - * Tests of obj is equal to this object. + * Tests if the given object is equal to this object. * * @param obj the object to test * - * @return true if both objects are equal, false otherwise. + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. */ public boolean equals(Object obj) { @@ -82,7 +95,7 @@ public final class Copies extends IntegerSyntax /** * Returns category of this class. * - * @return the class <code>Copies</code> itself + * @return The class <code>Copies</code> itself. */ public Class getCategory() { @@ -90,9 +103,9 @@ public final class Copies extends IntegerSyntax } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "copies" + * @return The name "copies". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/CopiesSupported.java b/libjava/classpath/javax/print/attribute/standard/CopiesSupported.java index 8062ebc..fec426b 100644 --- a/libjava/classpath/javax/print/attribute/standard/CopiesSupported.java +++ b/libjava/classpath/javax/print/attribute/standard/CopiesSupported.java @@ -1,5 +1,5 @@ /* CopiesSupported.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -42,7 +42,15 @@ import javax.print.attribute.SupportedValuesAttribute; /** + * The <code>CopiesSupported</code> attribute specifies the supported + * value or range of values for the + * {@link javax.print.attribute.standard.Copies} attribute. + * <p> + * <b>IPP Compatibility:</b> CopiesSupported is an IPP 1.1 attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) + * @author Wolfgang Baer (WBaer@gmx.de) */ public final class CopiesSupported extends SetOfIntegerSyntax implements SupportedValuesAttribute @@ -50,25 +58,59 @@ public final class CopiesSupported extends SetOfIntegerSyntax private static final long serialVersionUID = 6927711687034846001L; /** - * Constructs a <code>CopiesSupported</code> object. + * Constructs a <code>CopiesSupported</code> object with + * the given value. This means that only this value is + * supported for copies. + * + * @param member the member value + * @exception IllegalArgumentException if member is < 1 */ public CopiesSupported(int member) { super(member); + + if (member < 1) + throw new IllegalArgumentException("member may not be less than 1"); } /** - * Constructs a <code>CopiesSupported</code> object. + * Constructs a <code>CopiesSupported</code> object with + * the given range of values. This means that values for + * copies are supported inside the specified range. + * + * @param lowerBound the lower bound value + * @param upperBound the upper bound value + * + * @exception IllegalArgumentException if lowerBound < 1 */ public CopiesSupported(int lowerBound, int upperBound) { super(lowerBound, upperBound); + + if (lowerBound < 1) + throw new IllegalArgumentException("lowerBound may not be less than 1"); + } + + /** + * Tests if the given object is equal to this object. + * + * @param obj the object to test + * + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. + */ + public boolean equals(Object obj) + { + if(! (obj instanceof CopiesSupported)) + return false; + + return super.equals(obj); } /** * Returns category of this class. * - * @return the class <code>CopiesSupported</code> itself + * @return The class <code>CopiesSupported</code> itself. */ public Class getCategory() { @@ -78,7 +120,7 @@ public final class CopiesSupported extends SetOfIntegerSyntax /** * Returns the name of this attribute. * - * @return the name + * @return The name "copies-supported". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/DateTimeAtCompleted.java b/libjava/classpath/javax/print/attribute/standard/DateTimeAtCompleted.java index fbb9e08..36b740e 100644 --- a/libjava/classpath/javax/print/attribute/standard/DateTimeAtCompleted.java +++ b/libjava/classpath/javax/print/attribute/standard/DateTimeAtCompleted.java @@ -1,5 +1,5 @@ /* DateTimeAtCompleted.java -- - Copyright (C) 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -44,6 +44,14 @@ import javax.print.attribute.DateTimeSyntax; import javax.print.attribute.PrintJobAttribute; /** + * The <code>DateTimeAtCompleted</code> attribute specifies the date and + * the time at which a print job completed (or was canceled or aborted). + * <p> + * <b>IPP Compatibility:</b> DateTimeAtCompleted is an IPP 1.1 attribute. + * </p> + * @see javax.print.attribute.standard.DateTimeAtCreation + * @see javax.print.attribute.standard.DateTimeAtProcessing + * * @author Michael Koch (konqueror@gmx.de) */ public final class DateTimeAtCompleted extends DateTimeSyntax @@ -64,11 +72,12 @@ public final class DateTimeAtCompleted extends DateTimeSyntax } /** - * Tests of obj is equal to this object. + * Tests if the given object is equal to this object. * * @param obj the object to test * - * @return true if both objects are equal, false otherwise. + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. */ public boolean equals(Object obj) { @@ -81,7 +90,7 @@ public final class DateTimeAtCompleted extends DateTimeSyntax /** * Returns category of this class. * - * @return the class <code>DateTimeAtCompleted</code> itself + * @return The class <code>DateTimeAtCompleted</code> itself. */ public Class getCategory() { @@ -89,9 +98,9 @@ public final class DateTimeAtCompleted extends DateTimeSyntax } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "date-time-at-completed" + * @return The name "date-time-at-completed". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/DateTimeAtCreation.java b/libjava/classpath/javax/print/attribute/standard/DateTimeAtCreation.java index b98af57..b463c40 100644 --- a/libjava/classpath/javax/print/attribute/standard/DateTimeAtCreation.java +++ b/libjava/classpath/javax/print/attribute/standard/DateTimeAtCreation.java @@ -1,5 +1,5 @@ /* DateTimeAtCreation.java -- - Copyright (C) 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -44,6 +44,14 @@ import javax.print.attribute.DateTimeSyntax; import javax.print.attribute.PrintJobAttribute; /** + * The <code>DateTimeAtCreation</code> attribute specifies the + * date and the time at which a print job was created. + * <p> + * <b>IPP Compatibility:</b> DateTimeAtCreation is an IPP 1.1 attribute. + * </p> + * @see javax.print.attribute.standard.DateTimeAtCompleted + * @see javax.print.attribute.standard.DateTimeAtProcessing + * * @author Michael Koch (konqueror@gmx.de) */ public final class DateTimeAtCreation extends DateTimeSyntax @@ -64,11 +72,12 @@ public final class DateTimeAtCreation extends DateTimeSyntax } /** - * Tests of obj is equal to this object. + * Tests if the given object is equal to this object. * * @param obj the object to test * - * @return true if both objects are equal, false otherwise. + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. */ public boolean equals(Object obj) { @@ -81,7 +90,7 @@ public final class DateTimeAtCreation extends DateTimeSyntax /** * Returns category of this class. * - * @return the class <code>DateTimeAtCreation</code> itself + * @return The class <code>DateTimeAtCreation</code> itself. */ public Class getCategory() { @@ -89,9 +98,9 @@ public final class DateTimeAtCreation extends DateTimeSyntax } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "date-time-at-creation" + * @return The name "date-time-at-creation". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/DateTimeAtProcessing.java b/libjava/classpath/javax/print/attribute/standard/DateTimeAtProcessing.java index ff537b9..42dee80 100644 --- a/libjava/classpath/javax/print/attribute/standard/DateTimeAtProcessing.java +++ b/libjava/classpath/javax/print/attribute/standard/DateTimeAtProcessing.java @@ -1,5 +1,5 @@ /* DateTimeAtProcessing.java -- - Copyright (C) 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -44,6 +44,14 @@ import javax.print.attribute.DateTimeSyntax; import javax.print.attribute.PrintJobAttribute; /** + * The <code>DateTimeAtProcessing</code> attribute specifies the date + * and the time at which a print job started processing. + * <p> + * <b>IPP Compatibility:</b> DateTimeAtProcessing is an IPP 1.1 attribute. + * </p> + * @see javax.print.attribute.standard.DateTimeAtCompleted + * @see javax.print.attribute.standard.DateTimeAtCreation + * * @author Michael Koch (konqueror@gmx.de) */ public final class DateTimeAtProcessing extends DateTimeSyntax @@ -64,11 +72,12 @@ public final class DateTimeAtProcessing extends DateTimeSyntax } /** - * Tests of obj is equal to this object. + * Tests if the given object is equal to this object. * * @param obj the object to test * - * @return true if both objects are equal, false otherwise. + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. */ public boolean equals(Object obj) { @@ -81,7 +90,7 @@ public final class DateTimeAtProcessing extends DateTimeSyntax /** * Returns category of this class. * - * @return the class <code>DateTimeAtProcessing</code> itself + * @return The class <code>DateTimeAtProcessing</code> itself. */ public Class getCategory() { @@ -89,9 +98,9 @@ public final class DateTimeAtProcessing extends DateTimeSyntax } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "date-time-at-processing" + * @return The name "date-time-at-processing". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/Destination.java b/libjava/classpath/javax/print/attribute/standard/Destination.java index c2da199..1a4e79d 100644 --- a/libjava/classpath/javax/print/attribute/standard/Destination.java +++ b/libjava/classpath/javax/print/attribute/standard/Destination.java @@ -45,7 +45,27 @@ import javax.print.attribute.PrintRequestAttribute; import javax.print.attribute.URISyntax; /** + * The <code>Destination</code> attribute provides a URI for an alternate + * destination of the printing output. + * <p> + * As not an IPP attribute many print services will not support this + * attribute and only provide the printer device as a destination. + * An alternate output destination would be a file on the local harddisk + * given as a file scheme URI. + * </p> + * <p> + * If a print service does not support the destination attributes URI it + * will throw a PrintException. This exception may further implement the + * interface {@link javax.print.URIException}. + * </p> + * <p> + * <b>IPP Compatibility:</b> Destination is not an IPP 1.1 attribute. + * </p> + * @see javax.print.PrintException + * @see javax.print.URIException + * * @author Michael Koch (konqueror@gmx.de) + * @author Wolfgang Baer (WBaer@gmx.de) */ public final class Destination extends URISyntax implements PrintJobAttribute, PrintRequestAttribute @@ -54,16 +74,35 @@ public final class Destination extends URISyntax /** * Constructs a <code>Destination</code> object. + * + * @param uri the URI of the output destination. + * @throws NullPointerException if the given uri is null. */ public Destination(URI uri) { super(uri); } + + /** + * Tests if the given object is equal to this object. + * + * @param obj the object to test + * + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. + */ + public boolean equals(Object obj) + { + if(! (obj instanceof Destination)) + return false; + + return super.equals(obj); + } /** * Returns category of this class. * - * @return the class <code>Destination</code> itself + * @return The class <code>Destination</code> itself. */ public Class getCategory() { @@ -71,12 +110,12 @@ public final class Destination extends URISyntax } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "printer-uri" + * @return The name "spool-data-destination" */ public String getName() { - return "destination"; + return "spool-data-destination"; } } diff --git a/libjava/classpath/javax/print/attribute/standard/DocumentName.java b/libjava/classpath/javax/print/attribute/standard/DocumentName.java index 2c472aa..d1428ed 100644 --- a/libjava/classpath/javax/print/attribute/standard/DocumentName.java +++ b/libjava/classpath/javax/print/attribute/standard/DocumentName.java @@ -1,5 +1,5 @@ /* DocumentName.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -44,6 +44,18 @@ import javax.print.attribute.DocAttribute; import javax.print.attribute.TextSyntax; /** + * The <code>DocumentName</code> printing attribute specifies a document name. + * <p> + * The document name may be different than the name of the job. It must not be + * unique across multiple documents in the same print job. Normally, an + * application provides the document name for the user by using e.g. the file + * name or a name generated automatically by the application. + * </p> + * <p> + * <b>IPP Compatibility:</b> DocumentName is an IPP 1.1 attribute. + * </p> + * @see javax.print.attribute.standard.JobName + * * @author Michael Koch (konqueror@gmx.de) */ public final class DocumentName extends TextSyntax @@ -55,6 +67,8 @@ public final class DocumentName extends TextSyntax * Creates a <code>DocumentName</code> object. * * @param documentName the document name + * @param locale the locale to use, if <code>null</code> the default + * locale is used. * * @exception NullPointerException if documentName is null */ @@ -64,11 +78,12 @@ public final class DocumentName extends TextSyntax } /** - * Tests of obj is equal to this object. + * Tests if the given object is equal to this object. * * @param obj the object to test * - * @return true if both objects are equal, false otherwise. + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. */ public boolean equals(Object obj) { @@ -81,7 +96,7 @@ public final class DocumentName extends TextSyntax /** * Returns category of this class. * - * @return the class <code>DocumentName</code> itself + * @return The class <code>DocumentName</code> itself. */ public Class getCategory() { @@ -89,9 +104,9 @@ public final class DocumentName extends TextSyntax } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "document-name" + * @return The name "document-name". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/Fidelity.java b/libjava/classpath/javax/print/attribute/standard/Fidelity.java index 9b26906..02e292f 100644 --- a/libjava/classpath/javax/print/attribute/standard/Fidelity.java +++ b/libjava/classpath/javax/print/attribute/standard/Fidelity.java @@ -1,5 +1,5 @@ /* Fidelity.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -33,7 +33,8 @@ module. An independent module is a module which is not derived from or based on this library. If you modify this library, you may extend this exception to your version of the library, but you are not obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ +exception statement from your version. */ + package javax.print.attribute.standard; @@ -43,15 +44,53 @@ import javax.print.attribute.PrintRequestAttribute; /** + * The <code>Fidelity</code> attribute specifies how a print job is handled + * if the supplied attributes are not fully supported. + * <p> + * There may be conflicts between the client requested attributes and the + * attributes supported by the printer object. Such situations are controlled + * through the client by providing this attribute to indicate the wanted + * conflict handling mechanism: + * <ul> + * <li>{@link #FIDELITY_TRUE}: Reject the job since the job can not be + * processed exactly as specified by the attributes of the client.</li> + * <li>{@link #FIDELITY_FALSE}: The Printer may make any changes necessary + * to proceed with processing the Job as good as possible.</li> + * </ul> + * </p> + * <p> + * <b>IPP Compatibility:</b> Fidelity is an IPP 1.1 attribute. The IPP name + * is "ipp-attribute-fidelity". The IPP specification treats Fidelity as a + * boolean type which is not available in the Java Print Service API. The IPP + * boolean value "true" corresponds to <code>FIDELITY_TRUE</code> and "false" + * to <code>FIDELITY_FALSE</code>. + * </p> + * * @author Michael Koch (konqueror@gmx.de) + * @author Wolfgang Baer (WBaer@gmx.de) */ public final class Fidelity extends EnumSyntax implements PrintJobAttribute, PrintRequestAttribute { private static final long serialVersionUID = 6320827847329172308L; + /** + * Requests that the job is printed exactly as specified, + * or rejected otherwise. + */ public static final Fidelity FIDELITY_TRUE = new Fidelity(0); + + /** + * Requests that the job is printed as exactly as reasonable. This means + * that the print service may choose to substitute the default value + * associated with that attribute, or use some other supported value that + * is similar to the unsupported requested value. + */ public static final Fidelity FIDELITY_FALSE = new Fidelity(1); + + private static final String[] stringTable = { "true", "false" }; + private static final Fidelity[] enumValueTable = { FIDELITY_TRUE, + FIDELITY_FALSE }; /** * Constructs a <code>Fidelity</code> object. @@ -66,7 +105,7 @@ public final class Fidelity extends EnumSyntax /** * Returns category of this class. * - * @return the class <code>Fidelity</code> itself + * @return The class <code>Fidelity</code> itself. */ public Class getCategory() { @@ -76,10 +115,31 @@ public final class Fidelity extends EnumSyntax /** * Returns the name of this attribute. * - * @return the name + * @return The name "ipp-attribute-fidelity". */ public String getName() { - return "fidelity"; + return "ipp-attribute-fidelity"; + } + + /** + * Returns a table with the enumeration values represented as strings + * for this object. + * + * @return The enumeration values as strings. + */ + protected String[] getStringTable() + { + return stringTable; + } + + /** + * Returns a table with the enumeration values for this object. + * + * @return The enumeration values. + */ + protected EnumSyntax[] getEnumValueTable() + { + return enumValueTable; } } diff --git a/libjava/classpath/javax/print/attribute/standard/Finishings.java b/libjava/classpath/javax/print/attribute/standard/Finishings.java index 1224c1d..6d474a6 100644 --- a/libjava/classpath/javax/print/attribute/standard/Finishings.java +++ b/libjava/classpath/javax/print/attribute/standard/Finishings.java @@ -1,5 +1,5 @@ /* Finishings.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -33,7 +33,8 @@ module. An independent module is a module which is not derived from or based on this library. If you modify this library, you may extend this exception to your version of the library, but you are not obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ +exception statement from your version. */ + package javax.print.attribute.standard; @@ -44,32 +45,184 @@ import javax.print.attribute.PrintRequestAttribute; /** + * The <code>Finishings</code> attribute specifies the finishing operations + * that the Printer applies to every copy of each printed document in the Job. + * <p> + * Standard enum values are: <code>NONE</code>, <code>STAPLE</code>, + * <code>COVER</code>, <code>BIND</code>, <code>SADDLE_STITCH</code>, + * <code>EDGE_STITCH</code>. + * <br><br> + * The following values are more specific: + * <code>STAPLE_TOP_LEFT</code>, <code>STAPLE_BOTTOM_LEFT</code>, + * <code>STAPLE_TOP_RIGHT</code>, <code>STAPLE_BOTTOM_RIGHT</code>, + * <code>EDGE_STITCH_LEFT</code>, <code>EDGE_STITCH_TOP</code>, + * <code>EDGE_STITCH_RIGHT</code>, <code>EDGE_STITCH_BOTTOM</code>, + * <code>STAPLE_DUAL_LEFT</code>, <code>STAPLE_DUAL_TOP</code>, + * <code>STAPLE_DUAL_RIGHT</code>, <code>STAPLE_DUAL_BOTTOM</code>. + * </p> + * <p> + * <b>Note:</b> The effect of this attribute on jobs with multiple documents + * is controlled by the job attribute + * {@link javax.print.attribute.standard.MultipleDocumentHandling}. + * </p> + * <p> + * <b>IPP Compatibility:</b> Finishings is an IPP 1.1 attribute. Differences + * to the IPP specification are that in the Java Print Service API only one + * enum value is supported (in IPP a set of enums). Further the enum + * <code>punch</code> is not supported. + * </p> + * * @author Michael Koch (konqueror@gmx.de) + * @author Wolfgang Baer (WBaer@gmx.de) */ public class Finishings extends EnumSyntax implements DocAttribute, PrintJobAttribute, PrintRequestAttribute { private static final long serialVersionUID = -627840419548391754L; - public static final Finishings NONE = new Finishings(0); - public static final Finishings STAPLE = new Finishings(1); - public static final Finishings COVER = new Finishings(2); - public static final Finishings BIND = new Finishings(3); - public static final Finishings SADDLE_STITCH = new Finishings(4); - public static final Finishings EDGE_STITCH = new Finishings(5); - public static final Finishings STAPLE_TOP_LEFT = new Finishings(6); - public static final Finishings STAPLE_BOTTOM_LEFT = new Finishings(7); - public static final Finishings STAPLE_TOP_RIGHT = new Finishings(8); - public static final Finishings STAPLE_BOTTOM_RIGHT = new Finishings(9); - public static final Finishings EDGE_STITCH_LEFT = new Finishings(10); - public static final Finishings EDGE_STITCH_TOP = new Finishings(11); - public static final Finishings EDGE_STITCH_RIGHT = new Finishings(12); - public static final Finishings EDGE_STITCH_BOTTOM = new Finishings(13); - public static final Finishings STAPLE_DUAL_LEFT = new Finishings(14); - public static final Finishings STAPLE_DUAL_TOP = new Finishings(15); - public static final Finishings STAPLE_DUAL_RIGHT = new Finishings(16); - public static final Finishings STAPLE_DUAL_BOTTOM = new Finishings(17); + /** + * Perform no finishings of the documents. + */ + public static final Finishings NONE = new Finishings(3); + + /** + * Selects binding of the documents with one or more staples. + */ + public static final Finishings STAPLE = new Finishings(4); + + /** + * Selects the use of a non-printed (or pre-printed) cover for + * the document. + */ + public static final Finishings COVER = new Finishings(6); + + /** + * Selects that a binding is to be applied to the document. + * The type and placement of the binding is site-defined. + */ + public static final Finishings BIND = new Finishings(7); + + /** + * Selects binding of the documents with one or more staples + * along the middle fold. + */ + public static final Finishings SADDLE_STITCH = new Finishings(8); + + /** + * Selects binding of the documents with one or more staples + * along one edge. + */ + public static final Finishings EDGE_STITCH = new Finishings(9); + + /** + * Selects binding of the documents with one or more staples + * in the top left corner. + */ + public static final Finishings STAPLE_TOP_LEFT = new Finishings(20); + + /** + * Selects binding of the documents with one or more staples in the bottom + * left corner. + */ + public static final Finishings STAPLE_BOTTOM_LEFT = new Finishings(21); + + /** + * Selects binding of the documents with one or more staples in + * the top right corner. + */ + public static final Finishings STAPLE_TOP_RIGHT = new Finishings(22); + + /** + * Selects binding of the documents with one or more staples in + * the bottom right corner. + */ + public static final Finishings STAPLE_BOTTOM_RIGHT = new Finishings(23); + + /** + * Selects binding of the documents with one or more staples + * along the left edge. + */ + public static final Finishings EDGE_STITCH_LEFT = new Finishings(24); + + /** + * Selects binding of the documents with one or more staples along + * the top edge. + */ + public static final Finishings EDGE_STITCH_TOP = new Finishings(25); + + /** + * Selects binding of the documents with one or more staples along + * the right edge. + */ + public static final Finishings EDGE_STITCH_RIGHT = new Finishings(26); + + /** + * Selects binding of the documents with one or more staples along + * the bottom edge. + */ + public static final Finishings EDGE_STITCH_BOTTOM = new Finishings(27); + + /** + * Selects binding of the documents with two staples along the + * left edge assuming a portrait document. + */ + public static final Finishings STAPLE_DUAL_LEFT = new Finishings(28); + + /** + * Selects binding of the documents with two staples along the + * top edge assuming a portrait document. + */ + public static final Finishings STAPLE_DUAL_TOP = new Finishings(29); + + /** + * Selects binding of the documents with two staples along the + * right edge assuming a portrait document. + */ + public static final Finishings STAPLE_DUAL_RIGHT = new Finishings(30); + + /** + * Selects binding of the documents with two staples along the + * bottom edge assuming a portrait document. + */ + public static final Finishings STAPLE_DUAL_BOTTOM = new Finishings(31); + private static final String[] stringTable = { "none", "staple", null, + "cover", "bind", "saddle-stitch", + "edge-stitch", null, null, null, + null, null, null, null, null, + null, null, "staple-top-left", + "staple-bottom-left", + "staple-top-right", + "staple-bottom-right", + "edge-stitch-left", + "edge-stitch-top", + "edge-stitch-right", + "edge-stitch-bottom", + "staple-dual-left", + "staple-dual-top", + "staple-dual-right", + "staple-dual-bottom" }; + + private static final Finishings[] enumValueTable = { NONE, STAPLE, null, + COVER, BIND, + SADDLE_STITCH, + EDGE_STITCH, null, + null, null, null, + null, null, null, + null, null, null, + STAPLE_TOP_LEFT, + STAPLE_BOTTOM_LEFT, + STAPLE_TOP_RIGHT, + STAPLE_BOTTOM_RIGHT, + EDGE_STITCH_LEFT, + EDGE_STITCH_TOP, + EDGE_STITCH_RIGHT, + EDGE_STITCH_BOTTOM, + STAPLE_DUAL_LEFT, + STAPLE_DUAL_TOP, + STAPLE_DUAL_RIGHT, + STAPLE_DUAL_BOTTOM }; + /** * Constructs a <code>Finishings</code> object. * @@ -93,10 +246,41 @@ public class Finishings extends EnumSyntax /** * Returns the name of this attribute. * - * @return the name + * @return The name "finishings". */ public String getName() { return "finishings"; } + + /** + * Returns a table with the enumeration values represented as strings + * for this object. + * + * @return The enumeration values as strings. + */ + protected String[] getStringTable() + { + return stringTable; + } + + /** + * Returns a table with the enumeration values for this object. + * + * @return The enumeration values. + */ + protected EnumSyntax[] getEnumValueTable() + { + return enumValueTable; + } + + /** + * Returns the lowest used value by the enumerations of this class. + * . + * @return The lowest value used. + */ + protected int getOffset() + { + return 3; + } } diff --git a/libjava/classpath/javax/print/attribute/standard/JobHoldUntil.java b/libjava/classpath/javax/print/attribute/standard/JobHoldUntil.java index 5f05463..768600f 100644 --- a/libjava/classpath/javax/print/attribute/standard/JobHoldUntil.java +++ b/libjava/classpath/javax/print/attribute/standard/JobHoldUntil.java @@ -1,5 +1,5 @@ /* JobHoldUntil.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -45,6 +45,19 @@ import javax.print.attribute.PrintJobAttribute; import javax.print.attribute.PrintRequestAttribute; /** + * The <code>JobHoldUntil</code> attribute specifies the date + * and the time at which a print job must become a candidate + * for printing. + * <p> + * <b>IPP Compatibility:</b> JobHoldUntil is an IPP 1.1 attribute. + * However the attribute in IPP is based on keywords of named + * time periods like day-time or evening. It will depend on the + * concrete implementation of a print service how a mapping of the + * detailed provided date and time of this attribute to the named + * keyword or an alternate extension attribute will be done. E.g. + * CUPS supports also a HH:MM format as extension to the keywords. + * </p> + * * @author Michael Koch (konqueror@gmx.de) */ public final class JobHoldUntil extends DateTimeSyntax @@ -65,11 +78,12 @@ public final class JobHoldUntil extends DateTimeSyntax } /** - * Tests of obj is equal to this object. + * Tests if the given object is equal to this object. * * @param obj the object to test * - * @return true if both objects are equal, false otherwise. + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. */ public boolean equals(Object obj) { @@ -82,7 +96,7 @@ public final class JobHoldUntil extends DateTimeSyntax /** * Returns category of this class. * - * @return the class <code>JobHoldUntil</code> itself + * @return The class <code>JobHoldUntil</code> itself. */ public Class getCategory() { @@ -90,9 +104,9 @@ public final class JobHoldUntil extends DateTimeSyntax } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "job-hold-until" + * @return The name "job-hold-until". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/JobImpressions.java b/libjava/classpath/javax/print/attribute/standard/JobImpressions.java index a29c24c..0da3e59 100644 --- a/libjava/classpath/javax/print/attribute/standard/JobImpressions.java +++ b/libjava/classpath/javax/print/attribute/standard/JobImpressions.java @@ -1,5 +1,5 @@ /* JobImpressions.java -- - Copyright (C) 2003 Free Software Foundation, Inc. + Copyright (C) 2003, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -42,6 +42,31 @@ import javax.print.attribute.PrintJobAttribute; import javax.print.attribute.PrintRequestAttribute; /** + * The <code>JobImpressions</code> printing attribute specifies + * the total size in number of impressions of the documents + * of a a print job. + * <p> + * An impression is specified by the IPP specification as the image + * (possibly many print-stream pages in different configurations) + * imposed onto a single media sheet. This attribute must not include + * a multiplication factor from the number of copies which maybe specified + * in a Copies attribute. + * </p> + * <p> + * This attribute belongs to a group of job size attributes which are + * describing the size of a job to be printed. The values supplied by + * these attributes are intended to be used for routing and scheduling + * of jobs on the print service. A client may specify these attributes. + * If a clients supplies these attributes a print service may change + * the values if its be able to compute a more accurate value at the + * time of the job submission or also later. + * </p> + * <p> + * <b>IPP Compatibility:</b> JobImpressions is an IPP 1.1 attribute. + * </p> + * @see javax.print.attribute.standard.JobKOctets + * @see javax.print.attribute.standard.JobMediaSheets + * * @author Michael Koch */ public final class JobImpressions extends IntegerSyntax @@ -54,7 +79,7 @@ public final class JobImpressions extends IntegerSyntax * * @param value the number of impressions * - * @exception IllegalArgumentException if value < 0 + * @exception IllegalArgumentException if value < 0 */ public JobImpressions(int value) { @@ -65,11 +90,12 @@ public final class JobImpressions extends IntegerSyntax } /** - * Tests of obj is equal to this object. + * Tests if the given object is equal to this object. * * @param obj the object to test * - * @return true if both objects are equal, false otherwise. + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. */ public boolean equals(Object obj) { @@ -82,7 +108,7 @@ public final class JobImpressions extends IntegerSyntax /** * Returns category of this class. * - * @return the class <code>JobImpressions</code> itself + * @return The class <code>JobImpressions</code> itself. */ public Class getCategory() { @@ -90,9 +116,9 @@ public final class JobImpressions extends IntegerSyntax } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "job-impressions" + * @return The name "job-impressions". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/JobImpressionsCompleted.java b/libjava/classpath/javax/print/attribute/standard/JobImpressionsCompleted.java index d1b3e96..82da507 100644 --- a/libjava/classpath/javax/print/attribute/standard/JobImpressionsCompleted.java +++ b/libjava/classpath/javax/print/attribute/standard/JobImpressionsCompleted.java @@ -1,5 +1,5 @@ /* JobImpressionsCompleted.java -- - Copyright (C) 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -41,6 +41,23 @@ import javax.print.attribute.IntegerSyntax; import javax.print.attribute.PrintJobAttribute; /** + * The <code>JobImpressionsCompleted</code> printing attribute reports + * the number of impressions already processed. + * <p> + * An impression is specified by the IPP specification as the image imposed + * onto a single media sheet. This attribute will not include a multiplication + * factor from the number of copies. + * </p> + * <p> + * This attribute belongs to a group of job progress attributes which are + * reporting on the progress of a print job. + * </p> + * <p> + * <b>IPP Compatibility:</b> JobImpressionsCompleted is an IPP 1.1 attribute. + * </p> + * @see javax.print.attribute.standard.JobMediaSheetsCompleted + * @see javax.print.attribute.standard.JobKOctetsProcessed + * * @author Michael Koch (konqueror@gmx.de) */ public final class JobImpressionsCompleted extends IntegerSyntax @@ -53,7 +70,7 @@ public final class JobImpressionsCompleted extends IntegerSyntax * * @param value the number of completed impressions * - * @exception IllegalArgumentException if value < 0 + * @exception IllegalArgumentException if value < 0 */ public JobImpressionsCompleted(int value) { @@ -64,11 +81,12 @@ public final class JobImpressionsCompleted extends IntegerSyntax } /** - * Tests of obj is equal to this object. + * Tests if the given object is equal to this object. * * @param obj the object to test * - * @return true if both objects are equal, false otherwise. + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. */ public boolean equals(Object obj) { @@ -81,7 +99,7 @@ public final class JobImpressionsCompleted extends IntegerSyntax /** * Returns category of this class. * - * @return the class <code>JobImpressionsCompleted</code> itself + * @return The class <code>JobImpressionsCompleted</code> itself. */ public Class getCategory() { @@ -89,12 +107,12 @@ public final class JobImpressionsCompleted extends IntegerSyntax } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "job-impressions-completed" + * @return The name "job-impressions-completed". */ public String getName() { - return "job-impressions"; + return "job-impressions-completed"; } } diff --git a/libjava/classpath/javax/print/attribute/standard/JobImpressionsSupported.java b/libjava/classpath/javax/print/attribute/standard/JobImpressionsSupported.java index 0ba7089..bd10457 100644 --- a/libjava/classpath/javax/print/attribute/standard/JobImpressionsSupported.java +++ b/libjava/classpath/javax/print/attribute/standard/JobImpressionsSupported.java @@ -1,5 +1,5 @@ /* JobImpressionsSupported.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -42,7 +42,15 @@ import javax.print.attribute.SupportedValuesAttribute; /** + * The <code>JobImpressionsSupported</code> printing attribute specifies the + * supported range of values for the + * {@link javax.print.attribute.standard.JobImpressions} attribute. + * <p> + * <b>IPP Compatibility:</b> JobImpressionsSupported is an IPP 1.1 attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) + * @author Wolfgang Baer (WBaer@gmx.de) */ public final class JobImpressionsSupported extends SetOfIntegerSyntax implements SupportedValuesAttribute @@ -50,17 +58,43 @@ public final class JobImpressionsSupported extends SetOfIntegerSyntax private static final long serialVersionUID = -4887354803843173692L; /** - * Constructs a <code>JobImpressionsSupported</code> object. + * Constructs a <code>JobImpressionsSupported</code> object with the + * given range of supported job impressions values. + * + * @param lowerBound the lower bound value + * @param upperBound the upper bound value + * + * @exception IllegalArgumentException if lowerBound <= upperbound + * and lowerBound < 1 */ public JobImpressionsSupported(int lowerBound, int upperBound) { super(lowerBound, upperBound); + + if (lowerBound < 1) + throw new IllegalArgumentException("lowerBound may not be less than 1"); + } + + /** + * Tests if the given object is equal to this object. + * + * @param obj the object to test + * + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. + */ + public boolean equals(Object obj) + { + if (! (obj instanceof JobImpressionsSupported)) + return false; + + return super.equals(obj); } /** * Returns category of this class. * - * @return the class <code>JobImpressionsSupported</code> itself + * @return The class <code>JobImpressionsSupported</code> itself. */ public Class getCategory() { @@ -70,7 +104,7 @@ public final class JobImpressionsSupported extends SetOfIntegerSyntax /** * Returns the name of this attribute. * - * @return the name + * @return The name "job-impressions-supported". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/JobKOctets.java b/libjava/classpath/javax/print/attribute/standard/JobKOctets.java index 71f02c5..b380aa1 100644 --- a/libjava/classpath/javax/print/attribute/standard/JobKOctets.java +++ b/libjava/classpath/javax/print/attribute/standard/JobKOctets.java @@ -1,5 +1,5 @@ /* JobKOctets.java -- - Copyright (C) 2003 Free Software Foundation, Inc. + Copyright (C) 2003, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -42,6 +42,30 @@ import javax.print.attribute.PrintJobAttribute; import javax.print.attribute.PrintRequestAttribute; /** + * The <code>JobKOctets</code> printing attribute specifies + * the total size of all the documents of a print job in K octets. + * <p> + * The supplied value has to be rounded up, so that a range between + * 1 and 1024 octects is specified as 1 and a range between 1025 and + * 2048 octects as 2, etc. This attribute must not include a multiplication + * factor from the number of copies which maybe specified in a Copies + * attribute. + * </p> + * <p> + * This attribute belongs to a group of job size attributes which are + * describing the size of a job to be printed. The values supplied by + * these attributes are intended to be used for routing and scheduling + * of jobs on the print service. A client may specify these attributes. + * If a clients supplies these attributes a print service may change + * the values if its be able to compute a more accurate value at the + * time of the job submission or also later. + * </p> + * <p> + * <b>IPP Compatibility:</b> JobKOctets is an IPP 1.1 attribute. + * </p> + * @see javax.print.attribute.standard.JobMediaSheets + * @see javax.print.attribute.standard.JobImpressions + * * @author Michael Koch */ public final class JobKOctets extends IntegerSyntax @@ -51,10 +75,11 @@ public final class JobKOctets extends IntegerSyntax /** * Creates a <code>JobKOctets</code> object. + * The value is in units of K (1024) octets rounded up to the next highest K. * * @param value the number of K octets * - * @exception IllegalArgumentException if value < 0 + * @exception IllegalArgumentException if value < 0 */ public JobKOctets(int value) { @@ -65,11 +90,12 @@ public final class JobKOctets extends IntegerSyntax } /** - * Tests of obj is equal to this object. + * Tests if the given object is equal to this object. * * @param obj the object to test * - * @return true if both objects are equal, false otherwise. + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. */ public boolean equals(Object obj) { @@ -82,7 +108,7 @@ public final class JobKOctets extends IntegerSyntax /** * Returns category of this class. * - * @return the class <code>JobKOctets</code> itself + * @return The class <code>JobKOctets</code> itself. */ public Class getCategory() { @@ -90,9 +116,9 @@ public final class JobKOctets extends IntegerSyntax } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "job-k-octets" + * @return The name "job-k-octets". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/JobKOctetsProcessed.java b/libjava/classpath/javax/print/attribute/standard/JobKOctetsProcessed.java index 7561222..7623695 100644 --- a/libjava/classpath/javax/print/attribute/standard/JobKOctetsProcessed.java +++ b/libjava/classpath/javax/print/attribute/standard/JobKOctetsProcessed.java @@ -1,5 +1,5 @@ /* JobKOctetsProcessed.java -- - Copyright (C) 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -41,6 +41,23 @@ import javax.print.attribute.IntegerSyntax; import javax.print.attribute.PrintJobAttribute; /** + * The <code>JobKOctetsProcessed</code> printing attribute reports + * the total number of octets already processed in K octets units. + * <p> + * The supplied value will be rounded up to the next highest K octets. + * This attribute will not include a multiplication factor from the number + * of copies. + * </p> + * <p> + * This attribute belongs to a group of job progress attributes which are + * reporting on the progress of a print job. + * </p> + * <p> + * <b>IPP Compatibility:</b> JobKOctetsProcessed is an IPP 1.1 attribute. + * </p> + * @see javax.print.attribute.standard.JobMediaSheetsCompleted + * @see javax.print.attribute.standard.JobImpressionsCompleted + * * @author Michael Koch */ public final class JobKOctetsProcessed extends IntegerSyntax @@ -50,10 +67,11 @@ public final class JobKOctetsProcessed extends IntegerSyntax /** * Creates a <code>JobKOctetsProcessed</code> object. + * The value is in units of K (1024) octets rounded up to the next highest K. * * @param value the number of processed K octets * - * @exception IllegalArgumentException if value < 0 + * @exception IllegalArgumentException if value < 0 */ public JobKOctetsProcessed(int value) { @@ -64,11 +82,12 @@ public final class JobKOctetsProcessed extends IntegerSyntax } /** - * Tests of obj is equal to this object. + * Tests if the given object is equal to this object. * * @param obj the object to test * - * @return true if both objects are equal, false otherwise. + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. */ public boolean equals(Object obj) { @@ -81,7 +100,7 @@ public final class JobKOctetsProcessed extends IntegerSyntax /** * Returns category of this class. * - * @return the class <code>JobKOctetsProcessed</code> itself + * @return The class <code>JobKOctetsProcessed</code> itself. */ public Class getCategory() { @@ -89,9 +108,9 @@ public final class JobKOctetsProcessed extends IntegerSyntax } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "job-k-octets-processed" + * @return The name "job-k-octets-processed". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/JobKOctetsSupported.java b/libjava/classpath/javax/print/attribute/standard/JobKOctetsSupported.java index 303dc95..8a4cbfc 100644 --- a/libjava/classpath/javax/print/attribute/standard/JobKOctetsSupported.java +++ b/libjava/classpath/javax/print/attribute/standard/JobKOctetsSupported.java @@ -1,5 +1,5 @@ /* JobKOctetsSupported.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -42,7 +42,15 @@ import javax.print.attribute.SupportedValuesAttribute; /** + * The <code>JobKOctetsSupported</code> printing attribute specifies the + * supported range of values for the + * {@link javax.print.attribute.standard.JobKOctets} attribute. + * <p> + * <b>IPP Compatibility:</b> JobKOctetsSupported is an IPP 1.1 attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) + * @author Wolfgang Baer (WBaer@gmx.de) */ public final class JobKOctetsSupported extends SetOfIntegerSyntax implements SupportedValuesAttribute @@ -50,17 +58,43 @@ public final class JobKOctetsSupported extends SetOfIntegerSyntax private static final long serialVersionUID = -2867871140549897443L; /** - * Constructs a <code>JobKOctetsSupported</code> object. + * Constructs a <code>JobKOctetsSupported</code> object with the + * given range for supported K octets. + * + * @param lowerBound the lower bound value + * @param upperBound the upper bound value + * + * @exception IllegalArgumentException if lowerBound <= upperbound + * and lowerBound < 1 */ public JobKOctetsSupported(int lowerBound, int upperBound) { super(lowerBound, upperBound); + + if (lowerBound < 1) + throw new IllegalArgumentException("lowerBound may not be less than 1"); + } + + /** + * Tests if the given object is equal to this object. + * + * @param obj the object to test + * + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. + */ + public boolean equals(Object obj) + { + if (! (obj instanceof JobKOctetsSupported)) + return false; + + return super.equals(obj); } /** * Returns category of this class. * - * @return the class <code>ColorSupported</code> itself + * @return The class <code>JobKOctetsSupported</code> itself. */ public Class getCategory() { @@ -70,7 +104,7 @@ public final class JobKOctetsSupported extends SetOfIntegerSyntax /** * Returns the name of this attribute. * - * @return the name + * @return The name "job-k-octets-supported". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/JobMediaSheets.java b/libjava/classpath/javax/print/attribute/standard/JobMediaSheets.java index 662c54a..75e072c 100644 --- a/libjava/classpath/javax/print/attribute/standard/JobMediaSheets.java +++ b/libjava/classpath/javax/print/attribute/standard/JobMediaSheets.java @@ -1,5 +1,5 @@ /* JobMediaSheets.java -- - Copyright (C) 2003 Free Software Foundation, Inc. + Copyright (C) 2003, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -42,6 +42,28 @@ import javax.print.attribute.PrintJobAttribute; import javax.print.attribute.PrintRequestAttribute; /** + * The <code>JobMediaSheets</code> printing attribute specifies + * the total number of media sheets needed by a job. + * <p> + * In contrary to the other job size attributes this attribute must include + * the multiplication factor from the number of copies if a Copies attribute + * was specified for the job. + * </p> + * <p> + * This attribute belongs to a group of job size attributes which are + * describing the size of a job to be printed. The values supplied by + * these attributes are intended to be used for routing and scheduling + * of jobs on the print service. A client may specify these attributes. + * If a clients supplies these attributes a print service may change + * the values if its be able to compute a more accurate value at the + * time of the job submission or also later. + * </p> + * <p> + * <b>IPP Compatibility:</b> JobMediaSheets is an IPP 1.1 attribute. + * </p> + * @see javax.print.attribute.standard.JobKOctets + * @see javax.print.attribute.standard.JobImpressions + * * @author Michael Koch */ public class JobMediaSheets extends IntegerSyntax @@ -54,7 +76,7 @@ public class JobMediaSheets extends IntegerSyntax * * @param value the number of media sheets for a print job * - * @exception IllegalArgumentException if value < 0 + * @exception IllegalArgumentException if value < 0 */ public JobMediaSheets(int value) { @@ -65,11 +87,12 @@ public class JobMediaSheets extends IntegerSyntax } /** - * Tests of obj is equal to this object. + * Tests if the given object is equal to this object. * * @param obj the object to test * - * @return true if both objects are equal, false otherwise. + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. */ public boolean equals(Object obj) { @@ -82,7 +105,7 @@ public class JobMediaSheets extends IntegerSyntax /** * Returns category of this class. * - * @return the class <code>JobMediaSheets</code> itself + * @return The class <code>JobMediaSheets</code> itself. */ public Class getCategory() { @@ -90,9 +113,9 @@ public class JobMediaSheets extends IntegerSyntax } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "job-media-sheets" + * @return The name "job-media-sheets". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/JobMediaSheetsCompleted.java b/libjava/classpath/javax/print/attribute/standard/JobMediaSheetsCompleted.java index 09b82bf..85b9ab0 100644 --- a/libjava/classpath/javax/print/attribute/standard/JobMediaSheetsCompleted.java +++ b/libjava/classpath/javax/print/attribute/standard/JobMediaSheetsCompleted.java @@ -1,5 +1,5 @@ /* JobMediaSheetsCompleted.java -- - Copyright (C) 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -41,6 +41,18 @@ import javax.print.attribute.IntegerSyntax; import javax.print.attribute.PrintJobAttribute; /** + * The <code>JobMediaSheetsCompleted</code> printing attribute reports + * the number of media sheets already processed. + * <p> + * This attribute belongs to a group of job progress attributes which are + * reporting on the progress of a print job. + * </p> + * <p> + * <b>IPP Compatibility:</b> JobMediaSheetsCompleted is an IPP 1.1 attribute. + * </p> + * @see javax.print.attribute.standard.JobImpressionsCompleted + * @see javax.print.attribute.standard.JobKOctetsProcessed + * * @author Michael Koch */ public final class JobMediaSheetsCompleted extends IntegerSyntax @@ -51,9 +63,9 @@ public final class JobMediaSheetsCompleted extends IntegerSyntax /** * Creates a <code>JobMediaSheetsCompleted</code> object. * - * @param value the number of completed media sheets for a print job + * @param value the number of completed media sheets * - * @exception IllegalArgumentException if value < 0 + * @exception IllegalArgumentException if value < 0 */ public JobMediaSheetsCompleted(int value) { @@ -64,11 +76,12 @@ public final class JobMediaSheetsCompleted extends IntegerSyntax } /** - * Tests of obj is equal to this object. + * Tests if the given object is equal to this object. * * @param obj the object to test * - * @return true if both objects are equal, false otherwise. + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. */ public boolean equals(Object obj) { @@ -81,7 +94,7 @@ public final class JobMediaSheetsCompleted extends IntegerSyntax /** * Returns category of this class. * - * @return the class <code>JobMediaSheetsCompleted</code> itself + * @return The class <code>JobMediaSheetsCompleted</code> itself. */ public Class getCategory() { @@ -89,9 +102,9 @@ public final class JobMediaSheetsCompleted extends IntegerSyntax } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "job-media-sheets-completed" + * @return The name "job-media-sheets-completed". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/JobMediaSheetsSupported.java b/libjava/classpath/javax/print/attribute/standard/JobMediaSheetsSupported.java index 392fe7e..cb06af6 100644 --- a/libjava/classpath/javax/print/attribute/standard/JobMediaSheetsSupported.java +++ b/libjava/classpath/javax/print/attribute/standard/JobMediaSheetsSupported.java @@ -1,5 +1,5 @@ /* JobMediaSheetsSupported.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -42,7 +42,15 @@ import javax.print.attribute.SupportedValuesAttribute; /** + * The <code>JobMediaSheetsSupported</code> printing attribute specifies the + * supported range of values for the + * {@link javax.print.attribute.standard.JobMediaSheets} attribute. + * <p> + * <b>IPP Compatibility:</b> JobMediaSheetsSupported is an IPP 1.1 attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) + * @author Wolfgang Baer (WBaer@gmx.de) */ public final class JobMediaSheetsSupported extends SetOfIntegerSyntax implements SupportedValuesAttribute @@ -50,17 +58,43 @@ public final class JobMediaSheetsSupported extends SetOfIntegerSyntax private static final long serialVersionUID = 2953685470388672940L; /** - * Constructs a <code>JobMediaSheetsSupported</code> object. + * Constructs a <code>JobMediaSheetsSupported</code> object with the + * given range of supported job media sheets values. + * + * @param lowerBound the lower bound value + * @param upperBound the upper bound value + * + * @exception IllegalArgumentException if lowerBound <= upperbound + * and lowerBound < 1 */ public JobMediaSheetsSupported(int lowerBound, int upperBound) { super(lowerBound, upperBound); + + if (lowerBound < 1) + throw new IllegalArgumentException("lowerBound may not be less than 1"); + } + + /** + * Tests if the given object is equal to this object. + * + * @param obj the object to test + * + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. + */ + public boolean equals(Object obj) + { + if (! (obj instanceof JobMediaSheetsSupported)) + return false; + + return super.equals(obj); } /** * Returns category of this class. * - * @return the class <code>JobMediaSheetsSupported</code> itself + * @return The class <code>JobMediaSheetsSupported</code> itself. */ public Class getCategory() { @@ -70,7 +104,7 @@ public final class JobMediaSheetsSupported extends SetOfIntegerSyntax /** * Returns the name of this attribute. * - * @return the name + * @return The name "job-media-sheets-supported". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/JobMessageFromOperator.java b/libjava/classpath/javax/print/attribute/standard/JobMessageFromOperator.java index 84eab8b..8eaae35 100644 --- a/libjava/classpath/javax/print/attribute/standard/JobMessageFromOperator.java +++ b/libjava/classpath/javax/print/attribute/standard/JobMessageFromOperator.java @@ -1,5 +1,5 @@ /* JobMessageFromOperator.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -44,6 +44,15 @@ import javax.print.attribute.PrintJobAttribute; import javax.print.attribute.TextSyntax; /** + * The <code>JobMessageFromOperator</code> printing attribute provides + * a message from an operator or a system administrator related to the + * print job. This may include information why a certain action has been + * taken on the print job like a modification. + * <p> + * <b>IPP Compatibility:</b> JobMessageFromOperator is an IPP 1.1 + * attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) */ public final class JobMessageFromOperator extends TextSyntax @@ -55,8 +64,10 @@ public final class JobMessageFromOperator extends TextSyntax * Creates a <code>JobMessageFromOperator</code> object. * * @param message the message + * @param locale the locale to use, if <code>null</code> the default + * locale is used. * - * @exception NullPointerException if message is null + * @exception NullPointerException if message is <code>null</code>. */ public JobMessageFromOperator(String message, Locale locale) { @@ -64,11 +75,12 @@ public final class JobMessageFromOperator extends TextSyntax } /** - * Tests of obj is equal to this object. + * Tests if the given object is equal to this object. * * @param obj the object to test * - * @return true if both objects are equal, false otherwise. + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. */ public boolean equals(Object obj) { @@ -81,7 +93,7 @@ public final class JobMessageFromOperator extends TextSyntax /** * Returns category of this class. * - * @return the class <code>JobMessageFromOperator</code> itself + * @return The class <code>JobMessageFromOperator</code> itself. */ public Class getCategory() { @@ -89,9 +101,9 @@ public final class JobMessageFromOperator extends TextSyntax } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "job-message-from-operator" + * @return The name "job-message-from-operator". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/JobName.java b/libjava/classpath/javax/print/attribute/standard/JobName.java index a64a88c..c848a63 100644 --- a/libjava/classpath/javax/print/attribute/standard/JobName.java +++ b/libjava/classpath/javax/print/attribute/standard/JobName.java @@ -1,5 +1,5 @@ /* JobName.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -45,6 +45,12 @@ import javax.print.attribute.PrintRequestAttribute; import javax.print.attribute.TextSyntax; /** + * The <code>JobName</code> printing attribute provides the name of a + * print job for identification. + * <p> + * <b>IPP Compatibility:</b> JobName is an IPP 1.1 attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) */ public final class JobName extends TextSyntax @@ -55,9 +61,11 @@ public final class JobName extends TextSyntax /** * Creates a <code>JobName</code> object. * - * @param jobName the job name + * @param jobName the job name. + * @param locale the locale to use, if <code>null</code> the default + * locale is used. * - * @exception NullPointerException if jobName is null + * @exception NullPointerException if jobName is <code>null</code>. */ public JobName(String jobName, Locale locale) { @@ -65,11 +73,12 @@ public final class JobName extends TextSyntax } /** - * Tests of obj is equal to this object. + * Tests if the given object is equal to this object. * * @param obj the object to test * - * @return true if both objects are equal, false otherwise. + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. */ public boolean equals(Object obj) { @@ -82,7 +91,7 @@ public final class JobName extends TextSyntax /** * Returns category of this class. * - * @return the class <code>JobName</code> itself + * @return The class <code>JobName</code> itself. */ public Class getCategory() { @@ -90,9 +99,9 @@ public final class JobName extends TextSyntax } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "job-name" + * @return The name "job-name". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/JobOriginatingUserName.java b/libjava/classpath/javax/print/attribute/standard/JobOriginatingUserName.java index 116de28..2d6e79d 100644 --- a/libjava/classpath/javax/print/attribute/standard/JobOriginatingUserName.java +++ b/libjava/classpath/javax/print/attribute/standard/JobOriginatingUserName.java @@ -1,5 +1,5 @@ /* JobOriginatingUserName.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -44,6 +44,12 @@ import javax.print.attribute.PrintJobAttribute; import javax.print.attribute.TextSyntax; /** + * The <code>JobOriginatingUserName</code> attribute specifies the name of + * the user which submitted the print job. + * <p> + * <b>IPP Compatibility:</b> JobOriginatingUserName is an IPP 1.1 attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) */ public final class JobOriginatingUserName extends TextSyntax @@ -55,8 +61,10 @@ public final class JobOriginatingUserName extends TextSyntax * Creates a <code>JobOriginatingUserName</code> object. * * @param userName the user name + * @param locale the locale to use, if <code>null</code> the default + * locale is used. * - * @exception NullPointerException if userName is null + * @exception NullPointerException if userName is <code>null</code>. */ public JobOriginatingUserName(String userName, Locale locale) { @@ -64,11 +72,12 @@ public final class JobOriginatingUserName extends TextSyntax } /** - * Tests of obj is equal to this object. + * Tests if the given object is equal to this object. * * @param obj the object to test * - * @return true if both objects are equal, false otherwise. + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. */ public boolean equals(Object obj) { @@ -81,7 +90,7 @@ public final class JobOriginatingUserName extends TextSyntax /** * Returns category of this class. * - * @return the class <code>JobOriginatingUserName</code> itself + * @return The class <code>JobOriginatingUserName</code> itself. */ public Class getCategory() { @@ -89,9 +98,9 @@ public final class JobOriginatingUserName extends TextSyntax } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "job-originating-user-name" + * @return The name "job-originating-user-name". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/JobPriority.java b/libjava/classpath/javax/print/attribute/standard/JobPriority.java index 6c88dfc..bcfb239 100644 --- a/libjava/classpath/javax/print/attribute/standard/JobPriority.java +++ b/libjava/classpath/javax/print/attribute/standard/JobPriority.java @@ -1,5 +1,5 @@ /* JobPriority.java -- - Copyright (C) 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -43,6 +43,17 @@ import javax.print.attribute.PrintRequestAttribute; /** + * The <code>JobPriority</code> printing attribute specifies + * the priority for scheduling a job on the print service. + * <p> + * A client may specify any value between 1 (lowest priority) and 100 + * (highest priority). A print service prints jobs with a priority + * value of n before those with a priority value of n-1. + * </p> + * <p> + * <b>IPP Compatibility:</b> JobPriority is an IPP 1.1 attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) */ public final class JobPriority extends IntegerSyntax @@ -55,7 +66,7 @@ public final class JobPriority extends IntegerSyntax * * @param value the priority * - * @exception IllegalArgumentException if value < 1 or value > 100 + * @exception IllegalArgumentException if value < 1 or value > 100 */ public JobPriority(int value) { @@ -66,11 +77,12 @@ public final class JobPriority extends IntegerSyntax } /** - * Tests of obj is equal to this object. + * Tests if the given object is equal to this object. * * @param obj the object to test * - * @return true if both objects are equal, false otherwise. + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. */ public boolean equals(Object obj) { @@ -83,7 +95,7 @@ public final class JobPriority extends IntegerSyntax /** * Returns category of this class. * - * @return the class <code>JobPriority</code> itself + * @return The class <code>JobPriority</code> itself. */ public Class getCategory() { @@ -91,9 +103,9 @@ public final class JobPriority extends IntegerSyntax } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "job-priority" + * @return The name "job-priority". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/JobPrioritySupported.java b/libjava/classpath/javax/print/attribute/standard/JobPrioritySupported.java index fdfe6c7c..0db7107 100644 --- a/libjava/classpath/javax/print/attribute/standard/JobPrioritySupported.java +++ b/libjava/classpath/javax/print/attribute/standard/JobPrioritySupported.java @@ -1,5 +1,5 @@ /* JobPrioritySupported.java -- - Copyright (C) 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -42,6 +42,20 @@ import javax.print.attribute.SupportedValuesAttribute; /** + * The <code>JobPrioritySupported</code> printing attribute provides + * the supported values for the <code>JobPriority</code> attribute. + * <p> + * A client may specify any JobPriority value between 1 and 100. If a + * print service supports fewer priority levels it indicates the maximum + * levels through this attribute. The print service then automatically + * maps the job priority value provided by the client in an even distribution + * over the whole range of 1 to 100. + * </p> + * <p> + * <b>IPP Compatibility:</b> JobPrioritySupported is an IPP 1.1 attribute. + * </p> + * @see javax.print.attribute.standard.JobPriority + * * @author Michael Koch (konqueror@gmx.de) */ public final class JobPrioritySupported extends IntegerSyntax @@ -54,7 +68,7 @@ public final class JobPrioritySupported extends IntegerSyntax * * @param value the priority * - * @exception IllegalArgumentException if value < 1 or value > 100 + * @exception IllegalArgumentException if value < 1 or value > 100 */ public JobPrioritySupported(int value) { @@ -65,11 +79,12 @@ public final class JobPrioritySupported extends IntegerSyntax } /** - * Tests of obj is equal to this object. + * Tests if the given object is equal to this object. * * @param obj the object to test * - * @return true if both objects are equal, false otherwise. + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. */ public boolean equals(Object obj) { @@ -82,7 +97,7 @@ public final class JobPrioritySupported extends IntegerSyntax /** * Returns category of this class. * - * @return the class <code>JobPrioritySupported</code> itself + * @return The class <code>JobPrioritySupported</code> itself. */ public Class getCategory() { @@ -90,9 +105,9 @@ public final class JobPrioritySupported extends IntegerSyntax } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "job-priority-supported" + * @return The name "job-priority-supported". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/JobSheets.java b/libjava/classpath/javax/print/attribute/standard/JobSheets.java index 183aed2..d61acfe 100644 --- a/libjava/classpath/javax/print/attribute/standard/JobSheets.java +++ b/libjava/classpath/javax/print/attribute/standard/JobSheets.java @@ -1,5 +1,5 @@ /* JobSheets.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -43,18 +43,40 @@ import javax.print.attribute.PrintRequestAttribute; /** + * The <code>JobSheets</code> printing attribute specifies if a + * job start/end sheets should be printed. + * <p> + * <b>IPP Compatibility:</b> JobSheets is an IPP 1.1 attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) + * @author Wolfgang Baer (WBaer@gmx.de) */ public class JobSheets extends EnumSyntax implements PrintJobAttribute, PrintRequestAttribute { private static final long serialVersionUID = -4735258056132519759L; + /** + * No job sheet is printed. + */ public static final JobSheets NONE = new JobSheets(0); + + /** + * The standard job sheet is printed. The sheet and if it + * is printed only as start sheet or also as end sheet is + * site specific. + */ public static final JobSheets STANDARD = new JobSheets(1); + private static final String[] stringTable = { "none", "standard" }; + + private static final JobSheets[] enumValueTable = { NONE, STANDARD }; + /** * Constructs a <code>JobSheets</code> object. + * + * @param value the enum value. */ protected JobSheets(int value) { @@ -64,7 +86,7 @@ public class JobSheets extends EnumSyntax /** * Returns category of this class. * - * @return the class <code>JobSheets</code> itself + * @return The class <code>JobSheets</code> itself. */ public Class getCategory() { @@ -74,10 +96,31 @@ public class JobSheets extends EnumSyntax /** * Returns the name of this attribute. * - * @return the name + * @return The name "job-sheets". */ public String getName() { return "job-sheets"; } + + /** + * Returns a table with the enumeration values represented as strings + * for this object. + * + * @return The enumeration values as strings. + */ + protected String[] getStringTable() + { + return stringTable; + } + + /** + * Returns a table with the enumeration values for this object. + * + * @return The enumeration values. + */ + protected EnumSyntax[] getEnumValueTable() + { + return enumValueTable; + } } diff --git a/libjava/classpath/javax/print/attribute/standard/JobState.java b/libjava/classpath/javax/print/attribute/standard/JobState.java index 1350e69..bd09e1f 100644 --- a/libjava/classpath/javax/print/attribute/standard/JobState.java +++ b/libjava/classpath/javax/print/attribute/standard/JobState.java @@ -1,5 +1,5 @@ /* JobState.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -42,24 +42,90 @@ import javax.print.attribute.PrintJobAttribute; /** + * The <code>JobState</code> printing attribute reports + * the current state of a job. + * <p> + * The {@link javax.print.attribute.standard.JobStateReasons} + * attribute provides further detailed information about + * the given job state. Detailed information about the job + * state and job state reasons can be found in the RFC 2911. + * </p> + * <p> + * <b>IPP Compatibility:</b> JobState is an IPP 1.1 attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) + * @author Wolfgang Baer (WBaer@gmx.de) */ public class JobState extends EnumSyntax implements PrintJobAttribute { private static final long serialVersionUID = 400465010094018920L; + /** + * The job state is currently unknown. + */ public static final JobState UNKNOWN = new JobState(0); - public static final JobState PENDING = new JobState(1); - public static final JobState PENDING_HELD = new JobState(2); - public static final JobState PROCESSING = new JobState(3); - public static final JobState PROCESSING_STOPPED = new JobState(4); - public static final JobState CANCELED = new JobState(5); - public static final JobState ABORTED = new JobState(6); - public static final JobState COMPLETED = new JobState(7); + + /** + * The job is pending processing. + */ + public static final JobState PENDING = new JobState(3); + + /** + * The job is currently not a candidate for printing because + * of reasons reported by the job-state-reasons attribute. If + * the reasons are no longer present it will return to the + * pending state. + */ + public static final JobState PENDING_HELD = new JobState(4); + + /** + * The job is currently processed. + */ + public static final JobState PROCESSING = new JobState(5); + + /** + * The job's processing has stopped. The job-state-reasons + * attribute may indicate the reason(s). The job will return + * to the processing state if the reasons are no longer present. + */ + public static final JobState PROCESSING_STOPPED = new JobState(6); + + /** + * The job has been canceled by the client. + */ + public static final JobState CANCELED = new JobState(7); + + /** + * The job has been aborted by the system. + */ + public static final JobState ABORTED = new JobState(8); + + /** + * The job has completed successfully. + */ + public static final JobState COMPLETED = new JobState(9); + + private static final String[] stringTable = { "unknown", null, null, + "pending", "pending-held", + "processing", + "processing-stopped", + "canceled", "aborted", + "completed"}; + + private static final JobState[] enumValueTable = { UNKNOWN, null, null, + PENDING, PENDING_HELD, + PROCESSING, + PROCESSING_STOPPED, + CANCELED, ABORTED, + COMPLETED }; + /** * Constructs a <code>JobState</code> object. + * + * @param value the enum value. */ protected JobState(int value) { @@ -69,7 +135,7 @@ public class JobState extends EnumSyntax /** * Returns category of this class. * - * @return the class <code>JobState</code> itself + * @return The class <code>JobState</code> itself. */ public Class getCategory() { @@ -79,10 +145,31 @@ public class JobState extends EnumSyntax /** * Returns the name of this attribute. * - * @return the name + * @return The name "job-state". */ public String getName() { return "job-state"; } + + /** + * Returns a table with the enumeration values represented as strings + * for this object. + * + * @return The enumeration values as strings. + */ + protected String[] getStringTable() + { + return stringTable; + } + + /** + * Returns a table with the enumeration values for this object. + * + * @return The enumeration values. + */ + protected EnumSyntax[] getEnumValueTable() + { + return enumValueTable; + } } diff --git a/libjava/classpath/javax/print/attribute/standard/JobStateReason.java b/libjava/classpath/javax/print/attribute/standard/JobStateReason.java index 4a9f1a9..bd831cd 100644 --- a/libjava/classpath/javax/print/attribute/standard/JobStateReason.java +++ b/libjava/classpath/javax/print/attribute/standard/JobStateReason.java @@ -1,5 +1,5 @@ /* JobStateReason.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -42,45 +42,215 @@ import javax.print.attribute.EnumSyntax; /** + * The <code>JobStateReason</code> attribute provides additional + * information about the current state of a job. Its always part + * of the {@link javax.print.attribute.standard.JobStateReasons} + * printing attribute. + * <p> + * <b>IPP Compatibility:</b> JobStateReason is not an IPP 1.1 + * attribute itself but used inside the <code>JobStateReasons</code> + * attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) + * @author Wolfgang Baer (WBaer@gmx.de) */ public class JobStateReason extends EnumSyntax implements Attribute { private static final long serialVersionUID = -8765894420449009168L; + /** + * The printer has accepted the job or is retrieving document + * data for processing. + */ public static final JobStateReason JOB_INCOMING = new JobStateReason(0); + + /** + * The printer is expecting additional document data before it + * can move this job into the processing state. + */ public static final JobStateReason JOB_DATA_INSUFFICIENT = new JobStateReason(1); + + /** + * The printer is unable to access one or more documents provided + * by reference in the print job. + */ public static final JobStateReason DOCUMENT_ACCESS_ERROR = new JobStateReason(2); + + /** + * The printer has not received the whole job submission. This + * indicates no reason for the interruption. + */ public static final JobStateReason SUBMISSION_INTERRUPTED = new JobStateReason(3); + + /** + * The printer transfers the job to the actual output device. + */ public static final JobStateReason JOB_OUTGOING = new JobStateReason(4); + + /** + * The job was submitted with a <code>JobHoldUntil</code> attribute which + * specifies a time period still in the future and causes the job to + * be on hold. + */ public static final JobStateReason JOB_HOLD_UNTIL_SPECIFIED = new JobStateReason(5); + + /** + * One or more resources needed by the job are not ready. E.g. needed + * media type. + */ public static final JobStateReason RESOURCES_ARE_NOT_READY = new JobStateReason(6); + + /** + * The printer stopped partly. + */ public static final JobStateReason PRINTER_STOPPED_PARTLY = new JobStateReason(7); + + /** + * The printer stopped complete. + */ public static final JobStateReason PRINTER_STOPPED = new JobStateReason(8); + + /** + * The printer is currently interpreting the jobs document data. + * Detailed state of the job's processing state. + */ public static final JobStateReason JOB_INTERPRETING = new JobStateReason(9); + + /** + * The printer has queued the document data. + * Detailed state of the job's processing state. + */ public static final JobStateReason JOB_QUEUED = new JobStateReason(10); + + /** + * The printer is transforming the document data to another representation. + * Detailed state of the job's processing state. + */ public static final JobStateReason JOB_TRANSFORMING = new JobStateReason(11); + + /** + * The job is queued for marking. + */ public static final JobStateReason JOB_QUEUED_FOR_MARKER = new JobStateReason(12); + + /** + * The job is currently printing. + */ public static final JobStateReason JOB_PRINTING = new JobStateReason(13); + + /** + * The job was canceled by the user (the owner of the job). + */ public static final JobStateReason JOB_CANCELED_BY_USER = new JobStateReason(14); + + /** + * The job was canceled by the operator. + */ public static final JobStateReason JOB_CANCELED_BY_OPERATOR = new JobStateReason(15); + + /** + * The job was canceled by an unidentified local user at the device. + */ public static final JobStateReason JOB_CANCELED_AT_DEVICE = new JobStateReason(16); + + /** + * The job has been aborted by the system. + */ public static final JobStateReason ABORTED_BY_SYSTEM = new JobStateReason(17); + + /** + * The printer aborted the job because of an unsupported compression while + * trying to decompress the document data. + */ public static final JobStateReason UNSUPPORTED_COMPRESSION = new JobStateReason(18); + + /** + * The printer aborted the job because of a compression error while + * trying to decompress the document data. If this state is given the test + * for supported compression has already been passed. + */ public static final JobStateReason COMPRESSION_ERROR = new JobStateReason(19); + + /** + * The printer aborted the job because of the document format is not supported. + * This may happen if a job is specified as application/octet-stream format. + */ public static final JobStateReason UNSUPPORTED_DOCUMENT_FORMAT = new JobStateReason(20); + + /** + * The printer aborted the job because of an error in the document data. + */ public static final JobStateReason DOCUMENT_FORMAT_ERROR = new JobStateReason(21); + + /** + * The client has either canceled the job or the printer aborted the job. + * However the printer still performs some action on the job e.g. to cleanup. + */ public static final JobStateReason PROCESSING_TO_STOP_POINT = new JobStateReason(22); + + /** + * The printer is offline and therefore is not accepting jobs. + */ public static final JobStateReason SERVICE_OFF_LINE = new JobStateReason(23); + + /** + * The printer completed the job successfully. + */ public static final JobStateReason JOB_COMPLETED_SUCCESSFULLY = new JobStateReason(24); + + /** + * The printer completed the job with warnings. + */ public static final JobStateReason JOB_COMPLETED_WITH_WARNINGS = new JobStateReason(25); + + /** + * The printer completed the job with errors. + */ public static final JobStateReason JOB_COMPLETED_WITH_ERRORS = new JobStateReason(26); + + /** + * The job is retained and is able to be restared. + */ public static final JobStateReason JOB_RESTARTABLE = new JobStateReason(27); + + /** + * The printer has forwarded the job to the actual output device. This device + * is not capable of reporting the state back so that the job state is set + * to completed by the printer. + */ public static final JobStateReason QUEUED_IN_DEVICE = new JobStateReason(28); + private static final String[] stringTable = + { "job-incoming", "job-data-insufficient", "document-access-error", + "submission-interrupted", "job-outgoing", "job-hold-until-specified", + "resources-are-not-ready", "printer-stopped-partly", "printer-stopped", + "job-interpreting", "job-queued", "job-transforming", + "job-queued-for-marker", "job-printing", "job-canceled-by-user", + "job-canceled-by-operator", "job-canceled-at-device", + "aborted-by-system", "unsupported-compression", "compression-error", + "unsupported-document-format", "document-format-error", + "processing-to-stop-point", "service-off-line", + "job-completed-successfully", "job-completed-with-warnings", + "job-completed-with-errors", "job-restartable", "queued-in-device" }; + + private static final JobStateReason[] enumValueTable = + { JOB_INCOMING, JOB_DATA_INSUFFICIENT, DOCUMENT_ACCESS_ERROR, + SUBMISSION_INTERRUPTED, JOB_OUTGOING, JOB_HOLD_UNTIL_SPECIFIED, + RESOURCES_ARE_NOT_READY, PRINTER_STOPPED_PARTLY, PRINTER_STOPPED, + JOB_INTERPRETING, JOB_QUEUED, JOB_TRANSFORMING, JOB_QUEUED_FOR_MARKER, + JOB_PRINTING, JOB_CANCELED_BY_USER, JOB_CANCELED_BY_OPERATOR, + JOB_CANCELED_AT_DEVICE, ABORTED_BY_SYSTEM, UNSUPPORTED_COMPRESSION, + COMPRESSION_ERROR, UNSUPPORTED_DOCUMENT_FORMAT, DOCUMENT_FORMAT_ERROR, + PROCESSING_TO_STOP_POINT, SERVICE_OFF_LINE, JOB_COMPLETED_SUCCESSFULLY, + JOB_COMPLETED_WITH_WARNINGS, JOB_COMPLETED_WITH_ERRORS, JOB_RESTARTABLE, + QUEUED_IN_DEVICE }; + /** * Constructs a <code>JobStateReason</code> object. + * + * @param value the enum value. */ protected JobStateReason(int value) { @@ -90,7 +260,7 @@ public class JobStateReason extends EnumSyntax /** * Returns category of this class. * - * @return the class <code>JobStateReason</code> itself + * @return The class <code>JobStateReason</code> itself. */ public Class getCategory() { @@ -100,10 +270,31 @@ public class JobStateReason extends EnumSyntax /** * Returns the name of this attribute. * - * @return the name + * @return The name "job-state-reason". */ public String getName() { return "job-state-reason"; } + + /** + * Returns a table with the enumeration values represented as strings + * for this object. + * + * @return The enumeration values as strings. + */ + protected String[] getStringTable() + { + return stringTable; + } + + /** + * Returns a table with the enumeration values for this object. + * + * @return The enumeration values. + */ + protected EnumSyntax[] getEnumValueTable() + { + return enumValueTable; + } } diff --git a/libjava/classpath/javax/print/attribute/standard/JobStateReasons.java b/libjava/classpath/javax/print/attribute/standard/JobStateReasons.java index 3918737..9dbca0c 100644 --- a/libjava/classpath/javax/print/attribute/standard/JobStateReasons.java +++ b/libjava/classpath/javax/print/attribute/standard/JobStateReasons.java @@ -1,5 +1,5 @@ /* JobStateReasons.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,12 +38,23 @@ exception statement from your version. */ package javax.print.attribute.standard; +import java.util.Collection; import java.util.HashSet; +import java.util.Iterator; import javax.print.attribute.PrintJobAttribute; /** + * The <code>JobStateReasons</code> attribute provides the set of + * additional informations available about the current state of a print job. + * <p> + * <b>IPP Compatibility:</b> JobStateReasons is an IPP 1.1 attribute. + * </p> + * @see javax.print.attribute.standard.JobState + * @see javax.print.attribute.standard.JobStateReason + * * @author Michael Koch (konqueror@gmx.de) + * @author Wolfgang Baer (WBaer@gmx.de) */ public final class JobStateReasons extends HashSet implements PrintJobAttribute @@ -51,9 +62,82 @@ public final class JobStateReasons extends HashSet private static final long serialVersionUID = 8849088261264331812L; /** + * Constructs an empty <code>JobStateReasons</code> attribute. + */ + public JobStateReasons() + { + super(); + } + + /** + * Constructs an empty <code>JobStateReasons</code> attribute + * with the given initial capacity and load factor. + * + * @param initialCapacity the intial capacity. + * @param loadFactor the load factor of the underlying HashSet. + * + * @throws IllegalArgumentException if initialCapacity < 0 + * @throws IllegalArgumentException if initialCapacity or loadFactor < 0 + */ + public JobStateReasons(int initialCapacity, float loadFactor) + { + super(initialCapacity, loadFactor); + } + + /** + * Constructs an empty <code>JobStateReasons</code> attribute + * with the given initial capacity and the default load factor. + * + * @param initialCapacity the intial capacity. + * + * @throws IllegalArgumentException if initialCapacity < 0 + */ + public JobStateReasons(int initialCapacity) + { + super(initialCapacity); + } + + /** + * Constructs a <code>JobStateReasons</code> attribute + * with the content of the given collection. + * + * @param collection the collection for the initial values. + * + * @throws NullPointerException if collection or any value is + * <code>null</code>. + * @throws ClassCastException if values of collection are not of type + * <code>JobStateReason</code>. + */ + public JobStateReasons(Collection collection) + { + super(collection.size(), 0.75f); + Iterator it = collection.iterator(); + while (it.hasNext()) + add(it.next()); + } + + /** + * Adds the given job state reason object to the set. + * + * @param o the reason of type <code>JobStateReason</code>. + * @return <code>true</code> if set changed, <code>false</code> otherwise. + * + * @throws NullPointerException if given object is <code>null</code>. + * @throws ClassCastException if given object is not an instance of + * <code>JobStateReason</code>. + */ + public boolean add(Object o) + { + if (o == null) + throw new NullPointerException("reason is null"); + + return add((JobStateReason) o); + } + + /** * Returns category of this class. * - * @return the class <code>ColorSupported</code> itself + * @return The class <code>JobStateReasons</code> itself. */ public Class getCategory() { @@ -63,7 +147,7 @@ public final class JobStateReasons extends HashSet /** * Returns the name of this attribute. * - * @return the name + * @return The name "job-state-reasons". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/Media.java b/libjava/classpath/javax/print/attribute/standard/Media.java index ebb15d0..202a3f3 100644 --- a/libjava/classpath/javax/print/attribute/standard/Media.java +++ b/libjava/classpath/javax/print/attribute/standard/Media.java @@ -1,5 +1,5 @@ /* Media.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -44,7 +44,27 @@ import javax.print.attribute.PrintRequestAttribute; /** + * The <code>Media</code> printing attribute specifies which + * type of media should be used for printing. + * <p> + * The media to be used can be specified in three ways represented + * by the media subclasses {@link javax.print.attribute.standard.MediaTray}, + * {@link javax.print.attribute.standard.MediaName} and + * {@link javax.print.attribute.standard.MediaSizeName}: + * <ul> + * <li>Selection by paper source - selection of printer tray to be used.</li> + * <li>Selection by name - e.g. A4 paper.</li> + * <li>Selection by standard sizes - e.g. ISO A5, JIS B4.</li> + * </ul> + * Each of the sublcasses represents the IPP attribute <code>media</code> + * and provides predefined values to be used. + * </p> + * <p> + * <b>IPP Compatibility:</b> Media is an IPP 1.1 attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) + * @author Wolfgang Baer (WBaer@gmx.de) */ public abstract class Media extends EnumSyntax implements DocAttribute, PrintRequestAttribute, PrintJobAttribute @@ -53,16 +73,37 @@ public abstract class Media extends EnumSyntax /** * Constructs a <code>Media</code> object. + * + * @param value the enum value. */ protected Media(int value) { super(value); } + + /** + * Tests if the given object is equal to this object. + * The objects are considered equal if both are of the same + * Media subclass, not null and the values are equal. + * + * @param obj the object to test + * + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. + */ + public boolean equals(Object obj) + { + if (obj == null) + return false; + + return (obj.getClass() == this.getClass() + && ((Media) obj).getValue() == this.getValue()); + } /** * Returns category of this class. * - * @return the class <code>Media</code> itself + * @return The class <code>Media</code> itself. */ public Class getCategory() { @@ -72,7 +113,7 @@ public abstract class Media extends EnumSyntax /** * Returns the name of this attribute. * - * @return the name + * @return The name "media". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/MediaName.java b/libjava/classpath/javax/print/attribute/standard/MediaName.java new file mode 100644 index 0000000..2fa7cea --- /dev/null +++ b/libjava/classpath/javax/print/attribute/standard/MediaName.java @@ -0,0 +1,121 @@ +/* MediaName.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package javax.print.attribute.standard; + +import javax.print.attribute.EnumSyntax; + +/** + * <code>MediaName</code> is a subclass of the <code>Media</code> printing + * attribute and provides selection of media to be used by the means of + * defined names. The class pre-defines commonly available media names. + * This media type enumeration may be used in alternative to + * MediaSizeName/MediaTray. + * <p> + * <b>IPP Compatibility:</b> MediaName is not an IPP 1.1 attribute on its own. + * It provides parts of the <code>media</code> attribute type values. + * </p> + * + * @author Sven de Marothy + * @author Wolfgang Baer (WBaer@gmx.de) + */ +public class MediaName extends Media +{ + private static final long serialVersionUID = 4653117714524155448L; + + /** + * The North American letter white medium. + */ + public static final MediaName NA_LETTER_WHITE = new MediaName(0); + + /** + * The North American letter transparent medium. + */ + public static final MediaName NA_LETTER_TRANSPARENT = new MediaName(1); + + /** + * The ISO A4 white medium. + */ + public static final MediaName ISO_A4_WHITE = new MediaName(2); + + /** + * The ISO A4 transparent medium. + */ + public static final MediaName ISO_A4_TRANSPARENT = new MediaName(3); + + private static final String[] stringTable = { "na-letter-white", + "na-letter-transparent", + "iso-a4-white", + "iso-a4-transparent" }; + + private static final MediaName[] enumValueTable = { NA_LETTER_WHITE, + NA_LETTER_TRANSPARENT, + ISO_A4_WHITE, + ISO_A4_TRANSPARENT }; + + /** + * Creates a <code>MediaName</code> object. + * + * @param i the enum value. + */ + protected MediaName(int i) + { + super( i ); + } + + /** + * Returns a table with the enumeration values represented as strings + * for this object. + * + * @return The enumeration values as strings. + */ + protected String[] getStringTable() + { + return stringTable; + } + + /** + * Returns a table with the enumeration values for this object. + * + * @return The enumeration values. + */ + protected EnumSyntax[] getEnumValueTable() + { + return enumValueTable; + } +} + diff --git a/libjava/classpath/javax/print/attribute/standard/MediaPrintableArea.java b/libjava/classpath/javax/print/attribute/standard/MediaPrintableArea.java index c7cf8d3..9a1342c 100644 --- a/libjava/classpath/javax/print/attribute/standard/MediaPrintableArea.java +++ b/libjava/classpath/javax/print/attribute/standard/MediaPrintableArea.java @@ -43,23 +43,71 @@ import javax.print.attribute.PrintJobAttribute; import javax.print.attribute.PrintRequestAttribute; /** + * The <code>MediaPrintableArea</code> attribute specifies the area + * of a media sheet which is available for printing. + * <p> + * Due to hardware limitation its not possible with most printers to use the + * whole area of a media sheet for printing. This attribute defines the area + * for printing through the values of the upper left corner position (x,y) + * on the sheet and the available width and height of the area. The units of + * the values are determined by two defined constants: + * <ul> + * <li>INCH - defines an inch</li> + * <li>MM - defines a millimeter</li> + * </ul> + * </p> + * <p> + * <b>Internal storage:</b><br> + * The values of x, y, width and height are stored internally in micrometers. + * The values of the provided constants for inch (value 25400) and millimeters + * (value 1000) are used as conversion factors to the internal storage units. + * To get the internal micrometers values a multiplication of a given + * size value with its units constant value is done. Retrieving the size value + * for specific units is done by dividing the internal stored value by the + * units constant value. + * </p> + * <p> + * <b>IPP Compatibility:</b> MediaPrintableArea is not an IPP 1.1 attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) + * @author Wolfgang Baer (WBaer@gmx.de) */ public final class MediaPrintableArea implements DocAttribute, PrintJobAttribute, PrintRequestAttribute { private static final long serialVersionUID = -1597171464050795793L; + /** + * Constant for the units of inches. + * The actual value is the conversion factor to micrometers. + */ public static final int INCH = 25400; + + /** + * Constant for the units of millimeters. + * The actual value is the conversion factor to micrometers. + */ public static final int MM = 1000; - private float x; - private float y; - private float width; - private float height; + /** x in micrometers. */ + private int x; + /** y in micrometers. */ + private int y; + /** width in micrometers. */ + private int width; + /** height in micrometers. */ + private int height; /** - * Creates a new <code>MediaPrintableArea</code> object. + * Creates a new <code>MediaPrintableArea</code> object with the given + * float values for the given units. + * + * @param x start of the printable area on the sheet in x direction. + * @param y start of the printable area on the sheet in y direction. + * @param w the width of the printable area. + * @param h the height of the printable area. + * @param units the units of the given values. * * @throws IllegalArgumentException if x i< 0 or y i< 0 or w i<= 0 * or h i<= 0 or units i< 1 @@ -69,14 +117,21 @@ public final class MediaPrintableArea if (x < 0.0f || y < 0.0f || w <= 0.0f || h <= 0.0f) throw new IllegalArgumentException(); - this.x = x; - this.y = y; - this.width = w; - this.height = h; + this.x = (int) (x * units + 0.5f); + this.y = (int) (y * units + 0.5f); + this.width = (int) (w * units + 0.5f); + this.height = (int) (h * units + 0.5f); } /** - * Creates a new <code>MediaPrintableArea</code> object. + * Creates a new <code>MediaPrintableArea</code> object with the given + * int values for the given units. + * + * @param x start of the printable area on the sheet in x direction. + * @param y start of the printable area on the sheet in y direction. + * @param w the width of the printable area. + * @param h the height of the printable area. + * @param units the units of the given values. * * @throws IllegalArgumentException if x i< 0 or y i< 0 or w i<= 0 * or h i<= 0 or units i< 1 @@ -86,16 +141,16 @@ public final class MediaPrintableArea if (x < 0 || y < 0 || w <= 0 || h <= 0) throw new IllegalArgumentException(); - this.x = x; - this.y = y; - this.width = w; - this.height = h; + this.x = x * units; + this.y = y * units; + this.width = w * units; + this.height = h * units; } /** * Returns category of this class. * - * @return the class <code>MediaPrintableArea</code> itself + * @return The class <code>MediaPrintableArea</code> itself. */ public Class getCategory() { @@ -103,44 +158,154 @@ public final class MediaPrintableArea } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "media-printable-area" + * @return The name "media-printable-area". */ public String getName() { return "media-printable-area"; } + /** + * Returns the height of the printable area for the given units. + * + * @param units the units conversion factor. + * @return The height. + * + * @throws IllegalArgumentException if <code>units</code> is < 1 + */ public float getHeight(int units) { if (units < 1) - throw new IllegalArgumentException(); + throw new IllegalArgumentException("units may not be less than 1"); - return height * units; + return height / ((float)units); } + /** + * Returns the width of the printable area for the given units. + * + * @param units the units conversion factor. + * @return The width. + * + * @throws IllegalArgumentException if <code>units</code> is < 1 + */ public float getWidth(int units) { if (units < 1) - throw new IllegalArgumentException(); + throw new IllegalArgumentException("units may not be less than 1"); - return width * units; + return width / ((float)units); } + /** + * Returns the position in x direction of the printable area + * for the given units. + * + * @param units the units conversion factor. + * @return The position in x direction. + * + * @throws IllegalArgumentException if <code>units</code> is < 1 + */ public float getX(int units) { if (units < 1) - throw new IllegalArgumentException(); + throw new IllegalArgumentException("units may not be less than 1"); - return x * units; + return x / ((float)units); } + /** + * Returns the position in y direction of the printable area + * for the given units. + * + * @param units the units conversion factor. + * @return The position in y direction. + * + * @throws IllegalArgumentException if <code>units</code> is < 1 + */ public float getY(int units) { if (units < 1) - throw new IllegalArgumentException(); + throw new IllegalArgumentException("units may not be less than 1"); - return y * units; + return y / ((float)units); } + + /** + * Tests if the given object is equal to this object. + * + * @param obj the object to test + * + * @return <code>true</code> if both objects are equal, <code>false</code> otherwise. + */ + public boolean equals(Object obj) + { + if (! (obj instanceof MediaPrintableArea)) + return false; + + MediaPrintableArea tmp = (MediaPrintableArea) obj; + + return (x == tmp.getX(1) && y == tmp.getY(1) + && width == tmp.getWidth(1) && height == tmp.getHeight(1)); + } + + /** + * Returns the string representation for this object in units of millimeters.. + * <p> + * The returned string is in the form "(x,y)->(width,height)mm". + * </p> + * @return The string representation in millimeters. + */ + public String toString() + { + return toString(MM, "mm"); + } + + /** + * Returns the hashcode for this object. + * + * @return The hashcode. + */ + public int hashCode() + { + return x ^ y + width ^ height; + } + + /** + * Returns the string representation for this object in units of millimeters.. + * <p> + * The returned string is in the form "(x,y)->(width,height)unitsName". + * </p> + * @param units the units to use for conversion. + * @param unitsName the name of the used units, appended to the resulting + * string if not <code>null</code>. + * @return The string representation in millimeters. + * + * @throws IllegalArgumentException if <code>units</code> is < 1 + */ + public String toString(int units, String unitsName) + { + if (units < 1) + throw new IllegalArgumentException("units may not be less than 1"); + + String tmp = "(" + getX(units) + "," + getY(units) + ")->(" + + getWidth(units) + "," + getHeight(units) + ")"; + + return unitsName == null ? tmp : tmp + unitsName; + } + + /** + * Returns the printable area as an float[] with 4 values + * (order x, y, width, height) in the given units. + * + * @param units the units to use. + * @return The printable area as float array. + */ + public float[] getPrintableArea(int units) + { + return new float[] { getX(units), getY(units), + getWidth(units), getHeight(units) }; + } } diff --git a/libjava/classpath/javax/print/attribute/standard/MediaSize.java b/libjava/classpath/javax/print/attribute/standard/MediaSize.java index 6abf979..00bcb34 100644 --- a/libjava/classpath/javax/print/attribute/standard/MediaSize.java +++ b/libjava/classpath/javax/print/attribute/standard/MediaSize.java @@ -43,47 +43,171 @@ import java.util.ArrayList; import javax.print.attribute.Attribute; import javax.print.attribute.Size2DSyntax; +/** + * The <code>MediaSize</code> printing attribute class specifies the size + * of a printing media. The size is defined in portrait orientation with + * x at the bottom edge and y at the left edge. + * <p> + * There are several media sizes predefined through the nested classes. Further + * sizes may be provided by the application. <code>MediaSize</code> is not used + * as a printing attribute currently. It may be used to get the actual sizes + * for a named media or to find a suitable <code>MediaSizeName</code> instance + * by querying with the needed sizes. + * </p> + * <p> + * <b>IPP Compatibility:</b> MediaSize is not an IPP 1.1 attribute. + * </p> + * @see javax.print.attribute.standard.MediaSizeName + * + * @author Michael Koch (konqueror@gmx.de) + * @author Wolfgang Baer (WBaer@gmx.de) + */ public class MediaSize extends Size2DSyntax implements Attribute { private static final long serialVersionUID = -1967958664615414771L; - private static ArrayList mediaCache = new ArrayList(); + private static ArrayList mediaCache; + + static + { + mediaCache = new ArrayList(); + + MediaSize tmp = MediaSize.ISO.A0; + tmp = MediaSize.JIS.B0; + tmp = MediaSize.Engineering.A; + tmp = MediaSize.NA.LEGAL; + tmp = MediaSize.Other.EXECUTIVE; + } private MediaSizeName media; + /** + * Creates a <code>MediaSize</code> object. + * + * @param x the size in x direction + * @param y the size in y direction + * @param units the units to use for the sizes + * + * @exception IllegalArgumentException if x or y < 0 or units < 1 + */ public MediaSize(float x, float y, int units) { super(x, y, units); + mediaCache.add(this); } + /** + * Creates a <code>MediaSize</code> object associated with the given + * media name. + * + * @param x the size in x direction + * @param y the size in y direction + * @param units the units to use for the sizes + * @param media the media name to associate + * + * @exception IllegalArgumentException if x or y < 0 or units < 1 + */ public MediaSize(float x, float y, int units, MediaSizeName media) { super(x, y, units); this.media = media; + mediaCache.add(this); } + /** + * Creates a <code>MediaSize</code> object. + * + * @param x the size in x direction + * @param y the size in y direction + * @param units the units to use for the sizes + * + * @exception IllegalArgumentException if x or y < 0 or units < 1 + */ public MediaSize(int x, int y, int units) { super(x, y, units); + mediaCache.add(this); } + /** + * Creates a <code>MediaSize</code> object associated with the given + * media name. + * + * @param x the size in x direction + * @param y the size in y direction + * @param units the units to use for the sizes + * @param media the media name to associate + * + * @exception IllegalArgumentException if x or y < 0 or units < 1 + */ public MediaSize(int x, int y, int units, MediaSizeName media) { super(x, y, units); this.media = media; + mediaCache.add(this); } /** * Returns category of this class. * - * @return the class <code>MediaSize</code> itself + * @return The class <code>MediaSize</code> itself. */ public Class getCategory() { return MediaSize.class; } + + /** + * Searches for a MediaSize object with the given dimensions. + * If none is found with exact dimensions, the closest match is used. + * Afterwards the MediaSizeName of the found MediaSize object is + * returned - which might be null if none is specified. + * + * @param x the dimension for x + * @param y the dimension for y + * @param units the units to be used for comparison + * @return the corresponding MediaSizeName object, or null + */ + public static MediaSizeName findMedia(float x, float y, int units) + { + if (x <= 0.0f || y <= 0.0f) + throw new IllegalArgumentException( + "x and/or y may not be less or equal 0"); + + if (units < 1) + throw new IllegalArgumentException("units may not be less then 1"); + + MediaSize bestMatch = null; + int bestDistance = Integer.MAX_VALUE; + + int xMicro = (int) x * units; + int yMicro = (int) y * units; + + for (int i = 0; i < mediaCache.size(); i++) + { + MediaSize size = (MediaSize) mediaCache.get(i); + int dist = (Math.abs(size.getXMicrometers() - xMicro) + + Math.abs(size.getYMicrometers() - yMicro)); + if (dist < bestDistance) + { + bestMatch = size; + bestDistance = dist; + } + } + + return bestMatch.getMediaSizeName(); + } + + /** + * Returns the associated <code>MediaSize</code> instance for the + * given named media <code>MediaSizeName</code> instance. + * + * @param media the named media to search for. + * @return The corresponding <code>MediaSize</code> instance or + * <code>null</code> if none found. + */ public static MediaSize getMediaSizeForName(MediaSizeName media) { for (int i = 0; i < mediaCache.size(); i++) @@ -97,18 +221,605 @@ public class MediaSize extends Size2DSyntax return null; } + /** + * Tests if the given object is equal to this object. + * + * @param obj the object to test + * + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. + */ + public boolean equals(Object obj) + { + if (!(obj instanceof MediaSize)) + return false; + + MediaSize tmp = (MediaSize) obj; + return (tmp.getXMicrometers() == this.getXMicrometers() + && tmp.getYMicrometers() == this.getYMicrometers()); + } + + /** + * Returns the media name of this size. + * + * @return The media name. + */ public MediaSizeName getMediaSizeName() { return media; } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "media-size" + * @return The name "media-size". */ public String getName() { return "media-size"; } + + /** + * Container class for predefined ISO media sizes. + * + * @author Sven de Marothy (sven@physto.se) + */ + public static final class ISO + { + + /** + * ISO A0 paper, 841 mm x 1189 mm. + */ + public static final MediaSize A0 = new MediaSize(841, 1189, + MediaSize.MM, + MediaSizeName.ISO_A0); + + /** + * ISO A1 paper, 594 mm x 841 mm + */ + public static final MediaSize A1 = new MediaSize(594, 841, MediaSize.MM, + MediaSizeName.ISO_A1); + + /** + * ISO A2 paper, 420 mm x 594 mm + */ + public static final MediaSize A2 = new MediaSize(420, 594, MediaSize.MM, MediaSizeName.ISO_A2); + + /** + * ISO A3 paper, 297 mm x 420 mm + */ + public static final MediaSize A3 = new MediaSize(297, 420, MediaSize.MM, MediaSizeName.ISO_A3); + + /** + * ISO A4 paper, 210 mm x 297 mm + */ + public static final MediaSize A4 = new MediaSize(210, 297, MediaSize.MM, MediaSizeName.ISO_A4); + + /** + * ISO A5 paper, 148 mm x 210 mm + */ + public static final MediaSize A5 = new MediaSize(148, 210, MediaSize.MM, MediaSizeName.ISO_A5); + + /** + * ISO A6 paper, 105 mm x 148 mm + */ + public static final MediaSize A6 = new MediaSize(105, 148, MediaSize.MM, MediaSizeName.ISO_A6); + + /** + * ISO A7 paper, 74 mm x 105 mm + */ + public static final MediaSize A7 = new MediaSize(74, 105, MediaSize.MM, MediaSizeName.ISO_A7); + + /** + * ISO A8 paper, 52 mm x 74 mm + */ + public static final MediaSize A8 = new MediaSize(52, 74, MediaSize.MM, MediaSizeName.ISO_A8); + + /** + * ISO A9 paper, 37 mm x 52 mm + */ + public static final MediaSize A9 = new MediaSize(37, 52, MediaSize.MM, MediaSizeName.ISO_A9); + + /** + * ISO A10 paper, 26 mm x 37 mm + */ + public static final MediaSize A10 = new MediaSize(26, 37, MediaSize.MM, MediaSizeName.ISO_A10); + + + /** + * ISO B0 paper, 1000 mm x 1414 mm + */ + public static final MediaSize B0 = new MediaSize(1000, 1414, MediaSize.MM, MediaSizeName.ISO_B0); + + /** + * ISO B1 paper, 707 mm x 1000 mm + */ + public static final MediaSize B1 = new MediaSize(707, 1000, MediaSize.MM, MediaSizeName.ISO_B1); + + /** + * ISO B2 paper, 500 mm x 707 mm + */ + public static final MediaSize B2 = new MediaSize(500, 707, MediaSize.MM, MediaSizeName.ISO_B2); + + /** + * ISO B3 paper, 353 mm x 500 mm + */ + public static final MediaSize B3 = new MediaSize(353, 500, MediaSize.MM, MediaSizeName.ISO_B3); + + /** + * ISO B4 paper, 250 mm x 353 mm + */ + public static final MediaSize B4 = new MediaSize(250, 353, MediaSize.MM, MediaSizeName.ISO_B4); + + /** + * ISO B5 paper, 176 mm x 250 mm + */ + public static final MediaSize B5 = new MediaSize(176, 250, MediaSize.MM, MediaSizeName.ISO_B5); + + /** + * ISO B6 paper, 125 mm x 176 mm + */ + public static final MediaSize B6 = new MediaSize(125, 176, MediaSize.MM, MediaSizeName.ISO_B6); + + /** + * ISO B7 paper, 88 mm x 125 mm + */ + public static final MediaSize B7 = new MediaSize(88, 125, MediaSize.MM, MediaSizeName.ISO_B7); + + /** + * ISO B8 paper, 62 mm x 88 mm + */ + public static final MediaSize B8 = new MediaSize(62, 88, MediaSize.MM, MediaSizeName.ISO_B8); + + /** + * ISO B9 paper, 44 mm x 62 mm + */ + public static final MediaSize B9 = new MediaSize(44, 62, MediaSize.MM, MediaSizeName.ISO_B9); + + /** + * ISO B10 paper, 31 mm x 44 mm + */ + public static final MediaSize B10 = new MediaSize(31, 44, MediaSize.MM, MediaSizeName.ISO_B10); + + /** + * ISO C3 envelope, 324 mm x 458 mm + */ + public static final MediaSize C3 = new MediaSize(324, 458, MediaSize.MM, MediaSizeName.ISO_C3); + + /** + * ISO C4 envelope, 229 mm x 324 mm + */ + public static final MediaSize C4 = new MediaSize(229, 324, MediaSize.MM, MediaSizeName.ISO_C4); + + /** + * ISO C5 envelope, 162 mm x 229 mm + */ + public static final MediaSize C5 = new MediaSize(162, 229, MediaSize.MM, MediaSizeName.ISO_C5); + + /** + * ISO C6 envelope, 114 mm x 162 mm + */ + public static final MediaSize C6 = new MediaSize(114, 162, MediaSize.MM, MediaSizeName.ISO_C6); + + /** + * ISO ISO Designated Long paper, 324 mm x 458 mm + */ + public static final MediaSize DESIGNATED_LONG = + new MediaSize(324, 458, MediaSize.MM, MediaSizeName.ISO_DESIGNATED_LONG); + } + + /** + * Container class for predefined North American media sizes. + * + * @author Sven de Marothy (sven@physto.se) + */ + public static final class NA + { + /** + * US Legal paper size, 8.5 inch x 14 inch + */ + public static final MediaSize LEGAL = new MediaSize(8.5f, 14f, MediaSize.INCH, + MediaSizeName.NA_LEGAL); + + /** + * US Letter paper size, 8.5 inch x 11 inch + */ + public static final MediaSize LETTER = new MediaSize(8.5f, 11f, MediaSize.INCH, + MediaSizeName.NA_LETTER); + + /** + * 5 inch x 7 inch paper size. + */ + public static final MediaSize NA_5X7 = new MediaSize(5, 7, MediaSize.INCH, + MediaSizeName.NA_5X7); + + /** + * 8 inch x 10 inch paper size. + */ + public static final MediaSize NA_8X10 = new MediaSize(8, 10, MediaSize.INCH, + MediaSizeName.NA_8X10); + + /** + * 6 inch x 9 inch envelope size. + */ + public static final MediaSize NA_6X9_ENVELOPE = new MediaSize(6f, 9f, + MediaSize.INCH, + MediaSizeName.NA_6X9_ENVELOPE); + + /** + * 7 inch x 9 inch envelope size. + */ + public static final MediaSize NA_7X9_ENVELOPE = new MediaSize(7f, 9f, + MediaSize.INCH, + MediaSizeName.NA_7X9_ENVELOPE); + + /** + * 9 inch x 11 inch envelope size. + */ + public static final MediaSize NA_9x11_ENVELOPE = new MediaSize(9f, 11f, + MediaSize.INCH, + MediaSizeName.NA_9X11_ENVELOPE); + + /** + * 9 inch x 12 inch envelope size. + */ + public static final MediaSize NA_9x12_ENVELOPE = new MediaSize(9f, 12f, + MediaSize.INCH, + MediaSizeName.NA_9X12_ENVELOPE); + + + /** + * 10 inch x 13 inch envelope size. + */ + public static final MediaSize NA_10x13_ENVELOPE = new MediaSize(10f, 13f, + MediaSize.INCH, + MediaSizeName.NA_10X13_ENVELOPE); + + /** + * 10 inch x 14 inch envelope size. + */ + public static final MediaSize NA_10x14_ENVELOPE = new MediaSize(10f, 14f, + MediaSize.INCH, + MediaSizeName.NA_10X14_ENVELOPE); + + /** + * 10 inch x 15 inch envelope size. + */ + public static final MediaSize NA_10X15_ENVELOPE = new MediaSize(10f, 15f, + MediaSize.INCH, + MediaSizeName.NA_10X15_ENVELOPE); + + /** + * Number 9 envelope size. 4.5 inch x 10.375 inch + */ + public static final MediaSize NA_NUMBER_9_ENVELOPE = new MediaSize(3.875f, 8.875f, + MediaSize.INCH, + MediaSizeName.NA_NUMBER_9_ENVELOPE); + + /** + * Number 10 envelope size. 4.125 inch x 9.5 inch + */ + public static final MediaSize NA_NUMBER_10_ENVELOPE = + new MediaSize(4.125f, 9.5f, MediaSize.INCH, MediaSizeName.NA_NUMBER_10_ENVELOPE); + + /** + * Number 11 envelope size. 4.5 inch x 10.375 inch + */ + public static final MediaSize NA_NUMBER_11_ENVELOPE = new MediaSize(4.5f, 10.375f, MediaSize.INCH, + MediaSizeName.NA_NUMBER_11_ENVELOPE); + + /** + * Number 12 envelope size. 4.75 inch x 11 inch + */ + public static final MediaSize NA_NUMBER_12_ENVELOPE = new MediaSize(4.75f, 11f, + MediaSize.INCH, + MediaSizeName.NA_NUMBER_12_ENVELOPE); + + /** + * Number 14 envelope size. 5 inch x 11.5 inch + */ + public static final MediaSize NA_NUMBER_14_ENVELOPE = new MediaSize(5f, 11.5f, + MediaSize.INCH, + MediaSizeName.NA_NUMBER_14_ENVELOPE); + } + + /** + * Container class for predefined US Engineering media sizes. + * + * @author Sven de Marothy (sven@physto.se) + */ + public static final class Engineering + { + /** + * ANSI A paper size. 8.5 inch x 11 inch + */ + public static final MediaSize A = new MediaSize(8.5f, 11f, + MediaSize.INCH, MediaSizeName.A); + + /** + * ANSI B paper size. 11 inch x 17 inch + */ + public static final MediaSize B = new MediaSize(11f, 17f, + MediaSize.INCH, MediaSizeName.B); + + /** + * ANSI C paper size. 17 inch x 22 inch + */ + public static final MediaSize C = new MediaSize(17f, 22f, + MediaSize.INCH, MediaSizeName.C); + + /** + * ANSI D paper size. 22 inch x 34 inch + */ + public static final MediaSize D = new MediaSize(22f, 34f, + MediaSize.INCH, MediaSizeName.D); + + /** + * ANSI E paper size. 33 inch x 44 inch + */ + public static final MediaSize E = new MediaSize(34f, 44f, + MediaSize.INCH, MediaSizeName.E); + } + + /** + * Container class for predefined Japanese JIS media sizes. + * + * @author Sven de Marothy (sven@physto.se) + */ + public static final class JIS + { + /** + * JIS B0 paper. 1030 mm x 1456 mm + * Note: The JIS B-series is not identical to the ISO B-series. + */ + public static final MediaSize B0 = new MediaSize(1030, 1456, MediaSize.MM, MediaSizeName.JIS_B0); + + /** + * JIS B1 paper. 1030 mm x 1456 mm + * Note: The JIS B-series is not identical to the ISO B-series. + */ + public static final MediaSize B1 = new MediaSize(728, 1030, MediaSize.MM, MediaSizeName.JIS_B1); + + /** + * JIS B2 paper. 515 mm x 728 mm + * Note: The JIS B-series is not identical to the ISO B-series. + */ + public static final MediaSize B2 = new MediaSize(515, 728, MediaSize.MM, MediaSizeName.JIS_B2); + + /** + * JIS B3 paper. 364 mm x 515 mm + * Note: The JIS B-series is not identical to the ISO B-series. + */ + public static final MediaSize B3 = new MediaSize(364, 515, MediaSize.MM, MediaSizeName.JIS_B3); + + /** + * JIS B4 paper. 257 mm x 364 mm + * Note: The JIS B-series is not identical to the ISO B-series. + */ + public static final MediaSize B4 = new MediaSize(257, 364, MediaSize.MM, MediaSizeName.JIS_B4); + + /** + * JIS B5 paper. 1030 mm x 1456 mm + * Note: The JIS B-series is not identical to the ISO B-series. + */ + public static final MediaSize B5 = new MediaSize(182, 257, MediaSize.MM, MediaSizeName.JIS_B5); + + /** + * JIS B6 paper. 128 mm x 182 mm + * Note: The JIS B-series is not identical to the ISO B-series. + */ + public static final MediaSize B6 = new MediaSize(128, 182, MediaSize.MM, MediaSizeName.JIS_B6); + + /** + * JIS B7 paper. 91 mm x 128 mm + * Note: The JIS B-series is not identical to the ISO B-series. + */ + public static final MediaSize B7 = new MediaSize(91, 128, MediaSize.MM, MediaSizeName.JIS_B7); + + /** + * JIS B8 paper. 64 mm x 91 mm + * Note: The JIS B-series is not identical to the ISO B-series. + */ + public static final MediaSize B8 = new MediaSize(64, 91, MediaSize.MM, MediaSizeName.JIS_B8); + + /** + * JIS B9 paper. 45 mm x 64 mm + * Note: The JIS B-series is not identical to the ISO B-series. + */ + public static final MediaSize B9 = new MediaSize(45, 64, MediaSize.MM, MediaSizeName.JIS_B9); + + /** + * JIS B10 paper. 32 mm x 45 mm + * Note: The JIS B-series is not identical to the ISO B-series. + */ + public static final MediaSize B10 = new MediaSize(32, 45, MediaSize.MM, MediaSizeName.JIS_B10); + + /** + * JIS chou #1 envelope size, 142 mm x 332 mm + */ + public static final MediaSize CHOU_1 = new MediaSize(142, 332, MediaSize.MM); + + /** + * JIS chou #2 envelope size, 119 mm x 227 mm + */ + public static final MediaSize CHOU_2 = new MediaSize(119, 227, MediaSize.MM); + + /** + * JIS chou #3 envelope size, 120 mm x 235 mm + */ + public static final MediaSize CHOU_3 = new MediaSize(120, 235, MediaSize.MM); + + /** + * JIS chou #4 envelope size, 90 mm x 205 mm + */ + public static final MediaSize CHOU_4 = new MediaSize(90, 205, MediaSize.MM); + + /** + * JIS chou #30 envelope size, 92 mm x 235 mm + */ + public static final MediaSize CHOU_30 = new MediaSize(92, 235, MediaSize.MM); + + /** + * JIS chou #40 envelope size, 90 mm x 225 mm + */ + public static final MediaSize CHOU_40 = new MediaSize(90, 225, MediaSize.MM); + + /** + * JIS kaku #0 envelope size, 287 mm x 382 mm + */ + public static final MediaSize KAKU_0 = new MediaSize(287, 382, MediaSize.MM); + + /** + * JIS kaku #1 envelope size, 270 mm x 382 mm + */ + public static final MediaSize KAKU_1 = new MediaSize(270, 382, MediaSize.MM); + + /** + * JIS kaku #2 envelope size, 240 mm x 332 mm + */ + public static final MediaSize KAKU_2 = new MediaSize(240, 332, MediaSize.MM); + + /** + * JIS kaku #20 envelope size, 229 mm x 324 mm + */ + public static final MediaSize KAKU_20 = new MediaSize(229, 324, MediaSize.MM); + + /** + * JIS kaku #3 envelope size, 216 mm x 227 mm + */ + public static final MediaSize KAKU_3 = new MediaSize(216, 227, MediaSize.MM); + + /** + * JIS kaku #4 envelope size, 197 mm x 267 mm + */ + public static final MediaSize KAKU_4 = new MediaSize(197, 267, MediaSize.MM); + + /** + * JIS kaku #5 envelope size, 190 mm x 240 mm + */ + public static final MediaSize KAKU_5 = new MediaSize(190, 240, MediaSize.MM); + + /** + * JIS kaku #6 envelope size, 162 mm x 229 mm + */ + public static final MediaSize KAKU_6 = new MediaSize(162, 229, MediaSize.MM); + + /** + * JIS kaku #7 envelope size, 142 mm x 205 mm + */ + public static final MediaSize KAKU_7 = new MediaSize(142, 205, MediaSize.MM); + + /** + * JIS kaku #8 envelope size, 119 mm x 197 mm + */ + public static final MediaSize KAKU_8 = new MediaSize(119, 197, MediaSize.MM); + + /** + * JIS kaku A4 envelope size, 228 mm x 312 mm + */ + public static final MediaSize KAKU_A4 = new MediaSize(228, 312, MediaSize.MM); + + /** + * JIS you #1 envelope size, 120 mm x 176 mm + */ + public static final MediaSize YOU_1 = new MediaSize(120, 176, MediaSize.MM); + + /** + * JIS you #2 envelope size, 114 mm x 162 mm + */ + public static final MediaSize YOU_2 = new MediaSize(114, 162, MediaSize.MM); + + /** + * JIS you #3 envelope size, 98 mm x 148 mm + */ + public static final MediaSize YOU_3 = new MediaSize(98, 148, MediaSize.MM); + + /** + * JIS you #4 envelope size, 105 mm x 235 mm + */ + public static final MediaSize YOU_4 = new MediaSize(105, 235, MediaSize.MM); + + /** + * JIS you #5 envelope size, 95 mm x 217 mm + */ + public static final MediaSize YOU_5 = new MediaSize(95, 217, MediaSize.MM); + + /** + * JIS you #6 envelope size, 98 mm x 190 mm + */ + public static final MediaSize YOU_6 = new MediaSize(98, 190, MediaSize.MM); + + /** + * JIS you #7 envelope size, 92 mm x 165 mm + */ + public static final MediaSize YOU_7 = new MediaSize(92, 165, MediaSize.MM); + } + + /** + * Container class for miscellaneous media sizes. + * + * @author Sven de Marothy (sven@physto.se) + */ + public static final class Other + { + /** + * US Executive paper size, 7.25 inch x 10.5 inch + */ + public static final MediaSize EXECUTIVE = new MediaSize(7.25f, 10.5f, + MediaSize.INCH, MediaSizeName.EXECUTIVE); + + /** + * US Folio paper size, 8.5 inch x 13 inch + */ + public static final MediaSize FOLIO = new MediaSize(8.5f, 13f, MediaSize.INCH, MediaSizeName.FOLIO); + + /** + * US Quarto paper size, 8.5 inches by 10.83 inches. + */ + public static final MediaSize QUARTO = new MediaSize(8.5f, 10.83f, MediaSize.INCH, + MediaSizeName.QUARTO); + + /** + * US Invoice size, 5.5 inch x 8.5 inch + */ + public static final MediaSize INVOICE = new MediaSize(5.5f, 8.5f, + MediaSize.INCH, MediaSizeName.INVOICE); + + /** + * US Ledger size, 11 inch x 17 inch + */ + public static final MediaSize LEDGER = new MediaSize(11, 17, MediaSize.INCH, + MediaSizeName.LEDGER); + + /** + * Monarch (7 3/4) envelope size, 3.87 inch x 7.5 inch + */ + public static final MediaSize MONARCH_ENVELOPE = new MediaSize(3.87f, 7.5f, + MediaSize.INCH, + MediaSizeName.MONARCH_ENVELOPE); + + /** + * Personal envelope size, 3.625 inch x 6.5 inch. + */ + public static final MediaSize PERSONAL_ENVELOPE = new MediaSize(3.625f, 6.5f, MediaSize.INCH, + MediaSizeName.PERSONAL_ENVELOPE); + + /** + * Italian envelope size, 110 mm x 230 mm + */ + public static final MediaSize ITALY_ENVELOPE = new MediaSize(110, 230, + MediaSize.MM, + MediaSizeName.ITALY_ENVELOPE); + + /** + * Japanese postcard, 100 mm x 148 mm + */ + public static final MediaSize JAPANESE_POSTCARD = new MediaSize(100, 148, MediaSize.MM, MediaSizeName.JAPANESE_POSTCARD); + + /** + * Japanese double postcard, 148 mm x 200 mm + */ + public static final MediaSize JAPANESE_DOUBLE_POSTCARD = new MediaSize(148, 200, MediaSize.MM, MediaSizeName.JAPANESE_DOUBLE_POSTCARD); + } } + diff --git a/libjava/classpath/javax/print/attribute/standard/MediaSizeName.java b/libjava/classpath/javax/print/attribute/standard/MediaSizeName.java index 9990a2d..e29b1ae 100644 --- a/libjava/classpath/javax/print/attribute/standard/MediaSizeName.java +++ b/libjava/classpath/javax/print/attribute/standard/MediaSizeName.java @@ -1,5 +1,5 @@ /* MediaSizeName.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -37,99 +37,461 @@ exception statement from your version. */ package javax.print.attribute.standard; +import javax.print.attribute.EnumSyntax; + /** + * <code>MediaSizeName</code> is a subclass of the <code>Media</code> printing + * attribute and provides selection of media to be used by the means of + * defined size names. The class pre-defines commonly available media sizes. + * This media type enumeration may be used in alternative to + * MediaName/MediaTray. + * <p> + * <b>IPP Compatibility:</b> MediaSizeName is not an IPP 1.1 attribute on its + * own. It provides parts of the <code>media</code> attribute type values. + * </p> + * * @author Michael Koch (konqueror@gmx.de) + * @author Wolfgang Baer (WBaer@gmx.de) */ public class MediaSizeName extends Media { private static final long serialVersionUID = 2778798329756942747L; + /** + * The ISO A0 size: 841 mm by 1189 mm. + */ public static final MediaSizeName ISO_A0 = new MediaSizeName(0); + + /** + * The ISO A1 size: 594 mm by 841 mm. + */ public static final MediaSizeName ISO_A1 = new MediaSizeName(1); + + /** + * The ISO A2 size: 420 mm by 594 mm. + */ public static final MediaSizeName ISO_A2 = new MediaSizeName(2); + + /** + * The ISO A3 size: 297 mm by 420 mm. + */ public static final MediaSizeName ISO_A3 = new MediaSizeName(3); + + /** + * The ISO A4 size: 210 mm by 297 mm. + */ public static final MediaSizeName ISO_A4 = new MediaSizeName(4); + + /** + * The ISO A5 size: 148 mm by 210 mm. + */ public static final MediaSizeName ISO_A5 = new MediaSizeName(5); + + /** + * The ISO A6 size: 105 mm by 148 mm. + */ public static final MediaSizeName ISO_A6 = new MediaSizeName(6); + + /** + * The ISO A7 size: 74 mm by 105 mm. + */ public static final MediaSizeName ISO_A7 = new MediaSizeName(7); + + /** + * The ISO A8 size: 52 mm by 74 mm. + */ public static final MediaSizeName ISO_A8 = new MediaSizeName(8); + + /** + * The ISO A9 size: 37 mm by 52 mm. + */ public static final MediaSizeName ISO_A9 = new MediaSizeName(9); + + /** + * The ISO A10 size: 26 mm by 37 mm. + */ public static final MediaSizeName ISO_A10 = new MediaSizeName(10); + + /** + * The ISO B0 size: 1000 mm by 1414 mm. + */ public static final MediaSizeName ISO_B0 = new MediaSizeName(11); + + /** + * The ISO B1 size: 707 mm by 1000 mm. + */ public static final MediaSizeName ISO_B1 = new MediaSizeName(12); + + /** + * The ISO B2 size: 500 mm by 707 mm. + */ public static final MediaSizeName ISO_B2 = new MediaSizeName(13); + + /** + * The ISO B3 size: 353 mm by 500 mm. + */ public static final MediaSizeName ISO_B3 = new MediaSizeName(14); + + /** + * The ISO B4 size: 250 mm by 353 mm. + */ public static final MediaSizeName ISO_B4 = new MediaSizeName(15); + + /** + * The ISO B5 size: 176 mm by 250 mm. + */ public static final MediaSizeName ISO_B5 = new MediaSizeName(16); + + /** + * The ISO B6 size: 125 mm by 176 mm. + */ public static final MediaSizeName ISO_B6 = new MediaSizeName(17); + + /** + * The ISO B7 size: 88 mm by 125 mm. + */ public static final MediaSizeName ISO_B7 = new MediaSizeName(18); + + /** + * The ISO B8 size: 62 mm by 88 mm. + */ public static final MediaSizeName ISO_B8 = new MediaSizeName(19); + + /** + * The ISO B9 size: 44 mm by 62 mm. + */ public static final MediaSizeName ISO_B9 = new MediaSizeName(20); + + /** + * The ISO B10 size: 31 mm by 44 mm. + */ public static final MediaSizeName ISO_B10 = new MediaSizeName(21); + + /** + * The JIS B0 size: 1030mm x 1456mm. + */ public static final MediaSizeName JIS_B0 = new MediaSizeName(22); + + /** + * The JIS B1 size: 728mm x 1030mm. + */ public static final MediaSizeName JIS_B1 = new MediaSizeName(23); + + /** + * The JIS B2 size: 515mm x 728mm. + */ public static final MediaSizeName JIS_B2 = new MediaSizeName(24); + + /** + * The JIS B3 size: 364mm x 515mm. + */ public static final MediaSizeName JIS_B3 = new MediaSizeName(25); + + /** + * The JIS B4 size: 257mm x 364mm. + */ public static final MediaSizeName JIS_B4 = new MediaSizeName(26); + + /** + * The JIS B5 size: 182mm x 257mm. + */ public static final MediaSizeName JIS_B5 = new MediaSizeName(27); + + /** + * The JIS B6 size: 128mm x 182mm. + */ public static final MediaSizeName JIS_B6 = new MediaSizeName(28); + + /** + * The JIS B7 size: 91mm x 128mm. + */ public static final MediaSizeName JIS_B7 = new MediaSizeName(29); + + /** + * The JIS B8 size: 64mm x 91mm. + */ public static final MediaSizeName JIS_B8 = new MediaSizeName(30); + + /** + * The JIS B9 size: 45mm x 64mm. + */ public static final MediaSizeName JIS_B9 = new MediaSizeName(31); + + /** + * The JIS B10 size: 32mm x 45mm. + */ public static final MediaSizeName JIS_B10 = new MediaSizeName(32); + + /** + * The ISO C0 size: 917 mm by 1297 mm. + */ public static final MediaSizeName ISO_C0 = new MediaSizeName(33); + + /** + * The ISO C1 size: 648 mm by 917 mm. + */ public static final MediaSizeName ISO_C1 = new MediaSizeName(34); + + /** + * The ISO C2 size: 458 mm by 648 mm. + */ public static final MediaSizeName ISO_C2 = new MediaSizeName(35); + + /** + * The ISO C3 size: 324 mm by 458 mm. + */ public static final MediaSizeName ISO_C3 = new MediaSizeName(36); + + /** + * The ISO C4 size: 229 mm by 324 mm. + */ public static final MediaSizeName ISO_C4 = new MediaSizeName(37); + + /** + * The ISO C5 size: 162 mm by 229 mm. + */ public static final MediaSizeName ISO_C5 = new MediaSizeName(38); + + /** + * The ISO C6 size: 114 mm by 162 mm. + */ public static final MediaSizeName ISO_C6 = new MediaSizeName(39); + + /** + * The North American letter size: 8.5 inches by 11 inches. + */ public static final MediaSizeName NA_LETTER = new MediaSizeName(40); + + /** + * The North American legal size: 8.5 inches by 14 inches. + */ public static final MediaSizeName NA_LEGAL = new MediaSizeName(41); + + /** + * The executive size: 7.25 inches by 10.5 inches. + */ public static final MediaSizeName EXECUTIVE = new MediaSizeName(42); + + /** + * The ledger size: 11 inches by 17 inches. + */ public static final MediaSizeName LEDGER = new MediaSizeName(43); + + /** + * The tabloid size: 11 inches by 17 inches. + */ public static final MediaSizeName TABLOID = new MediaSizeName(44); + + /** + * The invoice size: 5.5 inches by 8.5 inches. + */ public static final MediaSizeName INVOICE = new MediaSizeName(45); + + /** + * The folio size: 8.5 inches by 13 inches. + */ public static final MediaSizeName FOLIO = new MediaSizeName(46); + + /** + * The quarto size: 8.5 inches by 10.83 inches. + */ public static final MediaSizeName QUARTO = new MediaSizeName(47); + + /** + * The Japanese postcard size, 100 mm by 148 mm. + */ public static final MediaSizeName JAPANESE_POSTCARD = new MediaSizeName(48); + + /** + * The Japanese Double postcard size: 148 mm by 200 mm. + */ public static final MediaSizeName JAPANESE_DOUBLE_POSTCARD = new MediaSizeName(49); + + /** + * The engineering ANSI A size medium: 8.5 inches x 11 inches. + */ public static final MediaSizeName A = new MediaSizeName(50); + + /** + * The engineering ANSI B size medium: 11 inches x 17 inches. + */ public static final MediaSizeName B = new MediaSizeName(51); + + /** + * The engineering ANSI C size medium: 17 inches x 22 inches. + */ public static final MediaSizeName C = new MediaSizeName(52); + + /** + * The engineering ANSI D size medium: 22 inches x 34 inches. + */ public static final MediaSizeName D = new MediaSizeName(53); + + /** + * The engineering ANSI E size medium: 34 inches x 44 inches. + */ public static final MediaSizeName E = new MediaSizeName(54); + + /** + * The ISO Designated Long size: 110 mm by 220 mm. + */ public static final MediaSizeName ISO_DESIGNATED_LONG = new MediaSizeName(55); + + /** + * The Italy envelope size: 110 mm by 230 mm. + */ public static final MediaSizeName ITALY_ENVELOPE = new MediaSizeName(56); + + /** + * The Monarch envelope size: 3.87 inch by 7.5 inch. + */ public static final MediaSizeName MONARCH_ENVELOPE = new MediaSizeName(57); + + /** + * The Personal envelope size: 3.625 inch by 6.5 inch. + */ public static final MediaSizeName PERSONAL_ENVELOPE = new MediaSizeName(58); + + /** + * The North American number 9 business envelope size: + * 3.875 inches by 8.875 inches. + */ public static final MediaSizeName NA_NUMBER_9_ENVELOPE = new MediaSizeName(59); + + /** + * The North American number 10 business envelope size: + * 4.125 inches by 9.5 inches. + */ public static final MediaSizeName NA_NUMBER_10_ENVELOPE = new MediaSizeName(60); + + /** + * The North American number 11 business envelope size: + * 4.5 inches by 10.375 inches. + */ public static final MediaSizeName NA_NUMBER_11_ENVELOPE = new MediaSizeName(61); + + /** + * The North American number 12 business envelope size: + * 4.75 inches by 11 inches. + */ public static final MediaSizeName NA_NUMBER_12_ENVELOPE = new MediaSizeName(62); + + /** + * The North American number 14 business envelope size: + * 5 inches by 11.5 inches. + */ public static final MediaSizeName NA_NUMBER_14_ENVELOPE = new MediaSizeName(63); + + /** + * The North American 6x9 inch envelope size. + */ public static final MediaSizeName NA_6X9_ENVELOPE = new MediaSizeName(64); + + /** + * The North American 7x9 inch envelope size. + */ public static final MediaSizeName NA_7X9_ENVELOPE = new MediaSizeName(65); + + /** + * The North American 9x11 inch envelope size. + */ public static final MediaSizeName NA_9X11_ENVELOPE = new MediaSizeName(66); + + /** + * The North American 9x12 inch envelope size. + */ public static final MediaSizeName NA_9X12_ENVELOPE = new MediaSizeName(67); + + /** + * The North American 10x13 inch envelope size. + */ public static final MediaSizeName NA_10X13_ENVELOPE = new MediaSizeName(68); + + /** + * The North American 10x14 inch envelope size. + */ public static final MediaSizeName NA_10X14_ENVELOPE = new MediaSizeName(69); + + /** + * The North American 10x15 inch envelope size. + */ public static final MediaSizeName NA_10X15_ENVELOPE = new MediaSizeName(70); + + /** + * The North American 5 inches by 7 inches. + */ public static final MediaSizeName NA_5X7 = new MediaSizeName(71); + + /** + * The North American 8 inches by 10 inches. + */ public static final MediaSizeName NA_8X10 = new MediaSizeName(72); + private static final String[] stringTable = + { "iso-a0", "iso-a1", "iso-a2", "iso-a3", "iso-a4", "iso-a5", "iso-a6", + "iso-a7", "iso-a8", "iso-a9", "iso-a10", "iso-b0", "iso-b1", "iso-b2", + "iso-b3", "iso-b4", "iso-b5", "iso-b6", "iso-b7", "iso-b8", "iso-b9", + "iso-b10", "jis-b0", "jis-b1", "jis-b2", "jis-b3", "jis-b4", "jis-b5", + "jis-b6", "jis-b7", "jis-b8", "jis-b9", "jis-b10", "iso-c0", "iso-c1", + "iso-c2", "iso-c3", "iso-c4", "iso-c5", "iso-c6", "na-letter", + "na-legal", "executive", "ledger", "tabloid", "invoice", "folio", + "quarto", "japanese-postcard", "oufuko-postcard", "a", "b", "c", "d", + "e", "iso-designated-long", "italian-envelope", "monarch-envelope", + "personal-envelope", "na-number-9-envelope", "na-number-10-envelope", + "na-number-11-envelope", "na-number-12-envelope", + "na-number-14-envelope", "na-6x9-envelope", "na-7x9-envelope", + "na-9x11-envelope", "na-9x12-envelope", "na-10x13-envelope", + "na-10x14-envelope", "na-10x15-envelope", "na-5x7", "na-8x10" }; + + private static final MediaSizeName[] enumValueTable = + { ISO_A0, ISO_A1, ISO_A2, ISO_A3, ISO_A4, ISO_A5, ISO_A6, ISO_A7, ISO_A8, + ISO_A9, ISO_A10, ISO_B0, ISO_B1, ISO_B2, ISO_B3, ISO_B4, ISO_B5, ISO_B6, + ISO_B7, ISO_B8, ISO_B9, ISO_B10, JIS_B0, JIS_B1, JIS_B2, JIS_B3, JIS_B4, + JIS_B5, JIS_B6, JIS_B7, JIS_B8, JIS_B9, JIS_B10, ISO_C0, ISO_C1, ISO_C2, + ISO_C3, ISO_C4, ISO_C5, ISO_C6, NA_LETTER, NA_LEGAL, EXECUTIVE, LEDGER, + TABLOID, INVOICE, FOLIO, QUARTO, JAPANESE_POSTCARD, + JAPANESE_DOUBLE_POSTCARD, A, B, C, D, E, ISO_DESIGNATED_LONG, + ITALY_ENVELOPE, MONARCH_ENVELOPE, PERSONAL_ENVELOPE, + NA_NUMBER_9_ENVELOPE, NA_NUMBER_10_ENVELOPE, NA_NUMBER_11_ENVELOPE, + NA_NUMBER_12_ENVELOPE, NA_NUMBER_14_ENVELOPE, NA_6X9_ENVELOPE, + NA_7X9_ENVELOPE, NA_9X11_ENVELOPE, NA_9X12_ENVELOPE, NA_10X13_ENVELOPE, + NA_10X14_ENVELOPE, NA_10X15_ENVELOPE, NA_5X7, NA_8X10 }; + /** * Constructs a <code>MediaSizeName</code> object. + * + * @param value the enum value. */ protected MediaSizeName(int value) { super(value); } + + /** + * Returns a table with the enumeration values represented as strings + * for this object. + * + * @return The enumeration values as strings. + */ + protected String[] getStringTable() + { + return stringTable; + } + + /** + * Returns a table with the enumeration values for this object. + * + * @return The enumeration values. + */ + protected EnumSyntax[] getEnumValueTable() + { + return enumValueTable; + } } diff --git a/libjava/classpath/javax/print/attribute/standard/MediaTray.java b/libjava/classpath/javax/print/attribute/standard/MediaTray.java new file mode 100644 index 0000000..23811a0 --- /dev/null +++ b/libjava/classpath/javax/print/attribute/standard/MediaTray.java @@ -0,0 +1,142 @@ +/* MediaTray.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package javax.print.attribute.standard; + +import javax.print.attribute.EnumSyntax; + +/** + * <code>MediaTray</code> is a subclass of the <code>Media</code> printing + * attribute and provides selection of media to be used by the means of the + * input tray of the printer. The class pre-defines commonly available types + * of input trays in printers. This media type enumeration may be used in + * alternative to MediaSizeName/MediaName. + * <p> + * <b>IPP Compatibility:</b> MediaTray is not an IPP 1.1 attribute on its own. + * It provides parts of the <code>media</code> attribute type values. + * </p> + * + * @author Sven de Marothy + * @author Wolfgang Baer (WBaer@gmx.de) + */ +public class MediaTray extends Media +{ + + private static final long serialVersionUID = -982503611095214703L; + + /** + * Top tray + */ + public static final MediaTray TOP = new MediaTray(0); + + /** + * Middle tray + */ + public static final MediaTray MIDDLE = new MediaTray(1); + + /** + * Bottom tray + */ + public static final MediaTray BOTTOM = new MediaTray(2); + + /** + * Envelope tray + */ + public static final MediaTray ENVELOPE = new MediaTray(3); + + /** + * Manual-feed tray + */ + public static final MediaTray MANUAL = new MediaTray(4); + + /** + * Large capacity tray + */ + public static final MediaTray LARGE_CAPACITY = new MediaTray(5); + + /** + * Main tray + */ + public static final MediaTray MAIN = new MediaTray(6); + + /** + * Side tray + */ + public static final MediaTray SIDE = new MediaTray(7); + + private static final String[] stringTable = { "top", "middle", "bottom", + "envelope", "manual", + "large-capacity", "main", + "side" }; + + private static final MediaTray[] enumValueTable = { TOP, MIDDLE, BOTTOM, + ENVELOPE, MANUAL, + LARGE_CAPACITY, MAIN, + SIDE }; + + /** + * Creates a <code>MediaTray</code> object. + * + * @param i the enum value. + */ + protected MediaTray(int i) + { + super( i ); + } + + /** + * Returns a table with the enumeration values represented as strings + * for this object. + * + * @return The enumeration values as strings. + */ + protected String[] getStringTable() + { + return stringTable; + } + + /** + * Returns a table with the enumeration values for this object. + * + * @return The enumeration values. + */ + protected EnumSyntax[] getEnumValueTable() + { + return enumValueTable; + } +} + diff --git a/libjava/classpath/javax/print/attribute/standard/MultipleDocumentHandling.java b/libjava/classpath/javax/print/attribute/standard/MultipleDocumentHandling.java index 8298092..1ed0c91 100644 --- a/libjava/classpath/javax/print/attribute/standard/MultipleDocumentHandling.java +++ b/libjava/classpath/javax/print/attribute/standard/MultipleDocumentHandling.java @@ -43,24 +43,60 @@ import javax.print.attribute.PrintRequestAttribute; /** + * The <code>MultipleDocumentHandling</code> printing attribute controls + * how certain printing attributes affect printing in case of multiple + * documents in a print job. This attribute is only relevant if a job + * has multiple documents. + * <p> + * <b>IPP Compatibility:</b> MultipleDocumentHandling is an IPP 1.1 attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) + * @author Wolfgang Baer (WBaer@gmx.de) */ public class MultipleDocumentHandling extends EnumSyntax implements PrintJobAttribute, PrintRequestAttribute { private static final long serialVersionUID = 8098326460746413466L; + /** + * Multiple documents are treated as a single document. + */ public static final MultipleDocumentHandling SINGLE_DOCUMENT = new MultipleDocumentHandling(0); + + /** + * Multiple documents are treated as uncollated copies. + */ public static final MultipleDocumentHandling SEPARATE_DOCUMENTS_UNCOLLATED_COPIES = new MultipleDocumentHandling(1); + + /** + * Multiple documents are treated as collated copies. + */ public static final MultipleDocumentHandling SEPARATE_DOCUMENTS_COLLATED_COPIES = new MultipleDocumentHandling(2); + + /** + * Multiple documents are treated so that every single document starts + * with a new sheet. + */ public static final MultipleDocumentHandling SINGLE_DOCUMENT_NEW_SHEET = new MultipleDocumentHandling(3); + + private static final String[] stringTable = { "single-document", + "separate-documents-uncollated-copies", + "separate-documents-collated-copies", + "single-document-new-sheet" }; + + private static final MultipleDocumentHandling[] enumValueTable = + { SINGLE_DOCUMENT, SEPARATE_DOCUMENTS_UNCOLLATED_COPIES, + SEPARATE_DOCUMENTS_COLLATED_COPIES, SINGLE_DOCUMENT_NEW_SHEET}; /** * Constructs a <code>MultipleDocumentHandling</code> object. + * + * @param value the enum value */ protected MultipleDocumentHandling(int value) { @@ -70,7 +106,7 @@ public class MultipleDocumentHandling extends EnumSyntax /** * Returns category of this class. * - * @return the class <code>MultipleDocumentHandling</code> itself + * @return The class <code>MultipleDocumentHandling</code> itself. */ public Class getCategory() { @@ -80,10 +116,31 @@ public class MultipleDocumentHandling extends EnumSyntax /** * Returns the name of this attribute. * - * @return the name + * @return The name "multiple-document-handling". */ public String getName() { return "multiple-document-handling"; } + + /** + * Returns a table with the enumeration values represented as strings + * for this object. + * + * @return The enumeration values as strings. + */ + protected String[] getStringTable() + { + return stringTable; + } + + /** + * Returns a table with the enumeration values for this object. + * + * @return The enumeration values. + */ + protected EnumSyntax[] getEnumValueTable() + { + return enumValueTable; + } } diff --git a/libjava/classpath/javax/print/attribute/standard/NumberOfDocuments.java b/libjava/classpath/javax/print/attribute/standard/NumberOfDocuments.java index cf2e9dc..b9363eb 100644 --- a/libjava/classpath/javax/print/attribute/standard/NumberOfDocuments.java +++ b/libjava/classpath/javax/print/attribute/standard/NumberOfDocuments.java @@ -1,5 +1,5 @@ /* NumberOfDocuments.java -- - Copyright (C) 2003 Free Software Foundation, Inc. + Copyright (C) 2003, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -41,6 +41,12 @@ import javax.print.attribute.IntegerSyntax; import javax.print.attribute.PrintJobAttribute; /** + * The <code>NumberOfDocuments</code> printing attribute specifies + * the number of documents in a job. + * <p> + * <b>IPP Compatibility:</b> NumberOfDocuments is an IPP 1.1 attribute. + * </p> + * * @author Michael Koch */ public final class NumberOfDocuments extends IntegerSyntax @@ -53,7 +59,7 @@ public final class NumberOfDocuments extends IntegerSyntax * * @param value the number of documents * - * @exception IllegalArgumentException if value < 0 + * @exception IllegalArgumentException if value < 0 */ public NumberOfDocuments(int value) { @@ -64,11 +70,12 @@ public final class NumberOfDocuments extends IntegerSyntax } /** - * Tests of obj is equal to this object. + * Tests if the given object is equal to this object. * * @param obj the object to test * - * @return true if both objects are equal, false otherwise. + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. */ public boolean equals(Object obj) { @@ -81,7 +88,7 @@ public final class NumberOfDocuments extends IntegerSyntax /** * Returns category of this class. * - * @return the class <code>NumberOfDocuments</code> itself + * @return The class <code>NumberOfDocuments</code> itself. */ public Class getCategory() { @@ -89,9 +96,9 @@ public final class NumberOfDocuments extends IntegerSyntax } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "number-of-documents" + * @return The name "number-of-documents". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/NumberOfInterveningJobs.java b/libjava/classpath/javax/print/attribute/standard/NumberOfInterveningJobs.java index 1da2e1b..d3c0952 100644 --- a/libjava/classpath/javax/print/attribute/standard/NumberOfInterveningJobs.java +++ b/libjava/classpath/javax/print/attribute/standard/NumberOfInterveningJobs.java @@ -1,5 +1,5 @@ /* NumberOfInterveningJobs.java -- - Copyright (C) 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -41,6 +41,13 @@ import javax.print.attribute.IntegerSyntax; import javax.print.attribute.PrintJobAttribute; /** + * The <code>NumberOfInterveningJobs</code> printing attribute provides + * the number of jobs ahead in the print service queue before the + * requested job. + * <p> + * <b>IPP Compatibility:</b> NumberOfInterveningJobs is an IPP 1.1 attribute. + * </p> + * * @author Michael Koch */ public final class NumberOfInterveningJobs extends IntegerSyntax @@ -53,7 +60,7 @@ public final class NumberOfInterveningJobs extends IntegerSyntax * * @param value the number of intervening jobs * - * @exception IllegalArgumentException if value < 0 + * @exception IllegalArgumentException if value < 0 */ public NumberOfInterveningJobs(int value) { @@ -64,11 +71,12 @@ public final class NumberOfInterveningJobs extends IntegerSyntax } /** - * Tests of obj is equal to this object. + * Tests if the given object is equal to this object. * * @param obj the object to test * - * @return true if both objects are equal, false otherwise. + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. */ public boolean equals(Object obj) { @@ -81,7 +89,7 @@ public final class NumberOfInterveningJobs extends IntegerSyntax /** * Returns category of this class. * - * @return the class <code>NumberOfInterveningJobs</code> itself + * @return The class <code>NumberOfInterveningJobs</code> itself. */ public Class getCategory() { @@ -89,9 +97,9 @@ public final class NumberOfInterveningJobs extends IntegerSyntax } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "number-of-intervening-jobs" + * @return The name "number-of-intervening-jobs". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/NumberUp.java b/libjava/classpath/javax/print/attribute/standard/NumberUp.java index 4dee553..aa23240 100644 --- a/libjava/classpath/javax/print/attribute/standard/NumberUp.java +++ b/libjava/classpath/javax/print/attribute/standard/NumberUp.java @@ -1,5 +1,5 @@ /* NumberUp.java -- - Copyright (C) 2003 Free Software Foundation, Inc. + Copyright (C) 2003, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -43,6 +43,17 @@ import javax.print.attribute.PrintJobAttribute; import javax.print.attribute.PrintRequestAttribute; /** + * The <code>NumberUp</code> printing attribute specifies the number of pages + * to be arranged upon a single media sheet. + * <p> + * <b>Note:</b> The effect of this attribute on jobs with multiple documents + * is controlled by the job attribute + * {@link javax.print.attribute.standard.MultipleDocumentHandling}. + * </p> + * <p> + * <b>IPP Compatibility:</b> NumberUp is an IPP 1.1 attribute. + * </p> + * * @author Michael Koch */ public final class NumberUp extends IntegerSyntax @@ -56,7 +67,7 @@ public final class NumberUp extends IntegerSyntax * @param value the number of print-stream pages to print on a single side * of a media * - * @exception IllegalArgumentException if value < 1 + * @exception IllegalArgumentException if value < 1 */ public NumberUp(int value) { @@ -64,11 +75,12 @@ public final class NumberUp extends IntegerSyntax } /** - * Tests of obj is equal to this object. + * Tests if the given object is equal to this object. * * @param obj the object to test * - * @return true if both objects are equal, false otherwise. + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. */ public boolean equals(Object obj) { @@ -81,7 +93,7 @@ public final class NumberUp extends IntegerSyntax /** * Returns category of this class. * - * @return the class <code>NumberUp</code> itself + * @return The class <code>NumberUp</code> itself. */ public Class getCategory() { @@ -89,9 +101,9 @@ public final class NumberUp extends IntegerSyntax } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "number-up" + * @return The name "number-up". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/NumberUpSupported.java b/libjava/classpath/javax/print/attribute/standard/NumberUpSupported.java index 512bdaa..71392a9 100644 --- a/libjava/classpath/javax/print/attribute/standard/NumberUpSupported.java +++ b/libjava/classpath/javax/print/attribute/standard/NumberUpSupported.java @@ -1,5 +1,5 @@ /* NumberUpSupported.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -42,7 +42,15 @@ import javax.print.attribute.SupportedValuesAttribute; /** + * The <code>NumberUpSupported</code> printing attribute specifies the + * supported value or range of values for the + * {@link javax.print.attribute.standard.NumberUp} attribute. + * <p> + * <b>IPP Compatibility:</b> NumberUpSupported is an IPP 1.1 attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) + * @author Wolfgang Baer (WBaer@gmx.de) */ public final class NumberUpSupported extends SetOfIntegerSyntax implements SupportedValuesAttribute @@ -50,33 +58,75 @@ public final class NumberUpSupported extends SetOfIntegerSyntax private static final long serialVersionUID = -1041573395759141805L; /** - * Constructs a <code>NumberUp</code> object. + * Constructs a <code>NumberUpSupported</code> object. + * + * @param member the only one value supported for number up. + * + * @exception IllegalArgumentException if member is < 1 */ public NumberUpSupported(int member) { super(member); + + if (member < 1) + throw new IllegalArgumentException("member may not be less than 1"); } /** - * Constructs a <code>NumberUp</code> object. + * Constructs a <code>NumberUpSupported</code> object. + * + * @param members the members supported for number up. + * + * @exception IllegalArgumentException if any element is invalid + * @exception NullPointerException if members is <code>null</code> or any + * element of members is <code>null</code>. */ public NumberUpSupported(int[][] members) { super(members); + + if (members == null) + throw new NullPointerException("members may not be null"); } /** - * Constructs a <code>NumberUp</code> object. + * Constructs a <code>NumberUpSupported</code> object with the + * given range for supported number up values. + * + * @param lowerBound the lower bound value + * @param upperBound the upper bound value + * + * @exception IllegalArgumentException if lowerBound <= upperbound + * and lowerBound < 1 */ public NumberUpSupported(int lowerBound, int upperBound) { super(lowerBound, upperBound); + + if (lowerBound < 1) + throw new IllegalArgumentException("lowerBound may not be less than 1"); + } + + /** + * Tests if the given object is equal to this object. + * + * @param obj the object to test + * + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. + */ + public boolean equals(Object obj) + { + if (! (obj instanceof NumberUpSupported)) + return false; + + return super.equals(obj); } /** * Returns category of this class. * - * @return the class <code>NumberUpSupported</code> itself + * @return The class <code>NumberUpSupported</code> itself. */ public Class getCategory() { @@ -86,7 +136,7 @@ public final class NumberUpSupported extends SetOfIntegerSyntax /** * Returns the name of this attribute. * - * @return the name + * @return The name "number-up-supported". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/OrientationRequested.java b/libjava/classpath/javax/print/attribute/standard/OrientationRequested.java index ca63fff..1f9f0bf 100644 --- a/libjava/classpath/javax/print/attribute/standard/OrientationRequested.java +++ b/libjava/classpath/javax/print/attribute/standard/OrientationRequested.java @@ -1,5 +1,5 @@ /* OrientationRequested.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -44,25 +44,64 @@ import javax.print.attribute.PrintRequestAttribute; /** + * The <code>OrientationRequested</code> printing attribute specifies + * the desired orientation of the print data on the media sheet. + * <p> + * The effect of this attribute may depend on the document format as + * some document formats (e.g. postscript) contains the orientation + * inside the print data. However for other formats like e.g. plain + * text this attribute will have an effect on the orientation. + * </p> + * <p> + * <b>IPP Compatibility:</b> OrientationRequested is an IPP 1.1 attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) + * @author Wolfgang Baer (WBaer@gmx.de) */ public final class OrientationRequested extends EnumSyntax implements DocAttribute, PrintRequestAttribute, PrintJobAttribute { private static final long serialVersionUID = -4447437289862822276L; + /** + * Orientation as portrait. + */ public static final OrientationRequested PORTRAIT = - new OrientationRequested(0); + new OrientationRequested(3); + + /** + * Orientation as landscape. + */ public static final OrientationRequested LANDSCAPE = - new OrientationRequested(1); + new OrientationRequested(4); + + /** + * Orientation as reversed landscape. + */ public static final OrientationRequested REVERSE_LANDSCAPE = - new OrientationRequested(2); + new OrientationRequested(5); + + /** + * Orientation as reversed portrait. + */ public static final OrientationRequested REVERSE_PORTRAIT = - new OrientationRequested(3); + new OrientationRequested(6); + - /** - * Constructs a <code>OrientationRequested</code> object. - */ + private static final String[] stringTable = { "portrait", "landscape", + "reverse-landscape", + "reverse-portrait" }; + + private static final OrientationRequested[] + enumValueTable = { PORTRAIT, LANDSCAPE, + REVERSE_LANDSCAPE, REVERSE_PORTRAIT }; + + /** + * Constructs a <code>OrientationRequested</code> object. + * + * @param value the value + */ protected OrientationRequested(int value) { super(value); @@ -71,7 +110,7 @@ public final class OrientationRequested extends EnumSyntax /** * Returns category of this class. * - * @return the class <code>OrientationRequested</code> itself + * @return The class <code>OrientationRequested</code> itself. */ public Class getCategory() { @@ -81,10 +120,41 @@ public final class OrientationRequested extends EnumSyntax /** * Returns the name of this attribute. * - * @return the name + * @return The name "orientation-requested". */ public String getName() { return "orientation-requested"; } + + /** + * Returns a table with the enumeration values represented as strings + * for this object. + * + * @return The enumeration values as strings. + */ + protected String[] getStringTable() + { + return stringTable; + } + + /** + * Returns a table with the enumeration values for this object. + * + * @return The enumeration values. + */ + protected EnumSyntax[] getEnumValueTable() + { + return enumValueTable; + } + + /** + * Returns the lowest used value by the enumerations of this class. + * . + * @return The lowest value used. + */ + protected int getOffset() + { + return 3; + } } diff --git a/libjava/classpath/javax/print/attribute/standard/OutputDeviceAssigned.java b/libjava/classpath/javax/print/attribute/standard/OutputDeviceAssigned.java index 4bc1f6c..917064f 100644 --- a/libjava/classpath/javax/print/attribute/standard/OutputDeviceAssigned.java +++ b/libjava/classpath/javax/print/attribute/standard/OutputDeviceAssigned.java @@ -1,5 +1,5 @@ /* OutputDeviceAssigned.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -44,6 +44,18 @@ import javax.print.attribute.PrintJobAttribute; import javax.print.attribute.TextSyntax; /** + * The <code>OutputDeviceAssigned</code> printing attribute specifies the + * output printer device assigned by a print service to a print job. + * <p> + * This may be empty if a print service is embedded in a printer, e.g. is the + * output device. However there exist print services with several physical + * output devices (e.g. CUPS classes) where this attribute provides the actual + * output device. + * </p> + * <p> + * <b>IPP Compatibility:</b> OutputDeviceAssigned is an IPP 1.1 attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) */ public final class OutputDeviceAssigned extends TextSyntax @@ -54,9 +66,11 @@ public final class OutputDeviceAssigned extends TextSyntax /** * Creates a <code>OutputDeviceAssigned</code> object. * - * @param deviceName the user name + * @param deviceName the name of the device. + * @param locale the locale to use, if <code>null</code> the default + * locale is used. * - * @exception NullPointerException if deviceName is null + * @exception NullPointerException if deviceName is <code>null</code>. */ public OutputDeviceAssigned(String deviceName, Locale locale) { @@ -64,11 +78,12 @@ public final class OutputDeviceAssigned extends TextSyntax } /** - * Tests of obj is equal to this object. + * Tests if the given object is equal to this object. * * @param obj the object to test * - * @return true if both objects are equal, false otherwise. + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. */ public boolean equals(Object obj) { @@ -81,7 +96,7 @@ public final class OutputDeviceAssigned extends TextSyntax /** * Returns category of this class. * - * @return the class <code>OutputDeviceAssigned</code> itself + * @return The class <code>OutputDeviceAssigned</code> itself. */ public Class getCategory() { @@ -89,9 +104,9 @@ public final class OutputDeviceAssigned extends TextSyntax } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "output-device-assigned" + * @return The name "output-device-assigned". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/PDLOverrideSupported.java b/libjava/classpath/javax/print/attribute/standard/PDLOverrideSupported.java index 7986539..d3be3e5 100644 --- a/libjava/classpath/javax/print/attribute/standard/PDLOverrideSupported.java +++ b/libjava/classpath/javax/print/attribute/standard/PDLOverrideSupported.java @@ -1,5 +1,5 @@ /* PDLOverrideSupported.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -42,20 +42,44 @@ import javax.print.attribute.PrintServiceAttribute; /** + * The <code>PDLOverrideSupported</code> printing attribute specifies + * if a print services is capable of attempting to override document data + * instructions with IPP attributesc. + * <p> + * <b>IPP Compatibility:</b> PDLOverrideSupported is an IPP 1.1 attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) + * @author Wolfgang Baer (WBaer@gmx.de) */ public class PDLOverrideSupported extends EnumSyntax implements PrintServiceAttribute { private static final long serialVersionUID = -4393264467928463934L; + /** + * Indicates that the print service is not capable of + * attempting to override document data instructions. + */ public static final PDLOverrideSupported NOT_ATTEMPTED = new PDLOverrideSupported(0); + + /** + * Indicates that the print service is capable of + * attempting to override document data instructions. + */ public static final PDLOverrideSupported ATTEMPTED = - new PDLOverrideSupported(0); + new PDLOverrideSupported(1); + + private static final String[] stringTable = { "not-attempted", "attempted" }; + + private static final PDLOverrideSupported[] enumValueTable = { NOT_ATTEMPTED, + ATTEMPTED}; /** * Constructs a <code>PDLOverrideSupported</code> object. + * + * @param value the enum value */ protected PDLOverrideSupported(int value) { @@ -65,7 +89,7 @@ public class PDLOverrideSupported extends EnumSyntax /** * Returns category of this class. * - * @return the class <code>PDLOverrideSupported</code> itself + * @return The class <code>PDLOverrideSupported</code> itself. */ public Class getCategory() { @@ -75,10 +99,31 @@ public class PDLOverrideSupported extends EnumSyntax /** * Returns the name of this attribute. * - * @return the name + * @return The name "pdl-override-supported". */ public String getName() { return "pdl-override-supported"; } + + /** + * Returns a table with the enumeration values represented as strings + * for this object. + * + * @return The enumeration values as strings. + */ + protected String[] getStringTable() + { + return stringTable; + } + + /** + * Returns a table with the enumeration values for this object. + * + * @return The enumeration values. + */ + protected EnumSyntax[] getEnumValueTable() + { + return enumValueTable; + } } diff --git a/libjava/classpath/javax/print/attribute/standard/PageRanges.java b/libjava/classpath/javax/print/attribute/standard/PageRanges.java index 2b3c632..3aa1b56 100644 --- a/libjava/classpath/javax/print/attribute/standard/PageRanges.java +++ b/libjava/classpath/javax/print/attribute/standard/PageRanges.java @@ -1,5 +1,5 @@ /* PageRanges.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -44,7 +44,19 @@ import javax.print.attribute.PrintRequestAttribute; import javax.print.attribute.SetOfIntegerSyntax; /** + * The <code>PageRanges</code> printing attribute specifies the + * range(s) of pages to be printed in a print job. + * <p> + * <b>Note:</b> The effect of this attribute on jobs with multiple + * documents is controlled by the job attribute + * {@link javax.print.attribute.standard.MultipleDocumentHandling}. + * </p> + * <p> + * <b>IPP Compatibility:</b> PageRanges is an IPP 1.1 attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) + * @author Wolfgang Baer (WBaer@gmx.de) */ public final class PageRanges extends SetOfIntegerSyntax implements DocAttribute, PrintRequestAttribute, PrintJobAttribute @@ -52,33 +64,95 @@ public final class PageRanges extends SetOfIntegerSyntax private static final long serialVersionUID = 8639895197656148392L; /** - * Constructs a <code>PageRanges</code> object. + * Constructs a <code>PageRanges</code> object with only one + * page to be printed. + * + * @param member the only page to be printed. + * + * @exception IllegalArgumentException if member is < 1 */ public PageRanges(int member) { super(member); + + if (member < 1) + throw new IllegalArgumentException("member may not be less than 1"); } /** - * Constructs a <code>PageRanges</code> object. + * Constructs a <code>PageRanges</code> object with a set + * of ranges to be printed. + * + * @param members the page ranges to be printed. + * + * @exception IllegalArgumentException if any element is invalid + * @exception NullPointerException if members is <code>null</code> or any + * element of members is <code>null</code>. */ public PageRanges(int[][] members) { super(members); + + if (members == null) + throw new NullPointerException("members may not be null"); } /** - * Constructs a <code>PageRanges</code> object. + * Constructs a <code>PageRanges</code> object with the + * given single range of pages to be printed. + * + * @param lowerBound the lower bound value + * @param upperBound the upper bound value + * + * @exception IllegalArgumentException if lowerBound <= upperbound + * and lowerBound < 1 */ public PageRanges(int lowerBound, int upperBound) { super(lowerBound, upperBound); + + if (lowerBound < 1) + throw new IllegalArgumentException("lowerbound may not be less than 1"); + } + + /** + * Constructs a <code>PageRanges</code> object with a set + * of ranges to be printed in string array form. + * + * @param members the page ranges to be printed in string form. + * + * @exception IllegalArgumentException if any element is invalid. + * @exception NullPointerException if members is <code>null</code> or any + * element of members is <code>null</code>. + */ + public PageRanges(String members) + { + super(members); + + if (members == null) + throw new NullPointerException("members may not be null"); + } + + /** + * Tests if the given object is equal to this object. + * + * @param obj the object to test + * + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. + */ + public boolean equals(Object obj) + { + if (! (obj instanceof PageRanges)) + return false; + + return super.equals(obj); } /** * Returns category of this class. * - * @return the class <code>PageRanges</code> itself + * @return The class <code>PageRanges</code> itself. */ public Class getCategory() { @@ -88,7 +162,7 @@ public final class PageRanges extends SetOfIntegerSyntax /** * Returns the name of this attribute. * - * @return the name + * @return The name "page-ranges". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/PagesPerMinute.java b/libjava/classpath/javax/print/attribute/standard/PagesPerMinute.java index db2658a..c06fb97 100644 --- a/libjava/classpath/javax/print/attribute/standard/PagesPerMinute.java +++ b/libjava/classpath/javax/print/attribute/standard/PagesPerMinute.java @@ -1,5 +1,5 @@ /* PagesPerMinute.java -- - Copyright (C) 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -42,6 +42,13 @@ import javax.print.attribute.IntegerSyntax; import javax.print.attribute.PrintServiceAttribute; /** + * The <code>PagesPerMinute</code> printing attribute specifies + * the nominal number of pages per minute which may be printed + * by the printer. + * <p> + * <b>IPP Compatibility:</b> PagesPerMinute is an IPP 1.1 attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) */ public final class PagesPerMinute extends IntegerSyntax @@ -54,7 +61,7 @@ public final class PagesPerMinute extends IntegerSyntax * * @param value the number of pages per minute * - * @exception IllegalArgumentException if value < 0 + * @exception IllegalArgumentException if value < 0 */ public PagesPerMinute(int value) { @@ -65,11 +72,12 @@ public final class PagesPerMinute extends IntegerSyntax } /** - * Tests of obj is equal to this object. + * Tests if the given object is equal to this object. * * @param obj the object to test * - * @return true if both objects are equal, false otherwise. + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. */ public boolean equals(Object obj) { @@ -82,7 +90,7 @@ public final class PagesPerMinute extends IntegerSyntax /** * Returns category of this class. * - * @return the class <code>PagesPerMinute</code> itself + * @return The class <code>PagesPerMinute</code> itself. */ public Class getCategory() { @@ -90,9 +98,9 @@ public final class PagesPerMinute extends IntegerSyntax } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "pages-per-minute" + * @return The name "pages-per-minute". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/PagesPerMinuteColor.java b/libjava/classpath/javax/print/attribute/standard/PagesPerMinuteColor.java index 85421d7..80a397e 100644 --- a/libjava/classpath/javax/print/attribute/standard/PagesPerMinuteColor.java +++ b/libjava/classpath/javax/print/attribute/standard/PagesPerMinuteColor.java @@ -1,5 +1,5 @@ /* PagesPerMinuteColor.java -- - Copyright (C) 2003 Free Software Foundation, Inc. + Copyright (C) 2003, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -41,6 +41,13 @@ import javax.print.attribute.IntegerSyntax; import javax.print.attribute.PrintServiceAttribute; /** + * The <code>PagesPerMinuteColor</code> printing attribute specifies + * the nominal number of pages per minute which may be printed in + * color by the printer. + * <p> + * <b>IPP Compatibility:</b> PagesPerMinuteColor is an IPP 1.1 attribute. + * </p> + * * @author Michael Koch */ public final class PagesPerMinuteColor extends IntegerSyntax @@ -51,9 +58,9 @@ public final class PagesPerMinuteColor extends IntegerSyntax /** * Creates a <code>PagesPerMinuteColor</code> object. * - * @param value the number of pages per minute + * @param value the number of pages per minute in color * - * @exception IllegalArgumentException if value < 0 + * @exception IllegalArgumentException if value < 0 */ public PagesPerMinuteColor(int value) { @@ -64,11 +71,12 @@ public final class PagesPerMinuteColor extends IntegerSyntax } /** - * Tests of obj is equal to this object. + * Tests if the given object is equal to this object. * * @param obj the object to test * - * @return true if both objects are equal, false otherwise. + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. */ public boolean equals(Object obj) { @@ -81,7 +89,7 @@ public final class PagesPerMinuteColor extends IntegerSyntax /** * Returns category of this class. * - * @return the class <code>PagesPerMinuteColor</code> itself + * @return The class <code>PagesPerMinuteColor</code> itself. */ public Class getCategory() { @@ -89,9 +97,9 @@ public final class PagesPerMinuteColor extends IntegerSyntax } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "pages-per-minute-color" + * @return The name "pages-per-minute-color". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/PresentationDirection.java b/libjava/classpath/javax/print/attribute/standard/PresentationDirection.java index bd1821d..3a479ab 100644 --- a/libjava/classpath/javax/print/attribute/standard/PresentationDirection.java +++ b/libjava/classpath/javax/print/attribute/standard/PresentationDirection.java @@ -1,5 +1,5 @@ /* PresentationDirection.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -43,32 +43,90 @@ import javax.print.attribute.PrintRequestAttribute; /** + * The <code>PresentationDirection</code> attribute specifies + * a value to be used together with the <code>NumberUp</code> attribute + * to indicate the layout of multiple pages on a single media sheet. + * <p> + * <b>IPP Compatibility:</b> PresentationDirection is not an IPP 1.1 + * attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) + * @author Wolfgang Baer (WBaer@gmx.de) */ public final class PresentationDirection extends EnumSyntax implements PrintRequestAttribute, PrintJobAttribute { private static final long serialVersionUID = 8294728067230931780L; + /** + * The single pages are arranged on the media in columns starting + * at the top left towards the bottom left. + */ public static final PresentationDirection TOBOTTOM_TORIGHT = new PresentationDirection(0); + + /** + * The single pages are arranged on the media in columns starting + * at the top right towards the bottom left. + */ public static final PresentationDirection TOBOTTOM_TOLEFT = new PresentationDirection(1); + + /** + * The single pages are arranged on the media in columns starting + * at the bottom left towards the top right. + */ public static final PresentationDirection TOTOP_TORIGHT = new PresentationDirection(2); + + /** + * The single pages are arranged on the media in columns starting + * at the bottom right towards the top left. + */ public static final PresentationDirection TOTOP_TOLEFT = new PresentationDirection(3); + + /** + * The single pages are arranged on the media in rows starting + * at the top left towards the right bottom. + */ public static final PresentationDirection TORIGHT_TOBOTTOM = new PresentationDirection(4); + + /** + * The single pages are arranged on the media in rows starting + * at the bottom left towards the right top. + */ public static final PresentationDirection TORIGHT_TOTOP = new PresentationDirection(5); + + /** + * The single pages are arranged on the media in rows starting + * at the top right towards the left bottom. + */ public static final PresentationDirection TOLEFT_TOBOTTOM = new PresentationDirection(6); + + /** + * The single pages are arranged on the media in rows starting + * at the bottom right towards the left top. + */ public static final PresentationDirection TOLEFT_TOTOP = new PresentationDirection(7); + private static final String[] stringTable = { "tobottom-toright", + "tobottom-toleft", "totop-toright", "totop-toleft", "toright-tobottom", + "toright-totop", "toleft-tobottom", "toleft-totop" }; + + private static final PresentationDirection[] enumValueTable = + { TOBOTTOM_TORIGHT, TOBOTTOM_TOLEFT, TOTOP_TORIGHT, TOTOP_TOLEFT, + TORIGHT_TOBOTTOM, TORIGHT_TOTOP, TOLEFT_TOBOTTOM, TOLEFT_TOTOP }; + /** * Constructs a <code>PresentationDirection</code> object. + * + * @param value the enum value. */ private PresentationDirection(int value) { @@ -78,7 +136,7 @@ public final class PresentationDirection extends EnumSyntax /** * Returns category of this class. * - * @return the class <code>PresentationDirection</code> itself + * @return The class <code>PresentationDirection</code> itself. */ public Class getCategory() { @@ -88,10 +146,31 @@ public final class PresentationDirection extends EnumSyntax /** * Returns the name of this attribute. * - * @return the name + * @return The name "presentation-direction". */ public String getName() { return "presentation-direction"; } + + /** + * Returns a table with the enumeration values represented as strings + * for this object. + * + * @return The enumeration values as strings. + */ + protected String[] getStringTable() + { + return stringTable; + } + + /** + * Returns a table with the enumeration values for this object. + * + * @return The enumeration values. + */ + protected EnumSyntax[] getEnumValueTable() + { + return enumValueTable; + } } diff --git a/libjava/classpath/javax/print/attribute/standard/PrintQuality.java b/libjava/classpath/javax/print/attribute/standard/PrintQuality.java index 63be24e..2f1a105 100644 --- a/libjava/classpath/javax/print/attribute/standard/PrintQuality.java +++ b/libjava/classpath/javax/print/attribute/standard/PrintQuality.java @@ -1,5 +1,5 @@ /* PrintQuality.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -44,19 +44,43 @@ import javax.print.attribute.PrintRequestAttribute; /** + * The <code>PrintQuality</code> printing attribute specifies the + * print quality that should be used by the print services for a job. + * <p> + * <b>IPP Compatibility:</b> PrintQuality is an IPP 1.1 attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) + * @author Wolfgang Baer (WBaer@gmx.de) */ public class PrintQuality extends EnumSyntax implements DocAttribute, PrintJobAttribute, PrintRequestAttribute { private static final long serialVersionUID = -3072341285225858365L; - public static final PrintQuality DRAFT = new PrintQuality(0); - public static final PrintQuality NORMAL = new PrintQuality(1); - public static final PrintQuality HIGH = new PrintQuality(2); + /** + * Draft quality of the printer. + */ + public static final PrintQuality DRAFT = new PrintQuality(3); + + /** + * Normal quality of the printer. + */ + public static final PrintQuality NORMAL = new PrintQuality(4); + + /** + * High quality of the printer. + */ + public static final PrintQuality HIGH = new PrintQuality(5); + private static final String[] stringTable = { "draft", "normal", "high" }; + + private static final PrintQuality[] enumValueTable = { DRAFT, NORMAL, HIGH }; + /** * Constructs a <code>PrintQuality</code> object. + * + * @param value the value of the enum */ protected PrintQuality(int value) { @@ -66,7 +90,7 @@ public class PrintQuality extends EnumSyntax /** * Returns category of this class. * - * @return the class <code>PrintQuality</code> itself + * @return The class <code>PrintQuality</code> itself. */ public Class getCategory() { @@ -74,12 +98,43 @@ public class PrintQuality extends EnumSyntax } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "print-quality" + * @return The name "print-quality". */ public String getName() { return "print-quality"; } + + /** + * Returns a table with the enumeration values represented as strings + * for this object. + * + * @return The enumeration values as strings. + */ + protected String[] getStringTable() + { + return stringTable; + } + + /** + * Returns a table with the enumeration values for this object. + * + * @return The enumeration values. + */ + protected EnumSyntax[] getEnumValueTable() + { + return enumValueTable; + } + + /** + * Returns the lowest used value by the enumerations of this class. + * . + * @return The lowest value used. + */ + protected int getOffset() + { + return 3; + } } diff --git a/libjava/classpath/javax/print/attribute/standard/PrinterInfo.java b/libjava/classpath/javax/print/attribute/standard/PrinterInfo.java index 66199c4..2cd496c 100644 --- a/libjava/classpath/javax/print/attribute/standard/PrinterInfo.java +++ b/libjava/classpath/javax/print/attribute/standard/PrinterInfo.java @@ -1,5 +1,5 @@ /* PrinterInfo.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -44,6 +44,12 @@ import javax.print.attribute.PrintServiceAttribute; import javax.print.attribute.TextSyntax; /** + * The <code>PrinterInfo</code> printing attribute provides + * informations about a printer device. + * <p> + * <b>IPP Compatibility:</b> PrinterInfo is an IPP 1.1 attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) */ public final class PrinterInfo extends TextSyntax @@ -55,9 +61,10 @@ public final class PrinterInfo extends TextSyntax * Creates a <code>PrinterInfo</code> object. * * @param printerInfo the printer info - * @param locale the locale of the info, null means default locale + * @param locale the locale to use, if <code>null</code> the default + * locale is used. * - * @exception NullPointerException if printerInfo is null + * @exception NullPointerException if printerInfo is <code>null</code>. */ public PrinterInfo(String printerInfo, Locale locale) { @@ -65,11 +72,12 @@ public final class PrinterInfo extends TextSyntax } /** - * Tests of obj is equal to this object. + * Tests if the given object is equal to this object. * * @param obj the object to test * - * @return true if both objects are equal, false otherwise. + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. */ public boolean equals(Object obj) { @@ -82,7 +90,7 @@ public final class PrinterInfo extends TextSyntax /** * Returns category of this class. * - * @return the class <code>PrinterInfo</code> itself + * @return The class <code>PrinterInfo</code> itself. */ public Class getCategory() { @@ -90,9 +98,9 @@ public final class PrinterInfo extends TextSyntax } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "printer-info" + * @return The name "printer-info". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/PrinterIsAcceptingJobs.java b/libjava/classpath/javax/print/attribute/standard/PrinterIsAcceptingJobs.java index 19b555a..51f96c1 100644 --- a/libjava/classpath/javax/print/attribute/standard/PrinterIsAcceptingJobs.java +++ b/libjava/classpath/javax/print/attribute/standard/PrinterIsAcceptingJobs.java @@ -1,5 +1,5 @@ /* PrinterIsAcceptingJobs.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -42,20 +42,46 @@ import javax.print.attribute.PrintServiceAttribute; /** + * The <code>PrinterIsAcceptingJobs</code> printing attribute signals + * if a print services is currently accepting jobs. + * <p> + * <b>IPP Compatibility:</b> PrinterIsAcceptingJobs is an IPP 1.1 attribute. + * The IPP specification treats PrinterIsAcceptingJobs as boolean type which + * is not available in the Java Print Service API. The IPP boolean value "true" + * corresponds to <code>ACCEPTING_JOBS</code> and "false" + * to <code>NOT_ACCEPTING_JOBS</code>. + * </p> + * * @author Michael Koch (konqueror@gmx.de) + * @author Wolfgang Baer (WBaer@gmx.de) */ public class PrinterIsAcceptingJobs extends EnumSyntax implements PrintServiceAttribute { private static final long serialVersionUID = -5052010680537678061L; + /** + * The printer is not accepting jobs currently. + */ public static final PrinterIsAcceptingJobs NOT_ACCEPTING_JOBS = new PrinterIsAcceptingJobs(0); + + /** + * The printer is accepting jobs. + */ public static final PrinterIsAcceptingJobs ACCEPTING_JOBS = new PrinterIsAcceptingJobs(1); + private static final String[] stringTable = { "not-accepting-jobs", + "accepting-jobs" }; + + private static final PrinterIsAcceptingJobs[] enumValueTable = + { NOT_ACCEPTING_JOBS, ACCEPTING_JOBS }; + /** * Constructs a <code>PrinterIsAcceptingJobs</code> object. + * + * @param value the enum value. */ protected PrinterIsAcceptingJobs(int value) { @@ -65,7 +91,7 @@ public class PrinterIsAcceptingJobs extends EnumSyntax /** * Returns category of this class. * - * @return the class <code>PrinterIsAcceptingJobs</code> itself + * @return The class <code>PrinterIsAcceptingJobs</code> itself. */ public Class getCategory() { @@ -75,10 +101,31 @@ public class PrinterIsAcceptingJobs extends EnumSyntax /** * Returns the name of this attribute. * - * @return the name + * @return The name "printer-is-accepting-jobs". */ public String getName() { return "printer-is-accepting-jobs"; } + + /** + * Returns a table with the enumeration values represented as strings + * for this object. + * + * @return The enumeration values as strings. + */ + protected String[] getStringTable() + { + return stringTable; + } + + /** + * Returns a table with the enumeration values for this object. + * + * @return The enumeration values. + */ + protected EnumSyntax[] getEnumValueTable() + { + return enumValueTable; + } } diff --git a/libjava/classpath/javax/print/attribute/standard/PrinterLocation.java b/libjava/classpath/javax/print/attribute/standard/PrinterLocation.java index f342e8c..35b61e4 100644 --- a/libjava/classpath/javax/print/attribute/standard/PrinterLocation.java +++ b/libjava/classpath/javax/print/attribute/standard/PrinterLocation.java @@ -1,5 +1,5 @@ /* PrinterLocation.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -44,6 +44,12 @@ import javax.print.attribute.PrintServiceAttribute; import javax.print.attribute.TextSyntax; /** + * The <code>PrinterLocation</code> printing attribute provides the location + * of a printer device. This may be a room and building name for example. + * <p> + * <b>IPP Compatibility:</b> PrinterLocation is an IPP 1.1 attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) */ public final class PrinterLocation extends TextSyntax @@ -55,9 +61,10 @@ public final class PrinterLocation extends TextSyntax * Creates a <code>PrinterLocation</code> object. * * @param printerLocation the printer location - * @param locale the locale of the location, null means default locale + * @param locale the locale to use, if <code>null</code> the default + * locale is used. * - * @exception NullPointerException if printerLocation is null + * @exception NullPointerException if printerLocation is <code>null</code>. */ public PrinterLocation(String printerLocation, Locale locale) { @@ -65,11 +72,12 @@ public final class PrinterLocation extends TextSyntax } /** - * Tests of obj is equal to this object. + * Tests if the given object is equal to this object. * * @param obj the object to test * - * @return true if both objects are equal, false otherwise. + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. */ public boolean equals(Object obj) { @@ -82,7 +90,7 @@ public final class PrinterLocation extends TextSyntax /** * Returns category of this class. * - * @return the class <code>PrinterLocation</code> itself + * @return The class <code>PrinterLocation</code> itself. */ public Class getCategory() { @@ -90,9 +98,9 @@ public final class PrinterLocation extends TextSyntax } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "printer-location" + * @return The name "printer-location". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/PrinterMakeAndModel.java b/libjava/classpath/javax/print/attribute/standard/PrinterMakeAndModel.java index c3f3a63..7010746 100644 --- a/libjava/classpath/javax/print/attribute/standard/PrinterMakeAndModel.java +++ b/libjava/classpath/javax/print/attribute/standard/PrinterMakeAndModel.java @@ -1,5 +1,5 @@ /* PrinterMakeAndModel.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -44,6 +44,12 @@ import javax.print.attribute.PrintServiceAttribute; import javax.print.attribute.TextSyntax; /** + * The <code>PrinterMakeAndModel</code> printing attribute provides the name + * of the maker and the model of the printer. + * <p> + * <b>IPP Compatibility:</b> PrinterMakeAndModel is an IPP 1.1 attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) */ public final class PrinterMakeAndModel extends TextSyntax @@ -55,9 +61,10 @@ public final class PrinterMakeAndModel extends TextSyntax * Creates a <code>PrinterMakeAndModel</code> object. * * @param makeAndModel the make and model string - * @param locale the locale of the make and model, null means default locale + * @param locale the locale to use, if <code>null</code> the default + * locale is used. * - * @exception NullPointerException if makeAndModel is null + * @exception NullPointerException if makeAndModel is <code>null</code>. */ public PrinterMakeAndModel(String makeAndModel, Locale locale) { @@ -65,11 +72,12 @@ public final class PrinterMakeAndModel extends TextSyntax } /** - * Tests of obj is equal to this object. + * Tests if the given object is equal to this object. * * @param obj the object to test * - * @return true if both objects are equal, false otherwise. + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. */ public boolean equals(Object obj) { @@ -82,7 +90,7 @@ public final class PrinterMakeAndModel extends TextSyntax /** * Returns category of this class. * - * @return the class <code>PrinterMakeAndModel</code> itself + * @return The class <code>PrinterMakeAndModel</code> itself. */ public Class getCategory() { @@ -90,9 +98,9 @@ public final class PrinterMakeAndModel extends TextSyntax } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "printer-make-and-model" + * @return The name "printer-make-and-model". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/PrinterMessageFromOperator.java b/libjava/classpath/javax/print/attribute/standard/PrinterMessageFromOperator.java index d231eb2..b4f5d88 100644 --- a/libjava/classpath/javax/print/attribute/standard/PrinterMessageFromOperator.java +++ b/libjava/classpath/javax/print/attribute/standard/PrinterMessageFromOperator.java @@ -1,5 +1,5 @@ /* PrinterMessageFromOperator.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -44,6 +44,15 @@ import javax.print.attribute.PrintServiceAttribute; import javax.print.attribute.TextSyntax; /** + * The <code>PrinterMessageFromOperator</code> printing attribute provides + * a message from an operator or a system administrator related to the + * printer. This may include informations about the status of the printer + * or expected downtimes, etc. + * <p> + * <b>IPP Compatibility:</b> PrinterMessageFromOperator is an IPP 1.1 + * attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) */ public final class PrinterMessageFromOperator extends TextSyntax @@ -55,9 +64,10 @@ public final class PrinterMessageFromOperator extends TextSyntax * Creates a <code>PrinterMessageFromOperator</code> object. * * @param message the message - * @param locale the locale of the message, null means default locale + * @param locale the locale to use, if <code>null</code> the default + * locale is used. * - * @exception NullPointerException if message is null + * @exception NullPointerException if message is <code>null</code>. */ public PrinterMessageFromOperator(String message, Locale locale) { @@ -65,11 +75,12 @@ public final class PrinterMessageFromOperator extends TextSyntax } /** - * Tests of obj is equal to this object. + * Tests if the given object is equal to this object. * * @param obj the object to test * - * @return true if both objects are equal, false otherwise. + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. */ public boolean equals(Object obj) { @@ -82,7 +93,7 @@ public final class PrinterMessageFromOperator extends TextSyntax /** * Returns category of this class. * - * @return the class <code>PrinterMessageFromOperator</code> itself + * @return The class <code>PrinterMessageFromOperator</code> itself. */ public Class getCategory() { @@ -90,9 +101,9 @@ public final class PrinterMessageFromOperator extends TextSyntax } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "printer-message-from-operator" + * @return The name "printer-message-from-operator". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/PrinterMoreInfo.java b/libjava/classpath/javax/print/attribute/standard/PrinterMoreInfo.java index b0cf973..28abd4e 100644 --- a/libjava/classpath/javax/print/attribute/standard/PrinterMoreInfo.java +++ b/libjava/classpath/javax/print/attribute/standard/PrinterMoreInfo.java @@ -1,5 +1,5 @@ /* PrinterMoreInfo.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -44,7 +44,18 @@ import javax.print.attribute.PrintServiceAttribute; import javax.print.attribute.URISyntax; /** + * The <code>PrinterMoreInfo</code> attribute provides a URI that can be used + * to obtain more information about the printer. + * <p> + * The URI may for example contain a reference to a HTML page with information. + * The information is normally intended for end users. + * </p> + * <p> + * <b>IPP Compatibility:</b> PrinterMoreInfo is an IPP 1.1 attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) + * @author Wolfgang Baer (WBaer@gmx.de) */ public final class PrinterMoreInfo extends URISyntax implements PrintServiceAttribute @@ -53,16 +64,35 @@ public final class PrinterMoreInfo extends URISyntax /** * Constructs a <code>PrinterMoreInfo</code> object. + * + * @param uri the URI of the information. + * @throws NullPointerException if the given uri is null. */ public PrinterMoreInfo(URI uri) { super(uri); } + + /** + * Tests if the given object is equal to this object. + * + * @param obj the object to test + * + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. + */ + public boolean equals(Object obj) + { + if(! (obj instanceof PrinterMoreInfo)) + return false; + + return super.equals(obj); + } /** * Returns category of this class. * - * @return the class <code>PrinterMoreInfo</code> itself + * @return The class <code>PrinterMoreInfo</code> itself. */ public Class getCategory() { @@ -72,7 +102,7 @@ public final class PrinterMoreInfo extends URISyntax /** * Returns the name of this attribute. * - * @return the name + * @return The name "printer-more-info". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/PrinterMoreInfoManufacturer.java b/libjava/classpath/javax/print/attribute/standard/PrinterMoreInfoManufacturer.java index 0a39b86..df0232e 100644 --- a/libjava/classpath/javax/print/attribute/standard/PrinterMoreInfoManufacturer.java +++ b/libjava/classpath/javax/print/attribute/standard/PrinterMoreInfoManufacturer.java @@ -1,5 +1,5 @@ /* PrinterMoreInfoManufacturer.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -44,7 +44,22 @@ import javax.print.attribute.PrintServiceAttribute; import javax.print.attribute.URISyntax; /** + * The <code>PrinterMoreInfoManufacturer</code> attribute provides a URI that + * can be used to obtain more information about the printer device type and + * its manufacturer. + * <p> + * The URI may for example contain a reference to a website of the + * manufacturer, containing informations and links to the latest firmware, + * printer drivers, manual etc. The information is normally intended for + * end users. + * </p> + * <p> + * <b>IPP Compatibility:</b> PrinterMoreInfoManufacturer is an IPP 1.1 + * attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) + * @author Wolfgang Baer (WBaer@gmx.de) */ public final class PrinterMoreInfoManufacturer extends URISyntax implements PrintServiceAttribute @@ -53,16 +68,35 @@ public final class PrinterMoreInfoManufacturer extends URISyntax /** * Constructs a <code>PrinterMoreInfoManufacturer</code> object. + * + * @param uri the URI of the information.. + * @throws NullPointerException if the given uri is null. */ public PrinterMoreInfoManufacturer(URI uri) { super(uri); } + + /** + * Tests if the given object is equal to this object. + * + * @param obj the object to test + * + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. + */ + public boolean equals(Object obj) + { + if(! (obj instanceof PrinterMoreInfoManufacturer)) + return false; + + return super.equals(obj); + } /** * Returns category of this class. * - * @return the class <code>PrinterMoreInfoManufacturer</code> itself + * @return The class <code>PrinterMoreInfoManufacturer</code> itself. */ public Class getCategory() { @@ -72,7 +106,7 @@ public final class PrinterMoreInfoManufacturer extends URISyntax /** * Returns the name of this attribute. * - * @return the name + * @return The name "printer-more-info-manufacturer". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/PrinterName.java b/libjava/classpath/javax/print/attribute/standard/PrinterName.java index d3b495b..5b7da60 100644 --- a/libjava/classpath/javax/print/attribute/standard/PrinterName.java +++ b/libjava/classpath/javax/print/attribute/standard/PrinterName.java @@ -1,5 +1,5 @@ /* PrinterName.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -44,6 +44,14 @@ import javax.print.attribute.PrintServiceAttribute; import javax.print.attribute.TextSyntax; /** + * The <code>PrinterName</code> printing attribute provides the name of a + * print service. The name may but must not be related to parts of the + * printer URI. + * <p> + * <b>IPP Compatibility:</b> PrinterName is an IPP 1.1 attribute. + * </p> + * @see javax.print.attribute.standard.PrinterURI + * * @author Michael Koch (konqueror@gmx.de) */ public final class PrinterName extends TextSyntax @@ -55,9 +63,10 @@ public final class PrinterName extends TextSyntax * Creates a <code>PrinterName</code> object. * * @param printerName the printer name - * @param locale the locale of the name, null means default locale + * @param locale the locale to use, if <code>null</code> the default + * locale is used. * - * @exception NullPointerException if printerName is null + * @exception NullPointerException if printerName is <code>null</code>. */ public PrinterName(String printerName, Locale locale) { @@ -65,11 +74,12 @@ public final class PrinterName extends TextSyntax } /** - * Tests of obj is equal to this object. + * Tests if the given object is equal to this object. * * @param obj the object to test * - * @return true if both objects are equal, false otherwise. + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. */ public boolean equals(Object obj) { @@ -82,7 +92,7 @@ public final class PrinterName extends TextSyntax /** * Returns category of this class. * - * @return the class <code>PrinterName</code> itself + * @return The class <code>PrinterName</code> itself. */ public Class getCategory() { @@ -90,9 +100,9 @@ public final class PrinterName extends TextSyntax } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "printer-name" + * @return The name "printer-name". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/PrinterResolution.java b/libjava/classpath/javax/print/attribute/standard/PrinterResolution.java index 6a237a8..f4cde0f 100644 --- a/libjava/classpath/javax/print/attribute/standard/PrinterResolution.java +++ b/libjava/classpath/javax/print/attribute/standard/PrinterResolution.java @@ -1,5 +1,5 @@ -/* PrinterMoreInfoManufacturer.java -- - Copyright (C) 2004 Free Software Foundation, Inc. +/* PrinterResolution.java -- + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -44,7 +44,14 @@ import javax.print.attribute.ResolutionSyntax; /** + * The <code>PrinterResolution</code> printing attribute specifies a + * resolution supported by a print service or to be used by a print job. + * <p> + * <b>IPP Compatibility:</b> PrinterResolution is an IPP 1.1 attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) + * @author Wolfgang Baer (WBaer@gmx.de) */ public final class PrinterResolution extends ResolutionSyntax implements DocAttribute, PrintJobAttribute, PrintRequestAttribute @@ -52,18 +59,41 @@ public final class PrinterResolution extends ResolutionSyntax private static final long serialVersionUID = 13090306561090558L; /** - * Constructs a <code>PrinterResolution</code> object. + * Creates a <code>PrinterResolution</code> object with the given cross + * feed and feed resolutions. + * + * @param crossFeedResolution the cross feed resolution + * @param feedResolution the feed resolution + * @param units the unit to use (e.g. {@link #DPCM} or {@link #DPI}) + * + * @exception IllegalArgumentException if either parameter is < 1 */ public PrinterResolution(int crossFeedResolution, int feedResolution, int units) { super(crossFeedResolution, feedResolution, units); } + + /** + * Tests if the given object is equal to this object. + * + * @param obj the object to test + * + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. + */ + public boolean equals(Object obj) + { + if(! (obj instanceof PrinterResolution)) + return false; + + return super.equals(obj); + } /** * Returns category of this class. * - * @return the class <code>PrinterResolution</code> itself + * @return The class <code>PrinterResolution</code> itself. */ public Class getCategory() { @@ -73,7 +103,7 @@ public final class PrinterResolution extends ResolutionSyntax /** * Returns the name of this attribute. * - * @return the name + * @return The name "printer-resolution". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/PrinterState.java b/libjava/classpath/javax/print/attribute/standard/PrinterState.java index 28d78cd..6fd4c3f 100644 --- a/libjava/classpath/javax/print/attribute/standard/PrinterState.java +++ b/libjava/classpath/javax/print/attribute/standard/PrinterState.java @@ -1,5 +1,5 @@ /* PrinterState.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -42,20 +42,61 @@ import javax.print.attribute.PrintServiceAttribute; /** + * The <code>PrinterState</code> printing attribute reports + * the current state of the printer device. + * <p> + * The {@link javax.print.attribute.standard.PrinterStateReasons} + * attribute provides further detailed information about + * the given printer state. Detailed information about the printer + * state and printer state reasons attributes can be found in the + * RFC 2911. + * </p> + * <p> + * <b>IPP Compatibility:</b> PrinterState is an IPP 1.1 attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) + * @author Wolfgang Baer (WBaer@gmx.de) */ public final class PrinterState extends EnumSyntax implements PrintServiceAttribute { private static final long serialVersionUID = -649578618346507718L; + /** + * The state is unknown currently. + */ public static final PrinterState UNKNOWN = new PrinterState(0); - public static final PrinterState IDLE = new PrinterState(1); - public static final PrinterState PROCESSING = new PrinterState(2); - public static final PrinterState STOPPED = new PrinterState(3); + + /** + * The printer device is in idle state. New jobs can start + * processing without waiting. + */ + public static final PrinterState IDLE = new PrinterState(3); + + /** + * The printer device is in processing state. + */ + public static final PrinterState PROCESSING = new PrinterState(4); + + /** + * The printer device has stopped. No jobs can be processed and + * normally manual intervention is needed. + */ + public static final PrinterState STOPPED = new PrinterState(5); + private static final String[] stringTable = { "unknown", null, null, + "idle", "processing", + "stopped" }; + + private static final PrinterState[] enumValueTable = { UNKNOWN, null, null, + IDLE, PROCESSING, + STOPPED }; + /** * Constructs a <code>PrinterState</code> object. + * + * @param value the enum value. */ protected PrinterState(int value) { @@ -65,7 +106,7 @@ public final class PrinterState extends EnumSyntax /** * Returns category of this class. * - * @return the class <code>PrinterState</code> itself + * @return The class <code>PrinterState</code> itself. */ public Class getCategory() { @@ -75,10 +116,31 @@ public final class PrinterState extends EnumSyntax /** * Returns the name of this attribute. * - * @return the name + * @return The name "printer-state". */ public String getName() { return "printer-state"; } + + /** + * Returns a table with the enumeration values represented as strings + * for this object. + * + * @return The enumeration values as strings. + */ + protected String[] getStringTable() + { + return stringTable; + } + + /** + * Returns a table with the enumeration values for this object. + * + * @return The enumeration values. + */ + protected EnumSyntax[] getEnumValueTable() + { + return enumValueTable; + } } diff --git a/libjava/classpath/javax/print/attribute/standard/PrinterStateReason.java b/libjava/classpath/javax/print/attribute/standard/PrinterStateReason.java index 847395e..3a13585 100644 --- a/libjava/classpath/javax/print/attribute/standard/PrinterStateReason.java +++ b/libjava/classpath/javax/print/attribute/standard/PrinterStateReason.java @@ -1,5 +1,5 @@ /* PrinterStateReason.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -42,76 +42,246 @@ import javax.print.attribute.Attribute; import javax.print.attribute.EnumSyntax; /** + * The <code>PrinterStateReason</code> attribute provides additional + * information about the current state of the printer device. Its always part + * of the {@link javax.print.attribute.standard.PrinterStateReasons} + * printing attribute. + * <p> + * <b>IPP Compatibility:</b> PrinterStateReason is not an IPP 1.1 + * attribute itself but used inside the <code>PrinterStateReasons</code> + * attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) + * @author Wolfgang Baer (WBaer@gmx.de) */ public class PrinterStateReason extends EnumSyntax implements Attribute { private static final long serialVersionUID = -1623720656201472593L; + /** + * Any state other state not listed here. + */ public static final PrinterStateReason OTHER = new PrinterStateReason(0); + + /** + * A media tray has run out of media. + */ public static final PrinterStateReason MEDIA_NEEDED = new PrinterStateReason(1); + + /** + * A media jam occured in the printer device. + */ public static final PrinterStateReason MEDIA_JAM = new PrinterStateReason(2); + + /** + * Indicates that the printer has been paused by the pause printer + * operation and is currently moving to the pause state. + */ public static final PrinterStateReason MOVING_TO_PAUSED = new PrinterStateReason(3); + + /** + * The printer device has be paused by the pause printer operation. + */ public static final PrinterStateReason PAUSED = new PrinterStateReason(4); + + /** + * The printer device has been shutdown or removed from service. + */ public static final PrinterStateReason SHUTDOWN = new PrinterStateReason(5); + + /** + * The printer object is connecting to the device. If a printer + * device is on the network the printer object may be unable to connect. + */ public static final PrinterStateReason CONNECTING_TO_DEVICE = new PrinterStateReason(6); + + /** + * The connection to the device has timed out. + */ public static final PrinterStateReason TIMED_OUT = new PrinterStateReason(7); + + /** + * The printer object is stopping the printer device. + */ public static final PrinterStateReason STOPPING = new PrinterStateReason(8); + + /** + * The printer object has stopped partly. A printer object may control + * several physical output devices (e.g. a printer class in CUPS) and + * stop only some of the devices. + */ public static final PrinterStateReason STOPPED_PARTLY = new PrinterStateReason(9); + + /** + * The printer device is low on toner. + */ public static final PrinterStateReason TONER_LOW = new PrinterStateReason(10); + + /** + * The printer device is out of toner. + */ public static final PrinterStateReason TONER_EMPTY = new PrinterStateReason(11); + + /** + * The printers spool area is currently full. The printer is + * currently not able to accept jobs. + */ public static final PrinterStateReason SPOOL_AREA_FULL = new PrinterStateReason(12); + + /** + * One or more covers of the printer device are open. + */ public static final PrinterStateReason COVER_OPEN = new PrinterStateReason(13); + + /** + * One or more interlocks of the printer device are open. + */ public static final PrinterStateReason INTERLOCK_OPEN = new PrinterStateReason(14); + + /** + * One or more doors of the printer device are open. + */ public static final PrinterStateReason DOOR_OPEN = new PrinterStateReason(15); + + /** + * One or more input trays are missing in the printer device. + */ public static final PrinterStateReason INPUT_TRAY_MISSING = new PrinterStateReason(16); + + /** + * The printer device is low on media. + */ public static final PrinterStateReason MEDIA_LOW = new PrinterStateReason(17); + + /** + * The printer device is out of media. + */ public static final PrinterStateReason MEDIA_EMPTY = new PrinterStateReason(18); + + /** + * One or more output trays are missing in the printer device. + */ public static final PrinterStateReason OUTPUT_TRAY_MISSING = new PrinterStateReason(19); + + /** + * One or more output areas of the printer device are almost full. + */ public static final PrinterStateReason OUTPUT_AREA_ALMOST_FULL = new PrinterStateReason(20); + + /** + * One or more output areas of the printer device are full. + */ public static final PrinterStateReason OUTPUT_AREA_FULL = new PrinterStateReason(21); + + /** + * The printer device is low on marker supply. + */ public static final PrinterStateReason MARKER_SUPPLY_LOW = new PrinterStateReason(22); + + /** + * The printer device is out of marker supply. + */ public static final PrinterStateReason MARKER_SUPPLY_EMPTY = new PrinterStateReason(23); + + /** + * The marker waste bin of the printer device is almost full. + */ public static final PrinterStateReason MARKER_WASTE_ALMOST_FULL = new PrinterStateReason(24); + + /** + * The marker waste bin of the printer device is full. + */ public static final PrinterStateReason MARKER_WASTE_FULL = new PrinterStateReason(25); + + /** + * The fuser of the printer device is over temperature. + */ public static final PrinterStateReason FUSER_OVER_TEMP = new PrinterStateReason(26); + + /** + * The fuser of the printer device is under the needed temperature. + */ public static final PrinterStateReason FUSER_UNDER_TEMP = new PrinterStateReason(27); + + /** + * The optical photo conductor is near its end of life (EOL). + */ public static final PrinterStateReason OPC_NEAR_EOL = new PrinterStateReason(28); + + /** + * The optical photo conductor has reached its end of life. + */ public static final PrinterStateReason OPC_LIFE_OVER = new PrinterStateReason(29); + + /** + * The printer device is low on developer. + */ public static final PrinterStateReason DEVELOPER_LOW = new PrinterStateReason(30); + + /** + * The printer device is out of developer. + */ public static final PrinterStateReason DEVELOPER_EMPTY = new PrinterStateReason(31); + + /** + * An interpreter resource (e.g. font) is unavailable. + */ public static final PrinterStateReason INTERPRETER_RESOURCE_UNAVAILABLE = new PrinterStateReason(32); + private static final String[] stringTable = + { "other", "media-needed", "media-jam", "moving-to-paused", "paused", + "shutdown", "connecting-to-device", "timed-out", "stopping", + "stopped-partly", "toner-low", "toner-empty", "spool-area-full", + "cover-open", "interlock-open", "door-open", "input-tray-missing", + "media-low", "media-empty", "output-tray-missing", "output-area-almost-full", + "output-area-full", "marker-supply-low", "marker-supply-empty", + "marker-waste-almost-full", "marker-waste-full", "fuser-over-temp", + "fuser-under-temp", "opc-near-eol", "opc-life-over", "developer-low", + "developer-empty", "interpreter-resource-unavailable" }; + + private static final PrinterStateReason[] enumValueTable = + { OTHER, MEDIA_NEEDED, MEDIA_JAM, MOVING_TO_PAUSED, PAUSED, SHUTDOWN, + CONNECTING_TO_DEVICE, TIMED_OUT, STOPPING, STOPPED_PARTLY, TONER_LOW, + TONER_EMPTY, SPOOL_AREA_FULL, COVER_OPEN, INTERLOCK_OPEN, DOOR_OPEN, + INPUT_TRAY_MISSING, MEDIA_LOW, MEDIA_EMPTY, OUTPUT_TRAY_MISSING, + OUTPUT_AREA_ALMOST_FULL, OUTPUT_AREA_FULL, MARKER_SUPPLY_LOW, + MARKER_SUPPLY_EMPTY, MARKER_WASTE_ALMOST_FULL, MARKER_WASTE_FULL, + FUSER_OVER_TEMP, FUSER_UNDER_TEMP, OPC_NEAR_EOL, OPC_LIFE_OVER, + DEVELOPER_LOW, DEVELOPER_EMPTY, INTERPRETER_RESOURCE_UNAVAILABLE }; + /** * Constructs a <code>PrinterStateReason</code> object. + * + * @param value the enum value. */ protected PrinterStateReason(int value) { @@ -121,7 +291,7 @@ public class PrinterStateReason extends EnumSyntax /** * Returns category of this class. * - * @return the class <code>PrintStateReason</code> itself + * @return The class <code>PrintStateReason</code> itself. */ public Class getCategory() { @@ -129,12 +299,33 @@ public class PrinterStateReason extends EnumSyntax } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "printer-state-reason" + * @return The name "printer-state-reason". */ public String getName() { return "printer-state-reason"; } + + /** + * Returns a table with the enumeration values represented as strings + * for this object. + * + * @return The enumeration values as strings. + */ + protected String[] getStringTable() + { + return stringTable; + } + + /** + * Returns a table with the enumeration values for this object. + * + * @return The enumeration values. + */ + protected EnumSyntax[] getEnumValueTable() + { + return enumValueTable; + } } diff --git a/libjava/classpath/javax/print/attribute/standard/PrinterStateReasons.java b/libjava/classpath/javax/print/attribute/standard/PrinterStateReasons.java index d81313f..67f160d 100644 --- a/libjava/classpath/javax/print/attribute/standard/PrinterStateReasons.java +++ b/libjava/classpath/javax/print/attribute/standard/PrinterStateReasons.java @@ -1,5 +1,5 @@ /* PrinterStateReasons.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,12 +38,35 @@ exception statement from your version. */ package javax.print.attribute.standard; +import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; import javax.print.attribute.PrintServiceAttribute; /** + * The <code>PrinterStateReasons</code> attribute provides the set of + * additional informations available about the current state of the printer + * device. + * <p> + * The attribute is basically a map with <code>PrinterStateReason</code> + * objects as keys associated with their severity level as + * <code>Severity</code> instances. The IPP keyword value can be + * constructed as follows: <br> + * <code>reason.toString() + '-' + severity.toString()</code> + * </p> + * <p> + * <b>IPP Compatibility:</b> PrinterStateReasons is an IPP 1.1 attribute. + * </p> + * @see javax.print.attribute.standard.PrinterState + * @see javax.print.attribute.standard.PrinterStateReason + * @see javax.print.attribute.standard.Severity + * * @author Michael Koch (konqueror@gmx.de) + * @author Wolfgang Baer (WBaer@gmx.de) */ public final class PrinterStateReasons extends HashMap implements PrintServiceAttribute @@ -51,9 +74,117 @@ public final class PrinterStateReasons extends HashMap private static final long serialVersionUID = -3731791085163619457L; /** + * Constructs an empty <code>PrinterStateReasons</code> attribute. + */ + public PrinterStateReasons() + { + super(); + } + + /** + * Constructs an empty <code>PrinterStateReasons</code> attribute + * with the given initial capacity and load factor. + * + * @param initialCapacity the intial capacity. + * @param loadFactor the load factor of the underlying HashMap. + * + * @throws IllegalArgumentException if initialCapacity < 0 + * @throws IllegalArgumentException if initialCapacity or loadFactor < 0 + */ + public PrinterStateReasons(int initialCapacity, float loadFactor) + { + super(initialCapacity, loadFactor); + } + + /** + * Constructs an empty <code>PrinterStateReasons</code> attribute + * with the given initial capacity and the default load factor. + * + * @param initialCapacity the intial capacity. + * + * @throws IllegalArgumentException if initialCapacity < 0 + */ + public PrinterStateReasons(int initialCapacity) + { + super(initialCapacity); + } + + /** + * Constructs a <code>PrinterStateReasons</code> attribute + * with the given content of the map. + * + * @param map the map for the initial values with the same + * <code>PrinterStateReason</code> to <code>Severity</code> mappings. + * + * @throws NullPointerException if map or any key/value is <code>null</code>. + * @throws ClassCastException if values of map are not of type + * <code>PrinterStateReason</code> and keys are not of type + * <code>Severity</code>. + */ + public PrinterStateReasons(Map map) + { + super(map.size(), 0.75f); + Iterator it = map.entrySet().iterator(); + while (it.hasNext()) + { + Map.Entry entry = (Map.Entry) it.next(); + put(entry.getKey(), entry.getValue()); + } + } + + /** + * Constructs an unmodifiable view of the contained printer state reasons + * associated with the given severity level. + * + * @param severity the severity level for the constructed set. + * @return The set of printer state reasons. + */ + public Set printerStateReasonSet(Severity severity) + { + if (severity == null) + throw new NullPointerException("severity is null"); + + HashSet set = new HashSet(); + Iterator it = entrySet().iterator(); + while (it.hasNext()) + { + Map.Entry entry = (Map.Entry) it.next(); + if (entry.getValue().equals(severity)) + set.add(entry.getKey()); + } + + return Collections.unmodifiableSet(set); + } + + /** + * Puts the given reason object associated with the given severity object + * into the set. + * + * @param reason the reason of type <code>PrinterStateReason</code>. + * @param severity the severity of the reason of type <code>Severity</code>. + * + * @return The previously associated severity of the reason or + * <code>null</code> if the reason object was not in the map before. + * + * @throws NullPointerException if any of the values is <code>null</code>. + * @throws ClassCastException if reason is not a + * <code>PrinterStateReason</code> and severity is not a + * <code>Severity</code> instance. + */ + public Object put(Object reason, Object severity) + { + if (reason == null) + throw new NullPointerException("reason is null"); + if (severity == null) + throw new NullPointerException("severity is null"); + + return put((PrinterStateReason) reason, (Severity) severity); + } + + /** * Returns category of this class. * - * @return the class <code>PrintStateReasons</code> itself + * @return The class <code>PrintStateReasons</code> itself. */ public Class getCategory() { @@ -61,9 +192,9 @@ public final class PrinterStateReasons extends HashMap } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "printer-state-reasons" + * @return The name "printer-state-reasons". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/PrinterURI.java b/libjava/classpath/javax/print/attribute/standard/PrinterURI.java index e4c89a5..0deca90 100644 --- a/libjava/classpath/javax/print/attribute/standard/PrinterURI.java +++ b/libjava/classpath/javax/print/attribute/standard/PrinterURI.java @@ -1,5 +1,5 @@ /* PrinterURI.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -44,7 +44,18 @@ import javax.print.attribute.PrintServiceAttribute; import javax.print.attribute.URISyntax; /** + * The <code>PrinterURI</code> attribute provides the URI of a printer. + * <p> + * The URI identifies the printer against all the other print services + * available. This attribute is used to direct a print service request + * to this specific printer. + * </p> + * <p> + * <b>IPP Compatibility:</b> PrinterURI is an IPP 1.1 attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) + * @author Wolfgang Baer (WBaer@gmx.de) */ public final class PrinterURI extends URISyntax implements PrintServiceAttribute @@ -53,16 +64,35 @@ public final class PrinterURI extends URISyntax /** * Constructs a <code>PrinterURI</code> object. + * + * @param uri the URI of the print service. + * @throws NullPointerException if the given uri is null. */ public PrinterURI(URI uri) { super(uri); } + + /** + * Tests if the given object is equal to this object. + * + * @param obj the object to test + * + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. + */ + public boolean equals(Object obj) + { + if(! (obj instanceof PrinterURI)) + return false; + + return super.equals(obj); + } /** * Returns category of this class. * - * @return the class <code>PrinterURI</code> itself + * @return The class <code>PrinterURI</code> itself. */ public Class getCategory() { @@ -70,9 +100,9 @@ public final class PrinterURI extends URISyntax } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "printer-uri" + * @return The name "printer-uri". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/QueuedJobCount.java b/libjava/classpath/javax/print/attribute/standard/QueuedJobCount.java index 7ee0f7c3..8ff46a9 100644 --- a/libjava/classpath/javax/print/attribute/standard/QueuedJobCount.java +++ b/libjava/classpath/javax/print/attribute/standard/QueuedJobCount.java @@ -1,5 +1,5 @@ /* QueuedJobCount.java -- - Copyright (C) 2003 Free Software Foundation, Inc. + Copyright (C) 2003, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -41,6 +41,15 @@ import javax.print.attribute.IntegerSyntax; import javax.print.attribute.PrintServiceAttribute; /** + * The <code>QueuedJobCount</code> printing attribute reports + * the number of jobs currently in the queue. These are jobs + * that are in 'pending', 'processing', 'pending-held' or + * 'processing-stopped' state. + * <p> + * <b>IPP Compatibility:</b> QueuedJobCount is an IPP 1.1 attribute. + * </p> + * @see javax.print.attribute.standard.JobState + * * @author Michael Koch */ public final class QueuedJobCount extends IntegerSyntax @@ -53,7 +62,7 @@ public final class QueuedJobCount extends IntegerSyntax * * @param value the number of queued jobs * - * @exception IllegalArgumentException if value < 0 + * @exception IllegalArgumentException if value < 0 */ public QueuedJobCount(int value) { @@ -64,11 +73,12 @@ public final class QueuedJobCount extends IntegerSyntax } /** - * Tests of obj is equal to this object. + * Tests if the given object is equal to this object. * * @param obj the object to test * - * @return true if both objects are equal, false otherwise. + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. */ public boolean equals(Object obj) { @@ -81,7 +91,7 @@ public final class QueuedJobCount extends IntegerSyntax /** * Returns category of this class. * - * @return the class <code>QueuedJobCount</code> itself + * @return The class <code>QueuedJobCount</code> itself. */ public Class getCategory() { @@ -89,9 +99,9 @@ public final class QueuedJobCount extends IntegerSyntax } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "queued-job-count" + * @return The name "queued-job-count". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/ReferenceUriSchemesSupported.java b/libjava/classpath/javax/print/attribute/standard/ReferenceUriSchemesSupported.java index b4c0d94..8a00218 100644 --- a/libjava/classpath/javax/print/attribute/standard/ReferenceUriSchemesSupported.java +++ b/libjava/classpath/javax/print/attribute/standard/ReferenceUriSchemesSupported.java @@ -1,5 +1,5 @@ /* ReferenceUriSchemesSupported.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -42,33 +42,82 @@ import javax.print.attribute.EnumSyntax; /** + * The <code>ReferenceUriSchemesSupported</code> attribute provides + * the supported URI schemes (e.g. ftp) which are supported by the + * printer service to be used as uri reference for document data. + * <p> + * <b>IPP Compatibility:</b> ReferenceUriSchemesSupported is an IPP 1.1 + * attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) + * @author Wolfgang Baer (WBaer@gmx.de) */ public class ReferenceUriSchemesSupported extends EnumSyntax implements Attribute { private static final long serialVersionUID = -8989076942813442805L; + /** + * The file transfer protocol (FTP). + */ public static final ReferenceUriSchemesSupported FTP = new ReferenceUriSchemesSupported(0); + + /** + * The hyper text transfer protocol (HTTP). + */ public static final ReferenceUriSchemesSupported HTTP = new ReferenceUriSchemesSupported(1); + + /** + * The secure hyper text transfer protocol (HTTPS). + */ public static final ReferenceUriSchemesSupported HTTPS = new ReferenceUriSchemesSupported(2); + + /** + * The gopher protocol. + */ public static final ReferenceUriSchemesSupported GOPHER = new ReferenceUriSchemesSupported(3); + + /** + * The USENET news - RFC 1738. + */ public static final ReferenceUriSchemesSupported NEWS = new ReferenceUriSchemesSupported(4); + + /** + * The network news transfer protocol (NNTP) - RFC 1738. + */ public static final ReferenceUriSchemesSupported NNTP = new ReferenceUriSchemesSupported(5); + + /** + * The wide area information server protocol (WAIS) - RFC 4156. + */ public static final ReferenceUriSchemesSupported WAIS = new ReferenceUriSchemesSupported(6); + + /** + * A filename specific to the host. + */ public static final ReferenceUriSchemesSupported FILE = new ReferenceUriSchemesSupported(7); - /** - * Constructs a <code>ReferenceUriSchemeSupported</code> object. - */ + private static final String[] stringTable = { "ftp", "http", "https", + "gopher", "news", "nntp", + "wais", "file" }; + + private static final ReferenceUriSchemesSupported[] enumValueTable = + { FTP, HTTP, HTTPS, GOPHER, NEWS, NNTP, WAIS, FILE }; + + /** + * Constructs a <code>ReferenceUriSchemeSupported</code> object. + * + * @param value the enum value. + */ protected ReferenceUriSchemesSupported(int value) { super(value); @@ -77,7 +126,7 @@ public class ReferenceUriSchemesSupported extends EnumSyntax /** * Returns category of this class. * - * @return the class <code>ReferenceUriSchemesSupported</code> itself + * @return The class <code>ReferenceUriSchemesSupported</code> itself. */ public Class getCategory() { @@ -85,12 +134,33 @@ public class ReferenceUriSchemesSupported extends EnumSyntax } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "reference-uri-schemes-supported" + * @return The name "reference-uri-schemes-supported". */ public String getName() { return "reference-uri-schemes-supported"; } + + /** + * Returns a table with the enumeration values represented as strings + * for this object. + * + * @return The enumeration values as strings. + */ + protected String[] getStringTable() + { + return stringTable; + } + + /** + * Returns a table with the enumeration values for this object. + * + * @return The enumeration values. + */ + protected EnumSyntax[] getEnumValueTable() + { + return enumValueTable; + } } diff --git a/libjava/classpath/javax/print/attribute/standard/RequestingUserName.java b/libjava/classpath/javax/print/attribute/standard/RequestingUserName.java index bca7fbb..8b94703 100644 --- a/libjava/classpath/javax/print/attribute/standard/RequestingUserName.java +++ b/libjava/classpath/javax/print/attribute/standard/RequestingUserName.java @@ -1,5 +1,5 @@ /* RequestingUserName.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -44,6 +44,12 @@ import javax.print.attribute.PrintRequestAttribute; import javax.print.attribute.TextSyntax; /** + * The <code>RequestingUserName</code> attribute provides the name of + * the user which requests the printing of the given job. + * <p> + * <b>IPP Compatibility:</b> RequestingUserName is an IPP 1.1 attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) */ public final class RequestingUserName extends TextSyntax @@ -54,10 +60,11 @@ public final class RequestingUserName extends TextSyntax /** * Creates a <code>RequestingUserName</code> object. * - * @param userName the job name - * @param locale the locale of the user, null means default locale + * @param userName the user name + * @param locale the locale to use, if <code>null</code> the default + * locale is used. * - * @exception NullPointerException if userName is null + * @exception NullPointerException if userName is <code>null</code>. */ public RequestingUserName(String userName, Locale locale) { @@ -65,11 +72,12 @@ public final class RequestingUserName extends TextSyntax } /** - * Tests of obj is equal to this object. + * Tests if the given object is equal to this object. * * @param obj the object to test * - * @return true if both objects are equal, false otherwise. + * @return <code>true</code> if both objects are equal, + * <code>false</code> otherwise. */ public boolean equals(Object obj) { @@ -82,7 +90,7 @@ public final class RequestingUserName extends TextSyntax /** * Returns category of this attribute. * - * @return the class <code>RequestingUserName</code> itself + * @return The class <code>RequestingUserName</code> itself. */ public Class getCategory() { @@ -90,9 +98,9 @@ public final class RequestingUserName extends TextSyntax } /** - * Returns name of this attribute. + * Returns the name of this attribute. * - * @return the string "requesting-user-name" + * @return The name "requesting-user-name". */ public String getName() { diff --git a/libjava/classpath/javax/print/attribute/standard/Severity.java b/libjava/classpath/javax/print/attribute/standard/Severity.java index c34ed3e..5569816 100644 --- a/libjava/classpath/javax/print/attribute/standard/Severity.java +++ b/libjava/classpath/javax/print/attribute/standard/Severity.java @@ -1,5 +1,5 @@ /* Severity.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -42,19 +42,50 @@ import javax.print.attribute.EnumSyntax; /** + * The <code>Severity</code> printing attribute specifies the severity + * for a <code>PrinterStateReason</code> attribute. + * <p> + * This attribute does not appear in the attribute set of a print service + * itself. Its used inside the <code>PrinterStateReasons</code> + * attribute which contains <code>PrinterStateReason</code> objects which + * informs about the print service's status. + * </p> + * <p> + * <b>IPP Compatibility:</b> Severity is not an IPP attribute on its own + * but used in the PrinterStateReason attribute to indicate the severity. + * </p> + * * @author Michael Koch (konqueror@gmx.de) + * @author Wolfgang Baer (WBaer@gmx.de) */ public final class Severity extends EnumSyntax implements Attribute { private static final long serialVersionUID = 8781881462717925380L; + /** + * Indicates that the reason is a report. + */ public static final Severity REPORT = new Severity(0); + + /** + * Indicates that the reason is a warning. + */ public static final Severity WARNING = new Severity(1); + + /** + * Indicates that the reason is an error. + */ public static final Severity ERROR = new Severity(2); + private static final String[] stringTable = { "report", "warning", "error" }; + + private static final Severity[] enumValueTable = { REPORT, WARNING, ERROR }; + /** * Constructs a <code>Severity</code> object. + * + * @param value the enum value. */ protected Severity(int value) { @@ -64,7 +95,7 @@ public final class Severity extends EnumSyntax /** * Returns category of this class. * - * @return the class <code>Severity</code> itself + * @return The class <code>Severity</code> itself. */ public Class getCategory() { @@ -72,12 +103,33 @@ public final class Severity extends EnumSyntax } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "severity" + * @return The name "severity". */ public String getName() { return "severity"; } + + /** + * Returns a table with the enumeration values represented as strings + * for this object. + * + * @return The enumeration values as strings. + */ + protected String[] getStringTable() + { + return stringTable; + } + + /** + * Returns a table with the enumeration values for this object. + * + * @return The enumeration values. + */ + protected EnumSyntax[] getEnumValueTable() + { + return enumValueTable; + } } diff --git a/libjava/classpath/javax/print/attribute/standard/SheetCollate.java b/libjava/classpath/javax/print/attribute/standard/SheetCollate.java index a4e31f4..5343bc6 100644 --- a/libjava/classpath/javax/print/attribute/standard/SheetCollate.java +++ b/libjava/classpath/javax/print/attribute/standard/SheetCollate.java @@ -1,5 +1,5 @@ /* SheetCollate.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -44,16 +44,49 @@ import javax.print.attribute.PrintRequestAttribute; /** + * The <code>SheetCollate</code> printing attribute specifies + * whether or not the sheets of each copy in a print job have to be + * in sequence. + * <p> + * The attribute only makes sense if multiple copies are specified through + * the <code>Copies</code> printing attribute. If <code>UNCOLLATED</code> + * is specified every page of a print job is printed for all requested + * copies before the next page is processed. <code>COLLATED</code> means + * that for every copy requested the pages have to be printed in sequence. + * </p> + * <p> + * <b>IPP Compatibility:</b> SheetCollate is not an IPP 1.1 attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) + * @author Wolfgang Baer (WBaer@gmx.de) */ public final class SheetCollate extends EnumSyntax implements DocAttribute, PrintRequestAttribute, PrintJobAttribute { private static final long serialVersionUID = 7080587914259873003L; + /** + * The sheets of the different copies are uncollated. + */ public static final SheetCollate UNCOLLATED = new SheetCollate(0); + + /** + * The sheets of the different copies are collated. + */ public static final SheetCollate COLLATED = new SheetCollate(1); + + private static final String[] stringTable = { "uncollated", "collated" }; + + private static final SheetCollate[] enumValueTable = { UNCOLLATED, + COLLATED }; + + /** + * Creates a <code>SheetCollate</code> object. + * + * @param value the enum value. + */ protected SheetCollate(int value) { super(value); @@ -62,7 +95,7 @@ public final class SheetCollate extends EnumSyntax /** * Returns category of this class. * - * @return the class <code>SheetCollate</code> itself + * @return The class <code>SheetCollate</code> itself. */ public Class getCategory() { @@ -70,12 +103,33 @@ public final class SheetCollate extends EnumSyntax } /** - * Returns name of this class. + * Returns the name of this attribute. * - * @return the string "sheet-collate" + * @return The name "sheet-collate". */ public String getName() { return "sheet-collate"; } + + /** + * Returns a table with the enumeration values represented as strings + * for this object. + * + * @return The enumeration values as strings. + */ + protected String[] getStringTable() + { + return stringTable; + } + + /** + * Returns a table with the enumeration values for this object. + * + * @return The enumeration values. + */ + protected EnumSyntax[] getEnumValueTable() + { + return enumValueTable; + } } diff --git a/libjava/classpath/javax/print/attribute/standard/Sides.java b/libjava/classpath/javax/print/attribute/standard/Sides.java index 94b473c..816365a 100644 --- a/libjava/classpath/javax/print/attribute/standard/Sides.java +++ b/libjava/classpath/javax/print/attribute/standard/Sides.java @@ -1,5 +1,5 @@ /* Sides.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -44,19 +44,55 @@ import javax.print.attribute.PrintRequestAttribute; /** + * The <code>Sides</code> printing attribute specifies how consecutive + * printing pages are arranged on the media sheet. + * <p> + * <b>IPP Compatibility:</b> Sides is an IPP 1.1 attribute. + * </p> + * * @author Michael Koch (konqueror@gmx.de) + * @author Wolfgang Baer (WBaer@gmx.de) */ public final class Sides extends EnumSyntax implements DocAttribute, PrintRequestAttribute, PrintJobAttribute { private static final long serialVersionUID = -6890309414893262822L; + /** + * Specifies that each page should be printed on one sheet. + */ public static final Sides ONE_SIDED = new Sides(0); + + /** + * Specifies that two following pages should be printed on the + * front and back of one sheet for binding on the long edge. + */ public static final Sides TWO_SIDED_LONG_EDGE = new Sides(1); + + /** + * Specifies that two following pages should be printed on the + * front and back of one sheet for binding on the short edge. + */ public static final Sides TWO_SIDED_SHORT_EDGE = new Sides(2); - public static final Sides DUPLEX = new Sides(3); - public static final Sides TUMBLE = new Sides(4); + + /** + * An alias constant for "two sided long edge". + */ + public static final Sides DUPLEX = new Sides(1); + + /** + * An alias constant for "two sided short edge". + */ + public static final Sides TUMBLE = new Sides(2); + private static final String[] stringTable = { "one-sided", + "two-sided-long-edge", + "two-sided-short-edge" }; + + private static final Sides[] enumValueTable = { ONE_SIDED, + TWO_SIDED_LONG_EDGE, + TWO_SIDED_SHORT_EDGE }; + /** * Creates a <code>Sides</code> object. * @@ -70,7 +106,7 @@ public final class Sides extends EnumSyntax /** * Returns category of this class. * - * @return the class <code>Sides</code> itself + * @return The class <code>Sides</code> itself. */ public Class getCategory() { @@ -80,10 +116,31 @@ public final class Sides extends EnumSyntax /** * Returns the name of this attribute. * - * @return the name + * @return The name "sides". */ public String getName() { return "sides"; } + + /** + * Returns a table with the enumeration values represented as strings + * for this object. + * + * @return The enumeration values as strings. + */ + protected String[] getStringTable() + { + return stringTable; + } + + /** + * Returns a table with the enumeration values for this object. + * + * @return The enumeration values. + */ + protected EnumSyntax[] getEnumValueTable() + { + return enumValueTable; + } } diff --git a/libjava/classpath/javax/print/attribute/standard/package.html b/libjava/classpath/javax/print/attribute/standard/package.html index 9d2d970..4248acf 100644 --- a/libjava/classpath/javax/print/attribute/standard/package.html +++ b/libjava/classpath/javax/print/attribute/standard/package.html @@ -1,7 +1,7 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <!-- package.html - describes classes in javax.print.attribute.standard package. - Copyright (C) 2003 Free Software Foundation, Inc. + Copyright (C) 2003, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -41,7 +41,10 @@ exception statement from your version. --> <head><title>GNU Classpath - javax.print.attribute.standard</title></head> <body> -<p></p> - +<p>Provides the printing attribute classes of the Java Print +Service API.</p> +<p> +<b>Since:</b> 1.4 +</p> </body> </html> diff --git a/libjava/classpath/javax/security/auth/login/AccountException.java b/libjava/classpath/javax/security/auth/login/AccountException.java new file mode 100644 index 0000000..32f739a --- /dev/null +++ b/libjava/classpath/javax/security/auth/login/AccountException.java @@ -0,0 +1,64 @@ +/* AccountException.java -- generic account exception + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.security.auth.login; + +/** + * This is the base class for various account-related exceptions. + * @since 1.5 + */ +public class AccountException extends LoginException +{ + private static final long serialVersionUID = -2112878680072211787L; + + /** + * Create a new exception object. + */ + public AccountException() + { + } + + /** + * Create a new exception with the indicated detail message. + * @param message the detail message + */ + public AccountException(String message) + { + super(message); + } +} diff --git a/libjava/classpath/javax/security/auth/login/AccountExpiredException.java b/libjava/classpath/javax/security/auth/login/AccountExpiredException.java index 74a97a7..c2b61c6 100644 --- a/libjava/classpath/javax/security/auth/login/AccountExpiredException.java +++ b/libjava/classpath/javax/security/auth/login/AccountExpiredException.java @@ -42,7 +42,7 @@ package javax.security.auth.login; * An exception that signals that an attempt was made to login to an account * that has expired. */ -public class AccountExpiredException extends LoginException +public class AccountExpiredException extends AccountException { // Constant. diff --git a/libjava/classpath/javax/security/auth/login/AccountLockedException.java b/libjava/classpath/javax/security/auth/login/AccountLockedException.java new file mode 100644 index 0000000..bcb8b4f --- /dev/null +++ b/libjava/classpath/javax/security/auth/login/AccountLockedException.java @@ -0,0 +1,64 @@ +/* AccountLockedException.java -- exception indicating locked account + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.security.auth.login; + +/** + * An exception indicating that an account is locked. + * @since 1.5 + */ +public class AccountLockedException extends AccountException +{ + private static final long serialVersionUID = 8280345554014066334L; + + /** + * Create a new exception object. + */ + public AccountLockedException() + { + } + + /** + * Create a new exception with the indicated detail message. + * @param message the detail message + */ + public AccountLockedException(String message) + { + super(message); + } +} diff --git a/libjava/classpath/javax/security/auth/login/AccountNotFoundException.java b/libjava/classpath/javax/security/auth/login/AccountNotFoundException.java new file mode 100644 index 0000000..a052fbf --- /dev/null +++ b/libjava/classpath/javax/security/auth/login/AccountNotFoundException.java @@ -0,0 +1,64 @@ +/* AccountNotFoundException.java -- exception indicating account not found + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.security.auth.login; + +/** + * An exception indicating that an account was not found. + * @since 1.5 + */ +public class AccountNotFoundException extends AccountException +{ + private static final long serialVersionUID = 1498349563916294614L; + + /** + * Create a new exception object. + */ + public AccountNotFoundException() + { + } + + /** + * Create a new exception with the given detail message. + * @param message the detail message + */ + public AccountNotFoundException(String message) + { + super(message); + } +} diff --git a/libjava/classpath/javax/security/auth/login/CredentialException.java b/libjava/classpath/javax/security/auth/login/CredentialException.java new file mode 100644 index 0000000..980adde --- /dev/null +++ b/libjava/classpath/javax/security/auth/login/CredentialException.java @@ -0,0 +1,64 @@ +/* CredentialException.java -- generic credential exception + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.security.auth.login; + +/** + * This is the base class for various credential-related exceptions. + * @since 1.5 + */ +public class CredentialException extends LoginException +{ + private static final long serialVersionUID = -4772893876810601859L; + + /** + * Create a new exception object. + */ + public CredentialException() + { + } + + /** + * Create a new exception with the given detail message. + * @param message the detail message + */ + public CredentialException(String message) + { + super(message); + } +} diff --git a/libjava/classpath/javax/security/auth/login/CredentialExpiredException.java b/libjava/classpath/javax/security/auth/login/CredentialExpiredException.java index 03f7ec9..9827a3d 100644 --- a/libjava/classpath/javax/security/auth/login/CredentialExpiredException.java +++ b/libjava/classpath/javax/security/auth/login/CredentialExpiredException.java @@ -42,7 +42,7 @@ package javax.security.auth.login; * An exception that signals an attempt to login with a credential that * has expired. */ -public class CredentialExpiredException extends LoginException +public class CredentialExpiredException extends CredentialException { // Constant. diff --git a/libjava/classpath/javax/security/auth/login/CredentialNotFoundException.java b/libjava/classpath/javax/security/auth/login/CredentialNotFoundException.java new file mode 100644 index 0000000..08ac115 --- /dev/null +++ b/libjava/classpath/javax/security/auth/login/CredentialNotFoundException.java @@ -0,0 +1,65 @@ +/* CredentialNotFoundException.java -- exception thrown when credentials + expire + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.security.auth.login; + +/** + * An exception that indicates that a credential was not found. + * @since 1.5 + */ +public class CredentialNotFoundException extends CredentialException +{ + private static final long serialVersionUID = -7779934467214319475L; + + /** + * Create a new exception. + */ + public CredentialNotFoundException() + { + } + + /** + * Create a new exception with the given detail message. + * @param message the detail message + */ + public CredentialNotFoundException(String message) + { + super(message); + } +} diff --git a/libjava/classpath/javax/security/auth/login/LoginContext.java b/libjava/classpath/javax/security/auth/login/LoginContext.java index a3cbf8f..740e67b 100644 --- a/libjava/classpath/javax/security/auth/login/LoginContext.java +++ b/libjava/classpath/javax/security/auth/login/LoginContext.java @@ -82,7 +82,17 @@ public class LoginContext final CallbackHandler cbHandler) throws LoginException { - Configuration config = Configuration.getConfig(); + this (name, subject, cbHandler, null); + } + + /** @since 1.5 */ + public LoginContext (final String name, final Subject subject, + final CallbackHandler cbHandler, + Configuration config) + throws LoginException + { + if (config == null) + config = Configuration.getConfig(); AppConfigurationEntry[] entries = config.getAppConfigurationEntry (name); if (entries == null) entries = config.getAppConfigurationEntry (OTHER); diff --git a/libjava/classpath/javax/swing/AbstractAction.java b/libjava/classpath/javax/swing/AbstractAction.java index da65bdd..bd3167e 100644 --- a/libjava/classpath/javax/swing/AbstractAction.java +++ b/libjava/classpath/javax/swing/AbstractAction.java @@ -79,7 +79,7 @@ public abstract class AbstractAction */ public AbstractAction() { - this(""); // TODO: default name + this(null); } /** @@ -90,7 +90,7 @@ public abstract class AbstractAction */ public AbstractAction(String name) { - this(name, null); // TODO: default icon?? + this(name, null); } /** @@ -174,7 +174,7 @@ public abstract class AbstractAction public void putValue(String key, Object value) { Object old = getValue(key); - if (old != value) + if (old == null || !old.equals(value)) { store.put(key, value); firePropertyChange(key, old, value); diff --git a/libjava/classpath/javax/swing/BoxLayout.java b/libjava/classpath/javax/swing/BoxLayout.java index ebc0b4c..408dea9 100644 --- a/libjava/classpath/javax/swing/BoxLayout.java +++ b/libjava/classpath/javax/swing/BoxLayout.java @@ -335,8 +335,15 @@ public class BoxLayout implements LayoutManager2, Serializable checkTotalRequirements(); Insets i = container.getInsets(); - return new Dimension(xTotal.maximum + i.left + i.right, - yTotal.maximum + i.top + i.bottom); + int xDim = xTotal.maximum + i.left + i.right; + int yDim = yTotal.maximum + i.top + i.bottom; + + // Check for overflow + if (xDim < xTotal.maximum) + xDim = Integer.MAX_VALUE; + if (yDim < yTotal.maximum) + yDim = Integer.MAX_VALUE; + return new Dimension(xDim, yDim); } } diff --git a/libjava/classpath/javax/swing/JComponent.java b/libjava/classpath/javax/swing/JComponent.java index deb08c5..747eba5 100644 --- a/libjava/classpath/javax/swing/JComponent.java +++ b/libjava/classpath/javax/swing/JComponent.java @@ -45,7 +45,6 @@ import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.EventQueue; -import java.awt.FlowLayout; import java.awt.FocusTraversalPolicy; import java.awt.Font; import java.awt.Graphics; @@ -621,7 +620,6 @@ public abstract class JComponent extends Container implements Serializable public JComponent() { super(); - super.setLayout(new FlowLayout()); setDropTarget(new DropTarget()); defaultLocale = Locale.getDefault(); debugGraphicsOptions = DebugGraphics.NONE_OPTION; @@ -801,14 +799,23 @@ public abstract class JComponent extends Container implements Serializable } /** - * Return all registered listeners of a particular type. - * - * @param listenerType The type of listener to return - * - * @return All listeners in the {@link #listenerList} which - * are of the specified type + * Returns all registered {@link EventListener}s of the given + * <code>listenerType</code>. * + * @param listenerType the class of listeners to filter (<code>null</code> + * not permitted). + * + * @return An array of registered listeners. + * + * @throws ClassCastException if <code>listenerType</code> does not implement + * the {@link EventListener} interface. + * @throws NullPointerException if <code>listenerType</code> is + * <code>null</code>. + * + * @see #getAncestorListeners() * @see #listenerList + * + * @since 1.3 */ public EventListener[] getListeners(Class listenerType) { @@ -1287,7 +1294,7 @@ public abstract class JComponent extends Container implements Serializable { Dimension prefSize = null; if (preferredSize != null) - prefSize = preferredSize; + prefSize = new Dimension(preferredSize); else if (ui != null) { @@ -1298,12 +1305,7 @@ public abstract class JComponent extends Container implements Serializable if (prefSize == null) prefSize = super.getPreferredSize(); - // make sure that prefSize is not smaller than minSize - if (minimumSize != null && prefSize != null - && (minimumSize.width > prefSize.width - || minimumSize.height > prefSize.height)) - prefSize = new Dimension(Math.max(minimumSize.width, prefSize.width), - Math.max(minimumSize.height, prefSize.height)); + return prefSize; } @@ -2530,7 +2532,10 @@ public abstract class JComponent extends Container implements Serializable public void setMaximumSize(Dimension max) { Dimension oldMaximumSize = maximumSize; - maximumSize = new Dimension(max); + if (max != null) + maximumSize = new Dimension(max); + else + maximumSize = null; firePropertyChange("maximumSize", oldMaximumSize, maximumSize); } @@ -2544,7 +2549,10 @@ public abstract class JComponent extends Container implements Serializable public void setMinimumSize(Dimension min) { Dimension oldMinimumSize = minimumSize; - minimumSize = new Dimension(min); + if (min != null) + minimumSize = new Dimension(min); + else + minimumSize = null; firePropertyChange("minimumSize", oldMinimumSize, minimumSize); } @@ -2558,7 +2566,10 @@ public abstract class JComponent extends Container implements Serializable public void setPreferredSize(Dimension pref) { Dimension oldPreferredSize = preferredSize; - preferredSize = new Dimension(pref); + if (pref != null) + preferredSize = new Dimension(pref); + else + preferredSize = null; firePropertyChange("preferredSize", oldPreferredSize, preferredSize); } @@ -2722,7 +2733,7 @@ public abstract class JComponent extends Container implements Serializable */ public void updateUI() { - System.out.println("update UI not overwritten in class: " + this); + // Nothing to do here. } public static Locale getDefaultLocale() @@ -3253,7 +3264,7 @@ public abstract class JComponent extends Container implements Serializable Rectangle target = SwingUtilities.convertRectangle(found, currentClip, newParent); - if (target.contains(parRect) || target.intersects(parRect)) + if (! target.intersection(parRect).equals(target)) { found = newParent; currentClip = target; @@ -3269,10 +3280,12 @@ public abstract class JComponent extends Container implements Serializable boolean skip = true; for (int i = children.length - 1; i >= 0; i--) { + boolean nextSkip = skip; if (children[i] == parent) - skip = false; + nextSkip = false; if (skip) continue; + skip = nextSkip; Component c = children[i]; Rectangle compBounds = c.getBounds(); // If the component completely overlaps the clip in question, we diff --git a/libjava/classpath/javax/swing/JEditorPane.java b/libjava/classpath/javax/swing/JEditorPane.java index 39f7c1f..3560ffd 100644 --- a/libjava/classpath/javax/swing/JEditorPane.java +++ b/libjava/classpath/javax/swing/JEditorPane.java @@ -43,8 +43,10 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; +import java.io.StringReader; import java.net.MalformedURLException; import java.net.URL; +import java.util.HashMap; import javax.accessibility.AccessibleContext; import javax.accessibility.AccessibleHyperlink; @@ -88,6 +90,7 @@ import javax.swing.text.html.HTMLEditorKit; * * @author original author unknown * @author Roman Kennke (roman@kennke.org) + * @author Anthony Balkissoon abalkiss at redhat dot com */ public class JEditorPane extends JTextComponent { @@ -168,6 +171,14 @@ public class JEditorPane extends JTextComponent { /** + * Creates a new JEditorPaneAccessibleHypertextSupport object. + */ + public JEditorPaneAccessibleHypertextSupport() + { + super(); + } + + /** * The accessible representation of a HTML link. * * @author Roman Kennke (kennke@aicas.com) @@ -499,9 +510,16 @@ public class JEditorPane extends JTextComponent private EditorKit editorKit; boolean focus_root; + + // A mapping between content types and registered EditorKit types + static HashMap registerMap; + + // A mapping between content types and used EditorKits + HashMap editorMap; public JEditorPane() { + init(); setEditorKit(createDefaultEditorKit()); } @@ -512,24 +530,69 @@ public class JEditorPane extends JTextComponent public JEditorPane(String type, String text) { + init(); setEditorKit(createEditorKitForContentType(type)); setText(text); } public JEditorPane(URL url) throws IOException { - this(); + init (); + setEditorKit (createEditorKitForContentType("text/html"));; setPage(url); } + + /** + * Called by the constructors to set up the default bindings for content + * types and EditorKits. + */ + void init() + { + editorMap = new HashMap(); + registerMap = new HashMap(); + registerEditorKitForContentType("application/rtf", + "javax.swing.text.rtf.RTFEditorKit"); + registerEditorKitForContentType("text/plain", + "javax.swing.JEditorPane$PlainEditorKit"); + registerEditorKitForContentType("text/html", + "javax.swing.text.html.HTMLEditorKit"); + registerEditorKitForContentType("text/rtf", + "javax.swing.text.rtf.RTFEditorKit"); + } protected EditorKit createDefaultEditorKit() { return new PlainEditorKit(); } + /** + * Creates and returns an EditorKit that is appropriate for the given + * content type. This is created using the default recognized types + * plus any EditorKit types that have been registered. + * + * @see #registerEditorKitForContentType(String, String) + * @see #registerEditorKitForContentType(String, String, ClassLoader) + * @param type the content type + * @return an EditorKit for use with the given content type + */ public static EditorKit createEditorKitForContentType(String type) { - return new PlainEditorKit(); + // TODO: Have to handle the case where a ClassLoader was specified + // when the EditorKit was registered + EditorKit e = null; + String className = (String)registerMap.get(type); + if (className != null) + { + try + { + e = (EditorKit) Class.forName(className).newInstance(); + } + catch (Exception e2) + { + // TODO: Not sure what to do here. + } + } + return e; } /** @@ -578,14 +641,44 @@ public class JEditorPane extends JTextComponent return editorKit; } + /** + * Returns the class name of the EditorKit associated with the given + * content type. + * + * @since 1.3 + * @param type the content type + * @return the class name of the EditorKit associated with this content type + */ public static String getEditorKitClassNameForContentType(String type) { - return "text/plain"; + return (String) registerMap.get(type); } + /** + * Returns the EditorKit to use for the given content type. If an + * EditorKit has been explicitly set via + * <code>setEditorKitForContentType</code> + * then it will be returned. Otherwise an attempt will be made to create + * an EditorKit from the default recognzied content types or any + * EditorKits that have been registered. If none can be created, a + * PlainEditorKit is created. + * + * @see #registerEditorKitForContentType(String, String) + * @see #registerEditorKitForContentType(String, String, ClassLoader) + * @param type the content type + * @return an appropriate EditorKit for the given content type + */ public EditorKit getEditorKitForContentType(String type) { - return editorKit; + // First check if an EditorKit has been explicitly set. + EditorKit e = (EditorKit) editorMap.get(type); + // Then check to see if we can create one. + if (e == null) + e = createEditorKitForContentType(type); + // Otherwise default to PlainEditorKit. + if (e == null) + e = new PlainEditorKit(); + return e; } /** @@ -669,12 +762,17 @@ public class JEditorPane extends JTextComponent } /** - * Establishes the default bindings of type to classname. + * Establishes a binding between type and classname. This enables + * us to create an EditorKit later for the given content type. + * + * @param type the content type + * @param classname the name of the class that is associated with this + * content type */ public static void registerEditorKitForContentType(String type, String classname) { - // TODO: Implement this properly. + registerMap.put(type, classname); } /** @@ -694,6 +792,7 @@ public class JEditorPane extends JTextComponent public void replaceSelection(String content) { // TODO: Implement this properly. + super.replaceSelection(content); } /** @@ -741,9 +840,14 @@ public class JEditorPane extends JTextComponent accessibleContext = null; } + /** + * Explicitly sets an EditorKit to be used for the given content type. + * @param type the content type + * @param k the EditorKit to use for the given content type + */ public void setEditorKitForContentType(String type, EditorKit k) { - // FIXME: editorKitCache.put(type, kit); + editorMap.put(type, k); } /** @@ -773,9 +877,36 @@ public class JEditorPane extends JTextComponent } } + /** + * Sets the text of the JEditorPane. The argument <code>t</code> + * is expected to be in the format of the current EditorKit. This removes + * the content of the current document and uses the EditorKit to read in the + * new text. This allows the EditorKit to handle the String rather than just + * inserting in plain text. + * + * @param t the text to display in this JEditorPane + */ public void setText(String t) { - super.setText(t); + try + { + // Remove the current content. + Document doc = getDocument(); + doc.remove(0, doc.getLength()); + if (t == null || t == "") + return; + + // Let the EditorKit read the text into the Document. + getEditorKit().read(new StringReader(t), doc, 0); + } + catch (BadLocationException ble) + { + // TODO: Don't know what to do here. + } + catch (IOException ioe) + { + // TODO: Don't know what to do here. + } } /** diff --git a/libjava/classpath/javax/swing/JFileChooser.java b/libjava/classpath/javax/swing/JFileChooser.java index 1598641..3a9d6a0 100644 --- a/libjava/classpath/javax/swing/JFileChooser.java +++ b/libjava/classpath/javax/swing/JFileChooser.java @@ -40,6 +40,7 @@ package javax.swing; import java.awt.Component; import java.awt.Frame; import java.awt.HeadlessException; +import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; @@ -407,8 +408,7 @@ public class JFileChooser extends JComponent implements Accessible */ public JFileChooser(String currentDirectoryPath) { - setup(null); - setCurrentDirectory(fsv.createFileObject(currentDirectoryPath)); + this(currentDirectoryPath, null); } /** @@ -424,7 +424,10 @@ public class JFileChooser extends JComponent implements Accessible public JFileChooser(String currentDirectoryPath, FileSystemView fsv) { setup(fsv); - setCurrentDirectory(fsv.createFileObject(currentDirectoryPath)); + File dir = null; + if (currentDirectoryPath != null) + dir = getFileSystemView().createFileObject(currentDirectoryPath); + setCurrentDirectory(dir); } /** @@ -525,7 +528,7 @@ public class JFileChooser extends JComponent implements Accessible */ public void setSelectedFile(File file) { - if (selectedFile != file) + if (selectedFile == null || !selectedFile.equals(file)) { File old = selectedFile; selectedFile = file; @@ -534,10 +537,10 @@ public class JFileChooser extends JComponent implements Accessible } /** - * Returns the selected file or files. + * Returns the selected file or files in an array. If no files are selected, + * an empty array is returned. * - * @return An array of the selected files, or <code>null</code> if there are - * no selected files. + * @return An array of the selected files (possibly empty). */ public File[] getSelectedFiles() { @@ -545,7 +548,7 @@ public class JFileChooser extends JComponent implements Accessible return selectedFiles; if (selectedFile != null) return new File[] { selectedFile }; - return null; + return new File[0]; } /** @@ -557,6 +560,12 @@ public class JFileChooser extends JComponent implements Accessible */ public void setSelectedFiles(File[] selectedFiles) { + if (selectedFiles == null) + selectedFiles = new File[0]; + if (selectedFiles.length > 0) + setSelectedFile(selectedFiles[0]); + else + setSelectedFile(null); if (this.selectedFiles != selectedFiles) { File[] old = this.selectedFiles; @@ -564,8 +573,6 @@ public class JFileChooser extends JComponent implements Accessible firePropertyChange(SELECTED_FILES_CHANGED_PROPERTY, old, selectedFiles); } - if (selectedFiles != null) - setSelectedFile(selectedFiles[0]); } /** @@ -607,8 +614,7 @@ public class JFileChooser extends JComponent implements Accessible */ public void changeToParentDirectory() { - if (fsv.getParentDirectory(currentDir) != null) - setCurrentDirectory(fsv.getParentDirectory(currentDir)); + setCurrentDirectory(fsv.getParentDirectory(currentDir)); } /** @@ -652,7 +658,8 @@ public class JFileChooser extends JComponent implements Accessible retval = ERROR_OPTION; - d.pack(); + Insets i = d.getInsets(); + d.setSize(500 + i.top + i.bottom, d.getPreferredSize().height); d.show(); return retval; } @@ -676,7 +683,8 @@ public class JFileChooser extends JComponent implements Accessible retval = ERROR_OPTION; - d.pack(); + Insets i = d.getInsets(); + d.setSize(500 + i.top + i.bottom, d.getPreferredSize().height); d.show(); return retval; } @@ -702,7 +710,8 @@ public class JFileChooser extends JComponent implements Accessible retval = ERROR_OPTION; - d.pack(); + Insets i = d.getInsets(); + d.setSize(500 + i.top + i.bottom, d.getPreferredSize().height); d.show(); return retval; } @@ -958,14 +967,19 @@ public class JFileChooser extends JComponent implements Accessible * {@link #CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY}) to all registered * listeners. * - * @param filter the filter. + * @param filter the filter (<code>null</code> permitted). */ public void addChoosableFileFilter(FileFilter filter) { - FileFilter[] old = getChoosableFileFilters(); - choosableFilters.add(filter); - FileFilter[] newFilters = getChoosableFileFilters(); - firePropertyChange(CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY, old, newFilters); + if (filter != null) + { + FileFilter[] old = getChoosableFileFilters(); + choosableFilters.add(filter); + FileFilter[] newFilters = getChoosableFileFilters(); + firePropertyChange(CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY, old, + newFilters); + } + setFileFilter(filter); } /** @@ -981,6 +995,8 @@ public class JFileChooser extends JComponent implements Accessible */ public boolean removeChoosableFileFilter(FileFilter f) { + if (f == currentFilter) + setFileFilter(null); FileFilter[] old = getChoosableFileFilters(); if (! choosableFilters.remove(f)) return false; @@ -1037,6 +1053,10 @@ public class JFileChooser extends JComponent implements Accessible if (isAcceptAll != b) { isAcceptAll = b; + if (b) + addChoosableFileFilter(getAcceptAllFileFilter()); + else + removeChoosableFileFilter(getAcceptAllFileFilter()); firePropertyChange(ACCEPT_ALL_FILE_FILTER_USED_CHANGED_PROPERTY, ! isAcceptAll, isAcceptAll); } @@ -1208,15 +1228,17 @@ public class JFileChooser extends JComponent implements Accessible * property name {@link #FILE_FILTER_CHANGED_PROPERTY}) to all registered * listeners. * - * @param filter the filter. + * @param filter the filter (<code>null</code> permitted). */ public void setFileFilter(FileFilter filter) { if (currentFilter != filter) { - FileFilter old = currentFilter; - currentFilter = filter; - firePropertyChange(FILE_FILTER_CHANGED_PROPERTY, old, currentFilter); + if (filter != null && !choosableFilters.contains(filter)) + addChoosableFileFilter(filter); + FileFilter old = currentFilter; + currentFilter = filter; + firePropertyChange(FILE_FILTER_CHANGED_PROPERTY, old, currentFilter); } } @@ -1356,8 +1378,12 @@ public class JFileChooser extends JComponent implements Accessible public boolean accept(File f) { if (f == null) - return false; - return getFileFilter().accept(f); + return true; + FileFilter ff = getFileFilter(); + if (ff != null) + return ff.accept(f); + else + return true; } /** diff --git a/libjava/classpath/javax/swing/JFormattedTextField.java b/libjava/classpath/javax/swing/JFormattedTextField.java index 9890df2..761955d 100644 --- a/libjava/classpath/javax/swing/JFormattedTextField.java +++ b/libjava/classpath/javax/swing/JFormattedTextField.java @@ -40,15 +40,21 @@ package javax.swing; import java.awt.event.FocusEvent; import java.io.Serializable; +import java.text.DateFormat; import java.text.Format; +import java.text.NumberFormat; import java.text.ParseException; import java.util.Date; +import javax.swing.text.AbstractDocument; import javax.swing.text.DateFormatter; import javax.swing.text.DefaultFormatter; +import javax.swing.text.DefaultFormatterFactory; import javax.swing.text.Document; import javax.swing.text.DocumentFilter; +import javax.swing.text.InternationalFormatter; import javax.swing.text.NavigationFilter; +import javax.swing.text.NumberFormatter; /** * A text field that makes use of a formatter to display and edit a specific @@ -62,6 +68,7 @@ import javax.swing.text.NavigationFilter; * formatting of the value of the JFormattedTextField. * * @author Michael Koch + * @author Anthony Balkissoon abalkiss at redhat dot com * * @since 1.4 */ @@ -85,58 +92,184 @@ public class JFormattedTextField extends JTextField //Do nothing here. } + /** + * Clones the AbstractFormatter and removes the association to any + * particular JFormattedTextField. + * + * @return a clone of this formatter with no association to any particular + * JFormattedTextField + * @throws CloneNotSupportedException if the Object's class doesn't support + * the {@link Cloneable} interface + */ protected Object clone () throws CloneNotSupportedException { - throw new InternalError ("not implemented"); + // Clone this formatter. + AbstractFormatter newFormatter = (AbstractFormatter)super.clone(); + + // And remove the association to the JFormattedTextField. + newFormatter.textField = null; + return newFormatter; } + /** + * Returns a custom set of Actions that this formatter supports. Should + * be subclassed by formatters that have a custom set of Actions. + * + * @return <code>null</code>. Should be subclassed by formatters that want + * to install custom Actions on the JFormattedTextField. + */ protected Action[] getActions () { - return textField.getActions(); + return null; } + /** + * Gets the DocumentFilter for this formatter. Should be subclassed + * by formatters wishing to install a filter that oversees Document + * mutations. + * + * @return <code>null</code>. Should be subclassed by formatters + * that want to restrict Document mutations. + */ protected DocumentFilter getDocumentFilter () { - throw new InternalError ("not implemented"); + // Subclasses should override this if they want to install a + // DocumentFilter. + return null; } + /** + * Returns the JFormattedTextField on which this formatter is + * currently installed. + * + * @return the JFormattedTextField on which this formatter is currently + * installed + */ protected JFormattedTextField getFormattedTextField () { return textField; } + /** + * Gets the NavigationFilter for this formatter. Should be subclassed + * by formatters (such as {@link DefaultFormatter}) that wish to + * restrict where the cursor can be placed within the text field. + * + * @return <code>null</code>. Subclassed by formatters that want to restrict + * cursor location within the JFormattedTextField. + */ protected NavigationFilter getNavigationFilter () { - return textField.getNavigationFilter(); + // This should be subclassed if the formatter wants to install + // a NavigationFilter on the JFormattedTextField. + return null; } + /** + * Installs this formatter on the specified JFormattedTextField. This + * converts the current value to a displayable String and displays it, + * and installs formatter specific Actions from <code>getActions</code>. + * It also installs a DocumentFilter and NavigationFilter on the + * JFormattedTextField. + * <p> + * If there is a <code>ParseException</code> this sets the text to an + * empty String and marks the text field in an invalid state. + * + * @param textField the JFormattedTextField on which to install this + * formatter + */ public void install(JFormattedTextField textField) { + // Uninstall the current textfield. if (this.textField != null) - uninstall(); + uninstall(); this.textField = textField; + + // Install some state on the text field, including display text, + // DocumentFilter, NavigationFilter, and formatter specific Actions. + if (textField != null) + { + try + { + // Set the text of the field. + textField.setText(valueToString(textField.getValue())); + Document doc = textField.getDocument(); + + // Set the DocumentFilter for the field's Document. + if (doc instanceof AbstractDocument) + ((AbstractDocument)doc).setDocumentFilter(getDocumentFilter()); + + // Set the NavigationFilter. + textField.setNavigationFilter(getNavigationFilter()); + + // Set the Formatter Actions + // FIXME: Have to add the actions from getActions() + } + catch (ParseException pe) + { + // Set the text to an empty String and mark the field as invalid. + textField.setText(""); + setEditValid(false); + } + } } + /** + * Clears the state installed on the JFormattedTextField by the formatter. + * This resets the DocumentFilter, NavigationFilter, and any additional + * Actions (returned by <code>getActions()</code>). + */ public void uninstall () { + // Set the DocumentFilter for the field's Document. + Document doc = textField.getDocument(); + if (doc instanceof AbstractDocument) + ((AbstractDocument)doc).setDocumentFilter(null); + textField.setNavigationFilter(null); + // FIXME: Have to remove the Actions from getActions() this.textField = null; } + /** + * Invoke this method when invalid values are entered. This forwards the + * call to the JFormattedTextField. + */ protected void invalidEdit () { textField.invalidEdit(); } + /** + * This method updates the <code>editValid</code> property of + * JFormattedTextField. + * + * @param valid the new state for the <code>editValid</code> property + */ protected void setEditValid (boolean valid) { textField.editValid = valid; } + /** + * Parses <code>text</code> to return a corresponding Object. + * + * @param text the String to parse + * @return an Object that <code>text</code> represented + * @throws ParseException if there is an error in the conversion + */ public abstract Object stringToValue (String text) throws ParseException; + /** + * Returns a String to be displayed, based on the Object + * <code>value</code>. + * + * @param value the Object from which to generate a String + * @return a String to be displayed + * @throws ParseException if there is an error in the conversion + */ public abstract String valueToString (Object value) throws ParseException; } @@ -155,88 +288,177 @@ public class JFormattedTextField extends JTextField public abstract AbstractFormatter getFormatter (JFormattedTextField tf); } - static class FormatterFactoryWrapper extends AbstractFormatterFactory - { - AbstractFormatter formatter; - - public FormatterFactoryWrapper(AbstractFormatter formatter) - { - this.formatter = formatter; - } - - public AbstractFormatter getFormatter(JFormattedTextField tf) - { - return formatter; - } - } - + /** The possible focusLostBehavior options **/ public static final int COMMIT = 0; public static final int COMMIT_OR_REVERT = 1; public static final int REVERT = 2; public static final int PERSIST = 3; + /** The most recent valid and committed value **/ private Object value; + + /** The behaviour for when this text field loses focus **/ private int focusLostBehavior = COMMIT_OR_REVERT; + + /** The formatter factory currently being used **/ private AbstractFormatterFactory formatterFactory; + + /** The formatter currently being used **/ + private AbstractFormatter formatter; + // Package-private to avoid an accessor method. boolean editValid = true; + /** + * Creates a JFormattedTextField with no formatter factory. + * <code>setValue</code> or <code>setFormatterFactory</code> will + * properly configure this text field to edit a particular type + * of value. + */ public JFormattedTextField () { this((AbstractFormatterFactory) null, null); } + /** + * Creates a JFormattedTextField that can handle the specified Format. + * An appopriate AbstractFormatter and AbstractFormatterFactory will + * be created for the specified Format. + * + * @param format the Format that this JFormattedTextField should be able + * to handle + */ public JFormattedTextField (Format format) { - throw new InternalError ("not implemented"); + this (); + setFormatterFactory(getAppropriateFormatterFactory(format)); } + /** + * Creates a JFormattedTextField with the specified formatter. This will + * create a {@link DefaultFormatterFactory} with this formatter as the default + * formatter. + * + * @param formatter the formatter to use for this JFormattedTextField + */ public JFormattedTextField (AbstractFormatter formatter) { - this(new FormatterFactoryWrapper(formatter), null); + this(new DefaultFormatterFactory (formatter)); } + /** + * Creates a JFormattedTextField with the specified formatter factory. + * + * @param factory the formatter factory to use for this JFormattedTextField + */ public JFormattedTextField (AbstractFormatterFactory factory) { - this(factory, null); + setFormatterFactory(factory); } + /** + * Creates a JFormattedTextField with the specified formatter factory and + * initial value. + * + * @param factory the initial formatter factory for this JFormattedTextField + * @param value the initial value for the text field + */ public JFormattedTextField (AbstractFormatterFactory factory, Object value) - { - this.formatterFactory = factory; - this.value = value; + { + setFormatterFactory(factory); + setValue(value); } + /** + * Creates a JFormattedTextField with the specified value. This creates a + * formatter and formatterFactory that are appropriate for the value. + * + * @param value the initial value for this JFormattedTextField + */ public JFormattedTextField (Object value) { - this.value = value; + setValue(value); + } + + /** + * Returns an AbstractFormatterFactory that will give an appropriate + * AbstractFormatter for the given Format. + * @param format the Format to match with an AbstractFormatter. + * @return a DefaultFormatterFactory whose defaultFormatter is appropriate + * for the given Format. + */ + private AbstractFormatterFactory getAppropriateFormatterFactory (Format format) + { + AbstractFormatter newFormatter; + if (format instanceof DateFormat) + newFormatter = new DateFormatter((DateFormat)format); + else if (format instanceof NumberFormat) + newFormatter = new NumberFormatter ((NumberFormat)format); + else + newFormatter = new InternationalFormatter(format); + + return new DefaultFormatterFactory(newFormatter); } + /** + * Forces the current value from the editor to be set as the current + * value. If there is no current formatted this has no effect. + * + * @throws ParseException if the formatter cannot format the current value + */ public void commitEdit () throws ParseException { - throw new InternalError ("not implemented"); + if (formatter == null) + return; + // Note: this code is a lot like setValue except that we don't want + // to create a new formatter. + Object oldValue = this.value; + + this.value = formatter.stringToValue(getText());; + editValid = true; + + firePropertyChange("value", oldValue, this.value); } + /** + * Gets the command list supplied by the UI augmented by the specific + * Actions for JFormattedTextField. + * + * @return an array of Actions that this text field supports + */ public Action[] getActions () { // FIXME: Add JFormattedTextField specific actions + // These are related to committing or cancelling edits. return super.getActions(); } + /** + * Returns the behaviour of this JFormattedTextField upon losing focus. This + * is one of <code>COMMIT</code>, <code>COMMIT_OR_REVERT</code>, + * <code>PERSIST</code>, or <code>REVERT</code>. + * @return the behaviour upon losing focus + */ public int getFocusLostBehavior() { return focusLostBehavior; } + /** + * Returns the current formatter used for this JFormattedTextField. + * @return the current formatter used for this JFormattedTextField + */ public AbstractFormatter getFormatter () { - if (formatterFactory == null) - return null; - - return formatterFactory.getFormatter(this); + return formatter; } - + + /** + * Returns the factory currently used to generate formatters for this + * JFormattedTextField. + * @return the factory currently used to generate formatters + */ public AbstractFormatterFactory getFormatterFactory () { return formatterFactory; @@ -247,31 +469,61 @@ public class JFormattedTextField extends JTextField return "FormattedTextFieldUI"; } + /** + * Returns the last valid value. This may not be the value currently shown + * in the text field depending on whether or not the formatter commits on + * valid edits and allows invalid input to be temporarily displayed. + * @return the last committed valid value + */ public Object getValue () { return value; } + /** + * This method is used to provide feedback to the user when an invalid value + * is input during editing. + */ protected void invalidEdit () { UIManager.getLookAndFeel().provideErrorFeedback(this); } + /** + * Returns true if the current value being edited is valid. This property is + * managed by the current formatted. + * @return true if the value being edited is valid. + */ public boolean isEditValid () { return editValid; } + /** + * Processes focus events. This is overridden because we may want to + * change the formatted depending on whether or not this field has + * focus. + * + * @param evt the FocusEvent + */ protected void processFocusEvent (FocusEvent evt) { - // it's safe to simply call super for now, until it gets clear - // what this method is supposed to do - // throw new InternalError ("not implemented"); super.processFocusEvent(evt); + // Let the formatterFactory change the formatter for this text field + // based on whether or not it has focus. + setFormatter (formatterFactory.getFormatter(this)); } - + + /** + * Associates this JFormattedTextField with a Document and propagates + * a PropertyChange event to each listener. + * + * @param newDocument the Document to associate with this text field + */ public void setDocument(Document newDocument) { + // FIXME: This method should do more than this. Must do some handling + // of the DocumentListeners. Document oldDocument = getDocument(); if (oldDocument == newDocument) @@ -280,6 +532,16 @@ public class JFormattedTextField extends JTextField super.setDocument(newDocument); } + /** + * Sets the behaviour of this JFormattedTextField upon losing focus. + * This must be <code>COMMIT</code>, <code>COMMIT_OR_REVERT</code>, + * <code>PERSIST</code>, or <code>REVERT</code> or an + * IllegalArgumentException will be thrown. + * + * @param behavior + * @throws IllegalArgumentException if <code>behaviour</code> is not + * one of the above + */ public void setFocusLostBehavior(int behavior) { if (behavior != COMMIT @@ -291,20 +553,38 @@ public class JFormattedTextField extends JTextField this.focusLostBehavior = behavior; } + /** + * Sets the formatter for this JFormattedTextField. Normally the formatter + * factory will take care of this, or calls to setValue will also make sure + * that the formatter is set appropriately. + * + * @param formatter the AbstractFormatter to use for formatting the value for + * this JFormattedTextField + */ protected void setFormatter (AbstractFormatter formatter) { AbstractFormatter oldFormatter = null; - if (formatterFactory != null) - oldFormatter = formatterFactory.getFormatter(this); + oldFormatter = this.formatter; - if (oldFormatter == formatter) - return; + if (oldFormatter != null) + oldFormatter.uninstall(); + + this.formatter = formatter; + + if (formatter != null) + formatter.install(this); - setFormatterFactory(new FormatterFactoryWrapper(formatter)); firePropertyChange("formatter", oldFormatter, formatter); } + /** + * Sets the factory from which this JFormattedTextField should obtain + * its formatters. + * + * @param factory the AbstractFormatterFactory that will be used to generate + * formatters for this JFormattedTextField + */ public void setFormatterFactory (AbstractFormatterFactory factory) { if (formatterFactory == factory) @@ -313,55 +593,56 @@ public class JFormattedTextField extends JTextField AbstractFormatterFactory oldFactory = formatterFactory; formatterFactory = factory; firePropertyChange("formatterFactory", oldFactory, factory); + + // Now set the formatter according to our new factory. + if (formatterFactory != null) + setFormatter(formatterFactory.getFormatter(this)); + else + setFormatter(null); } + /** + * Sets the value that will be formatted and displayed. + * + * @param newValue the value to be formatted and displayed + */ public void setValue (Object newValue) { if (value == newValue) return; - // format value - AbstractFormatter formatter = createFormatter(newValue); - try - { - setText(formatter.valueToString(newValue)); - } - catch (ParseException ex) - { - // TODO: what should we do with this? - } - Object oldValue = value; value = newValue; + + // If there is no formatterFactory then make one. + if (formatterFactory == null) + setFormatterFactory(createFormatterFactory(newValue)); + + // Set the formatter appropriately. This is because there may be a new + // formatterFactory from the line above, or we may want a new formatter + // depending on the type of newValue (or if newValue is null). + setFormatter (formatterFactory.getFormatter(this)); firePropertyChange("value", oldValue, newValue); } /** - * A helper method that attempts to create a formatter that is suitable - * to format objects of the type like <code>value</code>. + * A helper method that attempts to create a formatter factory that is + * suitable to format objects of the type like <code>value</code>. * - * If <code>formatterFactory</code> is not null and the returned formatter - * is also not <code>null</code> then this formatter is used. Otherwise we - * try to create one based on the type of <code>value</code>. + * @param value an object which should be formatted by the formatter factory. * - * @param value an object which should be formatted by the formatter - * - * @return a formatter able to format objects of the class of + * @return a formatter factory able to format objects of the class of * <code>value</code> */ - AbstractFormatter createFormatter(Object value) + AbstractFormatterFactory createFormatterFactory(Object value) { AbstractFormatter formatter = null; - if (formatterFactory != null - && formatterFactory.getFormatter(this) != null) - formatter = formatterFactory.getFormatter(this); - else - { - if (value instanceof Date) - formatter = new DateFormatter(); - else - formatter = new DefaultFormatter(); - } - return formatter; + if (value instanceof Date) + formatter = new DateFormatter(); + else if (value instanceof Number) + formatter = new NumberFormatter(); + else + formatter = new DefaultFormatter(); + return new DefaultFormatterFactory(formatter); } } diff --git a/libjava/classpath/javax/swing/JInternalFrame.java b/libjava/classpath/javax/swing/JInternalFrame.java index 479294b..948988c 100644 --- a/libjava/classpath/javax/swing/JInternalFrame.java +++ b/libjava/classpath/javax/swing/JInternalFrame.java @@ -1628,7 +1628,6 @@ public class JInternalFrame extends JComponent implements Accessible, { if (! isVisible()) { - moveToFront(); super.show(); JDesktopPane pane = getDesktopPane(); diff --git a/libjava/classpath/javax/swing/JLayeredPane.java b/libjava/classpath/javax/swing/JLayeredPane.java index 346570d..dc8b10d 100644 --- a/libjava/classpath/javax/swing/JLayeredPane.java +++ b/libjava/classpath/javax/swing/JLayeredPane.java @@ -436,7 +436,12 @@ public class JLayeredPane extends JComponent implements Accessible // should have found it throw new IllegalArgumentException(); - super.swapComponents (curr, targ); + if (curr == 0) + super.swapComponents(curr, targ); + else + while (curr > 0) + super.swapComponents (curr, --curr); + revalidate(); repaint(); } diff --git a/libjava/classpath/javax/swing/JList.java b/libjava/classpath/javax/swing/JList.java index caa7f31..d0e1090 100644 --- a/libjava/classpath/javax/swing/JList.java +++ b/libjava/classpath/javax/swing/JList.java @@ -1070,14 +1070,16 @@ public class JList extends JComponent implements Accessible, Scrollable layoutOrientation = VERTICAL; opaque = true; valueIsAdjusting = false; - visibleRowCount = 8; + visibleRowCount = 7; cellRenderer = new DefaultListCellRenderer(); listListener = new ListListener(); setModel(new DefaultListModel()); setSelectionModel(createSelectionModel()); - + setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + setLayout(null); + updateUI(); } @@ -1255,14 +1257,17 @@ public class JList extends JComponent implements Accessible, Scrollable * * @param a A number in the half-open range <code>[0, x)</code> where * <code>x = getModel.getSize()</code>, indicating the index of an - * element in the list to select. + * element in the list to select. When < 0 the selection is cleared. * * @see #setSelectionMode * @see #selectionModel */ public void setSelectedIndex(int a) { - selectionModel.setSelectionInterval(a, a); + if (a < 0) + selectionModel.clearSelection(); + else + selectionModel.setSelectionInterval(a, a); } /** diff --git a/libjava/classpath/javax/swing/JMenuItem.java b/libjava/classpath/javax/swing/JMenuItem.java index c87a4dc..b2cfbd1 100644 --- a/libjava/classpath/javax/swing/JMenuItem.java +++ b/libjava/classpath/javax/swing/JMenuItem.java @@ -1,5 +1,5 @@ /* JMenuItem.java -- - Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2005,2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -117,6 +117,24 @@ public class JMenuItem extends AbstractButton implements Accessible, super(); super.setAction(action); init(null, null); + if (action != null) + { + String name = (String) action.getValue(Action.NAME); + if (name != null) + setName(name); + + KeyStroke accel = (KeyStroke) action.getValue(Action.ACCELERATOR_KEY); + if (accel != null) + setAccelerator(accel); + + Integer mnemonic = (Integer) action.getValue(Action.MNEMONIC_KEY); + if (mnemonic != null) + setMnemonic(mnemonic.intValue()); + + String command = (String) action.getValue(Action.ACTION_COMMAND_KEY); + if (command != null) + setActionCommand(command); + } } /** @@ -273,8 +291,9 @@ public class JMenuItem extends AbstractButton implements Accessible, if (! (this instanceof JMenu) && action != null) { setAccelerator((KeyStroke) (action.getValue(Action.ACCELERATOR_KEY))); - super.registerKeyboardAction(action, accelerator, - JComponent.WHEN_IN_FOCUSED_WINDOW); + if (accelerator != null) + super.registerKeyboardAction(action, accelerator, + JComponent.WHEN_IN_FOCUSED_WINDOW); } } diff --git a/libjava/classpath/javax/swing/JProgressBar.java b/libjava/classpath/javax/swing/JProgressBar.java index 0de9115..abca3e7 100644 --- a/libjava/classpath/javax/swing/JProgressBar.java +++ b/libjava/classpath/javax/swing/JProgressBar.java @@ -262,7 +262,8 @@ public class JProgressBar extends JComponent implements SwingConstants, { this.model = model; changeListener = createChangeListener(); - model.addChangeListener(changeListener); + if (model != null) + model.addChangeListener(changeListener); updateUI(); } diff --git a/libjava/classpath/javax/swing/JTabbedPane.java b/libjava/classpath/javax/swing/JTabbedPane.java index 27ba7bb..8a7d4c0 100644 --- a/libjava/classpath/javax/swing/JTabbedPane.java +++ b/libjava/classpath/javax/swing/JTabbedPane.java @@ -497,7 +497,7 @@ public class JTabbedPane extends JComponent implements Serializable, */ public int getMnemonic() { - return (int) mnemonicKey; + return mnemonicKey; } /** @@ -592,9 +592,11 @@ public class JTabbedPane extends JComponent implements Serializable, /** * Creates a new JTabbedPane object using wrap tab layout and the given - * tabPlacement. + * <code>tabPlacement</code>, where <code>tabPlacement</code> can be one + * of the following values: {@link #TOP}, {@link #BOTTOM}, {@link #LEFT} or + * {@link #RIGHT}. * - * @param tabPlacement Where the tabs will be placed. + * @param tabPlacement where the tabs will be placed */ public JTabbedPane(int tabPlacement) { @@ -602,11 +604,14 @@ public class JTabbedPane extends JComponent implements Serializable, } /** - * Creates a new JTabbedPane object with the given tabPlacement and - * tabLayoutPolicy. + * Creates a new JTabbedPane object with the given <code>tabPlacement</code> + * and <code>tabLayoutPolicy</code>. The <code>tabPlacement</code> can be one + * of the following values: {@link #TOP}, {@link #BOTTOM}, {@link #LEFT} or + * {@link #RIGHT}. The <code>tabLayoutPolicy</code> can be either + * {@link #SCROLL_TAB_LAYOUT} or {@link #WRAP_TAB_LAYOUT}. * - * @param tabPlacement Where the tabs will be placed. - * @param tabLayoutPolicy The way tabs will be placed. + * @param tabPlacement where the tabs will be placed + * @param tabLayoutPolicy the way tabs will be placed * * @throws IllegalArgumentException If tabLayoutPolicy or tabPlacement are * not valid. @@ -913,7 +918,7 @@ public class JTabbedPane extends JComponent implements Serializable, if (getSelectedIndex() == -1) setSelectedIndex(0); - layout(); + revalidate(); repaint(); } diff --git a/libjava/classpath/javax/swing/JTable.java b/libjava/classpath/javax/swing/JTable.java index 69a865d..0875306 100644 --- a/libjava/classpath/javax/swing/JTable.java +++ b/libjava/classpath/javax/swing/JTable.java @@ -927,7 +927,47 @@ public class JTable // TODO Auto-generated method stub return null; } - + + /** + * Returns the accessible row at the specified index. + * + * @param index the index for which to query the row + * + * @return the row number at the specified table index + */ + public int getAccessibleRowAtIndex(int index) + { + // TODO: Back this up by a Mauve test and update API docs accordingly. + return index / getColumnCount(); + } + + /** + * Returns the accessible column at the specified index. + * + * @param index the index for which to query the column + * + * @return the column number at the specified table index + */ + public int getAccessibleColumnAtIndex(int index) + { + // TODO: Back this up by a Mauve test and update API docs accordingly. + return index % getColumnCount(); + } + + /** + * Returns the accessible child index at the specified column and row. + * + * @param row the row + * @param column the column + * + * @return the index of the accessible child at the specified row and + * column + */ + public int getAccessibleIndexAt(int row, int column) + { + // TODO: Back this up by a Mauve test and update API docs accordingly. + return row * getColumnCount() + column; + } } /** * Handles property changes from the <code>TableColumn</code>s of this @@ -949,10 +989,13 @@ public class JTable if (ev.getPropertyName().equals("preferredWidth")) { JTableHeader header = getTableHeader(); - TableColumn col = (TableColumn) ev.getSource(); - header.setResizingColumn(col); - doLayout(); - header.setResizingColumn(null); + if (header != null) + { + TableColumn col = (TableColumn) ev.getSource(); + header.setResizingColumn(col); + doLayout(); + header.setResizingColumn(null); + } } } } @@ -1461,6 +1504,12 @@ public class JTable new TableColumnPropertyChangeHandler(); /** + * Whether cell editors should receive keyboard focus when the table is + * activated. + */ + private boolean surrendersFocusOnKeystroke = false; + + /** * Creates a new <code>JTable</code> instance. */ public JTable () @@ -1763,7 +1812,7 @@ public class JTable if ((event.getFirstRow() ==TableModelEvent.HEADER_ROW) && autoCreateColumnsFromModel) - createDefaultColumnsFromModel(); + createDefaultColumnsFromModel(); // If the structure changes, we need to revalidate, since that might // affect the size parameters of the JTable. Otherwise we only need @@ -1796,7 +1845,6 @@ public class JTable { if (point != null) { - int x0 = getLocation().x; int ncols = getColumnCount(); Dimension gap = getIntercellSpacing(); TableColumnModel cols = getColumnModel(); @@ -1826,7 +1874,6 @@ public class JTable { if (point != null) { - int y0 = getLocation().y; int nrows = getRowCount(); int height = getRowHeight(); int y = point.y; @@ -1984,16 +2031,13 @@ public class JTable } } - - public TableCellRenderer getCellRenderer(int row, int column) { TableCellRenderer renderer = columnModel.getColumn(column).getCellRenderer(); - if (renderer == null) - renderer = getDefaultRenderer(dataModel.getColumnClass(column)); - + renderer = getDefaultRenderer(getColumnClass(column)); + return renderer; } @@ -2039,19 +2083,29 @@ public class JTable int row, int column) { - boolean rsa = getRowSelectionAllowed(); - boolean csa = getColumnSelectionAllowed(); - boolean rs = rsa ? getSelectionModel().isSelectedIndex(row) : false; - boolean cs = csa ? columnModel.getSelectionModel().isSelectedIndex(column) : false; - boolean isSelected = ((rsa && csa && rs && cs) - || (rsa && !csa && rs) - || (!rsa && csa && cs)); - + + boolean rowSelAllowed = getRowSelectionAllowed(); + boolean colSelAllowed = getColumnSelectionAllowed(); + boolean isSel = false; + if (rowSelAllowed && colSelAllowed || !rowSelAllowed && !colSelAllowed) + isSel = isCellSelected(row, column); + else + isSel = isRowSelected(row) && getRowSelectionAllowed() + || isColumnSelected(column) && getColumnSelectionAllowed(); + + // Determine the focused cell. The focused cell is the cell at the + // leadSelectionIndices of the row and column selection model. + ListSelectionModel rowSel = getSelectionModel(); + ListSelectionModel colSel = getColumnModel().getSelectionModel(); + boolean hasFocus = hasFocus() && isEnabled() + && rowSel.getLeadSelectionIndex() == row + && colSel.getLeadSelectionIndex() == column; + return renderer.getTableCellRendererComponent(this, dataModel.getValueAt(row, convertColumnIndexToModel(column)), - isSelected, - false, // hasFocus + isSel, + hasFocus, row, column); } @@ -2217,7 +2271,6 @@ public class JTable int lo = lsm.getMinSelectionIndex(); int hi = lsm.getMaxSelectionIndex(); int j = 0; - java.util.ArrayList ls = new java.util.ArrayList(); if (lo != -1 && hi != -1) { switch (lsm.getSelectionMode()) @@ -2973,7 +3026,7 @@ public class JTable public Class getColumnClass(int column) { - return dataModel.getColumnClass(column); + return getModel().getColumnClass(column); } public String getColumnName(int column) @@ -3274,4 +3327,37 @@ public class JTable revalidate(); repaint(); } + + /** + * Sets whether cell editors of this table should receive keyboard focus + * when the editor is activated by a keystroke. The default setting is + * <code>false</code> which means that the table should keep the keyboard + * focus until the cell is selected by a mouse click. + * + * @param value the value to set + * + * @since 1.4 + */ + public void setSurrendersFocusOnKeystroke(boolean value) + { + // TODO: Implement functionality of this property (in UI impl). + surrendersFocusOnKeystroke = value; + } + + /** + * Returns whether cell editors of this table should receive keyboard focus + * when the editor is activated by a keystroke. The default setting is + * <code>false</code> which means that the table should keep the keyboard + * focus until the cell is selected by a mouse click. + * + * @return whether cell editors of this table should receive keyboard focus + * when the editor is activated by a keystroke + * + * @since 1.4 + */ + public boolean getSurrendersFocusOnKeystroke() + { + // TODO: Implement functionality of this property (in UI impl). + return surrendersFocusOnKeystroke; + } } diff --git a/libjava/classpath/javax/swing/JTextArea.java b/libjava/classpath/javax/swing/JTextArea.java index 2fa185b..9b50feb 100644 --- a/libjava/classpath/javax/swing/JTextArea.java +++ b/libjava/classpath/javax/swing/JTextArea.java @@ -217,7 +217,11 @@ public class JTextArea extends JTextComponent public JTextArea(Document doc, String text, int rows, int columns) { setDocument(doc == null ? createDefaultModel() : doc); - setText(text); + // Only explicitly setText() when there is actual text since + // setText() might be overridden and not expected to be called + // from the constructor (as in JEdit). + if (text != null) + setText(text); setRows(rows); setColumns(columns); } diff --git a/libjava/classpath/javax/swing/JTextField.java b/libjava/classpath/javax/swing/JTextField.java index 8dc2f25..c490310 100644 --- a/libjava/classpath/javax/swing/JTextField.java +++ b/libjava/classpath/javax/swing/JTextField.java @@ -203,9 +203,22 @@ public class JTextField extends JTextComponent */ protected Document createDefaultModel() { - PlainDocument doc = new PlainDocument(); + return new PlainDocument(); + } + + /** + * Sets the document to be used for this JTextField. + * + * This sets the document property <code>filterNewlines</code> to + * <code>true</code> and then calls the super behaviour to setup a view and + * revalidate the text field. + * + * @param doc the document to set + */ + public void setDocument(Document doc) + { doc.putProperty("filterNewlines", Boolean.TRUE); - return doc; + super.setDocument(doc); } /** diff --git a/libjava/classpath/javax/swing/JTextPane.java b/libjava/classpath/javax/swing/JTextPane.java index a2aebd4..7c95d76 100644 --- a/libjava/classpath/javax/swing/JTextPane.java +++ b/libjava/classpath/javax/swing/JTextPane.java @@ -40,6 +40,7 @@ package javax.swing; import java.awt.Component; +import javax.swing.text.AbstractDocument; import javax.swing.text.AttributeSet; import javax.swing.text.BadLocationException; import javax.swing.text.Caret; @@ -151,38 +152,34 @@ public class JTextPane { Caret caret = getCaret(); StyledDocument doc = getStyledDocument(); + AttributeSet a = getInputAttributes().copyAttributes(); + if (doc == null) + return; int dot = caret.getDot(); int mark = caret.getMark(); - // If content is empty delete selection. - if (content == null) - { - caret.setDot(dot); - return; - } + int p0 = Math.min (dot, mark); + int p1 = Math.max (dot, mark); try { - int start = getSelectionStart(); - int end = getSelectionEnd(); - int contentLength = content.length(); - - // Remove selected text. - if (dot != mark) - doc.remove(start, end - start); - - // Insert new text. - doc.insertString(start, content, null); - // Set attributes for inserted text - doc.setCharacterAttributes(start, contentLength, getInputAttributes(), - true); - + if (doc instanceof AbstractDocument) + ((AbstractDocument)doc).replace(p0, p1 - p0, content, a); + else + { + // Remove selected text. + if (dot != mark) + doc.remove(p0, p1 - p0); + // Insert new text. + if (content != null && content.length() > 0) + doc.insertString(p0, content, a); + } } catch (BadLocationException e) { - throw new AssertionError - ("No BadLocationException should be thrown here"); + throw new AssertionError + ("No BadLocationException should be thrown here"); } } diff --git a/libjava/classpath/javax/swing/JTree.java b/libjava/classpath/javax/swing/JTree.java index 4422a19..cfcb229 100644 --- a/libjava/classpath/javax/swing/JTree.java +++ b/libjava/classpath/javax/swing/JTree.java @@ -1481,6 +1481,7 @@ public class JTree extends JComponent implements Scrollable, Accessible setRootVisible(true); setModel(model); setSelectionModel(new EmptySelectionModel()); + selectionModel.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); } /** diff --git a/libjava/classpath/javax/swing/JViewport.java b/libjava/classpath/javax/swing/JViewport.java index 5f20f0a..debb574 100644 --- a/libjava/classpath/javax/swing/JViewport.java +++ b/libjava/classpath/javax/swing/JViewport.java @@ -38,6 +38,8 @@ exception statement from your version. */ package javax.swing; +import gnu.classpath.SystemProperties; + import java.awt.Component; import java.awt.Dimension; import java.awt.Graphics; @@ -163,7 +165,13 @@ public class JViewport extends JComponent implements Accessible public static final int BACKINGSTORE_SCROLL_MODE = 2; private static final long serialVersionUID = -6925142919680527970L; - + + /** + * The default scrollmode to be used by all JViewports as determined by + * the system property gnu.javax.swing.JViewport.scrollMode. + */ + private static final int defaultScrollMode; + protected boolean scrollUnderway; protected boolean isViewSizeSet; @@ -243,21 +251,26 @@ public class JViewport extends JComponent implements Accessible */ boolean sizeChanged = true; - public JViewport() + /** + * Initializes the default setting for the scrollMode property. + */ + static { - setOpaque(true); String scrollModeProp = - System.getProperty("gnu.javax.swing.JViewport.scrollMode", + SystemProperties.getProperty("gnu.javax.swing.JViewport.scrollMode", "BLIT"); - int myScrollMode; if (scrollModeProp.equalsIgnoreCase("simple")) - myScrollMode = SIMPLE_SCROLL_MODE; + defaultScrollMode = SIMPLE_SCROLL_MODE; else if (scrollModeProp.equalsIgnoreCase("backingstore")) - myScrollMode = BACKINGSTORE_SCROLL_MODE; + defaultScrollMode = BACKINGSTORE_SCROLL_MODE; else - myScrollMode = BLIT_SCROLL_MODE; - setScrollMode(myScrollMode); + defaultScrollMode = BLIT_SCROLL_MODE; + } + public JViewport() + { + setOpaque(true); + setScrollMode(defaultScrollMode); updateUI(); setLayout(createLayoutManager()); lastPaintPosition = new Point(); @@ -410,8 +423,9 @@ public class JViewport extends JComponent implements Accessible public void setView(Component v) { - if (viewListener != null) - getView().removeComponentListener(viewListener); + Component currView = getView(); + if (viewListener != null && currView != null) + currView.removeComponentListener(viewListener); if (v != null) { @@ -772,6 +786,9 @@ public class JViewport extends JComponent implements Accessible */ void paintSimple(Graphics g) { + // We need to call this to properly clear the background. + paintComponent(g); + Point pos = getViewPosition(); Component view = getView(); boolean translated = false; diff --git a/libjava/classpath/javax/swing/LookAndFeel.java b/libjava/classpath/javax/swing/LookAndFeel.java index 1a67e84..358a811 100644 --- a/libjava/classpath/javax/swing/LookAndFeel.java +++ b/libjava/classpath/javax/swing/LookAndFeel.java @@ -300,11 +300,11 @@ public abstract class LookAndFeel /** * Returns a string that displays and identifies this object's properties. * - * @return the string "LookAndFeel" + * @return string containing the description and class name. */ public String toString() { - return "LookAndFeel"; + return getDescription() + " " + getClass().getName(); } /** diff --git a/libjava/classpath/javax/swing/Popup.java b/libjava/classpath/javax/swing/Popup.java index cbb243e..203ee3c 100644 --- a/libjava/classpath/javax/swing/Popup.java +++ b/libjava/classpath/javax/swing/Popup.java @@ -41,6 +41,7 @@ package javax.swing; import java.awt.Component; import java.awt.FlowLayout; import java.awt.Point; +import java.awt.Rectangle; /** @@ -291,7 +292,9 @@ public class Popup */ public void hide() { + Rectangle bounds = panel.getBounds(); layeredPane.remove(panel); + layeredPane.repaint(bounds.x, bounds.y, bounds.width, bounds.height); } } } diff --git a/libjava/classpath/javax/swing/RepaintManager.java b/libjava/classpath/javax/swing/RepaintManager.java index b857b12..0be8105 100644 --- a/libjava/classpath/javax/swing/RepaintManager.java +++ b/libjava/classpath/javax/swing/RepaintManager.java @@ -48,6 +48,7 @@ import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; +import java.util.WeakHashMap; /** * <p>The repaint manager holds a set of dirty regions, invalid components, @@ -68,7 +69,7 @@ public class RepaintManager /** * The current repaint managers, indexed by their ThreadGroups. */ - static HashMap currentRepaintManagers; + static WeakHashMap currentRepaintManagers; /** * <p>A helper class which is placed into the system event queue at @@ -286,7 +287,7 @@ public class RepaintManager public static RepaintManager currentManager(Component component) { if (currentRepaintManagers == null) - currentRepaintManagers = new HashMap(); + currentRepaintManagers = new WeakHashMap(); ThreadGroup threadGroup = Thread.currentThread().getThreadGroup(); RepaintManager currentManager = (RepaintManager) currentRepaintManagers.get(threadGroup); @@ -330,7 +331,7 @@ public class RepaintManager public static void setCurrentManager(RepaintManager manager) { if (currentRepaintManagers == null) - currentRepaintManagers = new HashMap(); + currentRepaintManagers = new WeakHashMap(); ThreadGroup threadGroup = Thread.currentThread().getThreadGroup(); currentRepaintManagers.put(threadGroup, manager); @@ -533,7 +534,14 @@ public class RepaintManager } for (Iterator i = workInvalidComponents.iterator(); i.hasNext(); ) { - JComponent comp = (JComponent) i.next(); + Component comp = (Component) i.next(); + // Find validate root. + while ((!(comp instanceof JComponent) + || !((JComponent) comp).isValidateRoot()) + && comp.getParent() != null) + comp = comp.getParent(); + + // Validate the validate root. if (! (comp.isVisible() && comp.isShowing())) continue; comp.validate(); diff --git a/libjava/classpath/javax/swing/SwingUtilities.java b/libjava/classpath/javax/swing/SwingUtilities.java index 58b3a78..2d859b7 100644 --- a/libjava/classpath/javax/swing/SwingUtilities.java +++ b/libjava/classpath/javax/swing/SwingUtilities.java @@ -1395,4 +1395,30 @@ public class SwingUtilities else return null; } + + /** + * Processes key bindings for the component that is associated with the + * key event. Note that this method does not make sense for + * JComponent-derived components, except when + * {@link JComponent#processKeyEvent(KeyEvent)} is overridden and super is + * not called. + * + * This method searches through the component hierarchy of the component's + * top-level container to find a <code>JComponent</code> that has a binding + * for the key event in the WHEN_IN_FOCUSED_WINDOW scope. + * + * @param ev the key event + * + * @return <code>true</code> if a binding has been found and processed, + * <code>false</code> otherwise + * + * @since 1.4 + */ + public static boolean processKeyBindings(KeyEvent ev) + { + Component c = ev.getComponent(); + KeyStroke s = KeyStroke.getKeyStrokeForEvent(ev); + KeyboardManager km = KeyboardManager.getManager(); + return km.processKeyStroke(c, s, ev); + } } diff --git a/libjava/classpath/javax/swing/TransferHandler.java b/libjava/classpath/javax/swing/TransferHandler.java index 4828fdb..830feee 100644 --- a/libjava/classpath/javax/swing/TransferHandler.java +++ b/libjava/classpath/javax/swing/TransferHandler.java @@ -1,5 +1,5 @@ /* TransferHandler.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -43,6 +43,7 @@ import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.event.ActionEvent; import java.awt.event.InputEvent; +import java.awt.Toolkit; import java.io.Serializable; public class TransferHandler implements Serializable @@ -53,6 +54,7 @@ public class TransferHandler implements Serializable public TransferAction(String command) { + super(command); this.command = command; } @@ -62,6 +64,13 @@ public class TransferHandler implements Serializable TransferHandler transferHandler = component.getTransferHandler(); Clipboard clipboard = getClipboard(component); + if (clipboard == null) + { + // Access denied! + Toolkit.getDefaultToolkit().beep(); + return; + } + if (command.equals(COMMAND_COPY)) transferHandler.exportToClipboard(component, clipboard, COPY); else if (command.equals(COMMAND_CUT)) @@ -76,37 +85,22 @@ public class TransferHandler implements Serializable } /** - * Get the system cliboard. If not available, create and return the VM-local - * clipboard. + * Get the system cliboard or null if the caller isn't allowed to + * access the system clipboard. * * @param component a component, used to get the toolkit. * @return the clipboard */ private static Clipboard getClipboard(JComponent component) { - // Avoid throwing exception if the system clipboard access failed - // in the past. - if (clipboard != null) - return clipboard; - else - { - try - { - SecurityManager sm = System.getSecurityManager(); - if (sm != null) - sm.checkSystemClipboardAccess(); - - // We may access system clipboard. - return component.getToolkit().getSystemClipboard(); - } - catch (Exception e) - { - // We may not access system clipboard. - // Create VM-local clipboard if none exists yet. - clipboard = new Clipboard("Clipboard"); - return clipboard; - } - } + try + { + return component.getToolkit().getSystemClipboard(); + } + catch (SecurityException se) + { + return null; + } } } @@ -125,12 +119,6 @@ public class TransferHandler implements Serializable private static Action cutAction = new TransferAction(COMMAND_CUT); private static Action pasteAction = new TransferAction(COMMAND_PASTE); - /** - * Clipboard if system clipboard may not be used. - * Package-private to avoid an accessor method. - */ - static Clipboard clipboard; - private int sourceActions; private Icon visualRepresentation; diff --git a/libjava/classpath/javax/swing/UIDefaults.java b/libjava/classpath/javax/swing/UIDefaults.java index f6aee1b..00d9700 100644 --- a/libjava/classpath/javax/swing/UIDefaults.java +++ b/libjava/classpath/javax/swing/UIDefaults.java @@ -54,6 +54,7 @@ import java.util.ResourceBundle; import javax.swing.border.Border; import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.InputMapUIResource; /** * UIDefaults is a database where all settings and interface bindings are @@ -95,10 +96,14 @@ public class UIDefaults extends Hashtable } public Object createValue(UIDefaults table) { - InputMap im = new InputMap (); + InputMapUIResource im = new InputMapUIResource (); for (int i = 0; 2*i+1 < bind.length; ++i) { - im.put (KeyStroke.getKeyStroke ((String) bind[2*i]), + Object curr = bind[2*i]; + if (curr instanceof KeyStroke) + im.put((KeyStroke) curr, bind[2*i+1]); + else + im.put(KeyStroke.getKeyStroke((String) curr), bind[2*i+1]); } return im; diff --git a/libjava/classpath/javax/swing/ViewportLayout.java b/libjava/classpath/javax/swing/ViewportLayout.java index 884f7cb..79fd26c 100644 --- a/libjava/classpath/javax/swing/ViewportLayout.java +++ b/libjava/classpath/javax/swing/ViewportLayout.java @@ -143,32 +143,32 @@ public class ViewportLayout implements LayoutManager, Serializable Dimension viewMinimum = view.getMinimumSize(); Point portLowerRight = new Point(portBounds.x + portBounds.width, portBounds.y + portBounds.height); - + // vertical implementation of the above rules + if ((! (view instanceof Scrollable) && viewPref.height < portBounds.height + || (view instanceof Scrollable + && ((Scrollable) view).getScrollableTracksViewportHeight()))) + viewPref.height = portBounds.height; + if (portBounds.height >= viewMinimum.height) - { - portBounds.y = 0; - if ( !(view instanceof Scrollable) || ((Scrollable)view).getScrollableTracksViewportHeight()) - viewPref.height = portBounds.height; - } + portBounds.y = 0; else { - viewPref.height = viewMinimum.height; int overextension = portLowerRight.y - viewPref.height; if (overextension > 0) portBounds.y -= overextension; } // horizontal implementation of the above rules + if ((! (view instanceof Scrollable) && viewPref.width < portBounds.width + || (view instanceof Scrollable + && ((Scrollable) view).getScrollableTracksViewportWidth()))) + viewPref.width = portBounds.width; + if (portBounds.width >= viewMinimum.width) - { - portBounds.x = 0; - if ( !(view instanceof Scrollable) || ((Scrollable)view).getScrollableTracksViewportWidth()) - viewPref.width = portBounds.width; - } + portBounds.x = 0; else { - viewPref.width = viewMinimum.width; int overextension = portLowerRight.x - viewPref.width; if (overextension > 0) portBounds.x -= overextension; diff --git a/libjava/classpath/javax/swing/event/EventListenerList.java b/libjava/classpath/javax/swing/event/EventListenerList.java index ee3f220..147d68e 100644 --- a/libjava/classpath/javax/swing/event/EventListenerList.java +++ b/libjava/classpath/javax/swing/event/EventListenerList.java @@ -228,7 +228,7 @@ public class EventListenerList count = getListenerCount(c); result = (EventListener[]) Array.newInstance(c, count); f = 0; - for (int i = 0; i < listenerList.length; i += 2) + for (int i = listenerList.length - 2; i >= 0; i -= 2) if (listenerList[i] == c) result[f++] = (EventListener) listenerList[i + 1]; diff --git a/libjava/classpath/javax/swing/plaf/ComponentUI.java b/libjava/classpath/javax/swing/plaf/ComponentUI.java index 6a736f2..be7b68a 100644 --- a/libjava/classpath/javax/swing/plaf/ComponentUI.java +++ b/libjava/classpath/javax/swing/plaf/ComponentUI.java @@ -41,7 +41,6 @@ package javax.swing.plaf; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; -import java.awt.Rectangle; import javax.accessibility.Accessible; import javax.swing.JComponent; @@ -185,12 +184,12 @@ public abstract class ComponentUI public void update(Graphics g, JComponent c) { if (c.isOpaque()) - { - Color oldColor = g.getColor(); - g.setColor(c.getBackground()); - g.fillRect(0, 0, c.getWidth(), c.getHeight()); - g.setColor(oldColor); - } + { + Color oldColor = g.getColor(); + g.setColor(c.getBackground()); + g.fillRect(0, 0, c.getWidth(), c.getHeight()); + g.setColor(oldColor); + } paint(g, c); } diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicArrowButton.java b/libjava/classpath/javax/swing/plaf/basic/BasicArrowButton.java index 69d4415..56e4e70 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicArrowButton.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicArrowButton.java @@ -162,8 +162,8 @@ public class BasicArrowButton extends JButton implements SwingConstants super.paint(g); Rectangle bounds = getBounds(); int size = bounds.height / 4; - int x = (bounds.width - size) / 2; - int y = (bounds.height - size) / 2; + int x = bounds.x + (bounds.width - size) / 2; + int y = (bounds.height - size) / 4; ButtonModel m = getModel(); if (m.isArmed()) { diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicComboBoxUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicComboBoxUI.java index b22aa15..288a8d8 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicComboBoxUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicComboBoxUI.java @@ -190,10 +190,19 @@ public class BasicComboBoxUI extends ComboBoxUI */ Dimension displaySize; - // FIXME: This fields aren't used anywhere at this moment. - protected Dimension cachedMinimumSize; + // FIXME: This field isn't used anywhere at this moment. protected CellRendererPane currentValuePane; - protected boolean isMinimumSizeDirty; + + /** + * The current minimum size if isMinimumSizeDirty is false. + * Setup by getMinimumSize() and invalidated by the various listeners. + */ + protected Dimension cachedMinimumSize; + + /** + * Indicates whether or not the cachedMinimumSize field is valid or not. + */ + protected boolean isMinimumSizeDirty = true; /** * Creates a new <code>BasicComboBoxUI</code> object. @@ -285,8 +294,7 @@ public class BasicComboBoxUI extends ComboBoxUI comboBox.addPropertyChangeListener(propertyChangeListener); focusListener = createFocusListener(); - comboBox.addFocusListener(focusListener); - listBox.addFocusListener(focusListener); + editor.addFocusListener(focusListener); itemListener = createItemListener(); comboBox.addItemListener(itemListener); @@ -563,6 +571,7 @@ public class BasicComboBoxUI extends ComboBoxUI { arrowButton.setEnabled(comboBox.isEnabled()); arrowButton.setFont(comboBox.getFont()); + arrowButton.setFocusable(false); } /** @@ -615,12 +624,14 @@ public class BasicComboBoxUI extends ComboBoxUI public void setPopupVisible(JComboBox c, boolean v) { if (v) - { - popup.show(); - popup.getList().requestFocus(); - } + popup.show(); else popup.hide(); + + if (comboBox.isEditable()) + editor.requestFocus(); + else + comboBox.requestFocus(); } /** @@ -668,7 +679,7 @@ public class BasicComboBoxUI extends ComboBoxUI /** * Returns the minimum size for this {@link JComboBox} for this - * look and feel. + * look and feel. Also makes sure cachedMinimimSize is setup correctly. * * @param c The {@link JComponent} to find the minimum size for. * @@ -676,10 +687,15 @@ public class BasicComboBoxUI extends ComboBoxUI */ public Dimension getMinimumSize(JComponent c) { - Dimension d = getDisplaySize(); - int arrowButtonWidth = d.height; - Dimension result = new Dimension(d.width + arrowButtonWidth, d.height); - return result; + if (isMinimumSizeDirty) + { + Dimension d = getDisplaySize(); + int arrowButtonWidth = d.height; + cachedMinimumSize = new Dimension(d.width + arrowButtonWidth, + d.height); + isMinimumSizeDirty = false; + } + return new Dimension(cachedMinimumSize); } /** The value returned by the getMaximumSize() method. */ @@ -1062,6 +1078,9 @@ public class BasicComboBoxUI extends ComboBoxUI */ public void focusGained(FocusEvent e) { + // Lets assume every change invalidates the minimumsize. + isMinimumSizeDirty = true; + hasFocus = true; comboBox.repaint(); } @@ -1074,6 +1093,9 @@ public class BasicComboBoxUI extends ComboBoxUI */ public void focusLost(FocusEvent e) { + // Lets assume every change invalidates the minimumsize. + isMinimumSizeDirty = true; + hasFocus = false; setPopupVisible(comboBox, false); comboBox.repaint(); @@ -1102,6 +1124,9 @@ public class BasicComboBoxUI extends ComboBoxUI */ public void itemStateChanged(ItemEvent e) { + // Lets assume every change invalidates the minimumsize. + isMinimumSizeDirty = true; + if (e.getStateChange() == ItemEvent.SELECTED && comboBox.isEditable()) comboBox.getEditor().setItem(e.getItem()); comboBox.repaint(); @@ -1149,6 +1174,9 @@ public class BasicComboBoxUI extends ComboBoxUI public void contentsChanged(ListDataEvent e) { // if the item is selected or deselected + + // Lets assume every change invalidates the minimumsize. + isMinimumSizeDirty = true; } /** @@ -1158,6 +1186,9 @@ public class BasicComboBoxUI extends ComboBoxUI */ public void intervalAdded(ListDataEvent e) { + // Lets assume every change invalidates the minimumsize. + isMinimumSizeDirty = true; + ComboBoxModel model = comboBox.getModel(); ListCellRenderer renderer = comboBox.getRenderer(); @@ -1179,6 +1210,9 @@ public class BasicComboBoxUI extends ComboBoxUI */ public void intervalRemoved(ListDataEvent e) { + // Lets assume every change invalidates the minimumsize. + isMinimumSizeDirty = true; + // recalculate display size of the JComboBox. displaySize = getDisplaySize(); comboBox.repaint(); @@ -1206,6 +1240,9 @@ public class BasicComboBoxUI extends ComboBoxUI */ public void propertyChange(PropertyChangeEvent e) { + // Lets assume every change invalidates the minimumsize. + isMinimumSizeDirty = true; + if (e.getPropertyName().equals("enabled")) { arrowButton.setEnabled(comboBox.isEnabled()); diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicComboPopup.java b/libjava/classpath/javax/swing/plaf/basic/BasicComboPopup.java index 73979bb..08dab7f 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicComboPopup.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicComboPopup.java @@ -442,6 +442,7 @@ public class BasicComboPopup extends JPopupMenu implements ComboPopup { list.setModel(comboBox.getModel()); list.setVisibleRowCount(comboBox.getMaximumRowCount()); + list.setFocusable(false); installListListeners(); } diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicFileChooserUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicFileChooserUI.java index 60179dc..30e3156 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicFileChooserUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicFileChooserUI.java @@ -37,19 +37,8 @@ exception statement from your version. */ package javax.swing.plaf.basic; -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Component; -import java.awt.Dimension; -import java.awt.Graphics; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.Point; -import java.awt.Polygon; import java.awt.Window; import java.awt.event.ActionEvent; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; @@ -62,23 +51,16 @@ import java.util.Hashtable; import javax.swing.AbstractAction; import javax.swing.Action; -import javax.swing.ButtonGroup; import javax.swing.Icon; import javax.swing.JButton; -import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JFileChooser; -import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; -import javax.swing.JScrollPane; import javax.swing.JTextField; -import javax.swing.JToggleButton; -import javax.swing.ListCellRenderer; -import javax.swing.SwingConstants; import javax.swing.SwingUtilities; -import javax.swing.Timer; +import javax.swing.UIDefaults; import javax.swing.UIManager; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; @@ -87,6 +69,7 @@ import javax.swing.filechooser.FileSystemView; import javax.swing.filechooser.FileView; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.FileChooserUI; +import javax.swing.plaf.metal.MetalIconFactory; /** @@ -144,7 +127,7 @@ public class BasicFileChooserUI extends FileChooserUI */ protected ApproveSelectionAction() { - // Nothing to do here. + super("approveSelection"); } /** @@ -154,17 +137,22 @@ public class BasicFileChooserUI extends FileChooserUI */ public void actionPerformed(ActionEvent e) { - Object obj = new String(parentPath + entry.getText()); + Object obj = null; + if (parentPath != null) + obj = new String(parentPath + getFileName()); + else + obj = filechooser.getSelectedFile(); if (obj != null) { - File f = filechooser.getFileSystemView().createFileObject( - obj.toString()); - if (filechooser.isTraversable(f) - && filechooser.isDirectorySelectionEnabled()) - filechooser.setCurrentDirectory(f); + File f = filechooser.getFileSystemView().createFileObject(obj.toString()); + File currSelected = filechooser.getSelectedFile(); + if (filechooser.isTraversable(f)) + { + filechooser.setCurrentDirectory(currSelected); + filechooser.rescanCurrentDirectory(); + } else { - filechooser.setSelectedFile(f); filechooser.approveSelection(); closeDialog(); } @@ -307,7 +295,7 @@ public class BasicFileChooserUI extends FileChooserUI */ protected CancelSelectionAction() { - // Nothing to do here. + super(null); } /** @@ -317,6 +305,8 @@ public class BasicFileChooserUI extends FileChooserUI */ public void actionPerformed(ActionEvent e) { + filechooser.setSelectedFile(null); + filechooser.setSelectedFiles(null); filechooser.cancelSelection(); closeDialog(); } @@ -335,7 +325,7 @@ public class BasicFileChooserUI extends FileChooserUI */ protected ChangeToParentDirectoryAction() { - // Nothing to do here. + super("Go Up"); } /** @@ -358,8 +348,6 @@ public class BasicFileChooserUI extends FileChooserUI */ protected class DoubleClickListener extends MouseAdapter { - /** A timer. */ - private Timer timer = null; /** DOCUMENT ME! */ private Object lastSelected = null; @@ -375,8 +363,6 @@ public class BasicFileChooserUI extends FileChooserUI public DoubleClickListener(JList list) { this.list = list; - timer = new Timer(1000, null); - timer.setRepeats(false); lastSelected = list.getSelectedValue(); setDirectorySelected(false); } @@ -388,14 +374,14 @@ public class BasicFileChooserUI extends FileChooserUI */ public void mouseClicked(MouseEvent e) { - if (list.getSelectedValue() == null) + Object p = list.getSelectedValue(); + if (p == null) return; FileSystemView fsv = filechooser.getFileSystemView(); - if (timer.isRunning() - && list.getSelectedValue().toString().equals(lastSelected.toString())) + if (e.getClickCount() >= 2 && lastSelected != null && + p.toString().equals(lastSelected.toString())) { File f = fsv.createFileObject(lastSelected.toString()); - timer.stop(); if (filechooser.isTraversable(f)) { filechooser.setCurrentDirectory(f); @@ -410,8 +396,19 @@ public class BasicFileChooserUI extends FileChooserUI } else { - String path = list.getSelectedValue().toString(); + String path = p.toString(); File f = fsv.createFileObject(path); + filechooser.setSelectedFile(f); + + if (filechooser.isMultiSelectionEnabled()) + { + int[] inds = list.getSelectedIndices(); + File[] allFiles = new File[inds.length]; + for (int i = 0; i < inds.length; i++) + allFiles[i] = (File) list.getModel().getElementAt(inds[i]); + filechooser.setSelectedFiles(allFiles); + } + if (filechooser.isTraversable(f)) { setDirectorySelected(true); @@ -424,8 +421,11 @@ public class BasicFileChooserUI extends FileChooserUI } lastSelected = path; parentPath = path.substring(0, path.lastIndexOf("/") + 1); - entry.setText(path.substring(path.lastIndexOf("/") + 1)); - timer.restart(); + if (f.isFile()) + setFileName(path.substring(path.lastIndexOf("/") + 1)); + else if (filechooser.getFileSelectionMode() == + JFileChooser.DIRECTORIES_ONLY) + setFileName(path); } } @@ -453,7 +453,7 @@ public class BasicFileChooserUI extends FileChooserUI */ protected GoHomeAction() { - // Nothing to do here. + super("Go Home"); } /** @@ -483,7 +483,7 @@ public class BasicFileChooserUI extends FileChooserUI */ protected NewFolderAction() { - // Nothing to do here. + super("New Folder"); } /** @@ -529,7 +529,8 @@ public class BasicFileChooserUI extends FileChooserUI */ public void valueChanged(ListSelectionEvent e) { - Object f = filelist.getSelectedValue(); + JList list = (JList) e.getSource(); + Object f = list.getSelectedValue(); if (f == null) return; File file = filechooser.getFileSystemView().createFileObject(f.toString()); @@ -552,7 +553,7 @@ public class BasicFileChooserUI extends FileChooserUI */ protected UpdateAction() { - // Nothing to do here. + super(null); } /** @@ -576,91 +577,13 @@ public class BasicFileChooserUI extends FileChooserUI protected String cancelButtonToolTipText; /** An icon representing a computer. */ - protected Icon computerIcon = new Icon() - { - public int getIconHeight() - { - return ICON_SIZE; - } - - public int getIconWidth() - { - return ICON_SIZE; - } - - public void paintIcon(Component c, Graphics g, int x, int y) - { - // FIXME: is this not implemented, or is the icon intentionally blank? - } - }; + protected Icon computerIcon; /** An icon for the "details view" button. */ - protected Icon detailsViewIcon = new Icon() - { - public int getIconHeight() - { - return ICON_SIZE; - } - - public int getIconWidth() - { - return ICON_SIZE; - } - - public void paintIcon(Component c, Graphics g, int x, int y) - { - Color saved = g.getColor(); - g.translate(x, y); - - g.setColor(Color.GRAY); - g.drawRect(1, 1, 15, 20); - g.drawLine(17, 6, 23, 6); - g.drawLine(17, 12, 23, 12); - g.drawLine(17, 18, 23, 18); - - g.setColor(saved); - g.translate(-x, -y); - } - }; + protected Icon detailsViewIcon; /** An icon representing a directory. */ - protected Icon directoryIcon = new Icon() - { - public int getIconHeight() - { - return ICON_SIZE; - } - - public int getIconWidth() - { - return ICON_SIZE; - } - - public void paintIcon(Component c, Graphics g, int x, int y) - { - Color saved = g.getColor(); - g.translate(x, y); - - Point ap = new Point(3, 7); - Point bp = new Point(3, 21); - Point cp = new Point(21, 21); - Point dp = new Point(21, 12); - Point ep = new Point(16, 12); - Point fp = new Point(13, 7); - - Polygon dir = new Polygon(new int[] { ap.x, bp.x, cp.x, dp.x, ep.x, fp.x }, - new int[] { ap.y, bp.y, cp.y, dp.y, ep.y, fp.y }, - 6); - - g.setColor(new Color(153, 204, 255)); - g.fillPolygon(dir); - g.setColor(Color.BLACK); - g.drawPolygon(dir); - - g.translate(-x, -y); - g.setColor(saved); - } - }; + protected Icon directoryIcon; /** The localised Mnemonic for the open button. */ protected int directoryOpenButtonMnemonic; @@ -672,82 +595,13 @@ public class BasicFileChooserUI extends FileChooserUI protected String directoryOpenButtonToolTipText; /** An icon representing a file. */ - protected Icon fileIcon = new Icon() - { - public int getIconHeight() - { - return ICON_SIZE; - } - - public int getIconWidth() - { - return ICON_SIZE; - } - - public void paintIcon(Component c, Graphics g, int x, int y) - { - Color saved = g.getColor(); - g.translate(x, y); - - Point a = new Point(5, 4); - Point b = new Point(5, 20); - Point d = new Point(19, 20); - Point e = new Point(19, 7); - Point f = new Point(16, 4); - - Polygon p = new Polygon(new int[] { a.x, b.x, d.x, e.x, f.x, }, - new int[] { a.y, b.y, d.y, e.y, f.y }, 5); - - g.setColor(Color.WHITE); - g.fillPolygon(p); - g.setColor(Color.BLACK); - g.drawPolygon(p); - - g.drawLine(16, 4, 14, 6); - g.drawLine(14, 6, 19, 7); - - g.setColor(saved); - g.translate(-x, -y); - } - }; + protected Icon fileIcon; /** An icon representing a floppy drive. */ - protected Icon floppyDriveIcon = new Icon() - { - public int getIconHeight() - { - return ICON_SIZE; - } - - public int getIconWidth() - { - return ICON_SIZE; - } - - public void paintIcon(Component c, Graphics g, int x, int y) - { - // FIXME: is this not implemented, or is the icon intentionally blank? - } - }; + protected Icon floppyDriveIcon; /** An icon representing a hard drive. */ - protected Icon hardDriveIcon = new Icon() - { - public int getIconHeight() - { - return ICON_SIZE; - } - - public int getIconWidth() - { - return ICON_SIZE; - } - - public void paintIcon(Component c, Graphics g, int x, int y) - { - // FIXME: is this not implemented, or is the icon intentionally blank? - } - }; + protected Icon hardDriveIcon; /** The localised mnemonic for the "help" button. */ protected int helpButtonMnemonic; @@ -759,86 +613,10 @@ public class BasicFileChooserUI extends FileChooserUI protected String helpButtonToolTipText; /** An icon representing the user's home folder. */ - protected Icon homeFolderIcon = new Icon() - { - public int getIconHeight() - { - return ICON_SIZE; - } - - public int getIconWidth() - { - return ICON_SIZE; - } - - public void paintIcon(Component c, Graphics g, int x, int y) - { - Color saved = g.getColor(); - g.translate(x, y); - - Point a = new Point(12, 3); - Point b = new Point(4, 10); - Point d = new Point(20, 10); - - Polygon p = new Polygon(new int[] { a.x, b.x, d.x }, - new int[] { a.y, b.y, d.y }, 3); - - g.setColor(new Color(104, 51, 0)); - g.fillPolygon(p); - g.setColor(Color.BLACK); - g.drawPolygon(p); - - g.setColor(Color.WHITE); - g.fillRect(8, 10, 8, 10); - g.setColor(Color.BLACK); - g.drawRect(8, 10, 8, 10); - - g.setColor(saved); - g.translate(-x, -y); - } - }; + protected Icon homeFolderIcon; /** An icon for the "list view" button. */ - protected Icon listViewIcon = new Icon() - { - public int getIconHeight() - { - return ICON_SIZE; - } - - public int getIconWidth() - { - return ICON_SIZE; - } - - // Not needed. Only simplifies things until we get real icons. - private void paintPartial(Graphics g, int x, int y) - { - Color saved = g.getColor(); - g.translate(x, y); - - g.setColor(Color.GRAY); - g.drawRect(1, 1, 7, 10); - g.drawLine(8, 6, 11, 6); - - g.setColor(saved); - g.translate(-x, -y); - } - - public void paintIcon(Component c, Graphics g, int x, int y) - { - Color saved = g.getColor(); - g.translate(x, y); - - paintPartial(g, 0, 0); - paintPartial(g, 12, 0); - paintPartial(g, 0, 12); - paintPartial(g, 12, 12); - - g.setColor(saved); - g.translate(-x, -y); - } - }; + protected Icon listViewIcon; /** An icon for the "new folder" button. */ protected Icon newFolderIcon = directoryIcon; @@ -871,65 +649,13 @@ public class BasicFileChooserUI extends FileChooserUI protected String updateButtonToolTipText; /** An icon for the "up folder" button. */ - protected Icon upFolderIcon = new Icon() - { - public int getIconHeight() - { - return ICON_SIZE; - } - - public int getIconWidth() - { - return ICON_SIZE; - } - - public void paintIcon(Component comp, Graphics g, int x, int y) - { - Color saved = g.getColor(); - g.translate(x, y); - - Point a = new Point(3, 7); - Point b = new Point(3, 21); - Point c = new Point(21, 21); - Point d = new Point(21, 12); - Point e = new Point(16, 12); - Point f = new Point(13, 7); - - Polygon dir = new Polygon(new int[] { a.x, b.x, c.x, d.x, e.x, f.x }, - new int[] { a.y, b.y, c.y, d.y, e.y, f.y }, 6); - - g.setColor(new Color(153, 204, 255)); - g.fillPolygon(dir); - g.setColor(Color.BLACK); - g.drawPolygon(dir); - - a = new Point(12, 15); - b = new Point(9, 18); - c = new Point(15, 18); - - Polygon arrow = new Polygon(new int[] { a.x, b.x, c.x }, - new int[] { a.y, b.y, c.y }, 3); - - g.fillPolygon(arrow); - - g.drawLine(12, 15, 12, 22); - - g.translate(-x, -y); - g.setColor(saved); - } - }; + protected Icon upFolderIcon; // -- begin private, but package local since used in inner classes -- /** The file chooser component represented by this UI delegate. */ JFileChooser filechooser; - /** The file list. */ - JList filelist; - - /** The combo box used to display/select file filters. */ - JComboBox filters; - /** The model for the directory list. */ BasicDirectoryModel model; @@ -939,32 +665,11 @@ public class BasicFileChooserUI extends FileChooserUI /** The default file view. */ FileView fv = new BasicFileView(); - /** The icon size. */ - static final int ICON_SIZE = 24; - - /** A combo box for display/selection of parent directories. */ - JComboBox parents; - - /** The current file name. */ - String filename; - /** The accept (open/save) button. */ JButton accept; - /** The cancel button. */ - JButton cancel; - - /** The button to move up to the parent directory. */ - JButton upFolderButton; - - /** The button to create a new directory. */ - JButton newFolderButton; - - /** The button to move to the user's home directory. */ - JButton homeFolderButton; - /** An optional accessory panel. */ - JPanel accessoryPanel; + JPanel accessoryPanel = new JPanel(); /** A property change listener. */ PropertyChangeListener propertyChangeListener; @@ -997,47 +702,43 @@ public class BasicFileChooserUI extends FileChooserUI /** Current parent path */ String parentPath; + /** + * The action for the 'approve' button. + * @see #getApproveSelectionAction() + */ + private ApproveSelectionAction approveSelectionAction; + + /** + * The action for the 'cancel' button. + * @see #getCancelSelectionAction() + */ + private CancelSelectionAction cancelSelectionAction; + + /** + * The action for the 'go home' control button. + * @see #getGoHomeAction() + */ + private GoHomeAction goHomeAction; + + /** + * The action for the 'up folder' control button. + * @see #getChangeToParentDirectoryAction() + */ + private ChangeToParentDirectoryAction changeToParentDirectoryAction; + + /** + * The action for the 'new folder' control button. + * @see #getNewFolderAction() + */ + private NewFolderAction newFolderAction; + + /** + * The action for ???. // FIXME: what is this? + * @see #getUpdateAction() + */ + private UpdateAction updateAction; + // -- end private -- - private class ListLabelRenderer extends JLabel implements ListCellRenderer - { - /** DOCUMENT ME! */ - final Color selected = new Color(153, 204, 255); - - /** - * Creates a new ListLabelRenderer object. - */ - public ListLabelRenderer() - { - super(); - setOpaque(true); - } - - /** - * DOCUMENT ME! - * - * @param list DOCUMENT ME! - * @param value DOCUMENT ME! - * @param index DOCUMENT ME! - * @param isSelected DOCUMENT ME! - * @param cellHasFocus DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - public Component getListCellRendererComponent(JList list, Object value, - int index, - boolean isSelected, - boolean cellHasFocus) - { - setHorizontalAlignment(SwingConstants.LEFT); - File file = (File) value; - setText(filechooser.getName(file)); - setIcon(filechooser.getIcon(file)); - setBackground(isSelected ? selected : Color.WHITE); - setForeground(Color.BLACK); - - return this; - } - } /** * Closes the dialog. @@ -1056,7 +757,6 @@ public class BasicFileChooserUI extends FileChooserUI */ public BasicFileChooserUI(JFileChooser b) { - this.filechooser = b; } /** @@ -1081,6 +781,7 @@ public class BasicFileChooserUI extends FileChooserUI if (c instanceof JFileChooser) { JFileChooser fc = (JFileChooser) c; + this.filechooser = fc; fc.resetChoosableFileFilters(); createModel(); clearIconCache(); @@ -1130,78 +831,7 @@ public class BasicFileChooserUI extends FileChooserUI if (parentFiles.size() == 0) return; - if (parents.getItemCount() > 0) - parents.removeAllItems(); - for (int i = parentFiles.size() - 1; i >= 0; i--) - parents.addItem(parentFiles.get(i)); - parents.setSelectedIndex(parentFiles.size() - 1); - parents.revalidate(); - parents.repaint(); - } - - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - private ItemListener createBoxListener() - { - return new ItemListener() - { - public void itemStateChanged(ItemEvent e) - { - if (parents.getItemCount() - 1 == parents.getSelectedIndex()) - return; - StringBuffer dir = new StringBuffer(); - for (int i = 0; i <= parents.getSelectedIndex(); i++) - { - dir.append(parents.getItemAt(i)); - dir.append(File.separatorChar); - } - filechooser.setCurrentDirectory(filechooser.getFileSystemView() - .createFileObject(dir - .toString())); - } - }; - } - - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - private ItemListener createFilterListener() - { - return new ItemListener() - { - public void itemStateChanged(ItemEvent e) - { - int index = filters.getSelectedIndex(); - if (index == -1) - return; - filechooser.setFileFilter(filechooser.getChoosableFileFilters()[index]); - } - }; - } - - void filterEntries() - { - FileFilter[] list = filechooser.getChoosableFileFilters(); - if (filters.getItemCount() > 0) - filters.removeAllItems(); - - int index = -1; - String selected = filechooser.getFileFilter().getDescription(); - for (int i = 0; i < list.length; i++) - { - if (selected.equals(list[i].getDescription())) - index = i; - filters.addItem(list[i].getDescription()); - } - filters.setSelectedIndex(index); - filters.revalidate(); - filters.repaint(); - } + } /** * Creates and install the subcomponents for the file chooser. @@ -1210,121 +840,6 @@ public class BasicFileChooserUI extends FileChooserUI */ public void installComponents(JFileChooser fc) { - JLabel look = new JLabel("Look In:"); - - parents = new JComboBox(); - parents.setRenderer(new BasicComboBoxRenderer()); - boxEntries(); - look.setLabelFor(parents); - JPanel parentsPanel = new JPanel(); - parentsPanel.add(look); - parentsPanel.add(parents); - JPanel buttonPanel = new JPanel(); - - upFolderButton = new JButton(); - upFolderButton.setIcon(upFolderIcon); - buttonPanel.add(upFolderButton); - - homeFolderButton = new JButton(); - homeFolderButton = new JButton(homeFolderIcon); - buttonPanel.add(homeFolderButton); - - newFolderButton = new JButton(); - newFolderButton.setIcon(newFolderIcon); - buttonPanel.add(newFolderButton); - - ButtonGroup toggles = new ButtonGroup(); - JToggleButton listViewButton = new JToggleButton(); - listViewButton.setIcon(listViewIcon); - toggles.add(listViewButton); - buttonPanel.add(listViewButton); - - JToggleButton detailsViewButton = new JToggleButton(); - detailsViewButton.setIcon(detailsViewIcon); - toggles.add(detailsViewButton); - buttonPanel.add(detailsViewButton); - - JPanel topPanel = new JPanel(); - parentsPanel.add(buttonPanel); - topPanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 0, 0)); - topPanel.add(parentsPanel); - - accessoryPanel = new JPanel(); - if (filechooser.getAccessory() != null) - accessoryPanel.add(filechooser.getAccessory(), BorderLayout.CENTER); - - filelist = new JList(model); - filelist.setVisibleRowCount(6); - JScrollPane scrollp = new JScrollPane(filelist); - scrollp.setPreferredSize(new Dimension(400, 175)); - filelist.setBackground(Color.WHITE); - - filelist.setLayoutOrientation(JList.VERTICAL_WRAP); - filelist.setCellRenderer(new ListLabelRenderer()); - - GridBagConstraints c = new GridBagConstraints(); - c.gridx = 0; - c.gridy = 0; - c.fill = GridBagConstraints.BOTH; - c.weightx = 1; - c.weighty = 1; - - JPanel centrePanel = new JPanel(); - centrePanel.setLayout(new GridBagLayout()); - centrePanel.add(scrollp, c); - - c.gridx = 1; - centrePanel.add(accessoryPanel, c); - - JLabel fileNameLabel = new JLabel("File Name:"); - JLabel fileTypesLabel = new JLabel("Files of Type:"); - - entry = new JTextField(); - filters = new JComboBox(); - filterEntries(); - - fileNameLabel.setLabelFor(entry); - fileNameLabel.setHorizontalTextPosition(SwingConstants.LEFT); - fileTypesLabel.setLabelFor(filters); - fileTypesLabel.setHorizontalTextPosition(SwingConstants.LEFT); - - closePanel = new JPanel(); - accept = getApproveButton(filechooser); - cancel = new JButton(cancelButtonText); - cancel.setMnemonic(cancelButtonMnemonic); - cancel.setToolTipText(cancelButtonToolTipText); - closePanel.add(accept); - closePanel.add(cancel); - - c.anchor = GridBagConstraints.WEST; - c.weighty = 0; - c.weightx = 0; - c.gridx = 0; - - bottomPanel = new JPanel(); - bottomPanel.setLayout(new GridBagLayout()); - bottomPanel.add(fileNameLabel, c); - - c.gridy = 1; - bottomPanel.add(fileTypesLabel, c); - c.gridx = 1; - c.gridy = 0; - c.weightx = 1; - c.weighty = 1; - bottomPanel.add(entry, c); - - c.gridy = 1; - bottomPanel.add(filters, c); - - c.fill = GridBagConstraints.NONE; - c.gridy = 2; - c.anchor = GridBagConstraints.EAST; - bottomPanel.add(closePanel, c); - - filechooser.setLayout(new BorderLayout()); - filechooser.add(topPanel, BorderLayout.NORTH); - filechooser.add(centrePanel, BorderLayout.CENTER); - filechooser.add(bottomPanel, BorderLayout.SOUTH); } /** @@ -1334,15 +849,6 @@ public class BasicFileChooserUI extends FileChooserUI */ public void uninstallComponents(JFileChooser fc) { - parents = null; - - accept = null; - cancel = null; - upFolderButton = null; - homeFolderButton = null; - newFolderButton = null; - - filelist = null; } /** @@ -1354,17 +860,6 @@ public class BasicFileChooserUI extends FileChooserUI { propertyChangeListener = createPropertyChangeListener(filechooser); filechooser.addPropertyChangeListener(propertyChangeListener); - - //parents.addItemListener(createBoxListener()); - accept.addActionListener(getApproveSelectionAction()); - cancel.addActionListener(getCancelSelectionAction()); - upFolderButton.addActionListener(getChangeToParentDirectoryAction()); - homeFolderButton.addActionListener(getGoHomeAction()); - newFolderButton.addActionListener(getNewFolderAction()); - filters.addItemListener(createFilterListener()); - - filelist.addMouseListener(createDoubleClickListener(filechooser, filelist)); - filelist.addListSelectionListener(createListSelectionListener(filechooser)); } /** @@ -1401,24 +896,42 @@ public class BasicFileChooserUI extends FileChooserUI } /** - * Installs the icons for this UI delegate (NOT YET IMPLEMENTED). + * Installs the icons for this UI delegate. * - * @param fc the file chooser. + * @param fc the file chooser (ignored). */ protected void installIcons(JFileChooser fc) { - // FIXME: Implement. + UIDefaults defaults = UIManager.getLookAndFeelDefaults(); + computerIcon = MetalIconFactory.getTreeComputerIcon(); + detailsViewIcon = defaults.getIcon("FileChooser.detailsViewIcon"); + directoryIcon = new MetalIconFactory.TreeFolderIcon(); + fileIcon = new MetalIconFactory.TreeLeafIcon(); + floppyDriveIcon = MetalIconFactory.getTreeFloppyDriveIcon(); + hardDriveIcon = MetalIconFactory.getTreeHardDriveIcon(); + homeFolderIcon = defaults.getIcon("FileChooser.homeFolderIcon"); + listViewIcon = defaults.getIcon("FileChooser.listViewIcon"); + newFolderIcon = defaults.getIcon("FileChooser.newFolderIcon"); + upFolderIcon = defaults.getIcon("FileChooser.upFolderIcon"); } /** - * Uninstalls the icons previously added by this UI delegate (NOT YET - * IMPLEMENTED). + * Uninstalls the icons previously added by this UI delegate. * * @param fc the file chooser. */ protected void uninstallIcons(JFileChooser fc) { - // FIXME: Implement. + computerIcon = null; + detailsViewIcon = null; + directoryIcon = null; + fileIcon = null; + floppyDriveIcon = null; + hardDriveIcon = null; + homeFolderIcon = null; + listViewIcon = null; + newFolderIcon = null; + upFolderIcon = null; } /** @@ -1428,25 +941,36 @@ public class BasicFileChooserUI extends FileChooserUI */ protected void installStrings(JFileChooser fc) { - acceptAllFileFilterText = UIManager.getString("FileChooser.acceptAllFileFilterText"); - cancelButtonMnemonic = UIManager.getInt("FileChooser.cancelButtonMnemonic"); - cancelButtonText = UIManager.getString("FileChooser.cancelButtonText"); - cancelButtonToolTipText = UIManager.getString("FileChooser.cancelButtonToolTipText"); + UIDefaults defaults = UIManager.getLookAndFeelDefaults(); + + dirDescText = defaults.getString("FileChooser.directoryDescriptionText"); + fileDescText = defaults.getString("FileChooser.fileDescriptionText"); - dirDescText = UIManager.getString("FileChooser.directoryDescriptionText"); - fileDescText = UIManager.getString("FileChooser.fileDescriptionText"); + acceptAllFileFilterText = defaults.getString("FileChooser.acceptAllFileFilterText"); + cancelButtonText = "Cancel"; + cancelButtonToolTipText = "Abort file chooser dialog"; + cancelButtonMnemonic = new Integer((String) UIManager.get("FileChooser.cancelButtonMnemonic")).intValue(); - helpButtonMnemonic = UIManager.getInt("FileChooser.helpButtonMnemonic"); - helpButtonText = UIManager.getString("FileChooser.helpButtonText"); - helpButtonToolTipText = UIManager.getString("FileChooser.helpButtonToolTipText"); + directoryOpenButtonText = "Open"; + directoryOpenButtonToolTipText = "Open selected directory"; + directoryOpenButtonMnemonic + = new Integer((String) UIManager.get("FileChooser.directoryOpenButtonMnemonic")).intValue(); + + helpButtonText = "Help"; + helpButtonToolTipText = "FileChooser help"; + helpButtonMnemonic = new Integer((String) UIManager.get("FileChooser.helpButtonMnemonic")).intValue(); - openButtonMnemonic = UIManager.getInt("FileChooser.openButtonMnemonic"); - openButtonText = UIManager.getString("FileChooser.openButtonText"); - openButtonToolTipText = UIManager.getString("FileChooser.openButtonToolTipText"); + openButtonText = "Open"; + openButtonToolTipText = "Open selected file"; + openButtonMnemonic = new Integer((String) UIManager.get("FileChooser.openButtonMnemonic")).intValue(); - saveButtonMnemonic = UIManager.getInt("FileChooser.saveButtonMnemonic"); - saveButtonText = UIManager.getString("FileChooser.saveButtonText"); - saveButtonToolTipText = UIManager.getString("FileChooser.saveButtonToolTipText"); + saveButtonText = "Save"; + saveButtonToolTipText = "Save selected file"; + saveButtonMnemonic = new Integer((String) UIManager.get("FileChooser.saveButtonMnemonic")).intValue(); + + updateButtonText = "Update"; + updateButtonToolTipText = "Update directory listing"; + updateButtonMnemonic = new Integer((String) UIManager.get("FileChooser.updateButtonMnemonic")).intValue(); } /** @@ -1457,24 +981,26 @@ public class BasicFileChooserUI extends FileChooserUI protected void uninstallStrings(JFileChooser fc) { acceptAllFileFilterText = null; - cancelButtonMnemonic = 0; + dirDescText = null; + fileDescText = null; + cancelButtonText = null; cancelButtonToolTipText = null; - dirDescText = null; - fileDescText = null; + directoryOpenButtonText = null; + directoryOpenButtonToolTipText = null; - helpButtonMnemonic = 0; helpButtonText = null; helpButtonToolTipText = null; - openButtonMnemonic = 0; openButtonText = null; openButtonToolTipText = null; - saveButtonMnemonic = 0; saveButtonText = null; saveButtonToolTipText = null; + + updateButtonText = null; + updateButtonToolTipText = null; } /** @@ -1509,110 +1035,6 @@ public class BasicFileChooserUI extends FileChooserUI { public void propertyChange(PropertyChangeEvent e) { - // FIXME: Multiple file selection waiting on JList multiple selection - // bug. - if (e.getPropertyName().equals( - JFileChooser.SELECTED_FILE_CHANGED_PROPERTY)) - { - if (filechooser.getSelectedFile() == null) - setFileName(null); - else - setFileName(filechooser.getSelectedFile().toString()); - int index = -1; - File file = filechooser.getSelectedFile(); - for (index = 0; index < model.getSize(); index++) - if (((File) model.getElementAt(index)).equals(file)) - break; - if (index == -1) - return; - filelist.setSelectedIndex(index); - filelist.ensureIndexIsVisible(index); - filelist.revalidate(); - filelist.repaint(); - } - else if (e.getPropertyName().equals( - JFileChooser.DIRECTORY_CHANGED_PROPERTY)) - { - filelist.clearSelection(); - filelist.revalidate(); - filelist.repaint(); - setDirectorySelected(false); - setDirectory(filechooser.getCurrentDirectory()); - boxEntries(); - } - else if (e.getPropertyName().equals( - JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) - || e.getPropertyName().equals( - JFileChooser.FILE_FILTER_CHANGED_PROPERTY)) - filterEntries(); - else if (e.getPropertyName().equals( - JFileChooser.DIALOG_TYPE_CHANGED_PROPERTY) - || e.getPropertyName().equals( - JFileChooser.DIALOG_TITLE_CHANGED_PROPERTY)) - { - Window owner = SwingUtilities.windowForComponent(filechooser); - if (owner instanceof JDialog) - ((JDialog) owner).setTitle(getDialogTitle(filechooser)); - accept.setText(getApproveButtonText(filechooser)); - accept.setToolTipText(getApproveButtonToolTipText(filechooser)); - accept.setMnemonic(getApproveButtonMnemonic(filechooser)); - } - else if (e.getPropertyName().equals( - JFileChooser.APPROVE_BUTTON_TEXT_CHANGED_PROPERTY)) - accept.setText(getApproveButtonText(filechooser)); - else if (e.getPropertyName().equals( - JFileChooser.APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY)) - accept.setToolTipText(getApproveButtonToolTipText(filechooser)); - else if (e.getPropertyName().equals( - JFileChooser.APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY)) - accept.setMnemonic(getApproveButtonMnemonic(filechooser)); - else if (e.getPropertyName().equals( - JFileChooser.CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY)) - { - if (filechooser.getControlButtonsAreShown()) - { - GridBagConstraints c = new GridBagConstraints(); - c.gridy = 1; - bottomPanel.add(filters, c); - - c.fill = GridBagConstraints.BOTH; - c.gridy = 2; - c.anchor = GridBagConstraints.EAST; - bottomPanel.add(closePanel, c); - bottomPanel.revalidate(); - bottomPanel.repaint(); - bottomPanel.doLayout(); - } - else - bottomPanel.remove(closePanel); - } - else if (e.getPropertyName().equals( - JFileChooser.ACCEPT_ALL_FILE_FILTER_USED_CHANGED_PROPERTY)) - { - if (filechooser.isAcceptAllFileFilterUsed()) - filechooser.addChoosableFileFilter(getAcceptAllFileFilter(filechooser)); - else - filechooser.removeChoosableFileFilter(getAcceptAllFileFilter(filechooser)); - } - else if (e.getPropertyName().equals( - JFileChooser.ACCESSORY_CHANGED_PROPERTY)) - { - JComponent old = (JComponent) e.getOldValue(); - if (old != null) - getAccessoryPanel().remove(old); - JComponent newval = (JComponent) e.getNewValue(); - if (newval != null) - getAccessoryPanel().add(newval); - } - if (e.getPropertyName().equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY) - || e.getPropertyName().equals( - JFileChooser.FILE_FILTER_CHANGED_PROPERTY) - || e.getPropertyName().equals( - JFileChooser.FILE_HIDING_CHANGED_PROPERTY)) - rescanCurrentDirectory(filechooser); - - filechooser.revalidate(); - filechooser.repaint(); } }; } @@ -1624,7 +1046,9 @@ public class BasicFileChooserUI extends FileChooserUI */ public String getFileName() { - return filename; + // FIXME: I'm thinking that this method just provides access to the + // text value in the JTextField component...but not sure yet + return null; //filename; } /** @@ -1649,7 +1073,9 @@ public class BasicFileChooserUI extends FileChooserUI */ public void setFileName(String filename) { - this.filename = filename; + // FIXME: it might be the case that this method provides an access + // point for the JTextField (or whatever) a subclass is using... + //this.filename = filename; } /** @@ -1672,7 +1098,6 @@ public class BasicFileChooserUI extends FileChooserUI public void rescanCurrentDirectory(JFileChooser fc) { getModel().validateFileCache(); - filelist.revalidate(); } /** @@ -1708,17 +1133,14 @@ public class BasicFileChooserUI extends FileChooserUI } /** - * Creates and returns an approve (open or save) button for the dialog. + * Returns the approve (open or save) button for the dialog. * * @param fc the file chooser. * * @return The button. */ - public JButton getApproveButton(JFileChooser fc) + protected JButton getApproveButton(JFileChooser fc) { - accept = new JButton(getApproveButtonText(fc)); - accept.setMnemonic(getApproveButtonMnemonic(fc)); - accept.setToolTipText(getApproveButtonToolTipText(fc)); return accept; } @@ -1830,9 +1252,8 @@ public class BasicFileChooserUI extends FileChooserUI } /** - * Returns the file view for the file chooser. This returns either the - * file view that has been explicitly set for the {@link JFileChooser}, or - * a default file view. + * Returns the default file view (NOT the file view from the file chooser, + * if there is one). * * @param fc the file chooser component. * @@ -1856,24 +1277,10 @@ public class BasicFileChooserUI extends FileChooserUI */ public String getDialogTitle(JFileChooser fc) { - String ret = fc.getDialogTitle(); - if (ret != null) - return ret; - switch (fc.getDialogType()) - { - case JFileChooser.OPEN_DIALOG: - ret = openButtonText; - break; - case JFileChooser.SAVE_DIALOG: - ret = saveButtonText; - break; - default: - ret = fc.getApproveButtonText(); - break; - } - if (ret == null) - ret = openButtonText; - return ret; + String result = fc.getDialogTitle(); + if (result == null) + result = getApproveButtonText(fc); + return result; } /** @@ -1906,23 +1313,28 @@ public class BasicFileChooserUI extends FileChooserUI */ public String getApproveButtonText(JFileChooser fc) { - if (fc.getApproveButtonText() != null) - return fc.getApproveButtonText(); - else if (fc.getDialogType() == JFileChooser.SAVE_DIALOG) - return saveButtonText; - else - return openButtonText; + String result = fc.getApproveButtonText(); + if (result == null) + { + if (fc.getDialogType() == JFileChooser.SAVE_DIALOG) + result = saveButtonText; + else + result = openButtonText; + } + return result; } /** * Creates and returns a new action that will be used with the "new folder" * button. * - * @return A new instance of {@link GoHomeAction}. + * @return A new instance of {@link NewFolderAction}. */ public Action getNewFolderAction() { - return new NewFolderAction(); + if (newFolderAction == null) + newFolderAction = new NewFolderAction(); + return newFolderAction; } /** @@ -1933,49 +1345,56 @@ public class BasicFileChooserUI extends FileChooserUI */ public Action getGoHomeAction() { - return new GoHomeAction(); + if (goHomeAction == null) + goHomeAction = new GoHomeAction(); + return goHomeAction; } /** - * Creates and returns a new action that will be used with the "up folder" - * button. + * Returns the action that handles events for the "up folder" control button. * - * @return A new instance of {@link ChangeToParentDirectoryAction}. + * @return An instance of {@link ChangeToParentDirectoryAction}. */ public Action getChangeToParentDirectoryAction() { - return new ChangeToParentDirectoryAction(); + if (changeToParentDirectoryAction == null) + changeToParentDirectoryAction = new ChangeToParentDirectoryAction(); + return changeToParentDirectoryAction; } /** - * Creates and returns a new action that will be used with the "approve" - * button. + * Returns the action that handles events for the "approve" button. * - * @return A new instance of {@link ApproveSelectionAction}. + * @return An instance of {@link ApproveSelectionAction}. */ public Action getApproveSelectionAction() { - return new ApproveSelectionAction(); + if (approveSelectionAction == null) + approveSelectionAction = new ApproveSelectionAction(); + return approveSelectionAction; } /** - * Creates and returns a new action that will be used with the "cancel" - * button. + * Returns the action that handles events for the "cancel" button. * - * @return A new instance of {@link CancelSelectionAction}. + * @return An instance of {@link CancelSelectionAction}. */ public Action getCancelSelectionAction() { - return new CancelSelectionAction(); + if (cancelSelectionAction == null) + cancelSelectionAction = new CancelSelectionAction(); + return cancelSelectionAction; } /** - * Creates and returns a new instance of {@link UpdateAction}. + * Returns the update action (an instance of {@link UpdateAction}). * * @return An action. */ public Action getUpdateAction() { - return new UpdateAction(); + if (updateAction == null) + updateAction = new UpdateAction(); + return updateAction; } } diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicHTML.java b/libjava/classpath/javax/swing/plaf/basic/BasicHTML.java new file mode 100644 index 0000000..b9891e1 --- /dev/null +++ b/libjava/classpath/javax/swing/plaf/basic/BasicHTML.java @@ -0,0 +1,154 @@ +/* BasicHTML.java -- Provides HTML support to ComponentUI implementations + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.swing.plaf.basic; + +import java.io.IOException; +import java.io.StringReader; + +import javax.swing.JComponent; +import javax.swing.text.BadLocationException; +import javax.swing.text.Element; +import javax.swing.text.View; +import javax.swing.text.ViewFactory; +import javax.swing.text.html.HTMLDocument; +import javax.swing.text.html.HTMLEditorKit; + +/** + * Provides support for HTML rendering to {@link javax.swing.plaf.ComponentUI} + * implementations. + * + * @author Roman Kennke (kennke@aicas.com) + */ +public class BasicHTML +{ + + /** + * The key that is used to store a HTML view in a JComponent's client + * properties. + */ + public static final String propertyKey = "html"; + + /** + * The key that is used to store the document base in a JComponent's client + * properties. The document base is used to resolve relative references + * in HTML. + */ + public static final String documentBaseKey = "html.base"; + + /** + * Creates a new instance of BasicHTML. This should not be necessary since + * all methods in this class are static. + */ + public BasicHTML() + { + // Nothing to do here. + } + + /** + * Creates a {@link View} instance that can be used by the component + * <code>c</code> to render the HTML string <code>html</code>. + * + * @param c the component that needs to render the HTML string + * @param html the HTML string to be rendered + * + * @return a view that can render the HTML string + */ + public static View createHTMLView(JComponent c, String html) + { + // TODO: This might be wrong. Lets see if it turns out good when + // the javax.swing.text.html package is in a good shape. + HTMLDocument doc = new HTMLDocument(); + HTMLEditorKit kit = new HTMLEditorKit(); + StringReader reader = new StringReader(html); + try + { + kit.read(reader, doc, 0); + } + catch (IOException ex) + { + AssertionError err = new AssertionError("unexpected IOException"); + err.initCause(ex); + throw err; + } + catch (BadLocationException ex) + { + AssertionError err = + new AssertionError("unexpected BadLocationException"); + err.initCause(ex); + throw err; + } + ViewFactory vf = kit.getViewFactory(); + Element root = doc.getDefaultRootElement(); + View view = vf.create(root); + return view; + } + + /** + * Returns <code>true</code> if <code>s</code> is HTML, <code>false</code> + * otherwise. + * + * @param s the string to test + * + * @return <code>true</code> if <code>s</code> is HTML, <code>false</code> + * otherwise + */ + public static boolean isHTMLString(String s) + { + // We consider a string to be HTML if it contains both the '<' and '>' + // character at least once. + return s.contains("<") && s.contains(">"); + } + + /** + * Stores a HTML renderer in <code>c</code>'s client property if + * <code>text</code> is HTML, otherwise it clears the corresponding client + * property. This is useful for {@link java.swing.plaf.ComponentUI} + * implementations that are shared between it's components. + * + * @param c the component to update the renderer for + * @param text the string to be rendered + */ + public static void updateRenderer(JComponent c, String text) + { + if (isHTMLString(text)) + c.putClientProperty(propertyKey, createHTMLView(c, text)); + else + c.putClientProperty(propertyKey, null); + } +} diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameUI.java index d9dadda..f9653bd 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicInternalFrameUI.java @@ -46,6 +46,7 @@ import java.awt.Dimension; import java.awt.Graphics; import java.awt.Insets; import java.awt.LayoutManager; +import java.awt.LayoutManager2; import java.awt.Point; import java.awt.Rectangle; import java.awt.event.ComponentEvent; @@ -1164,9 +1165,6 @@ public class BasicInternalFrameUI extends InternalFrameUI { frame = (JInternalFrame) c; - internalFrameLayout = createLayoutManager(); - frame.setLayout(internalFrameLayout); - ((JComponent) frame.getRootPane().getGlassPane()).setOpaque(false); frame.getRootPane().getGlassPane().setVisible(true); @@ -1192,7 +1190,6 @@ public class BasicInternalFrameUI extends InternalFrameUI uninstallListeners(); uninstallDefaults(); - frame.setLayout(null); ((JComponent) frame.getRootPane().getGlassPane()).setOpaque(true); frame.getRootPane().getGlassPane().setVisible(false); @@ -1204,6 +1201,8 @@ public class BasicInternalFrameUI extends InternalFrameUI */ protected void installDefaults() { + internalFrameLayout = createLayoutManager(); + frame.setLayout(internalFrameLayout); LookAndFeel.installBorder(frame, "InternalFrame.border"); frame.setFrameIcon(UIManager.getIcon("InternalFrame.icon")); // InternalFrames are invisible by default. @@ -1256,6 +1255,8 @@ public class BasicInternalFrameUI extends InternalFrameUI protected void uninstallDefaults() { frame.setBorder(null); + frame.setLayout(null); + internalFrameLayout = null; } /** @@ -1329,7 +1330,13 @@ public class BasicInternalFrameUI extends InternalFrameUI */ public Dimension getPreferredSize(JComponent x) { - return internalFrameLayout.preferredLayoutSize(x); + Dimension pref = null; + LayoutManager layout = frame.getLayout(); + if (frame == x && layout != null) + pref = layout.preferredLayoutSize(frame); + else + pref = new Dimension(100, 100); + return pref; } /** @@ -1341,7 +1348,13 @@ public class BasicInternalFrameUI extends InternalFrameUI */ public Dimension getMinimumSize(JComponent x) { - return internalFrameLayout.minimumLayoutSize(x); + Dimension min = null; + LayoutManager layout = frame.getLayout(); + if (frame == x && layout != null) + min = layout.minimumLayoutSize(frame); + else + min = new Dimension(0, 0); + return min; } /** @@ -1353,7 +1366,13 @@ public class BasicInternalFrameUI extends InternalFrameUI */ public Dimension getMaximumSize(JComponent x) { - return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); + Dimension max = null; + LayoutManager layout = frame.getLayout(); + if (frame == x && layout != null && layout instanceof LayoutManager2) + max = ((LayoutManager2) layout).maximumLayoutSize(frame); + else + max = new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); + return max; } /** diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicLabelUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicLabelUI.java index c8f677f..fd4cff5 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicLabelUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicLabelUI.java @@ -39,7 +39,6 @@ package javax.swing.plaf.basic; import java.awt.Color; import java.awt.Dimension; -import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Insets; @@ -104,7 +103,7 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener Rectangle ir = new Rectangle(); Rectangle tr = new Rectangle(); Insets insets = lab.getInsets(); - FontMetrics fm = lab.getToolkit().getFontMetrics(lab.getFont()); + FontMetrics fm = lab.getFontMetrics(lab.getFont()); layoutCL(lab, fm, lab.getText(), lab.getIcon(), vr, ir, tr); Rectangle cr = tr.union(ir); return new Dimension(insets.left + cr.width + insets.right, insets.top @@ -150,17 +149,11 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener { JLabel b = (JLabel) c; - Font saved_font = g.getFont(); - Rectangle tr = new Rectangle(); Rectangle ir = new Rectangle(); Rectangle vr = new Rectangle(); - Font f = c.getFont(); - - g.setFont(f); - FontMetrics fm = g.getFontMetrics(f); - + FontMetrics fm = g.getFontMetrics(); vr = SwingUtilities.calculateInnerArea(c, vr); if (vr.width < 0) @@ -182,8 +175,6 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener else paintDisabledText(b, g, text, tr.x, tr.y + fm.getAscent()); } - - g.setFont(saved_font); } /** diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicListUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicListUI.java index 2d66645..00d157a 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicListUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicListUI.java @@ -41,13 +41,11 @@ package javax.swing.plaf.basic; import java.awt.Component; import java.awt.Dimension; import java.awt.Graphics; +import java.awt.Insets; import java.awt.Point; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.awt.event.ComponentAdapter; -import java.awt.event.ComponentEvent; -import java.awt.event.ComponentListener; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.awt.event.MouseEvent; @@ -61,7 +59,6 @@ import javax.swing.DefaultListSelectionModel; import javax.swing.InputMap; import javax.swing.JComponent; import javax.swing.JList; -import javax.swing.JViewport; import javax.swing.KeyStroke; import javax.swing.ListCellRenderer; import javax.swing.ListModel; @@ -87,21 +84,6 @@ public class BasicListUI extends ListUI { /** - * A helper class which listens for {@link ComponentEvent}s from - * the JList. - */ - private class ComponentHandler extends ComponentAdapter { - - /** - * Called when the component is hidden. Invalidates the internal - * layout. - */ - public void componentResized(ComponentEvent ev) { - BasicListUI.this.damageLayout(); - } - } - - /** * A helper class which listens for {@link FocusEvent}s * from the JList. */ @@ -153,7 +135,7 @@ public class BasicListUI extends ListUI */ public void contentsChanged(ListDataEvent e) { - BasicListUI.this.damageLayout(); + list.revalidate(); } /** @@ -163,7 +145,7 @@ public class BasicListUI extends ListUI */ public void intervalAdded(ListDataEvent e) { - BasicListUI.this.damageLayout(); + list.revalidate(); } /** @@ -173,7 +155,7 @@ public class BasicListUI extends ListUI */ public void intervalRemoved(ListDataEvent e) { - BasicListUI.this.damageLayout(); + list.revalidate(); } } @@ -524,7 +506,14 @@ public class BasicListUI extends ListUI */ public void mouseDragged(MouseEvent event) { - // TODO: What should be done here, if anything? + Point click = event.getPoint(); + int index = locationToIndex(list, click); + if (index == -1) + return; + if (!event.isShiftDown() && !event.isControlDown()) + list.setSelectedIndex(index); + + list.ensureIndexIsVisible(list.getLeadSelectionIndex()); } /** @@ -562,20 +551,19 @@ public class BasicListUI extends ListUI } // Update the updateLayoutStateNeeded flag. if (e.getPropertyName().equals("model")) - updateLayoutStateNeeded += modelChanged; + updateLayoutStateNeeded |= modelChanged; else if (e.getPropertyName().equals("selectionModel")) - updateLayoutStateNeeded += selectionModelChanged; + updateLayoutStateNeeded |= selectionModelChanged; else if (e.getPropertyName().equals("font")) - updateLayoutStateNeeded += fontChanged; + updateLayoutStateNeeded |= fontChanged; else if (e.getPropertyName().equals("fixedCellWidth")) - updateLayoutStateNeeded += fixedCellWidthChanged; + updateLayoutStateNeeded |= fixedCellWidthChanged; else if (e.getPropertyName().equals("fixedCellHeight")) - updateLayoutStateNeeded += fixedCellHeightChanged; + updateLayoutStateNeeded |= fixedCellHeightChanged; else if (e.getPropertyName().equals("prototypeCellValue")) - updateLayoutStateNeeded += prototypeCellValueChanged; + updateLayoutStateNeeded |= prototypeCellValueChanged; else if (e.getPropertyName().equals("cellRenderer")) - updateLayoutStateNeeded += cellRendererChanged; - BasicListUI.this.damageLayout(); + updateLayoutStateNeeded |= cellRendererChanged; } } @@ -641,11 +629,6 @@ public class BasicListUI extends ListUI /** The property change listener listening to the list. */ protected PropertyChangeListener propertyChangeListener; - - /** The component listener that receives notification for resizing the - * JList component.*/ - private ComponentListener componentListener; - /** Saved reference to the list this UI was created for. */ protected JList list; @@ -738,13 +721,12 @@ public class BasicListUI extends ListUI int maxIndex = Math.max(index1, index2); Point loc = indexToLocation(list, minIndex); Rectangle bounds = new Rectangle(loc.x, loc.y, cellWidth, - getRowHeight(minIndex)); - + getCellHeight(minIndex)); for (int i = minIndex + 1; i <= maxIndex; i++) { Point hiLoc = indexToLocation(list, i); Rectangle hibounds = new Rectangle(hiLoc.x, hiLoc.y, cellWidth, - getRowHeight(i)); + getCellHeight(i)); bounds = bounds.union(hibounds); } @@ -752,6 +734,29 @@ public class BasicListUI extends ListUI } /** + * Calculates the maximum cell height. + * + * @param index the index of the cell + * + * @return the maximum cell height + */ + private int getCellHeight(int index) + { + int height = cellHeight; + if (height <= 0) + { + if (list.getLayoutOrientation() == JList.VERTICAL) + height = getRowHeight(index); + else + { + for (int j = 0; j < cellHeights.length; j++) + height = Math.max(height, cellHeights[j]); + } + } + return height; + } + + /** * Calculate the Y coordinate of the upper edge of a particular row, * considering the Y coordinate <code>0</code> to occur at the top of the * list. @@ -804,7 +809,7 @@ public class BasicListUI extends ListUI // Update the layout if necessary. maybeUpdateLayoutState(); - int index = list.getModel().getSize() - 1;; + int index = list.getModel().getSize() - 1; // If a fixed cell height is set, then we can work more efficient. if (cellHeight > 0) @@ -884,24 +889,12 @@ public class BasicListUI extends ListUI } /** - * Marks the current layout as damaged and requests revalidation from the - * JList. - * This is package-private to avoid an accessor method. - * - * @see #updateLayoutStateNeeded - */ - void damageLayout() - { - updateLayoutStateNeeded = 1; - } - - /** * Calls {@link #updateLayoutState} if {@link #updateLayoutStateNeeded} * is nonzero, then resets {@link #updateLayoutStateNeeded} to zero. */ protected void maybeUpdateLayoutState() { - if (updateLayoutStateNeeded != 0) + if (updateLayoutStateNeeded != 0 || !list.isValid()) { updateLayoutState(); updateLayoutStateNeeded = 0; @@ -968,12 +961,6 @@ public class BasicListUI extends ListUI if (propertyChangeListener == null) propertyChangeListener = createPropertyChangeListener(); list.addPropertyChangeListener(propertyChangeListener); - - // FIXME: Are these two really needed? At least they are not documented. - //keyListener = new KeyHandler(); - componentListener = new ComponentHandler(); - list.addComponentListener(componentListener); - //list.addKeyListener(keyListener); } /** @@ -985,7 +972,6 @@ public class BasicListUI extends ListUI list.getModel().removeListDataListener(listDataListener); list.removeListSelectionListener(listSelectionListener); list.removeMouseListener(mouseInputListener); - //list.removeKeyListener(keyListener); list.removeMouseMotionListener(mouseInputListener); list.removePropertyChangeListener(propertyChangeListener); } @@ -1073,33 +1059,62 @@ public class BasicListUI extends ListUI */ public Dimension getPreferredSize(JComponent c) { + maybeUpdateLayoutState(); int size = list.getModel().getSize(); - if (size == 0) - return new Dimension(0, 0); int visibleRows = list.getVisibleRowCount(); int layoutOrientation = list.getLayoutOrientation(); - Rectangle bounds = getCellBounds(list, 0, list.getModel().getSize() - 1); - Dimension retVal = bounds.getSize(); - Component parent = list.getParent(); - if ((visibleRows == -1) && (parent instanceof JViewport)) - { - JViewport viewport = (JViewport) parent; - if (layoutOrientation == JList.HORIZONTAL_WRAP) + int h; + int w; + int maxCellHeight = cellHeight; + if (maxCellHeight <= 0) + { + for (int i = 0; i < cellHeights.length; i++) + maxCellHeight = Math.max(maxCellHeight, cellHeights[i]); + } + if (layoutOrientation == JList.HORIZONTAL_WRAP) + { + if (visibleRows > 0) { - int h = viewport.getSize().height; - int cellsPerCol = h / cellHeight; - int w = size / cellsPerCol * cellWidth; - retVal = new Dimension(w, h); + // We cast to double here to force double divisions. + double modelSize = size; + int neededColumns = (int) Math.ceil(modelSize / visibleRows); + int adjustedRows = (int) Math.ceil(modelSize / neededColumns); + h = maxCellHeight * adjustedRows; + w = cellWidth * neededColumns; } - else if (layoutOrientation == JList.VERTICAL_WRAP) + else { - int w = viewport.getSize().width; - int cellsPerRow = Math.max(w / cellWidth, 1); - int h = size / cellsPerRow * cellHeight; - retVal = new Dimension(w, h); + int neededColumns = Math.min(1, list.getWidth() / cellWidth); + h = size / neededColumns * maxCellHeight; + w = neededColumns * cellWidth; } } + else if (layoutOrientation == JList.VERTICAL_WRAP) + { + if (visibleRows > 0) + h = visibleRows * maxCellHeight; + else + h = Math.max(list.getHeight(), maxCellHeight); + int neededColumns = h / maxCellHeight; + w = cellWidth * neededColumns; + } + else + { + if (list.getFixedCellWidth() > 0) + w = list.getFixedCellWidth(); + else + w = cellWidth; + if (list.getFixedCellHeight() > 0) + // FIXME: We need to add some cellVerticalMargins here, according + // to the specs. + h = list.getFixedCellHeight() * size; + else + h = maxCellHeight * size; + } + Insets insets = list.getInsets(); + Dimension retVal = new Dimension(w + insets.left + insets.right, + h + insets.top + insets.bottom); return retVal; } @@ -1148,9 +1163,9 @@ public class BasicListUI extends ListUI int lead = sel.getLeadSelectionIndex(); Rectangle clip = g.getClipBounds(); - int startIndex = list.locationToIndex(new Point(clip.x, clip.y)); - int endIndex = list.locationToIndex(new Point(clip.x + clip.width, - clip.y + clip.height)); + int startIndex = locationToIndex(list, new Point(clip.x, clip.y)); + int endIndex = locationToIndex(list, new Point(clip.x + clip.width, + clip.y + clip.height)); for (int row = startIndex; row <= endIndex; ++row) { @@ -1165,13 +1180,13 @@ public class BasicListUI extends ListUI * location lies outside the bounds of the list, the greatest index in the * list model is returned. * - * @param list the list which on which the computation is based on + * @param l the list which on which the computation is based on * @param location the coordinates * * @return the index of the list item that is located at the given * coordinates or <code>-1</code> if the list model is empty */ - public int locationToIndex(JList list, Point location) + public int locationToIndex(JList l, Point location) { int layoutOrientation = list.getLayoutOrientation(); int index = -1; @@ -1182,52 +1197,34 @@ public class BasicListUI extends ListUI break; case JList.HORIZONTAL_WRAP: // determine visible rows and cells per row - int visibleRows = list.getVisibleRowCount(); + int maxCellHeight = getCellHeight(0); + int visibleRows = list.getHeight() / maxCellHeight; int cellsPerRow = -1; int numberOfItems = list.getModel().getSize(); - Dimension listDim = list.getSize(); - if (visibleRows <= 0) - { - try - { - cellsPerRow = listDim.width / cellWidth; - } - catch (ArithmeticException ex) - { - cellsPerRow = 1; - } - } - else - { - cellsPerRow = numberOfItems / visibleRows + 1; - } + cellsPerRow = numberOfItems / visibleRows + 1; // determine index for the given location int cellsPerColumn = numberOfItems / cellsPerRow + 1; int gridX = Math.min(location.x / cellWidth, cellsPerRow - 1); - int gridY = Math.min(location.y / cellHeight, cellsPerColumn); + int gridY = Math.min(location.y / maxCellHeight, cellsPerColumn); index = gridX + gridY * cellsPerRow; break; case JList.VERTICAL_WRAP: // determine visible rows and cells per column - int visibleRows2 = list.getVisibleRowCount(); - if (visibleRows2 <= 0) - { - Dimension listDim2 = list.getSize(); - visibleRows2 = listDim2.height / cellHeight; - } + int maxCellHeight2 = getCellHeight(0); + int visibleRows2 = list.getHeight() / maxCellHeight2; int numberOfItems2 = list.getModel().getSize(); int cellsPerRow2 = numberOfItems2 / visibleRows2 + 1; int gridX2 = Math.min(location.x / cellWidth, cellsPerRow2 - 1); - int gridY2 = Math.min(location.y / cellHeight, visibleRows2); + int gridY2 = Math.min(location.y / maxCellHeight2, visibleRows2); index = gridY2 + gridX2 * visibleRows2; break; } return index; } - public Point indexToLocation(JList list, int index) + public Point indexToLocation(JList l, int index) { int layoutOrientation = list.getLayoutOrientation(); Point loc = null; @@ -1238,40 +1235,31 @@ public class BasicListUI extends ListUI break; case JList.HORIZONTAL_WRAP: // determine visible rows and cells per row - int visibleRows = list.getVisibleRowCount(); + int maxCellHeight = getCellHeight(0); + int visibleRows = list.getHeight() / maxCellHeight; int numberOfCellsPerRow = -1; - if (visibleRows <= 0) - { - Dimension listDim = list.getSize(); - numberOfCellsPerRow = Math.max(listDim.width / cellWidth, 1); - } - else - { - int numberOfItems = list.getModel().getSize(); - numberOfCellsPerRow = numberOfItems / visibleRows + 1; - } + int numberOfItems = list.getModel().getSize(); + numberOfCellsPerRow = numberOfItems / visibleRows + 1; + // compute coordinates inside the grid int gridX = index % numberOfCellsPerRow; int gridY = index / numberOfCellsPerRow; int locX = gridX * cellWidth; - int locY = gridY * cellHeight; + int locY; + locY = gridY * maxCellHeight; loc = new Point(locX, locY); break; case JList.VERTICAL_WRAP: // determine visible rows and cells per column - int visibleRows2 = list.getVisibleRowCount(); - if (visibleRows2 <= 0) - { - Dimension listDim2 = list.getSize(); - visibleRows2 = listDim2.height / cellHeight; - } + int maxCellHeight2 = getCellHeight(0); + int visibleRows2 = list.getHeight() / maxCellHeight2; // compute coordinates inside the grid if (visibleRows2 > 0) { int gridY2 = index % visibleRows2; int gridX2 = index / visibleRows2; int locX2 = gridX2 * cellWidth; - int locY2 = gridY2 * cellHeight; + int locY2 = gridY2 * maxCellHeight2; loc = new Point(locX2, locY2); } else diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java b/libjava/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java index 13c78ad..f5217be 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java @@ -41,16 +41,26 @@ package javax.swing.plaf.basic; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; -import java.awt.event.InputEvent; -import java.awt.event.KeyEvent; +import java.awt.event.ActionEvent; +import java.io.IOException; +import java.io.InputStream; import java.io.Serializable; import java.util.Enumeration; import java.util.ResourceBundle; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.Clip; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.UnsupportedAudioFileException; +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.ActionMap; import javax.swing.BorderFactory; import javax.swing.KeyStroke; import javax.swing.LookAndFeel; import javax.swing.UIDefaults; +import javax.swing.UIManager; import javax.swing.border.BevelBorder; import javax.swing.border.Border; import javax.swing.plaf.BorderUIResource; @@ -59,7 +69,6 @@ import javax.swing.plaf.DimensionUIResource; import javax.swing.plaf.FontUIResource; import javax.swing.plaf.IconUIResource; import javax.swing.plaf.InsetsUIResource; -import javax.swing.text.JTextComponent; /** * BasicLookAndFeel @@ -68,8 +77,68 @@ import javax.swing.text.JTextComponent; public abstract class BasicLookAndFeel extends LookAndFeel implements Serializable { + /** + * An action that can play an audio file. + * + * @author Roman Kennke (kennke@aicas.com) + */ + private class AudioAction extends AbstractAction + { + /** + * The UIDefaults key that specifies the sound. + */ + Object key; + + /** + * Creates a new AudioAction. + * + * @param key the key that describes the audio action, normally a filename + * of an audio file relative to the current package + */ + AudioAction(Object key) + { + this.key = key; + } + + /** + * Plays the sound represented by this action. + * + * @param event the action event that triggers this audio action + */ + public void actionPerformed(ActionEvent event) + { + // We only can handle strings for now. + if (key instanceof String) + { + String name = UIManager.getString(key); + InputStream stream = getClass().getResourceAsStream(name); + try + { + Clip clip = AudioSystem.getClip(); + AudioInputStream audioStream = + AudioSystem.getAudioInputStream(stream); + clip.open(audioStream); + } + catch (LineUnavailableException ex) + { + // Nothing we can do about it. + } + catch (IOException ex) + { + // Nothing we can do about it. + } + catch (UnsupportedAudioFileException e) + { + // Nothing we can do about it. + } + } + } + } + static final long serialVersionUID = -6096995660290287879L; + private ActionMap audioActionMap; + /** * Creates a new instance of the Basic look and feel. */ @@ -148,7 +217,6 @@ public abstract class BasicLookAndFeel extends LookAndFeel "TextPaneUI", "javax.swing.plaf.basic.BasicTextPaneUI", "TextAreaUI", "javax.swing.plaf.basic.BasicTextAreaUI", "TextFieldUI", "javax.swing.plaf.basic.BasicTextFieldUI", - "TextPaneUI", "javax.swing.plaf.basic.BasicTextPaneUI", "ToggleButtonUI", "javax.swing.plaf.basic.BasicToggleButtonUI", "ToolBarSeparatorUI", "javax.swing.plaf.basic.BasicToolBarSeparatorUI", "ToolBarUI", "javax.swing.plaf.basic.BasicToolBarUI", @@ -265,12 +333,12 @@ public abstract class BasicLookAndFeel extends LookAndFeel } }, "Button.darkShadow", new ColorUIResource(Color.BLACK), - "Button.focusInputMap", new UIDefaults.LazyInputMap(new Object[] { - "SPACE", "pressed", - "released SPACE", "released" - }), "Button.font", new FontUIResource("Dialog", Font.PLAIN, 12), "Button.foreground", new ColorUIResource(Color.BLACK), + "Button.focusInputMap", new UIDefaults.LazyInputMap(new Object[] { + KeyStroke.getKeyStroke("SPACE"), "pressed", + KeyStroke.getKeyStroke("released SPACE"), "released" + }), "Button.highlight", new ColorUIResource(Color.WHITE), "Button.light", new ColorUIResource(Color.LIGHT_GRAY), "Button.margin", new InsetsUIResource(2, 14, 2, 14), @@ -281,8 +349,8 @@ public abstract class BasicLookAndFeel extends LookAndFeel "CheckBox.border", new BorderUIResource.CompoundBorderUIResource(null, null), "CheckBox.focusInputMap", new UIDefaults.LazyInputMap(new Object[] { - "SPACE", "pressed", - "released SPACE", "released" + KeyStroke.getKeyStroke("SPACE"), "pressed", + KeyStroke.getKeyStroke("released SPACE"), "released" }), "CheckBox.font", new FontUIResource("Dialog", Font.PLAIN, 12), "CheckBox.foreground", new ColorUIResource(darkShadow), @@ -342,12 +410,12 @@ public abstract class BasicLookAndFeel extends LookAndFeel "ColorChooser.okText", "OK", "ColorChooser.previewText", "Preview", "ColorChooser.resetText", "Reset", - "ColorChooser.rgbBlueMnemonic", new Integer(66), + "ColorChooser.rgbBlueMnemonic", "66", "ColorChooser.rgbBlueText", "Blue", - "ColorChooser.rgbGreenMnemonic", new Integer(71), + "ColorChooser.rgbGreenMnemonic", "78", "ColorChooser.rgbGreenText", "Green", "ColorChooser.rgbNameText", "RGB", - "ColorChooser.rgbRedMnemonic", new Integer(82), + "ColorChooser.rgbRedMnemonic", "68", "ColorChooser.rgbRedText", "Red", "ColorChooser.sampleText", "Sample Text Sample Text", "ColorChooser.swatchesDefaultRecentColor", new ColorUIResource(light), @@ -403,20 +471,63 @@ public abstract class BasicLookAndFeel extends LookAndFeel "EditorPane.font", new FontUIResource("Serif", Font.PLAIN, 12), "EditorPane.foreground", new ColorUIResource(Color.black), "EditorPane.inactiveForeground", new ColorUIResource(Color.gray), - "EditorPane.keyBindings", new JTextComponent.KeyBinding[] { - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_UP, - 0), "caret-up"), - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, - 0), "caret-down"), - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, - 0), "page-up"), - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, - 0), "page-down"), - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, - 0), "insert-break"), - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, - 0), "insert-tab") - }, + "EditorPane.focusInputMap", new UIDefaults.LazyInputMap(new Object[] { + KeyStroke.getKeyStroke("shift UP"), "selection-up", + KeyStroke.getKeyStroke("ctrl RIGHT"), "caret-next-word", + KeyStroke.getKeyStroke("shift ctrl LEFT"), "selection-previous-word", + KeyStroke.getKeyStroke("shift KP_UP"), "selection-up", + KeyStroke.getKeyStroke("DOWN"), "caret-down", + KeyStroke.getKeyStroke("shift ctrl T"), "previous-link-action", + KeyStroke.getKeyStroke("ctrl LEFT"), "caret-previous-word", + KeyStroke.getKeyStroke("CUT"), "cut-to-clipboard", + KeyStroke.getKeyStroke("END"), "caret-end-line", + KeyStroke.getKeyStroke("shift PAGE_UP"), "selection-page-up", + KeyStroke.getKeyStroke("KP_UP"), "caret-up", + KeyStroke.getKeyStroke("DELETE"), "delete-next", + KeyStroke.getKeyStroke("ctrl HOME"), "caret-begin", + KeyStroke.getKeyStroke("shift LEFT"), "selection-backward", + KeyStroke.getKeyStroke("ctrl END"), "caret-end", + KeyStroke.getKeyStroke("BACK_SPACE"), "delete-previous", + KeyStroke.getKeyStroke("shift ctrl RIGHT"), "selection-next-word", + KeyStroke.getKeyStroke("LEFT"), "caret-backward", + KeyStroke.getKeyStroke("KP_LEFT"), "caret-backward", + KeyStroke.getKeyStroke("shift KP_RIGHT"), "selection-forward", + KeyStroke.getKeyStroke("ctrl SPACE"), "activate-link-action", + KeyStroke.getKeyStroke("ctrl H"), "delete-previous", + KeyStroke.getKeyStroke("ctrl BACK_SLASH"), "unselect", + KeyStroke.getKeyStroke("ENTER"), "insert-break", + KeyStroke.getKeyStroke("shift HOME"), "selection-begin-line", + KeyStroke.getKeyStroke("RIGHT"), "caret-forward", + KeyStroke.getKeyStroke("shift ctrl PAGE_UP"), "selection-page-left", + KeyStroke.getKeyStroke("shift DOWN"), "selection-down", + KeyStroke.getKeyStroke("PAGE_DOWN"), "page-down", + KeyStroke.getKeyStroke("shift KP_LEFT"), "selection-backward", + KeyStroke.getKeyStroke("shift ctrl O"), "toggle-componentOrientation", + KeyStroke.getKeyStroke("ctrl X"), "cut-to-clipboard", + KeyStroke.getKeyStroke("shift ctrl PAGE_DOWN"), "selection-page-right", + KeyStroke.getKeyStroke("ctrl C"), "copy-to-clipboard", + KeyStroke.getKeyStroke("ctrl KP_RIGHT"), "caret-next-word", + KeyStroke.getKeyStroke("shift END"), "selection-end-line", + KeyStroke.getKeyStroke("ctrl KP_LEFT"), "caret-previous-word", + KeyStroke.getKeyStroke("HOME"), "caret-begin-line", + KeyStroke.getKeyStroke("ctrl V"), "paste-from-clipboard", + KeyStroke.getKeyStroke("KP_DOWN"), "caret-down", + KeyStroke.getKeyStroke("ctrl A"), "select-all", + KeyStroke.getKeyStroke("shift RIGHT"), "selection-forward", + KeyStroke.getKeyStroke("shift ctrl END"), "selection-end", + KeyStroke.getKeyStroke("COPY"), "copy-to-clipboard", + KeyStroke.getKeyStroke("shift ctrl KP_LEFT"), "selection-previous-word", + KeyStroke.getKeyStroke("ctrl T"), "next-link-action", + KeyStroke.getKeyStroke("shift KP_DOWN"), "selection-down", + KeyStroke.getKeyStroke("TAB"), "insert-tab", + KeyStroke.getKeyStroke("UP"), "caret-up", + KeyStroke.getKeyStroke("shift ctrl HOME"), "selection-begin", + KeyStroke.getKeyStroke("shift PAGE_DOWN"), "selection-page-down", + KeyStroke.getKeyStroke("KP_RIGHT"), "caret-forward", + KeyStroke.getKeyStroke("shift ctrl KP_RIGHT"), "selection-next-word", + KeyStroke.getKeyStroke("PAGE_UP"), "page-up", + KeyStroke.getKeyStroke("PASTE"), "paste-from-clipboard" + }), "EditorPane.margin", new InsetsUIResource(3, 3, 3, 3), "EditorPane.selectionBackground", new ColorUIResource(Color.black), "EditorPane.selectionForeground", new ColorUIResource(Color.white), @@ -424,51 +535,74 @@ public abstract class BasicLookAndFeel extends LookAndFeel "FileChooser.ancestorInputMap", new UIDefaults.LazyInputMap(new Object[] { "ESCAPE", "cancelSelection" }), - "FileChooser.cancelButtonMnemonic", new Integer(67), + "FileChooser.cancelButtonMnemonic", "67", "FileChooser.cancelButtonText", "Cancel", "FileChooser.cancelButtonToolTipText", "Abort file chooser dialog", - // XXX Don't use gif -// "FileChooser.detailsViewIcon", new IconUIResource(new ImageIcon("icons/DetailsView.gif")), "FileChooser.directoryDescriptionText", "Directory", "FileChooser.fileDescriptionText", "Generic File", - "FileChooser.helpButtonMnemonic", new Integer(72), + "FileChooser.directoryOpenButtonMnemonic", "79", + "FileChooser.helpButtonMnemonic", "72", "FileChooser.helpButtonText", "Help", "FileChooser.helpButtonToolTipText", "FileChooser help", - // XXX Don't use gif -// "FileChooser.homeFolderIcon", new IconUIResource(new ImageIcon("icons/HomeFolder.gif")), - // XXX Don't use gif -// "FileChooser.listViewIcon", new IconUIResource(new ImageIcon("icons/ListView.gif")), "FileChooser.newFolderErrorSeparator", ":", "FileChooser.newFolderErrorText", "Error creating new folder", - // XXX Don't use gif -// "FileChooser.newFolderIcon", new IconUIResource(new ImageIcon("icons/NewFolder.gif")), - "FileChooser.openButtonMnemonic", new Integer(79), + "FileChooser.openButtonMnemonic", "79", "FileChooser.openButtonText", "Open", "FileChooser.openButtonToolTipText", "Open selected file", - "FileChooser.saveButtonMnemonic", new Integer(83), + "FileChooser.saveButtonMnemonic", "83", "FileChooser.saveButtonText", "Save", "FileChooser.saveButtonToolTipText", "Save selected file", - // XXX Don't use gif -// "FileChooser.upFolderIcon", new IconUIResource(new ImageIcon("icons/UpFolder.gif")), - "FileChooser.updateButtonMnemonic", new Integer(85), + "FileChooser.updateButtonMnemonic", "85", "FileChooser.updateButtonText", "Update", "FileChooser.updateButtonToolTipText", "Update directory listing", - // XXX Don't use gif -// "FileView.computerIcon", new IconUIResource(new ImageIcon("icons/Computer.gif")), - // XXX Don't use gif -// "FileView.directoryIcon", new IconUIResource(new ImageIcon("icons/Directory.gif")), - // XXX Don't use gif -// "FileView.fileIcon", new IconUIResource(new ImageIcon("icons/File.gif")), - // XXX Don't use gif -// "FileView.floppyDriveIcon", new IconUIResource(new ImageIcon("icons/Floppy.gif")), - // XXX Don't use gif -// "FileView.hardDriveIcon", new IconUIResource(new ImageIcon("icons/HardDrive.gif")), "FocusManagerClassName", "TODO", "FormattedTextField.background", new ColorUIResource(light), "FormattedTextField.caretForeground", new ColorUIResource(Color.black), + "FormattedTextField.margin", new InsetsUIResource(0, 0, 0, 0), + "FormattedTextField.caretBlinkRate", new Integer(500), "FormattedTextField.font", new FontUIResource("SansSerif", Font.PLAIN, 12), "FormattedTextField.foreground", new ColorUIResource(Color.black), + "FormattedTextField.focusInputMap", new UIDefaults.LazyInputMap(new Object[] { + KeyStroke.getKeyStroke("KP_UP"), "increment", + KeyStroke.getKeyStroke("END"), "caret-end-line", + KeyStroke.getKeyStroke("shift ctrl O"), "toggle-componentOrientation", + KeyStroke.getKeyStroke("shift KP_LEFT"), "selection-backward", + KeyStroke.getKeyStroke("shift RIGHT"), "selection-forward", + KeyStroke.getKeyStroke("KP_DOWN"), "decrement", + KeyStroke.getKeyStroke("HOME"), "caret-begin-line", + KeyStroke.getKeyStroke("ctrl V"), "paste-from-clipboard", + KeyStroke.getKeyStroke("ctrl H"), "delete-previous", + KeyStroke.getKeyStroke("KP_LEFT"), "caret-backward", + KeyStroke.getKeyStroke("LEFT"), "caret-backward", + KeyStroke.getKeyStroke("ctrl X"), "cut-to-clipboard", + KeyStroke.getKeyStroke("KP_RIGHT"), "caret-forward", + KeyStroke.getKeyStroke("UP"), "increment", + KeyStroke.getKeyStroke("shift ctrl KP_RIGHT"), "selection-next-word", + KeyStroke.getKeyStroke("COPY"), "copy-to-clipboard", + KeyStroke.getKeyStroke("shift HOME"), "selection-begin-line", + KeyStroke.getKeyStroke("ESCAPE"), "reset-field-edit", + KeyStroke.getKeyStroke("RIGHT"), "caret-forward", + KeyStroke.getKeyStroke("shift ctrl LEFT"), "selection-previous-word", + KeyStroke.getKeyStroke("ctrl KP_LEFT"), "caret-previous-word", + KeyStroke.getKeyStroke("DOWN"), "decrement", + KeyStroke.getKeyStroke("ctrl KP_RIGHT"), "caret-next-word", + KeyStroke.getKeyStroke("PASTE"), "paste-from-clipboard", + KeyStroke.getKeyStroke("shift ctrl RIGHT"), "selection-next-word", + KeyStroke.getKeyStroke("ctrl BACK_SLASH"), "unselect", + KeyStroke.getKeyStroke("ctrl A"), "select-all", + KeyStroke.getKeyStroke("shift KP_RIGHT"), "selection-forward", + KeyStroke.getKeyStroke("CUT"), "cut-to-clipboard", + KeyStroke.getKeyStroke("ctrl LEFT"), "caret-previous-word", + KeyStroke.getKeyStroke("BACK_SPACE"), "delete-previous", + KeyStroke.getKeyStroke("shift ctrl KP_LEFT"), "selection-previous-word", + KeyStroke.getKeyStroke("ctrl C"), "copy-to-clipboard", + KeyStroke.getKeyStroke("shift END"), "selection-end-line", + KeyStroke.getKeyStroke("ctrl RIGHT"), "caret-next-word", + KeyStroke.getKeyStroke("DELETE"), "delete-next", + KeyStroke.getKeyStroke("ENTER"), "notify-field-accept", + KeyStroke.getKeyStroke("shift LEFT"), "selection-backward" + }), "FormattedTextField.inactiveBackground", new ColorUIResource(light), "FormattedTextField.inactiveForeground", new ColorUIResource(Color.gray), "FormattedTextField.selectionBackground", @@ -504,7 +638,6 @@ public abstract class BasicLookAndFeel extends LookAndFeel "InternalFrame.borderLight", new ColorUIResource(Color.LIGHT_GRAY), "InternalFrame.borderShadow", new ColorUIResource(Color.GRAY), "InternalFrame.closeIcon", BasicIconFactory.createEmptyFrameIcon(), - // FIXME: Set a nice icon for InternalFrames here. "InternalFrame.icon", new UIDefaults.LazyValue() { @@ -533,67 +666,67 @@ public abstract class BasicLookAndFeel extends LookAndFeel "List.background", new ColorUIResource(Color.white), "List.border", new BasicBorders.MarginBorder(), "List.focusInputMap", new UIDefaults.LazyInputMap(new Object[] { - "ctrl DOWN", "selectNextRowChangeLead", - "shift UP", "selectPreviousRowExtendSelection", - "ctrl RIGHT", "selectNextColumnChangeLead", - "shift ctrl LEFT", "selectPreviousColumnExtendSelection", - "shift KP_UP", "selectPreviousRowChangeLead", - "DOWN", "selectNextRow", - "ctrl UP", "selectPreviousRowChangeLead", - "ctrl LEFT", "selectPreviousColumnChangeLead", - "CUT", "cut", - "END", "selectLastRow", - "shift PAGE_UP","scrollUpExtendSelection", - "KP_UP", "selectPreviousRow", - "shift ctrl UP", "selectPreviousRowExtendSelection", - "ctrl HOME", "selectFirstRowChangeLead", - "shift LEFT", "selectPreviousColumnExtendSelection", - "ctrl END", "selectLastRowChangeLead", - "ctrl PAGE_DOWN", "scrollDownChangeLead", - "shift ctrl RIGHT", "selectNextColumnExtendSelection", - "LEFT", "selectPreviousColumn", - "ctrl PAGE_UP", "scrollUpChangeLead", - "KP_LEFT", "selectPreviousColumn", - "shift KP_RIGHT", "selectNextColumnExtendSelection", - "SPACE", "addToSelection", - "ctrl SPACE", "toggleAndAnchor", - "shift SPACE", "extendTo", - "shift ctrl SPACE", "moveSelectionTo", - "shift ctrl DOWN", "selectNextRowExtendSelection", - "ctrl BACK_SLASH", "clearSelection", - "shift HOME", "selectFirstRowExtendSelection", - "RIGHT", "selectNextColumn", - "shift ctrl PAGE_UP", "scrollUpExtendSelection", - "shift DOWN", "selectNextRowExtendSelection", - "PAGE_DOWN", "scrollDown", - "shift ctrl KP_UP", "selectPreviousRowExtendSelection", - "shift KP_LEFT", "selectPreviousColumnExtendSelection", - "ctrl X", "cut", - "shift ctrl PAGE_DOWN", "scrollDownExtendSelection", - "ctrl SLASH", "selectAll", - "ctrl C", "copy", - "ctrl KP_RIGHT", "selectNextColumnChangeLead", - "shift END", "selectLastRowExtendSelection", - "shift ctrl KP_DOWN", "selectNextRowExtendSelection", - "ctrl KP_LEFT", "selectPreviousColumnChangeLead", - "HOME", "selectFirstRow", - "ctrl V", "paste", - "KP_DOWN", "selectNextRow", - "ctrl KP_DOWN", "selectNextRowChangeLead", - "shift RIGHT", "selectNextColumnExtendSelection", - "ctrl A", "selectAll", - "shift ctrl END", "selectLastRowExtendSelection", - "COPY", "copy", - "ctrl KP_UP", "selectPreviousRowChangeLead", - "shift ctrl KP_LEFT", "selectPreviousColumnExtendSelection", - "shift KP_DOWN", "selectNextRowExtendSelection", - "UP", "selectPreviousRow", - "shift ctrl HOME", "selectFirstRowExtendSelection", - "shift PAGE_DOWN", "scrollDownExtendSelection", - "KP_RIGHT", "selectNextColumn", - "shift ctrl KP_RIGHT", "selectNextColumnExtendSelection", - "PAGE_UP", "scrollUp", - "PASTE", "paste" + KeyStroke.getKeyStroke("ctrl DOWN"), "selectNextRowChangeLead", + KeyStroke.getKeyStroke("shift UP"), "selectPreviousRowExtendSelection", + KeyStroke.getKeyStroke("ctrl RIGHT"), "selectNextColumnChangeLead", + KeyStroke.getKeyStroke("shift ctrl LEFT"), "selectPreviousColumnExtendSelection", + KeyStroke.getKeyStroke("shift KP_UP"), "selectPreviousRowExtendSelection", + KeyStroke.getKeyStroke("DOWN"), "selectNextRow", + KeyStroke.getKeyStroke("ctrl UP"), "selectPreviousRowChangeLead", + KeyStroke.getKeyStroke("ctrl LEFT"), "selectPreviousColumnChangeLead", + KeyStroke.getKeyStroke("CUT"), "cut", + KeyStroke.getKeyStroke("END"), "selectLastRow", + KeyStroke.getKeyStroke("shift PAGE_UP"), "scrollUpExtendSelection", + KeyStroke.getKeyStroke("KP_UP"), "selectPreviousRow", + KeyStroke.getKeyStroke("shift ctrl UP"), "selectPreviousRowExtendSelection", + KeyStroke.getKeyStroke("ctrl HOME"), "selectFirstRowChangeLead", + KeyStroke.getKeyStroke("shift LEFT"), "selectPreviousColumnExtendSelection", + KeyStroke.getKeyStroke("ctrl END"), "selectLastRowChangeLead", + KeyStroke.getKeyStroke("ctrl PAGE_DOWN"), "scrollDownChangeLead", + KeyStroke.getKeyStroke("shift ctrl RIGHT"), "selectNextColumnExtendSelection", + KeyStroke.getKeyStroke("LEFT"), "selectPreviousColumn", + KeyStroke.getKeyStroke("ctrl PAGE_UP"), "scrollUpChangeLead", + KeyStroke.getKeyStroke("KP_LEFT"), "selectPreviousColumn", + KeyStroke.getKeyStroke("shift KP_RIGHT"), "selectNextColumnExtendSelection", + KeyStroke.getKeyStroke("SPACE"), "addToSelection", + KeyStroke.getKeyStroke("ctrl SPACE"), "toggleAndAnchor", + KeyStroke.getKeyStroke("shift SPACE"), "extendTo", + KeyStroke.getKeyStroke("shift ctrl SPACE"), "moveSelectionTo", + KeyStroke.getKeyStroke("shift ctrl DOWN"), "selectNextRowExtendSelection", + KeyStroke.getKeyStroke("ctrl BACK_SLASH"), "clearSelection", + KeyStroke.getKeyStroke("shift HOME"), "selectFirstRowExtendSelection", + KeyStroke.getKeyStroke("RIGHT"), "selectNextColumn", + KeyStroke.getKeyStroke("shift ctrl PAGE_UP"), "scrollUpExtendSelection", + KeyStroke.getKeyStroke("shift DOWN"), "selectNextRowExtendSelection", + KeyStroke.getKeyStroke("PAGE_DOWN"), "scrollDown", + KeyStroke.getKeyStroke("shift ctrl KP_UP"), "selectPreviousRowExtendSelection", + KeyStroke.getKeyStroke("shift KP_LEFT"), "selectPreviousColumnExtendSelection", + KeyStroke.getKeyStroke("ctrl X"), "cut", + KeyStroke.getKeyStroke("shift ctrl PAGE_DOWN"), "scrollDownExtendSelection", + KeyStroke.getKeyStroke("ctrl SLASH"), "selectAll", + KeyStroke.getKeyStroke("ctrl C"), "copy", + KeyStroke.getKeyStroke("ctrl KP_RIGHT"), "selectNextColumnChangeLead", + KeyStroke.getKeyStroke("shift END"), "selectLastRowExtendSelection", + KeyStroke.getKeyStroke("shift ctrl KP_DOWN"), "selectNextRowExtendSelection", + KeyStroke.getKeyStroke("ctrl KP_LEFT"), "selectPreviousColumnChangeLead", + KeyStroke.getKeyStroke("HOME"), "selectFirstRow", + KeyStroke.getKeyStroke("ctrl V"), "paste", + KeyStroke.getKeyStroke("KP_DOWN"), "selectNextRow", + KeyStroke.getKeyStroke("ctrl KP_DOWN"), "selectNextRowChangeLead", + KeyStroke.getKeyStroke("shift RIGHT"), "selectNextColumnExtendSelection", + KeyStroke.getKeyStroke("ctrl A"), "selectAll", + KeyStroke.getKeyStroke("shift ctrl END"), "selectLastRowExtendSelection", + KeyStroke.getKeyStroke("COPY"), "copy", + KeyStroke.getKeyStroke("ctrl KP_UP"), "selectPreviousRowChangeLead", + KeyStroke.getKeyStroke("shift ctrl KP_LEFT"), "selectPreviousColumnExtendSelection", + KeyStroke.getKeyStroke("shift KP_DOWN"), "selectNextRowExtendSelection", + KeyStroke.getKeyStroke("UP"), "selectPreviousRow", + KeyStroke.getKeyStroke("shift ctrl HOME"), "selectFirstRowExtendSelection", + KeyStroke.getKeyStroke("shift PAGE_DOWN"), "scrollDownExtendSelection", + KeyStroke.getKeyStroke("KP_RIGHT"), "selectNextColumn", + KeyStroke.getKeyStroke("shift ctrl KP_RIGHT"), "selectNextColumnExtendSelection", + KeyStroke.getKeyStroke("PAGE_UP"), "scrollUp", + KeyStroke.getKeyStroke("PASTE"), "paste" }), "List.font", new FontUIResource("Dialog", Font.PLAIN, 12), "List.foreground", new ColorUIResource(Color.black), @@ -603,6 +736,7 @@ public abstract class BasicLookAndFeel extends LookAndFeel new BorderUIResource. LineBorderUIResource(new ColorUIResource(Color.yellow)), "Menu.acceleratorFont", new FontUIResource("Dialog", Font.PLAIN, 12), + "Menu.crossMenuMnemonic", Boolean.TRUE, "Menu.acceleratorForeground", new ColorUIResource(darkShadow), "Menu.acceleratorSelectionForeground", new ColorUIResource(Color.white), "Menu.arrowIcon", BasicIconFactory.getMenuArrowIcon(), @@ -627,6 +761,10 @@ public abstract class BasicLookAndFeel extends LookAndFeel "ENTER", "return", "SPACE", "return" }, + "Menu.menuPopupOffsetX", new Integer(0), + "Menu.menuPopupOffsetY", new Integer(0), + "Menu.submenuPopupOffsetX", new Integer(0), + "Menu.submenuPopupOffsetY", new Integer(0), "Menu.selectionBackground", new ColorUIResource(Color.black), "Menu.selectionForeground", new ColorUIResource(Color.white), "MenuBar.background", new ColorUIResource(light), @@ -638,7 +776,7 @@ public abstract class BasicLookAndFeel extends LookAndFeel "MenuBar.windowBindings", new Object[] { "F10", "takeFocus" }, - "MenuItem.acceleratorDelimiter", "-", + "MenuItem.acceleratorDelimiter", "+", "MenuItem.acceleratorFont", new FontUIResource("Dialog", Font.PLAIN, 12), "MenuItem.acceleratorForeground", new ColorUIResource(darkShadow), "MenuItem.acceleratorSelectionForeground", @@ -657,15 +795,10 @@ public abstract class BasicLookAndFeel extends LookAndFeel new BorderUIResource.EmptyBorderUIResource(0, 0, 0, 0), "OptionPane.buttonAreaBorder", new BorderUIResource.EmptyBorderUIResource(0, 0, 0, 0), + "OptionPane.buttonClickThreshhold", new Integer(500), "OptionPane.cancelButtonText", "Cancel", - // XXX Don't use gif -// "OptionPane.errorIcon", -// new IconUIResource(new ImageIcon("icons/Error.gif")), "OptionPane.font", new FontUIResource("Dialog", Font.PLAIN, 12), "OptionPane.foreground", new ColorUIResource(darkShadow), - // XXX Don't use gif -// "OptionPane.informationIcon", -// new IconUIResource(new ImageIcon("icons/Inform.gif")), "OptionPane.messageAreaBorder", new BorderUIResource.EmptyBorderUIResource(0, 0, 0, 0), "OptionPane.messageForeground", new ColorUIResource(darkShadow), @@ -674,12 +807,6 @@ public abstract class BasicLookAndFeel extends LookAndFeel BasicOptionPaneUI.MinimumHeight), "OptionPane.noButtonText", "No", "OptionPane.okButtonText", "OK", - // XXX Don't use gif -// "OptionPane.questionIcon", -// new IconUIResource(new ImageIcon("icons/Question.gif")), - // XXX Don't use gif -// "OptionPane.warningIcon", -// new IconUIResource(new ImageIcon("icons/Warn.gif")), "OptionPane.windowBindings", new Object[] { "ESCAPE", "close" }, @@ -692,14 +819,45 @@ public abstract class BasicLookAndFeel extends LookAndFeel null, null), "PasswordField.caretBlinkRate", new Integer(500), "PasswordField.caretForeground", new ColorUIResource(Color.black), - "PasswordField.font", new FontUIResource("Dialog", Font.PLAIN, 12), + "PasswordField.font", new FontUIResource("MonoSpaced", Font.PLAIN, 12), "PasswordField.foreground", new ColorUIResource(Color.black), "PasswordField.inactiveBackground", new ColorUIResource(light), "PasswordField.inactiveForeground", new ColorUIResource(Color.gray), - "PasswordField.keyBindings", new JTextComponent.KeyBinding[] { - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, - 0), - "notify-field-accept")}, + "PasswordField.focusInputMap", new UIDefaults.LazyInputMap(new Object[] { + KeyStroke.getKeyStroke("END"), "caret-end-line", + KeyStroke.getKeyStroke("shift ctrl O"), "toggle-componentOrientation", + KeyStroke.getKeyStroke("shift KP_LEFT"), "selection-backward", + KeyStroke.getKeyStroke("shift RIGHT"), "selection-forward", + KeyStroke.getKeyStroke("HOME"), "caret-begin-line", + KeyStroke.getKeyStroke("ctrl V"), "paste-from-clipboard", + KeyStroke.getKeyStroke("ctrl H"), "delete-previous", + KeyStroke.getKeyStroke("KP_LEFT"), "caret-backward", + KeyStroke.getKeyStroke("LEFT"), "caret-backward", + KeyStroke.getKeyStroke("ctrl X"), "cut-to-clipboard", + KeyStroke.getKeyStroke("KP_RIGHT"), "caret-forward", + KeyStroke.getKeyStroke("shift ctrl KP_RIGHT"), "selection-end-line", + KeyStroke.getKeyStroke("COPY"), "copy-to-clipboard", + KeyStroke.getKeyStroke("shift HOME"), "selection-begin-line", + KeyStroke.getKeyStroke("RIGHT"), "caret-forward", + KeyStroke.getKeyStroke("shift ctrl LEFT"), "selection-begin-line", + KeyStroke.getKeyStroke("ctrl KP_LEFT"), "caret-begin-line", + KeyStroke.getKeyStroke("ctrl KP_RIGHT"), "caret-end-line", + KeyStroke.getKeyStroke("PASTE"), "paste-from-clipboard", + KeyStroke.getKeyStroke("shift ctrl RIGHT"), "selection-end-line", + KeyStroke.getKeyStroke("ctrl BACK_SLASH"), "unselect", + KeyStroke.getKeyStroke("ctrl A"), "select-all", + KeyStroke.getKeyStroke("shift KP_RIGHT"), "selection-forward", + KeyStroke.getKeyStroke("CUT"), "cut-to-clipboard", + KeyStroke.getKeyStroke("ctrl LEFT"), "caret-begin-line", + KeyStroke.getKeyStroke("BACK_SPACE"), "delete-previous", + KeyStroke.getKeyStroke("shift ctrl KP_LEFT"), "selection-begin-line", + KeyStroke.getKeyStroke("ctrl C"), "copy-to-clipboard", + KeyStroke.getKeyStroke("shift END"), "selection-end-line", + KeyStroke.getKeyStroke("ctrl RIGHT"), "caret-end-line", + KeyStroke.getKeyStroke("DELETE"), "delete-next", + KeyStroke.getKeyStroke("ENTER"), "notify-field-accept", + KeyStroke.getKeyStroke("shift LEFT"), "selection-backward" + }), "PasswordField.margin", new InsetsUIResource(0, 0, 0, 0), "PasswordField.selectionBackground", new ColorUIResource(Color.black), "PasswordField.selectionForeground", new ColorUIResource(Color.white), @@ -723,8 +881,8 @@ public abstract class BasicLookAndFeel extends LookAndFeel null), "RadioButton.darkShadow", new ColorUIResource(shadow), "RadioButton.focusInputMap", new UIDefaults.LazyInputMap(new Object[] { - "SPACE", "pressed", - "released SPACE", "released" + KeyStroke.getKeyStroke("SPACE"), "pressed", + KeyStroke.getKeyStroke("released SPACE"), "released" }), "RadioButton.font", new FontUIResource("Dialog", Font.PLAIN, 12), "RadioButton.foreground", new ColorUIResource(darkShadow), @@ -818,18 +976,20 @@ public abstract class BasicLookAndFeel extends LookAndFeel "Slider.background", new ColorUIResource(light), "Slider.focus", new ColorUIResource(shadow), "Slider.focusInputMap", new UIDefaults.LazyInputMap(new Object[] { - "PAGE_UP", "positiveBlockIncrement", - "PAGE_DOWN", "negativeBlockIncrement", - "END", "maxScroll", - "HOME", "minScroll", - "LEFT", "negativeUnitIncrement", - "KP_UP", "positiveUnitIncrement", - "KP_DOWN", "negativeUnitIncrement", - "UP", "positiveUnitIncrement", - "RIGHT", "positiveUnitIncrement", - "KP_LEFT", "negativeUnitIncrement", - "DOWN", "negativeUnitIncrement", - "KP_RIGHT", "positiveUnitIncrement" + "ctrl PAGE_DOWN", "negativeBlockIncrement", + "PAGE_DOWN", "negativeBlockIncrement", + "PAGE_UP", "positiveBlockIncrement", + "ctrl PAGE_UP", "positiveBlockIncrement", + "KP_RIGHT", "positiveUnitIncrement", + "DOWN", "negativeUnitIncrement", + "KP_LEFT", "negativeUnitIncrement", + "RIGHT", "positiveUnitIncrement", + "KP_DOWN", "negativeUnitIncrement", + "UP", "positiveUnitIncrement", + "KP_UP", "positiveUnitIncrement", + "LEFT", "negativeUnitIncrement", + "HOME", "minScroll", + "END", "maxScroll" }), "Slider.focusInsets", new InsetsUIResource(2, 2, 2, 2), "Slider.foreground", new ColorUIResource(light), @@ -840,6 +1000,9 @@ public abstract class BasicLookAndFeel extends LookAndFeel "Slider.tickHeight", new Integer(12), "Spinner.background", new ColorUIResource(light), "Spinner.foreground", new ColorUIResource(light), + "Spinner.arrowButtonSize", new DimensionUIResource(16, 5), + "Spinner.editorBorderPainted", Boolean.FALSE, + "Spinner.font", new FontUIResource("MonoSpaced", Font.PLAIN, 12), "SplitPane.ancestorInputMap", new UIDefaults.LazyInputMap(new Object[] { "F6", "toggleFocus", "F8", "startResize", @@ -857,7 +1020,7 @@ public abstract class BasicLookAndFeel extends LookAndFeel "SplitPane.background", new ColorUIResource(light), "SplitPane.border", new BasicBorders.SplitPaneBorder(null, null), "SplitPane.darkShadow", new ColorUIResource(shadow), - "SplitPane.dividerSize", new Integer(10), + "SplitPane.dividerSize", new Integer(7), "SplitPane.highlight", new ColorUIResource(highLight), "SplitPane.shadow", new ColorUIResource(shadow), "TabbedPane.ancestorInputMap", new UIDefaults.LazyInputMap(new Object[] { @@ -871,16 +1034,16 @@ public abstract class BasicLookAndFeel extends LookAndFeel "TabbedPane.darkShadow", new ColorUIResource(shadow), "TabbedPane.focus", new ColorUIResource(darkShadow), "TabbedPane.focusInputMap", new UIDefaults.LazyInputMap(new Object[] { - "LEFT", "navigateLeft", - "KP_UP", "navigateUp", - "ctrl DOWN", "requestFocusForVisibleComponent", - "UP", "navigateUp", - "KP_DOWN", "navigateDown", - "RIGHT", "navigateRight", - "KP_LEFT", "navigateLeft", - "ctrl KP_DOWN", "requestFocusForVisibleComponent", - "KP_RIGHT", "navigateRight", - "DOWN", "navigateDown" + KeyStroke.getKeyStroke("ctrl DOWN"), "requestFocusForVisibleComponent", + KeyStroke.getKeyStroke("KP_UP"), "navigateUp", + KeyStroke.getKeyStroke("LEFT"), "navigateLeft", + KeyStroke.getKeyStroke("ctrl KP_DOWN"), "requestFocusForVisibleComponent", + KeyStroke.getKeyStroke("UP"), "navigateUp", + KeyStroke.getKeyStroke("KP_DOWN"), "navigateDown", + KeyStroke.getKeyStroke("KP_LEFT"), "navigateLeft", + KeyStroke.getKeyStroke("RIGHT"), "navigateRight", + KeyStroke.getKeyStroke("KP_RIGHT"), "navigateRight", + KeyStroke.getKeyStroke("DOWN"), "navigateDown" }), "TabbedPane.font", new FontUIResource("Dialog", Font.PLAIN, 12), "TabbedPane.foreground", new ColorUIResource(darkShadow), @@ -888,10 +1051,10 @@ public abstract class BasicLookAndFeel extends LookAndFeel "TabbedPane.light", new ColorUIResource(highLight), "TabbedPane.selectedTabPadInsets", new InsetsUIResource(2, 2, 2, 1), "TabbedPane.shadow", new ColorUIResource(shadow), - "TabbedPane.tabbedPaneTabAreaInsets", new InsetsUIResource(3, 2, 1, 2), - "TabbedPane.tabbedPaneTabInsets", new InsetsUIResource(1, 4, 1, 4), "TabbedPane.tabbedPaneContentBorderInsets", new InsetsUIResource(3, 2, 1, 2), "TabbedPane.tabbedPaneTabPadInsets", new InsetsUIResource(1, 1, 1, 1), + "TabbedPane.tabAreaInsets", new InsetsUIResource(3, 2, 0, 2), + "TabbedPane.tabInsets", new InsetsUIResource(0, 4, 1, 4), "TabbedPane.tabRunOverlay", new Integer(2), "TabbedPane.textIconGap", new Integer(4), "Table.ancestorInputMap", new UIDefaults.LazyInputMap(new Object[] { @@ -976,32 +1139,73 @@ public abstract class BasicLookAndFeel extends LookAndFeel "Table.selectionBackground", new ColorUIResource(new ColorUIResource(0, 0, 128)), "Table.selectionForeground", new ColorUIResource(new ColorUIResource(255, 255, 255)), "TableHeader.background", new ColorUIResource(new ColorUIResource(192, 192, 192)), - "TableHeader.cellBorder", new BorderUIResource.BevelBorderUIResource(0), "TableHeader.font", new FontUIResource("Dialog", Font.PLAIN, 12), "TableHeader.foreground", new ColorUIResource(new ColorUIResource(0, 0, 0)), - "TextArea.background", new ColorUIResource(light), - "TextArea.border", - new BorderUIResource(BasicBorders.getMarginBorder()), + "TextArea.background", new ColorUIResource(light), + "TextArea.border", new BorderUIResource(BasicBorders.getMarginBorder()), "TextArea.caretBlinkRate", new Integer(500), "TextArea.caretForeground", new ColorUIResource(Color.black), "TextArea.font", new FontUIResource("MonoSpaced", Font.PLAIN, 12), "TextArea.foreground", new ColorUIResource(Color.black), "TextArea.inactiveForeground", new ColorUIResource(Color.gray), - "TextArea.keyBindings", new JTextComponent.KeyBinding[] { - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_UP, - 0), "caret-up"), - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, - 0), "caret-down"), - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, - 0), "page-up"), - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, - 0), "page-down"), - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, - 0), "insert-break"), - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, - 0), "insert-tab") - }, + "TextArea.focusInputMap", new UIDefaults.LazyInputMap(new Object[] { + KeyStroke.getKeyStroke("shift UP"), "selection-up", + KeyStroke.getKeyStroke("ctrl RIGHT"), "caret-next-word", + KeyStroke.getKeyStroke("shift ctrl LEFT"), "selection-previous-word", + KeyStroke.getKeyStroke("shift KP_UP"), "selection-up", + KeyStroke.getKeyStroke("DOWN"), "caret-down", + KeyStroke.getKeyStroke("shift ctrl T"), "previous-link-action", + KeyStroke.getKeyStroke("ctrl LEFT"), "caret-previous-word", + KeyStroke.getKeyStroke("CUT"), "cut-to-clipboard", + KeyStroke.getKeyStroke("END"), "caret-end-line", + KeyStroke.getKeyStroke("shift PAGE_UP"), "selection-page-up", + KeyStroke.getKeyStroke("KP_UP"), "caret-up", + KeyStroke.getKeyStroke("DELETE"), "delete-next", + KeyStroke.getKeyStroke("ctrl HOME"), "caret-begin", + KeyStroke.getKeyStroke("shift LEFT"), "selection-backward", + KeyStroke.getKeyStroke("ctrl END"), "caret-end", + KeyStroke.getKeyStroke("BACK_SPACE"), "delete-previous", + KeyStroke.getKeyStroke("shift ctrl RIGHT"), "selection-next-word", + KeyStroke.getKeyStroke("LEFT"), "caret-backward", + KeyStroke.getKeyStroke("KP_LEFT"), "caret-backward", + KeyStroke.getKeyStroke("shift KP_RIGHT"), "selection-forward", + KeyStroke.getKeyStroke("ctrl SPACE"), "activate-link-action", + KeyStroke.getKeyStroke("ctrl H"), "delete-previous", + KeyStroke.getKeyStroke("ctrl BACK_SLASH"), "unselect", + KeyStroke.getKeyStroke("ENTER"), "insert-break", + KeyStroke.getKeyStroke("shift HOME"), "selection-begin-line", + KeyStroke.getKeyStroke("RIGHT"), "caret-forward", + KeyStroke.getKeyStroke("shift ctrl PAGE_UP"), "selection-page-left", + KeyStroke.getKeyStroke("shift DOWN"), "selection-down", + KeyStroke.getKeyStroke("PAGE_DOWN"), "page-down", + KeyStroke.getKeyStroke("shift KP_LEFT"), "selection-backward", + KeyStroke.getKeyStroke("shift ctrl O"), "toggle-componentOrientation", + KeyStroke.getKeyStroke("ctrl X"), "cut-to-clipboard", + KeyStroke.getKeyStroke("shift ctrl PAGE_DOWN"), "selection-page-right", + KeyStroke.getKeyStroke("ctrl C"), "copy-to-clipboard", + KeyStroke.getKeyStroke("ctrl KP_RIGHT"), "caret-next-word", + KeyStroke.getKeyStroke("shift END"), "selection-end-line", + KeyStroke.getKeyStroke("ctrl KP_LEFT"), "caret-previous-word", + KeyStroke.getKeyStroke("HOME"), "caret-begin-line", + KeyStroke.getKeyStroke("ctrl V"), "paste-from-clipboard", + KeyStroke.getKeyStroke("KP_DOWN"), "caret-down", + KeyStroke.getKeyStroke("ctrl A"), "select-all", + KeyStroke.getKeyStroke("shift RIGHT"), "selection-forward", + KeyStroke.getKeyStroke("shift ctrl END"), "selection-end", + KeyStroke.getKeyStroke("COPY"), "copy-to-clipboard", + KeyStroke.getKeyStroke("shift ctrl KP_LEFT"), "selection-previous-word", + KeyStroke.getKeyStroke("ctrl T"), "next-link-action", + KeyStroke.getKeyStroke("shift KP_DOWN"), "selection-down", + KeyStroke.getKeyStroke("TAB"), "insert-tab", + KeyStroke.getKeyStroke("UP"), "caret-up", + KeyStroke.getKeyStroke("shift ctrl HOME"), "selection-begin", + KeyStroke.getKeyStroke("shift PAGE_DOWN"), "selection-page-down", + KeyStroke.getKeyStroke("KP_RIGHT"), "caret-forward", + KeyStroke.getKeyStroke("shift ctrl KP_RIGHT"), "selection-next-word", + KeyStroke.getKeyStroke("PAGE_UP"), "page-up", + KeyStroke.getKeyStroke("PASTE"), "paste-from-clipboard" + }), "TextArea.margin", new InsetsUIResource(0, 0, 0, 0), "TextArea.selectionBackground", new ColorUIResource(Color.black), "TextArea.selectionForeground", new ColorUIResource(Color.white), @@ -1017,17 +1221,41 @@ public abstract class BasicLookAndFeel extends LookAndFeel "TextField.inactiveForeground", new ColorUIResource(Color.GRAY), "TextField.light", new ColorUIResource(highLight), "TextField.highlight", new ColorUIResource(light), - "TextField.keyBindings", new JTextComponent.KeyBinding[] { - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, - 0), - "notify-field-accept"), - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, - InputEvent.SHIFT_DOWN_MASK), - "selection-backward"), - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, - InputEvent.SHIFT_DOWN_MASK), - "selection-forward"), - }, + "TextField.focusInputMap", new UIDefaults.LazyInputMap(new Object[] { + KeyStroke.getKeyStroke("ENTER"), "notify-field-accept", + KeyStroke.getKeyStroke("LEFT"), "caret-backward", + KeyStroke.getKeyStroke("RIGHT"), "caret-forward", + KeyStroke.getKeyStroke("BACK_SPACE"), "delete-previous", + KeyStroke.getKeyStroke("ctrl X"), "cut-to-clipboard", + KeyStroke.getKeyStroke("ctrl C"), "copy-to-clipboard", + KeyStroke.getKeyStroke("ctrl V"), "paste-from-clipboard", + KeyStroke.getKeyStroke("shift LEFT"), "selection-backward", + KeyStroke.getKeyStroke("shift RIGHT"), "selection-forward", + KeyStroke.getKeyStroke("HOME"), "caret-begin-line", + KeyStroke.getKeyStroke("END"), "caret-end-line", + KeyStroke.getKeyStroke("DELETE"), "delete-next", + KeyStroke.getKeyStroke("shift ctrl O"), "toggle-componentOrientation", + KeyStroke.getKeyStroke("shift KP_LEFT"), "selection-backward", + KeyStroke.getKeyStroke("ctrl H"), "delete-previous", + KeyStroke.getKeyStroke("KP_LEFT"), "caret-backward", + KeyStroke.getKeyStroke("KP_RIGHT"), "caret-forward", + KeyStroke.getKeyStroke("shift ctrl KP_RIGHT"), "selection-next-word", + KeyStroke.getKeyStroke("COPY"), "copy-to-clipboard", + KeyStroke.getKeyStroke("shift HOME"), "selection-begin-line", + KeyStroke.getKeyStroke("shift ctrl LEFT"), "selection-previous-word", + KeyStroke.getKeyStroke("ctrl KP_LEFT"), "caret-previous-word", + KeyStroke.getKeyStroke("ctrl KP_RIGHT"), "caret-next-word", + KeyStroke.getKeyStroke("PASTE"), "paste-from-clipboard", + KeyStroke.getKeyStroke("shift ctrl RIGHT"), "selection-next-word", + KeyStroke.getKeyStroke("ctrl BACK_SLASH"), "unselect", + KeyStroke.getKeyStroke("ctrl A"), "select-all", + KeyStroke.getKeyStroke("shift KP_RIGHT"), "selection-forward", + KeyStroke.getKeyStroke("CUT"), "cut-to-clipboard", + KeyStroke.getKeyStroke("ctrl LEFT"), "caret-previous-word", + KeyStroke.getKeyStroke("shift ctrl KP_LEFT"), "selection-previous-word", + KeyStroke.getKeyStroke("shift END"), "selection-end-line", + KeyStroke.getKeyStroke("ctrl RIGHT"), "caret-next-word" + }), "TextField.margin", new InsetsUIResource(0, 0, 0, 0), "TextField.selectionBackground", new ColorUIResource(Color.black), "TextField.selectionForeground", new ColorUIResource(Color.white), @@ -1038,20 +1266,63 @@ public abstract class BasicLookAndFeel extends LookAndFeel "TextPane.font", new FontUIResource("Serif", Font.PLAIN, 12), "TextPane.foreground", new ColorUIResource(Color.black), "TextPane.inactiveForeground", new ColorUIResource(Color.gray), - "TextPane.keyBindings", new JTextComponent.KeyBinding[] { - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_UP, - 0), "caret-up"), - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, - 0), "caret-down"), - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, - 0), "page-up"), - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, - 0), "page-down"), - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, - 0), "insert-break"), - new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, - 0), "insert-tab") - }, + "TextPane.focusInputMap", new UIDefaults.LazyInputMap(new Object[] { + KeyStroke.getKeyStroke("shift UP"), "selection-up", + KeyStroke.getKeyStroke("ctrl RIGHT"), "caret-next-word", + KeyStroke.getKeyStroke("shift ctrl LEFT"), "selection-previous-word", + KeyStroke.getKeyStroke("shift KP_UP"), "selection-up", + KeyStroke.getKeyStroke("DOWN"), "caret-down", + KeyStroke.getKeyStroke("shift ctrl T"), "previous-link-action", + KeyStroke.getKeyStroke("ctrl LEFT"), "caret-previous-word", + KeyStroke.getKeyStroke("CUT"), "cut-to-clipboard", + KeyStroke.getKeyStroke("END"), "caret-end-line", + KeyStroke.getKeyStroke("shift PAGE_UP"), "selection-page-up", + KeyStroke.getKeyStroke("KP_UP"), "caret-up", + KeyStroke.getKeyStroke("DELETE"), "delete-next", + KeyStroke.getKeyStroke("ctrl HOME"), "caret-begin", + KeyStroke.getKeyStroke("shift LEFT"), "selection-backward", + KeyStroke.getKeyStroke("ctrl END"), "caret-end", + KeyStroke.getKeyStroke("BACK_SPACE"), "delete-previous", + KeyStroke.getKeyStroke("shift ctrl RIGHT"), "selection-next-word", + KeyStroke.getKeyStroke("LEFT"), "caret-backward", + KeyStroke.getKeyStroke("KP_LEFT"), "caret-backward", + KeyStroke.getKeyStroke("shift KP_RIGHT"), "selection-forward", + KeyStroke.getKeyStroke("ctrl SPACE"), "activate-link-action", + KeyStroke.getKeyStroke("ctrl H"), "delete-previous", + KeyStroke.getKeyStroke("ctrl BACK_SLASH"), "unselect", + KeyStroke.getKeyStroke("ENTER"), "insert-break", + KeyStroke.getKeyStroke("shift HOME"), "selection-begin-line", + KeyStroke.getKeyStroke("RIGHT"), "caret-forward", + KeyStroke.getKeyStroke("shift ctrl PAGE_UP"), "selection-page-left", + KeyStroke.getKeyStroke("shift DOWN"), "selection-down", + KeyStroke.getKeyStroke("PAGE_DOWN"), "page-down", + KeyStroke.getKeyStroke("shift KP_LEFT"), "selection-backward", + KeyStroke.getKeyStroke("shift ctrl O"), "toggle-componentOrientation", + KeyStroke.getKeyStroke("ctrl X"), "cut-to-clipboard", + KeyStroke.getKeyStroke("shift ctrl PAGE_DOWN"), "selection-page-right", + KeyStroke.getKeyStroke("ctrl C"), "copy-to-clipboard", + KeyStroke.getKeyStroke("ctrl KP_RIGHT"), "caret-next-word", + KeyStroke.getKeyStroke("shift END"), "selection-end-line", + KeyStroke.getKeyStroke("ctrl KP_LEFT"), "caret-previous-word", + KeyStroke.getKeyStroke("HOME"), "caret-begin-line", + KeyStroke.getKeyStroke("ctrl V"), "paste-from-clipboard", + KeyStroke.getKeyStroke("KP_DOWN"), "caret-down", + KeyStroke.getKeyStroke("ctrl A"), "select-all", + KeyStroke.getKeyStroke("shift RIGHT"), "selection-forward", + KeyStroke.getKeyStroke("shift ctrl END"), "selection-end", + KeyStroke.getKeyStroke("COPY"), "copy-to-clipboard", + KeyStroke.getKeyStroke("shift ctrl KP_LEFT"), "selection-previous-word", + KeyStroke.getKeyStroke("ctrl T"), "next-link-action", + KeyStroke.getKeyStroke("shift KP_DOWN"), "selection-down", + KeyStroke.getKeyStroke("TAB"), "insert-tab", + KeyStroke.getKeyStroke("UP"), "caret-up", + KeyStroke.getKeyStroke("shift ctrl HOME"), "selection-begin", + KeyStroke.getKeyStroke("shift PAGE_DOWN"), "selection-page-down", + KeyStroke.getKeyStroke("KP_RIGHT"), "caret-forward", + KeyStroke.getKeyStroke("shift ctrl KP_RIGHT"), "selection-next-word", + KeyStroke.getKeyStroke("PAGE_UP"), "page-up", + KeyStroke.getKeyStroke("PASTE"), "paste-from-clipboard" + }), "TextPane.margin", new InsetsUIResource(3, 3, 3, 3), "TextPane.selectionBackground", new ColorUIResource(Color.black), "TextPane.selectionForeground", new ColorUIResource(Color.white), @@ -1063,8 +1334,8 @@ public abstract class BasicLookAndFeel extends LookAndFeel new BorderUIResource.CompoundBorderUIResource(null, null), "ToggleButton.darkShadow", new ColorUIResource(shadow), "ToggleButton.focusInputMap", new UIDefaults.LazyInputMap(new Object[] { - "SPACE", "pressed", - "released SPACE", "released" + KeyStroke.getKeyStroke("SPACE"), "pressed", + KeyStroke.getKeyStroke("released SPACE"), "released" }), "ToggleButton.font", new FontUIResource("Dialog", Font.PLAIN, 12), "ToggleButton.foreground", new ColorUIResource(darkShadow), @@ -1095,7 +1366,7 @@ public abstract class BasicLookAndFeel extends LookAndFeel "ToolBar.foreground", new ColorUIResource(darkShadow), "ToolBar.highlight", new ColorUIResource(highLight), "ToolBar.light", new ColorUIResource(highLight), - "ToolBar.separatorSize", new DimensionUIResource(20, 20), + "ToolBar.separatorSize", new DimensionUIResource(10, 10), "ToolBar.shadow", new ColorUIResource(shadow), "ToolTip.background", new ColorUIResource(light), "ToolTip.border", new BorderUIResource.LineBorderUIResource(Color.lightGray), @@ -1106,72 +1377,147 @@ public abstract class BasicLookAndFeel extends LookAndFeel }), "Tree.background", new ColorUIResource(new Color(255, 255, 255)), "Tree.changeSelectionWithFocus", Boolean.TRUE, -// "Tree.closedIcon", new IconUIResource(new ImageIcon("icons/TreeClosed.png")), -// "Tree.collapsedIcon", new IconUIResource(new ImageIcon("icons/TreeCollapsed.png")), "Tree.drawsFocusBorderAroundIcon", Boolean.FALSE, "Tree.editorBorder", new BorderUIResource.LineBorderUIResource(Color.lightGray), "Tree.focusInputMap", new UIDefaults.LazyInputMap(new Object[] { - "shift PAGE_DOWN", "scrollDownExtendSelection", - "PAGE_DOWN", "scrollDownChangeSelection", - "END", "selectLast", - "ctrl KP_UP", "selectPreviousChangeLead", - "shift END", "selectLastExtendSelection", - "HOME", "selectFirst", - "ctrl END", "selectLastChangeLead", - "ctrl SLASH", "selectAll", - "LEFT", "selectParent", - "shift HOME", "selectFirstExtendSelection", - "UP", "selectPrevious", - "ctrl KP_DOWN", "selectNextChangeLead", - "RIGHT", "selectChild", - "ctrl HOME", "selectFirstChangeLead", - "DOWN", "selectNext", - "ctrl KP_LEFT", "scrollLeft", - "shift UP", "selectPreviousExtendSelection", - "F2", "startEditing", - "ctrl LEFT", "scrollLeft", - "ctrl KP_RIGHT","scrollRight", - "ctrl UP", "selectPreviousChangeLead", - "shift DOWN", "selectNextExtendSelection", - "ENTER", "toggle", - "KP_UP", "selectPrevious", - "KP_DOWN", "selectNext", - "ctrl RIGHT", "scrollRight", - "KP_LEFT", "selectParent", - "KP_RIGHT", "selectChild", - "ctrl DOWN", "selectNextChangeLead", - "ctrl A", "selectAll", - "shift KP_UP", "selectPreviousExtendSelection", - "shift KP_DOWN","selectNextExtendSelection", - "ctrl SPACE", "toggleSelectionPreserveAnchor", - "ctrl shift PAGE_UP", "scrollUpExtendSelection", - "ctrl BACK_SLASH", "clearSelection", - "shift SPACE", "extendSelection", - "ctrl PAGE_UP", "scrollUpChangeLead", - "shift PAGE_UP","scrollUpExtendSelection", - "SPACE", "toggleSelectionPreserveAnchor", - "ctrl shift PAGE_DOWN", "scrollDownExtendSelection", - "PAGE_UP", "scrollUpChangeSelection", - "ctrl PAGE_DOWN", "scrollDownChangeLead" + KeyStroke.getKeyStroke("ctrl DOWN"), "selectNextChangeLead", + KeyStroke.getKeyStroke("shift UP"), "selectPreviousExtendSelection", + KeyStroke.getKeyStroke("ctrl RIGHT"), "scrollRight", + KeyStroke.getKeyStroke("shift KP_UP"), "selectPreviousExtendSelection", + KeyStroke.getKeyStroke("DOWN"), "selectNext", + KeyStroke.getKeyStroke("ctrl UP"), "selectPreviousChangeLead", + KeyStroke.getKeyStroke("ctrl LEFT"), "scrollLeft", + KeyStroke.getKeyStroke("CUT"), "cut", + KeyStroke.getKeyStroke("END"), "selectLast", + KeyStroke.getKeyStroke("shift PAGE_UP"), "scrollUpExtendSelection", + KeyStroke.getKeyStroke("KP_UP"), "selectPrevious", + KeyStroke.getKeyStroke("shift ctrl UP"), "selectPreviousExtendSelection", + KeyStroke.getKeyStroke("ctrl HOME"), "selectFirstChangeLead", + KeyStroke.getKeyStroke("ctrl END"), "selectLastChangeLead", + KeyStroke.getKeyStroke("ctrl PAGE_DOWN"), "scrollDownChangeLead", + KeyStroke.getKeyStroke("LEFT"), "selectParent", + KeyStroke.getKeyStroke("ctrl PAGE_UP"), "scrollUpChangeLead", + KeyStroke.getKeyStroke("KP_LEFT"), "selectParent", + KeyStroke.getKeyStroke("SPACE"), "addToSelection", + KeyStroke.getKeyStroke("ctrl SPACE"), "toggleAndAnchor", + KeyStroke.getKeyStroke("shift SPACE"), "extendTo", + KeyStroke.getKeyStroke("shift ctrl SPACE"), "moveSelectionTo", + KeyStroke.getKeyStroke("ADD"), "expand", + KeyStroke.getKeyStroke("ctrl BACK_SLASH"), "clearSelection", + KeyStroke.getKeyStroke("shift ctrl DOWN"), "selectNextExtendSelection", + KeyStroke.getKeyStroke("shift HOME"), "selectFirstExtendSelection", + KeyStroke.getKeyStroke("RIGHT"), "selectChild", + KeyStroke.getKeyStroke("shift ctrl PAGE_UP"), "scrollUpExtendSelection", + KeyStroke.getKeyStroke("shift DOWN"), "selectNextExtendSelection", + KeyStroke.getKeyStroke("PAGE_DOWN"), "scrollDownChangeSelection", + KeyStroke.getKeyStroke("shift ctrl KP_UP"), "selectPreviousExtendSelection", + KeyStroke.getKeyStroke("SUBTRACT"), "collapse", + KeyStroke.getKeyStroke("ctrl X"), "cut", + KeyStroke.getKeyStroke("shift ctrl PAGE_DOWN"), "scrollDownExtendSelection", + KeyStroke.getKeyStroke("ctrl SLASH"), "selectAll", + KeyStroke.getKeyStroke("ctrl C"), "copy", + KeyStroke.getKeyStroke("ctrl KP_RIGHT"), "scrollRight", + KeyStroke.getKeyStroke("shift END"), "selectLastExtendSelection", + KeyStroke.getKeyStroke("shift ctrl KP_DOWN"), "selectNextExtendSelection", + KeyStroke.getKeyStroke("ctrl KP_LEFT"), "scrollLeft", + KeyStroke.getKeyStroke("HOME"), "selectFirst", + KeyStroke.getKeyStroke("ctrl V"), "paste", + KeyStroke.getKeyStroke("KP_DOWN"), "selectNext", + KeyStroke.getKeyStroke("ctrl A"), "selectAll", + KeyStroke.getKeyStroke("ctrl KP_DOWN"), "selectNextChangeLead", + KeyStroke.getKeyStroke("shift ctrl END"), "selectLastExtendSelection", + KeyStroke.getKeyStroke("COPY"), "copy", + KeyStroke.getKeyStroke("ctrl KP_UP"), "selectPreviousChangeLead", + KeyStroke.getKeyStroke("shift KP_DOWN"), "selectNextExtendSelection", + KeyStroke.getKeyStroke("UP"), "selectPrevious", + KeyStroke.getKeyStroke("shift ctrl HOME"), "selectFirstExtendSelection", + KeyStroke.getKeyStroke("shift PAGE_DOWN"), "scrollDownExtendSelection", + KeyStroke.getKeyStroke("KP_RIGHT"), "selectChild", + KeyStroke.getKeyStroke("F2"), "startEditing", + KeyStroke.getKeyStroke("PAGE_UP"), "scrollUpChangeSelection", + KeyStroke.getKeyStroke("PASTE"), "paste" }), "Tree.font", new FontUIResource("Dialog", Font.PLAIN, 12), "Tree.foreground", new ColorUIResource(Color.black), "Tree.hash", new ColorUIResource(new Color(128, 128, 128)), "Tree.leftChildIndent", new Integer(7), "Tree.rightChildIndent", new Integer(13), - "Tree.rowHeight", new Integer(0), + "Tree.rowHeight", new Integer(16), "Tree.scrollsOnExpand", Boolean.TRUE, "Tree.selectionBackground", new ColorUIResource(Color.black), "Tree.nonSelectionBackground", new ColorUIResource(new Color(255, 255, 255)), "Tree.selectionBorderColor", new ColorUIResource(Color.black), "Tree.selectionBorder", new BorderUIResource.LineBorderUIResource(Color.black), "Tree.selectionForeground", new ColorUIResource(new Color(255, 255, 255)), - "Tree.textBackground", new ColorUIResource(new Color(192, 192, 192)), - "Tree.textForeground", new ColorUIResource(new Color(0, 0, 0)), "Viewport.background", new ColorUIResource(light), "Viewport.foreground", new ColorUIResource(Color.black), "Viewport.font", new FontUIResource("Dialog", Font.PLAIN, 12) }; defaults.putDefaults(uiDefaults); } -} // class BasicLookAndFeel + + /** + * Returns the <code>ActionMap</code> that stores all the actions that are + * responsibly for rendering auditory cues. + * + * @return the action map that stores all the actions that are + * responsibly for rendering auditory cues + * + * @see #createAudioAction + * @see #playSound + * + * @since 1.4 + */ + protected ActionMap getAudioActionMap() + { + if (audioActionMap != null) + audioActionMap = new ActionMap(); + return audioActionMap; + } + + /** + * Creates an <code>Action</code> that can play an auditory cue specified by + * the key. The UIDefaults value for the key is normally a String that points + * to an audio file relative to the current package. + * + * @param key a UIDefaults key that specifies the sound + * + * @return an action that can play the sound + * + * @see #playSound + * + * @since 1.4 + */ + protected Action createAudioAction(Object key) + { + return new AudioAction(key); + } + + /** + * Plays the sound of the action if it is listed in + * <code>AuditoryCues.playList</code>. + * + * @param audioAction the audio action to play + * + * @since 1.4 + */ + protected void playSound(Action audioAction) + { + if (audioAction instanceof AudioAction) + { + Object[] playList = (Object[]) UIManager.get("AuditoryCues.playList"); + for (int i = 0; i < playList.length; ++i) + { + if (playList[i].equals(((AudioAction) audioAction).key)) + { + ActionEvent ev = new ActionEvent(this, + ActionEvent.ACTION_PERFORMED, + (String) playList[i]); + audioAction.actionPerformed(ev); + break; + } + } + } + } + +} diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicMenuItemUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicMenuItemUI.java index c8754a3..63f0ce2 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicMenuItemUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicMenuItemUI.java @@ -206,7 +206,10 @@ public class BasicMenuItemUI extends MenuItemUI map.remove((KeyStroke)e.getOldValue()); else map = new ComponentInputMapUIResource(menuItem); - map.put((KeyStroke)e.getNewValue(), "doClick"); + + KeyStroke accelerator = (KeyStroke) e.getNewValue(); + if (accelerator != null) + map.put(accelerator, "doClick"); } } } @@ -485,7 +488,9 @@ public class BasicMenuItemUI extends MenuItemUI InputMap focusedWindowMap = SwingUtilities.getUIInputMap(menuItem, JComponent.WHEN_IN_FOCUSED_WINDOW); if (focusedWindowMap == null) focusedWindowMap = new ComponentInputMapUIResource(menuItem); - focusedWindowMap.put(menuItem.getAccelerator(), "doClick"); + KeyStroke accelerator = menuItem.getAccelerator(); + if (accelerator != null) + focusedWindowMap.put(accelerator, "doClick"); SwingUtilities.replaceUIInputMap(menuItem, JComponent.WHEN_IN_FOCUSED_WINDOW, focusedWindowMap); ActionMap UIActionMap = SwingUtilities.getUIActionMap(menuItem); @@ -555,17 +560,16 @@ public class BasicMenuItemUI extends MenuItemUI // Menu item is considered to be highlighted when it is selected. // But we don't want to paint the background of JCheckBoxMenuItems ButtonModel mod = menuItem.getModel(); - if ((menuItem.isSelected() && checkIcon == null) || (mod != null && - mod.isArmed()) - && (menuItem.getParent() instanceof MenuElement)) + if (menuItem.isContentAreaFilled()) { - if (menuItem.isContentAreaFilled()) - { - g.setColor(selectionBackground); - g.fillRect(0, 0, menuItem.getWidth(), menuItem.getHeight()); - } - } - + if ((menuItem.isSelected() && checkIcon == null) || (mod != null && + mod.isArmed()) + && (menuItem.getParent() instanceof MenuElement)) + g.setColor(selectionBackground); + else + g.setColor(bgColor); + g.fillRect(0, 0, menuItem.getWidth(), menuItem.getHeight()); + } } /** @@ -608,7 +612,7 @@ public class BasicMenuItemUI extends MenuItemUI FontMetrics fm = g.getFontMetrics(f); SwingUtilities.calculateInnerArea(m, br); SwingUtilities.calculateInsetArea(br, m.getInsets(), vr); - paintBackground(g, m, m.getBackground()); + paintBackground(g, m, background); /* * MenuItems insets are equal to menuItems margin, space between text and diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicOptionPaneUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicOptionPaneUI.java index 6b37d31..005a3b3 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicOptionPaneUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicOptionPaneUI.java @@ -774,7 +774,7 @@ public class BasicOptionPaneUI extends OptionPaneUI // it will create a box and burst the string. // otherwise, it will just create a label and re-call // this method with the label o.O - if (msg.toString().length() > maxll) + if (msg.toString().length() > maxll || msg.toString().contains("\n")) { Box tmp = new Box(BoxLayout.Y_AXIS); burstStringInto(tmp, msg.toString(), maxll); @@ -796,17 +796,35 @@ public class BasicOptionPaneUI extends OptionPaneUI */ protected void burstStringInto(Container c, String d, int maxll) { - // FIXME: Verify that this is the correct behaviour. - // One interpretation of the spec is that this method - // should recursively call itself to create (and add) - // JLabels to the container if the length of the String d - // is greater than maxll. - // but in practice, even with a really long string, this is - // all that happens. if (d == null || c == null) return; - JLabel label = new JLabel(d); + + int newlineIndex = d.indexOf('\n'); + String line; + String remainder; + if (newlineIndex >= 0 && newlineIndex < maxll) + { + line = d.substring(0, newlineIndex); + remainder = d.substring(newlineIndex + 1); + } + else + { + line = d.substring(0, maxll); + remainder = d.substring(maxll); + } + JLabel label = new JLabel(line); c.add(label); + + // If there is nothing left to burst, then we can stop. + if (remainder.length() == 0) + return; + + // Recursivly call ourselves to burst the remainder of the string, + if ((remainder.length() > maxll || remainder.contains("\n"))) + burstStringInto(c, remainder, maxll); + else + // Add the remainder to the container and be done. + c.add(new JLabel(remainder)); } /** diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicScrollPaneUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicScrollPaneUI.java index 808ed27..71671b7 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicScrollPaneUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicScrollPaneUI.java @@ -505,7 +505,8 @@ public class BasicScrollPaneUI extends ScrollPaneUI JViewport oldViewport = (JViewport) ev.getOldValue(); oldViewport.removeChangeListener(viewportChangeListener); JViewport newViewport = (JViewport) ev.getNewValue(); - oldViewport.addChangeListener(viewportChangeListener); + newViewport.addChangeListener(viewportChangeListener); + syncScrollPaneWithViewport(); } } diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneDivider.java b/libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneDivider.java index 69ed2be..ff17ff0 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneDivider.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicSplitPaneDivider.java @@ -376,6 +376,11 @@ public class BasicSplitPaneDivider extends Container dividerSize = getSize(); border.paintBorder(this, g, 0, 0, dividerSize.width, dividerSize.height); } + if (splitPane.isOneTouchExpandable()) + { + ((BasicArrowButton) rightButton).paint(g); + ((BasicArrowButton) leftButton).paint(g); + } } /** @@ -583,7 +588,7 @@ public class BasicSplitPaneDivider extends Container public void mouseReleased(MouseEvent e) { if (isDragging) - dragger.completeDrag(e); + dragger.completeDrag(e); isDragging = false; } @@ -596,7 +601,7 @@ public class BasicSplitPaneDivider extends Container public void mouseDragged(MouseEvent e) { if (dragger != null) - dragger.continueDrag(e); + dragger.continueDrag(e); } /** diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTabbedPaneUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTabbedPaneUI.java index ce9ea3e..a8f52ce 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicTabbedPaneUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicTabbedPaneUI.java @@ -208,7 +208,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants incrButton = createIncreaseButton(); decrButton = createDecreaseButton(); } - tabPane.layout(); + tabPane.revalidate(); tabPane.repaint(); } } @@ -241,6 +241,9 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants */ public void calculateLayoutInfo() { + assureRectsCreated(tabPane.getTabCount()); + contentRect = SwingUtilities.calculateInnerArea(tabPane, contentRect); + calculateTabRects(tabPane.getTabPlacement(), tabPane.getTabCount()); if (tabPane.getSelectedIndex() != -1) @@ -286,8 +289,6 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants componentWidth = Math.max(componentWidth, dims.width); } } - Insets insets = tabPane.getInsets(); - if (tabPlacement == SwingConstants.TOP || tabPlacement == SwingConstants.BOTTOM) { @@ -331,7 +332,6 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { if (tabCount == 0) return; - assureRectsCreated(tabCount); FontMetrics fm = getFontMetrics(); SwingUtilities.calculateInnerArea(tabPane, calcRect); @@ -944,13 +944,11 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { if (tabCount == 0) return; - assureRectsCreated(tabCount); FontMetrics fm = getFontMetrics(); SwingUtilities.calculateInnerArea(tabPane, calcRect); Insets tabAreaInsets = getTabAreaInsets(tabPlacement); Insets insets = tabPane.getInsets(); - int max = 0; int runs = 1; int start = 0; int top = 0; @@ -959,7 +957,6 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { int maxHeight = calculateMaxTabHeight(tabPlacement); calcRect.width -= tabAreaInsets.left + tabAreaInsets.right; - max = calcRect.width + tabAreaInsets.left + insets.left; start = tabAreaInsets.left + insets.left; int width = 0; int runWidth = start; @@ -996,7 +993,6 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants int maxWidth = calculateMaxTabWidth(tabPlacement); calcRect.height -= tabAreaInsets.top + tabAreaInsets.bottom; - max = calcRect.height + tabAreaInsets.top; int height = 0; start = tabAreaInsets.top + insets.top; int runHeight = start; @@ -1048,8 +1044,8 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants if (tabCount == 0) return; int tabPlacement = tabPane.getTabPlacement(); - incrButton.hide(); - decrButton.hide(); + incrButton.setVisible(false); + decrButton.setVisible(false); if (tabPlacement == SwingConstants.TOP || tabPlacement == SwingConstants.BOTTOM) { @@ -1068,8 +1064,8 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants decrDims.width, tabAreaRect.height); tabAreaRect.width -= decrDims.width + incrDims.width; - incrButton.show(); - decrButton.show(); + incrButton.setVisible(true); + decrButton.setVisible(true); } } @@ -1092,8 +1088,8 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants incrDims.height); tabAreaRect.height -= decrDims.height + incrDims.height; - incrButton.show(); - decrButton.show(); + incrButton.setVisible(true); + decrButton.setVisible(true); } } viewport.setBounds(tabAreaRect.x, tabAreaRect.y, tabAreaRect.width, @@ -1348,6 +1344,8 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants public BasicTabbedPaneUI() { super(); + rects = new Rectangle[0]; + tabRuns = new int[10]; } /** @@ -1460,7 +1458,6 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants layoutManager = createLayoutManager(); tabPane.setLayout(layoutManager); - tabPane.layout(); } } @@ -1552,9 +1549,9 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants textIconGap = UIManager.getInt("TabbedPane.textIconGap"); tabRunOverlay = UIManager.getInt("TabbedPane.tabRunOverlay"); - tabInsets = UIManager.getInsets("TabbedPane.tabbedPaneTabInsets"); + tabInsets = UIManager.getInsets("TabbedPane.tabInsets"); selectedTabPadInsets = UIManager.getInsets("TabbedPane.tabbedPaneTabPadInsets"); - tabAreaInsets = UIManager.getInsets("TabbedPane.tabbedPaneTabAreaInsets"); + tabAreaInsets = UIManager.getInsets("TabbedPane.tabAreaInsets"); contentBorderInsets = UIManager.getInsets("TabbedPane.tabbedPaneContentBorderInsets"); calcRect = new Rectangle(); @@ -1884,7 +1881,8 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants protected void paintIcon(Graphics g, int tabPlacement, int tabIndex, Icon icon, Rectangle iconRect, boolean isSelected) { - icon.paintIcon(tabPane, g, iconRect.x, iconRect.y); + if (icon != null) + icon.paintIcon(tabPane, g, iconRect.x, iconRect.y); } /** @@ -2110,7 +2108,6 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants protected void paintContentBorder(Graphics g, int tabPlacement, int selectedIndex) { - Insets insets = getContentBorderInsets(tabPlacement); int x = contentRect.x; int y = contentRect.y; int w = contentRect.width; @@ -2396,16 +2393,13 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants */ protected void assureRectsCreated(int tabCount) { - if (rects == null) - rects = new Rectangle[tabCount]; - if (tabCount == rects.length) - return; - else + if (rects.length < tabCount) { - int numToCopy = Math.min(tabCount, rects.length); - Rectangle[] tmp = new Rectangle[tabCount]; - System.arraycopy(rects, 0, tmp, 0, numToCopy); - rects = tmp; + Rectangle[] old = rects; + rects = new Rectangle[tabCount]; + System.arraycopy(old, 0, rects, 0, old.length); + for (int i = old.length; i < rects.length; i++) + rects[i] = new Rectangle(); } } @@ -2763,7 +2757,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants */ protected FontMetrics getFontMetrics() { - FontMetrics fm = tabPane.getToolkit().getFontMetrics(tabPane.getFont()); + FontMetrics fm = tabPane.getFontMetrics(tabPane.getFont()); return fm; } diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTableHeaderUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTableHeaderUI.java index ec0467a..9c8a5ef 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicTableHeaderUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicTableHeaderUI.java @@ -139,6 +139,7 @@ public class BasicTableHeaderUI extends TableHeaderUI public void installUI(JComponent c) { header = (JTableHeader) c; + rendererPane = new CellRendererPane(); installDefaults(); installKeyboardActions(); installListeners(); @@ -194,18 +195,15 @@ public class BasicTableHeaderUI extends TableHeaderUI false, // isSelected false, // isFocused -1, i); + // FIXME: The following settings should be performed in + // rend.getTableCellRendererComponent(). comp.setFont(header.getFont()); comp.setBackground(header.getBackground()); comp.setForeground(header.getForeground()); if (comp instanceof JComponent) ((JComponent)comp).setBorder(cellBorder); - gfx.translate(bounds.x, bounds.y); - gfx.setClip(0, 0, bounds.width, bounds.height); - comp.setSize(bounds.width, bounds.height); - comp.setLocation(0,0); - comp.paint(gfx); - gfx.translate(-bounds.x, -bounds.y); - gfx.setClip(oldClip); + rendererPane.paintComponent(gfx, comp, header, bounds.x, bounds.y, + bounds.width, bounds.height); } } diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTableUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTableUI.java index 0154439..18b6912 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicTableUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicTableUI.java @@ -1193,29 +1193,9 @@ public class BasicTableUI extends TableUI TableCellRenderer rend, TableModel data, int rowLead, int colLead) { - boolean rowSelAllowed = table.getRowSelectionAllowed(); - boolean colSelAllowed = table.getColumnSelectionAllowed(); - boolean isSel = false; - if (rowSelAllowed && colSelAllowed || !rowSelAllowed && !colSelAllowed) - isSel = table.isCellSelected(row, col); - else - isSel = table.isRowSelected(row) && table.getRowSelectionAllowed() - || table.isColumnSelected(col) && table.getColumnSelectionAllowed(); - - // Determine the focused cell. The focused cell is the cell at the - // leadSelectionIndices of the row and column selection model. - ListSelectionModel rowSel = table.getSelectionModel(); - ListSelectionModel colSel = table.getColumnModel().getSelectionModel(); - boolean hasFocus = table.hasFocus() && table.isEnabled() - && rowSel.getLeadSelectionIndex() == row - && colSel.getLeadSelectionIndex() == col; - - Component comp = rend.getTableCellRendererComponent(table, - data.getValueAt(row, col), - isSel, hasFocus, row, col); - + Component comp = table.prepareRenderer(rend, row, col); rendererPane.paintComponent(g, comp, table, bounds); - + // FIXME: this is manual painting of the Caret, why doesn't the // JTextField take care of this itself? if (comp instanceof JTextField) @@ -1263,7 +1243,7 @@ public class BasicTableUI extends TableUI width - gap.width + 1, height - gap.height); if (bounds.intersects(clip)) - { + { paintCell(gfx, r, c, bounds, table.getCellRenderer(r, c), table.getModel(), table.getSelectionModel().getLeadSelectionIndex(), @@ -1286,12 +1266,10 @@ public class BasicTableUI extends TableUI x = x0; Color save = gfx.getColor(); gfx.setColor(grid); - boolean paintedLine = false; for (int c = 0; c < ncols && x < xmax; ++c) { x += cols.getColumn(c).getWidth(); gfx.drawLine(x, y0, x, ymax); - paintedLine = true; } gfx.setColor(save); } @@ -1302,12 +1280,10 @@ public class BasicTableUI extends TableUI y = y0; Color save = gfx.getColor(); gfx.setColor(grid); - boolean paintedLine = false; for (int r = 0; r < nrows && y < ymax; ++r) { y += height; gfx.drawLine(x0, y, xmax, y); - paintedLine = true; } gfx.setColor(save); } diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java index e8eeece..fc38894 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicTextUI.java @@ -46,15 +46,20 @@ import java.awt.Insets; import java.awt.Point; import java.awt.Rectangle; import java.awt.Shape; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; +import java.awt.event.KeyEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.ActionMap; import javax.swing.InputMap; import javax.swing.JComponent; +import javax.swing.KeyStroke; import javax.swing.LookAndFeel; import javax.swing.SwingConstants; import javax.swing.SwingUtilities; @@ -62,6 +67,7 @@ import javax.swing.UIManager; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.plaf.ActionMapUIResource; +import javax.swing.plaf.InputMapUIResource; import javax.swing.plaf.TextUI; import javax.swing.plaf.UIResource; import javax.swing.text.BadLocationException; @@ -334,9 +340,9 @@ public abstract class BasicTextUI extends TextUI * Returns the document position that is (visually) nearest to the given * document position <code>pos</code> in the given direction <code>d</code>. * - * @param c the text component * @param pos the document position * @param b the bias for <code>pos</code> + * @param a the allocation for the view * @param d the direction, must be either {@link SwingConstants#NORTH}, * {@link SwingConstants#SOUTH}, {@link SwingConstants#WEST} or * {@link SwingConstants#EAST} @@ -351,12 +357,11 @@ public abstract class BasicTextUI extends TextUI * @throws BadLocationException if <code>pos</code> is not a valid offset in * the document model */ - public int getNextVisualPositionFrom(JTextComponent c, int pos, - Position.Bias b, int d, - Position.Bias[] biasRet) + public int getNextVisualPositionFrom(int pos, Position.Bias b, Shape a, + int d, Position.Bias[] biasRet) throws BadLocationException { - return view.getNextVisualPositionFrom(c, pos, b, d, biasRet); + return view.getNextVisualPositionFrom(pos, b, a, d, biasRet); } } @@ -616,15 +621,25 @@ public abstract class BasicTextUI extends TextUI */ protected Keymap createKeymap() { + JTextComponent.KeyBinding[] bindings = null; String prefix = getPropertyPrefix(); - JTextComponent.KeyBinding[] bindings = - (JTextComponent.KeyBinding[]) UIManager.get(prefix + ".keyBindings"); + InputMapUIResource m = (InputMapUIResource) UIManager.get(prefix + ".focusInputMap"); + if (m != null) + { + KeyStroke[] keys = m.keys(); + int len = keys.length; + bindings = new JTextComponent.KeyBinding[len]; + for (int i = 0; i < len; i++) + { + KeyStroke curr = keys[i]; + bindings[i] = new JTextComponent.KeyBinding(curr, + (String) m.get(curr)); + } + } if (bindings == null) { bindings = new JTextComponent.KeyBinding[0]; - // FIXME: Putting something into the defaults map is certainly wrong. - // Must be fixed somehow. - UIManager.put(prefix + ".keyBindings", bindings); + UIManager.put(prefix + ".focusInputMap", bindings); } Keymap km = JTextComponent.addKeymap(getKeymapName(), @@ -637,18 +652,45 @@ public abstract class BasicTextUI extends TextUI * Installs the keyboard actions on the text components. */ protected void installKeyboardActions() - { - // load any bindings for the older Keymap interface + { + // load key bindings for the older interface Keymap km = JTextComponent.getKeymap(getKeymapName()); if (km == null) km = createKeymap(); textComponent.setKeymap(km); // load any bindings for the newer InputMap / ActionMap interface - SwingUtilities.replaceUIInputMap(textComponent, - JComponent.WHEN_FOCUSED, + SwingUtilities.replaceUIInputMap(textComponent, JComponent.WHEN_FOCUSED, getInputMap(JComponent.WHEN_FOCUSED)); - SwingUtilities.replaceUIActionMap(textComponent, getActionMap()); + SwingUtilities.replaceUIActionMap(textComponent, createActionMap()); + + ActionMap parentActionMap = new ActionMapUIResource(); + Action[] actions = textComponent.getActions(); + for (int j = 0; j < actions.length; j++) + { + Action currAction = actions[j]; + parentActionMap.put(currAction.getValue(Action.NAME), currAction); + } + + SwingUtilities.replaceUIActionMap(textComponent, parentActionMap); + } + + /** + * Creates an ActionMap to be installed on the text component. + * + * @return an ActionMap to be installed on the text component + */ + ActionMap createActionMap() + { + Action[] actions = textComponent.getActions(); + ActionMap am = new ActionMapUIResource(); + for (int i = 0; i < actions.length; ++i) + { + String name = (String) actions[i].getValue(Action.NAME); + if (name != null) + am.put(name, actions[i]); + } + return am; } /** @@ -675,46 +717,6 @@ public abstract class BasicTextUI extends TextUI } /** - * Returns the ActionMap to be installed on the text component. - * - * @return the ActionMap to be installed on the text component - */ - // FIXME: The UIDefaults have no entries for .actionMap, so this should - // be handled somehow different. - ActionMap getActionMap() - { - String prefix = getPropertyPrefix(); - ActionMap am = (ActionMap) UIManager.get(prefix + ".actionMap"); - if (am == null) - { - am = createActionMap(); - // FIXME: Putting something in the UIDefaults map is certainly wrong. - // However, the whole method seems wrong and must be replaced by - // something that is less wrong. - UIManager.put(prefix + ".actionMap", am); - } - return am; - } - - /** - * Creates an ActionMap to be installed on the text component. - * - * @return an ActionMap to be installed on the text component - */ - ActionMap createActionMap() - { - Action[] actions = textComponent.getActions(); - ActionMap am = new ActionMapUIResource(); - for (int i = 0; i < actions.length; ++i) - { - String name = (String) actions[i].getValue(Action.NAME); - if (name != null) - am.put(name, actions[i]); - } - return am; - } - - /** * Uninstalls this TextUI from the text component. * * @param component the text component to uninstall the UI from diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicToolBarUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicToolBarUI.java index 7bf2a4a..261db68 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicToolBarUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicToolBarUI.java @@ -1060,7 +1060,7 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants isDragging = true; if (dragWindow != null) - dragWindow.setOffset(new Point(e.getX(), e.getY())); + dragWindow.setOffset(new Point(cachedBounds.width/2, cachedBounds.height/2)); dragTo(e.getPoint(), origin); } diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java index 2d54983..f2ebcfc 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java @@ -112,7 +112,6 @@ import javax.swing.tree.TreeSelectionModel; * the Basic look and feel. * * @see javax.swing.JTree - * * @author Lillian Angel (langel@redhat.com) * @author Sascha Brawer (brawer@dandelis.ch) */ @@ -173,7 +172,7 @@ public class BasicTreeUI extends TreeUI /** Size needed to completely display all the nodes. */ protected Dimension preferredSize; - + /** Minimum size needed to completely display all the nodes. */ protected Dimension preferredMinSize; @@ -225,7 +224,7 @@ public class BasicTreeUI extends TreeUI /** Set to true if the editor has a different size than the renderer. */ protected boolean editorHasDifferentSize; - + /** The action listener for the editor's Timer. */ Timer editorTimer = new EditorUpdateTimer(); @@ -234,29 +233,38 @@ public class BasicTreeUI extends TreeUI /** The action bound to KeyStrokes. */ TreeAction action; - + /** Boolean to keep track of editing. */ boolean isEditing; - + /** The current path of the visible nodes in the tree. */ TreePath currentVisiblePath; - + /** The gap between the icon and text. */ int gap = 4; - - /** Default row height, if none was set. */ - int rowHeight = 20; + + /** The max height of the nodes in the tree. */ + int maxHeight = 0; /** Listeners */ private PropertyChangeListener propertyChangeListener; + private FocusListener focusListener; + private TreeSelectionListener treeSelectionListener; + private MouseListener mouseListener; + private KeyListener keyListener; + private PropertyChangeListener selectionModelPropertyChangeListener; + private ComponentListener componentListener; + CellEditorListener cellEditorListener; + private TreeExpansionListener treeExpansionListener; + private TreeModelListener treeModelListener; /** @@ -437,7 +445,7 @@ public class BasicTreeUI extends TreeUI protected void setRowHeight(int rowHeight) { if (rowHeight == 0) - rowHeight = this.rowHeight; + rowHeight = Math.max(getMaxHeight(tree), 20); treeState.setRowHeight(rowHeight); } @@ -625,19 +633,49 @@ public class BasicTreeUI extends TreeUI */ public Rectangle getPathBounds(JTree tree, TreePath path) { - Rectangle bounds = null; int row = -1; Object cell = null; if (path != null) { row = getRowForPath(tree, path); cell = path.getLastPathComponent(); - bounds = new Rectangle(0, row * getRowHeight(), 0, 0); } - return nodeDimensions.getNodeDimensions(cell, row, - getLevel(cell), + return nodeDimensions.getNodeDimensions(cell, row, getLevel(cell), tree.isExpanded(path), - bounds); + new Rectangle()); + } + + /** + * Returns the max height of all the nodes in the tree. + * + * @param tree - + * the current tree + * @return the max height. + */ + private int getMaxHeight(JTree tree) + { + if (maxHeight != 0) + return maxHeight; + + Icon e = UIManager.getIcon("Tree.openIcon"); + Icon c = UIManager.getIcon("Tree.closedIcon"); + Icon l = UIManager.getIcon("Tree.leafIcon"); + int rc = getRowCount(tree); + int iconHeight = 0; + + for (int row = 0; row < rc; row++) + { + if (isLeaf(row)) + iconHeight = l.getIconHeight(); + else if (tree.isExpanded(row)) + iconHeight = e.getIconHeight(); + else + iconHeight = c.getIconHeight(); + + maxHeight = Math.max(maxHeight, iconHeight + gap); + } + + return maxHeight; } /** @@ -684,7 +722,7 @@ public class BasicTreeUI extends TreeUI { if (dest.equals(nodes[row])) return row; - row++; + row++; } } return -1; @@ -720,7 +758,7 @@ public class BasicTreeUI extends TreeUI */ public TreePath getClosestPathForLocation(JTree tree, int x, int y) { - int row = Math.round(y / getRowHeight()); + int row = Math.round(y / getMaxHeight(tree)); TreePath path = getPathForRow(tree, row); // no row is visible at this node @@ -977,10 +1015,12 @@ public class BasicTreeUI extends TreeUI protected TreeCellEditor createDefaultCellEditor() { if (currentCellRenderer != null) - return new DefaultTreeCellEditor(tree, + return new DefaultTreeCellEditor( + tree, (DefaultTreeCellRenderer) currentCellRenderer, cellEditor); - return new DefaultTreeCellEditor(tree, + return new DefaultTreeCellEditor( + tree, (DefaultTreeCellRenderer) createDefaultCellRenderer(), cellEditor); } @@ -1034,7 +1074,8 @@ public class BasicTreeUI extends TreeUI protected void uninstallKeyboardActions() { action = null; - tree.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).setParent(null); + tree.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).setParent( + null); tree.getActionMap().setParent(null); } @@ -1094,7 +1135,7 @@ public class BasicTreeUI extends TreeUI { Enumeration expanded = tree.getExpandedDescendants(path); while (expanded.hasMoreElements()) - treeState.setExpandedState(((TreePath) expanded.nextElement()), true); + treeState.setExpandedState(((TreePath) expanded.nextElement()), true); } /** @@ -1125,7 +1166,7 @@ public class BasicTreeUI extends TreeUI protected void updateCellEditor() { if (tree.isEditable() && cellEditor == null) - setCellEditor(createDefaultCellEditor()); + setCellEditor(createDefaultCellEditor()); createdCellEditor = true; } @@ -1136,10 +1177,10 @@ public class BasicTreeUI extends TreeUI { if (tree != null) { - if(tree.getCellRenderer() == null) - { - if(currentCellRenderer == null) - currentCellRenderer = createDefaultCellRenderer(); + if (tree.getCellRenderer() == null) + { + if (currentCellRenderer == null) + currentCellRenderer = createDefaultCellRenderer(); tree.setCellRenderer(currentCellRenderer); } } @@ -1186,9 +1227,13 @@ public class BasicTreeUI extends TreeUI bounds.width += getCurrentControlIcon(curr).getIconWidth(); maxWidth = Math.max(maxWidth, bounds.x + bounds.width); } - preferredSize = new Dimension(maxWidth, (getRowHeight() * path.length)); + + maxHeight = 0; + maxHeight = getMaxHeight(tree); + preferredSize = new Dimension(maxWidth, (maxHeight * path.length)); } - else preferredSize = new Dimension(0, 0); + else + preferredSize = new Dimension(0, 0); validCachedPreferredSize = true; } @@ -1201,7 +1246,6 @@ public class BasicTreeUI extends TreeUI protected void pathWasExpanded(TreePath path) { validCachedPreferredSize = false; - tree.revalidate(); tree.repaint(); } @@ -1211,7 +1255,6 @@ public class BasicTreeUI extends TreeUI protected void pathWasCollapsed(TreePath path) { validCachedPreferredSize = false; - tree.revalidate(); tree.repaint(); } @@ -1345,19 +1388,12 @@ public class BasicTreeUI extends TreeUI installComponents(); installKeyboardActions(); installListeners(); - + setCellEditor(createDefaultCellEditor()); createdCellEditor = true; isEditing = false; - TreeModel mod = tree.getModel(); - setModel(mod); - if (mod != null) - { - TreePath path = new TreePath(mod.getRoot()); - if (!tree.isExpanded(path)) - toggleExpandState(path); - } + setModel(tree.getModel()); treeSelectionModel = tree.getSelectionModel(); completeUIInstall(); @@ -1406,8 +1442,7 @@ public class BasicTreeUI extends TreeUI public void paint(Graphics g, JComponent c) { JTree tree = (JTree) c; - if (currentVisiblePath == null) - updateCurrentVisiblePath(); + updateCurrentVisiblePath(); Rectangle clip = g.getClipBounds(); Insets insets = tree.getInsets(); @@ -1451,7 +1486,7 @@ public class BasicTreeUI extends TreeUI endRow = beginRow; beginRow = temp; } - + for (int i = beginRow; i < endRow; i++) { TreePath path = getPathForRow(tree, i); @@ -1508,8 +1543,8 @@ public class BasicTreeUI extends TreeUI */ public Dimension getPreferredSize(JComponent c, boolean checkConsistancy) { - // FIXME: checkConsistancy not implemented, c not used - if(!validCachedPreferredSize) + // FIXME: checkConsistancy not implemented, c not used + if (!validCachedPreferredSize) updateCachedPreferredSize(); return preferredSize; } @@ -1524,7 +1559,7 @@ public class BasicTreeUI extends TreeUI */ public Dimension getMinimumSize(JComponent c) { - Dimension min = getPreferredMinSize(); + Dimension min = getPreferredMinSize(); if (min == null) return new Dimension(); return min; @@ -1636,7 +1671,7 @@ public class BasicTreeUI extends TreeUI tree.add(editingComponent.getParent()); editingComponent.getParent().validate(); validCachedPreferredSize = false; - tree.revalidate(); + ((JTextField) editingComponent).requestFocusInWindow(false); editorTimer.start(); return true; @@ -1682,12 +1717,13 @@ public class BasicTreeUI extends TreeUI { boolean cntlClick = false; int row = getRowForPath(tree, path); - + if (!isLeaf(row)) { Rectangle bounds = getPathBounds(tree, path); - if (hasControlIcons() && (mouseX < bounds.x) + if (hasControlIcons() + && (mouseX < bounds.x) && (mouseX > (bounds.x - getCurrentControlIcon(path).getIconWidth() - gap))) cntlClick = true; } @@ -1725,7 +1761,6 @@ public class BasicTreeUI extends TreeUI tree.collapsePath(path); else tree.expandPath(path); - updateCurrentVisiblePath(); } /** @@ -1739,8 +1774,7 @@ public class BasicTreeUI extends TreeUI */ protected boolean isToggleSelectionEvent(MouseEvent event) { - return (tree.getSelectionModel().getSelectionMode() == - TreeSelectionModel.SINGLE_TREE_SELECTION); + return (tree.getSelectionModel().getSelectionMode() == TreeSelectionModel.SINGLE_TREE_SELECTION); } /** @@ -1754,8 +1788,7 @@ public class BasicTreeUI extends TreeUI */ protected boolean isMultiSelectEvent(MouseEvent event) { - return (tree.getSelectionModel().getSelectionMode() == - TreeSelectionModel.CONTIGUOUS_TREE_SELECTION); + return (tree.getSelectionModel().getSelectionMode() == TreeSelectionModel.CONTIGUOUS_TREE_SELECTION); } /** @@ -1834,8 +1867,7 @@ public class BasicTreeUI extends TreeUI * are pressed for the JTree. The actionPerformed method is called when a key * that has been registered for the JTree is received. */ - class TreeAction - extends AbstractAction + class TreeAction extends AbstractAction { /** @@ -1877,7 +1909,7 @@ public class BasicTreeUI extends TreeUI else if (e.getActionCommand().equals("toggle")) { if (tree.isEditing()) - tree.stopEditing(); + tree.stopEditing(); else { Object last = lead.getLastPathComponent(); @@ -1903,8 +1935,7 @@ public class BasicTreeUI extends TreeUI * to the true receiver after altering the actionCommand property of the * event. */ - private static class ActionListenerProxy - extends AbstractAction + private static class ActionListenerProxy extends AbstractAction { ActionListener target; @@ -1929,9 +1960,7 @@ public class BasicTreeUI extends TreeUI /** * The timer that updates the editor component. */ - private class EditorUpdateTimer - extends Timer - implements ActionListener + private class EditorUpdateTimer extends Timer implements ActionListener { /** * Creates a new EditorUpdateTimer object with a default delay of 0.3 @@ -1975,8 +2004,8 @@ public class BasicTreeUI extends TreeUI /** * Updates the preferred size when scrolling, if necessary. */ - public class ComponentHandler extends ComponentAdapter - implements ActionListener + public class ComponentHandler extends ComponentAdapter implements + ActionListener { /** * Timer used when inside a scrollpane and the scrollbar is adjusting @@ -2006,8 +2035,8 @@ public class BasicTreeUI extends TreeUI } /** - * Creates, if necessary, and starts a Timer to check if needed to resize the - * bounds + * Creates, if necessary, and starts a Timer to check if needed to resize + * the bounds */ protected void startTimer() { @@ -2082,7 +2111,6 @@ public class BasicTreeUI extends TreeUI tree.requestFocusInWindow(false); editorTimer.stop(); validCachedPreferredSize = false; - tree.revalidate(); tree.repaint(); } @@ -2113,7 +2141,6 @@ public class BasicTreeUI extends TreeUI editorTimer.stop(); isEditing = false; validCachedPreferredSize = false; - tree.revalidate(); tree.repaint(); } }// CellEditorHandler @@ -2121,8 +2148,7 @@ public class BasicTreeUI extends TreeUI /** * Repaints the lead selection row when focus is lost/grained. */ - public class FocusHandler - implements FocusListener + public class FocusHandler implements FocusListener { /** * Constructor @@ -2161,8 +2187,7 @@ public class BasicTreeUI extends TreeUI * This is used to get multiple key down events to appropriately genereate * events. */ - public class KeyHandler - extends KeyAdapter + public class KeyHandler extends KeyAdapter { /** Key code that is being generated for. */ protected Action repeatKeyAction; @@ -2247,7 +2272,7 @@ public class BasicTreeUI extends TreeUI boolean cntlClick = isLocationInExpandControl(path, click.x, click.y); boolean isLeaf = isLeaf(row); - + TreeCellRenderer tcr = getCellRenderer(); Icon icon; if (isLeaf) @@ -2256,17 +2281,17 @@ public class BasicTreeUI extends TreeUI icon = UIManager.getIcon("Tree.openIcon"); else icon = UIManager.getIcon("Tree.closedIcon"); - + if (tcr instanceof DefaultTreeCellRenderer) { - Icon tmp = ((DefaultTreeCellRenderer) tcr).getIcon(); - if (tmp != null) - icon = tmp; + Icon tmp = ((DefaultTreeCellRenderer) tcr).getIcon(); + if (tmp != null) + icon = tmp; } - + // add gap*2 for the space before and after the text if (icon != null) - bounds.width += icon.getIconWidth() + gap*2; + bounds.width += icon.getIconWidth() + gap * 2; boolean inBounds = bounds.contains(click.x, click.y); if ((inBounds || cntlClick) && tree.isVisible(path)) @@ -2275,9 +2300,9 @@ public class BasicTreeUI extends TreeUI { selectPath(tree, path); if (e.getClickCount() == 2 && !isLeaf(row)) - toggleExpandState(path); + toggleExpandState(path); } - + if (cntlClick) { handleExpandControlClick(path, click.x, click.y); @@ -2455,8 +2480,7 @@ public class BasicTreeUI extends TreeUI * BasicTreeUI method. X location does not include insets, that is handled in * getPathBounds. */ - public class NodeDimensionsHandler - extends AbstractLayoutCache.NodeDimensions + public class NodeDimensionsHandler extends AbstractLayoutCache.NodeDimensions { /** * Constructor @@ -2467,10 +2491,10 @@ public class BasicTreeUI extends TreeUI } /** - * Returns, by reference in bounds, the size and x origin to place value at. - * The calling method is responsible for determining the Y location. - * If bounds is null, a newly created Rectangle should be returned, - * otherwise the value should be placed in bounds and returned. + * Returns, by reference in bounds, the size and x origin to place value at. + * The calling method is responsible for determining the Y location. If + * bounds is null, a newly created Rectangle should be returned, otherwise + * the value should be placed in bounds and returned. * * @param cell * the value to be represented @@ -2498,8 +2522,10 @@ public class BasicTreeUI extends TreeUI { size.x = getRowX(row, depth); size.width = SwingUtilities.computeStringWidth(fm, s); - size.height = fm.getHeight(); + size.height = getMaxHeight(tree); + size.y = size.height * row; } + return size; } @@ -2520,8 +2546,7 @@ public class BasicTreeUI extends TreeUI * PropertyChangeListener for the tree. Updates the appropriate varaible, or * TreeState, based on what changes. */ - public class PropertyChangeHandler - implements PropertyChangeListener + public class PropertyChangeHandler implements PropertyChangeListener { /** @@ -2544,8 +2569,6 @@ public class BasicTreeUI extends TreeUI if ((event.getPropertyName()).equals("rootVisible")) { validCachedPreferredSize = false; - updateCurrentVisiblePath(); - tree.revalidate(); tree.repaint(); } } @@ -2555,8 +2578,8 @@ public class BasicTreeUI extends TreeUI * Listener on the TreeSelectionModel, resets the row selection if any of the * properties of the model change. */ - public class SelectionModelPropertyChangeHandler - implements PropertyChangeListener + public class SelectionModelPropertyChangeHandler implements + PropertyChangeListener { /** @@ -2583,8 +2606,7 @@ public class BasicTreeUI extends TreeUI /** * ActionListener that invokes cancelEditing when action performed. */ - public class TreeCancelEditingAction - extends AbstractAction + public class TreeCancelEditingAction extends AbstractAction { /** @@ -2621,8 +2643,7 @@ public class BasicTreeUI extends TreeUI /** * Updates the TreeState in response to nodes expanding/collapsing. */ - public class TreeExpansionHandler - implements TreeExpansionListener + public class TreeExpansionHandler implements TreeExpansionListener { /** @@ -2642,8 +2663,6 @@ public class BasicTreeUI extends TreeUI public void treeExpanded(TreeExpansionEvent event) { validCachedPreferredSize = false; - updateCurrentVisiblePath(); - tree.revalidate(); tree.repaint(); } @@ -2656,8 +2675,6 @@ public class BasicTreeUI extends TreeUI public void treeCollapsed(TreeExpansionEvent event) { validCachedPreferredSize = false; - updateCurrentVisiblePath(); - tree.revalidate(); tree.repaint(); } }// TreeExpansionHandler @@ -2666,8 +2683,7 @@ public class BasicTreeUI extends TreeUI * TreeHomeAction is used to handle end/home actions. Scrolls either the first * or last cell to be visible based on direction. */ - public class TreeHomeAction - extends AbstractAction + public class TreeHomeAction extends AbstractAction { /** direction is either home or end */ @@ -2713,8 +2729,7 @@ public class BasicTreeUI extends TreeUI * TreeIncrementAction is used to handle up/down actions. Selection is moved * up or down based on direction. */ - public class TreeIncrementAction - extends AbstractAction + public class TreeIncrementAction extends AbstractAction { /** Specifies the direction to adjust the selection by. */ @@ -2746,7 +2761,7 @@ public class BasicTreeUI extends TreeUI if (e.getActionCommand().equals("selectPreviousChangeLead")) { Object prev = getPreviousVisibleNode(last); - + if (prev != null) { TreePath newPath = new TreePath(getPathToRoot(prev, 0)); @@ -2767,7 +2782,7 @@ public class BasicTreeUI extends TreeUI else if (e.getActionCommand().equals("selectPrevious")) { Object prev = getPreviousVisibleNode(last); - + if (prev != null) { TreePath newPath = new TreePath(getPathToRoot(prev, 0)); @@ -2777,7 +2792,7 @@ public class BasicTreeUI extends TreeUI else if (e.getActionCommand().equals("selectNext")) { Object next = getNextVisibleNode(last); - + if (next != null) { TreePath newPath = new TreePath(getPathToRoot(next, 0)); @@ -2847,8 +2862,6 @@ public class BasicTreeUI extends TreeUI public void treeNodesChanged(TreeModelEvent e) { validCachedPreferredSize = false; - updateCurrentVisiblePath(); - tree.revalidate(); tree.repaint(); } @@ -2863,8 +2876,6 @@ public class BasicTreeUI extends TreeUI public void treeNodesInserted(TreeModelEvent e) { validCachedPreferredSize = false; - updateCurrentVisiblePath(); - tree.revalidate(); tree.repaint(); } @@ -2882,8 +2893,6 @@ public class BasicTreeUI extends TreeUI public void treeNodesRemoved(TreeModelEvent e) { validCachedPreferredSize = false; - updateCurrentVisiblePath(); - tree.revalidate(); tree.repaint(); } @@ -2902,9 +2911,7 @@ public class BasicTreeUI extends TreeUI if (e.getPath().length == 1 && !e.getPath()[0].equals(treeModel.getRoot())) tree.expandPath(new TreePath(treeModel.getRoot())); - updateCurrentVisiblePath(); validCachedPreferredSize = false; - tree.revalidate(); tree.repaint(); } }// TreeModelHandler @@ -3102,7 +3109,7 @@ public class BasicTreeUI extends TreeUI return true; return false; } - + /** * Returns control icon. It is null if the LookAndFeel does not implements the * control icons. Package private for use in inner classes. @@ -3127,10 +3134,9 @@ public class BasicTreeUI extends TreeUI */ Object getParent(Object root, Object node) { - if (root == null || node == null || - root.equals(node)) + if (root == null || node == null || root.equals(node)) return null; - + if (node instanceof TreeNode) return ((TreeNode) node).getParent(); return findNode(root, node); @@ -3163,7 +3169,7 @@ public class BasicTreeUI extends TreeUI } return null; } - + /** * Get previous visible node in the tree. Package private for use in inner * classes. @@ -3182,8 +3188,8 @@ public class BasicTreeUI extends TreeUI while (i < nodes.length && !node.equals(nodes[i])) i++; // return the next node - if (i-1 >= 0) - return nodes[i-1]; + if (i - 1 >= 0) + return nodes[i - 1]; } return null; } @@ -3191,7 +3197,7 @@ public class BasicTreeUI extends TreeUI /** * Returns the next node in the tree Package private for use in inner classes. * - * @param curr - + * @param curr - * current node * @return the next node in the tree */ @@ -3208,7 +3214,7 @@ public class BasicTreeUI extends TreeUI node = getParent(treeModel.getRoot(), node); } while (sibling == null && node != null); - + return sibling; } @@ -3250,7 +3256,7 @@ public class BasicTreeUI extends TreeUI * Returns the next sibling in the tree Package private for use in inner * classes. * - * @param node - + * @param node - * current node * @return the next sibling in the tree */ @@ -3270,7 +3276,7 @@ public class BasicTreeUI extends TreeUI return treeModel.getChild(parent, index); } - + /** * Returns the previous sibling in the tree Package private for use in inner * classes. @@ -3309,15 +3315,13 @@ public class BasicTreeUI extends TreeUI { if (path != null) { - if (tree.getSelectionModel().getSelectionMode() == - TreeSelectionModel.SINGLE_TREE_SELECTION) + if (tree.getSelectionModel().getSelectionMode() == TreeSelectionModel.SINGLE_TREE_SELECTION) { tree.getSelectionModel().clearSelection(); tree.addSelectionPath(path); tree.setLeadSelectionPath(path); } - else if (tree.getSelectionModel().getSelectionMode() == - TreeSelectionModel.CONTIGUOUS_TREE_SELECTION) + else if (tree.getSelectionModel().getSelectionMode() == TreeSelectionModel.CONTIGUOUS_TREE_SELECTION) { // TODO } @@ -3325,8 +3329,8 @@ public class BasicTreeUI extends TreeUI { tree.addSelectionPath(path); tree.setLeadSelectionPath(path); - tree.getSelectionModel().setSelectionMode - (TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION); + tree.getSelectionModel().setSelectionMode( + TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION); } } } @@ -3351,7 +3355,8 @@ public class BasicTreeUI extends TreeUI return new Object[depth]; } - Object[] path = getPathToRoot(getParent(treeModel.getRoot(), node), depth + 1); + Object[] path = getPathToRoot(getParent(treeModel.getRoot(), node), + depth + 1); path[path.length - depth - 1] = node; return path; } @@ -3374,7 +3379,7 @@ public class BasicTreeUI extends TreeUI Object root = treeModel.getRoot(); if (!tree.isRootVisible() && tree.isExpanded(new TreePath(root))) count--; - + do { current = getParent(root, current); @@ -3441,28 +3446,32 @@ public class BasicTreeUI extends TreeUI * @param x * is the center position in x-direction * @param y - * is the center position in y-direction + * is the center position in y-direction */ protected void drawCentered(Component c, Graphics g, Icon icon, int x, int y) { x -= icon.getIconWidth() / 2; y -= icon.getIconHeight() / 2; - + if (x < 0) x = 0; if (y < 0) y = 0; - + icon.paintIcon(c, g, x, y); } - + /** * Draws a dashed horizontal line. * - * @param g - the graphics configuration. - * @param y - the y location to start drawing at - * @param x1 - the x location to start drawing at - * @param x2 - the x location to finish drawing at + * @param g - + * the graphics configuration. + * @param y - + * the y location to start drawing at + * @param x1 - + * the x location to start drawing at + * @param x2 - + * the x location to finish drawing at */ protected void drawDashedHorizontalLine(Graphics g, int y, int x1, int x2) { @@ -3470,14 +3479,18 @@ public class BasicTreeUI extends TreeUI for (int i = x1; i < x2; i += 2) g.drawLine(i, y, i + 1, y); } - + /** * Draws a dashed vertical line. * - * @param g - the graphics configuration. - * @param x - the x location to start drawing at - * @param y1 - the y location to start drawing at - * @param y2 - the y location to finish drawing at + * @param g - + * the graphics configuration. + * @param x - + * the x location to start drawing at + * @param y1 - + * the y location to start drawing at + * @param y2 - + * the y location to finish drawing at */ protected void drawDashedVerticalLine(Graphics g, int x, int y1, int y2) { @@ -3485,72 +3498,89 @@ public class BasicTreeUI extends TreeUI for (int i = y1; i < y2; i += 2) g.drawLine(x, i, x, i + 1); } - + /** - * Paints the expand (toggle) part of a row. The receiver should NOT modify + * Paints the expand (toggle) part of a row. The receiver should NOT modify * clipBounds, or insets. * - * @param g - the graphics configuration - * @param clipBounds - - * @param insets - - * @param bounds - bounds of expand control - * @param path - path to draw control for - * @param row - row to draw control for - * @param isExpanded - is the row expanded - * @param hasBeenExpanded - has the row already been expanded - * @param isLeaf - is the path a leaf + * @param g - + * the graphics configuration + * @param clipBounds - + * @param insets - + * @param bounds - + * bounds of expand control + * @param path - + * path to draw control for + * @param row - + * row to draw control for + * @param isExpanded - + * is the row expanded + * @param hasBeenExpanded - + * has the row already been expanded + * @param isLeaf - + * is the path a leaf */ protected void paintExpandControl(Graphics g, Rectangle clipBounds, Insets insets, Rectangle bounds, - TreePath path, int row, - boolean isExpanded, boolean hasBeenExpanded, - boolean isLeaf) + TreePath path, int row, boolean isExpanded, + boolean hasBeenExpanded, boolean isLeaf) { if (shouldPaintExpandControl(path, row, isExpanded, hasBeenExpanded, isLeaf)) { Icon icon = getCurrentControlIcon(path); int iconW = icon.getIconWidth(); - int x = bounds.x - rightChildIndent + iconW/2; + int x = bounds.x - rightChildIndent + iconW / 2; if (x + iconW > bounds.x) x = bounds.x - rightChildIndent - gap; - icon.paintIcon(tree, g, x, bounds.y + bounds.height/2 - icon.getIconHeight()/2); + icon.paintIcon(tree, g, x, bounds.y + bounds.height / 2 + - icon.getIconHeight() / 2); } } /** - * Paints the horizontal part of the leg. The receiver should NOT modify - * clipBounds, or insets. - * NOTE: parentRow can be -1 if the root is not visible. - * - * @param g - the graphics configuration - * @param clipBounds - - * @param insets - - * @param bounds - bounds of the cell - * @param path - path to draw leg for - * @param row - row to start drawing at - * @param isExpanded - is the row expanded - * @param hasBeenExpanded - has the row already been expanded - * @param isLeaf - is the path a leaf + * Paints the horizontal part of the leg. The receiver should NOT modify + * clipBounds, or insets. NOTE: parentRow can be -1 if the root is not + * visible. + * + * @param g - + * the graphics configuration + * @param clipBounds - + * @param insets - + * @param bounds - + * bounds of the cell + * @param path - + * path to draw leg for + * @param row - + * row to start drawing at + * @param isExpanded - + * is the row expanded + * @param hasBeenExpanded - + * has the row already been expanded + * @param isLeaf - + * is the path a leaf */ protected void paintHorizontalPartOfLeg(Graphics g, Rectangle clipBounds, Insets insets, Rectangle bounds, TreePath path, int row, - boolean isExpanded, boolean hasBeenExpanded, + boolean isExpanded, + boolean hasBeenExpanded, boolean isLeaf) { if (row != 0) - paintHorizontalLine(g, tree, bounds.y + bounds.height/2, bounds.x - gap - 2, - bounds.x); + paintHorizontalLine(g, tree, bounds.y + bounds.height / 2, bounds.x - gap + - 2, bounds.x); } - + /** - * Paints the vertical part of the leg. The receiver should NOT modify + * Paints the vertical part of the leg. The receiver should NOT modify * clipBounds, insets. * - * @param g - the graphics configuration. - * @param clipBounds - - * @param insets - - * @param path - the path to draw the vertical part for. + * @param g - + * the graphics configuration. + * @param clipBounds - + * @param insets - + * @param path - + * the path to draw the vertical part for. */ protected void paintVerticalPartOfLeg(Graphics g, Rectangle clipBounds, Insets insets, TreePath path) @@ -3564,56 +3594,65 @@ public class BasicTreeUI extends TreeUI if (numChild > 0 && tree.isExpanded(currPath)) { Rectangle bounds = getPathBounds(tree, currPath); - Rectangle lastChildBounds = getPathBounds(tree, - new TreePath(getPathToRoot( - treeModel.getChild(curr, numChild - 1), - 0))); - paintVerticalLine(g, tree, bounds.x + gap + 2, bounds.y + - bounds.height - 2, lastChildBounds.y + - lastChildBounds.height/2); + Rectangle lastChildBounds = getPathBounds( + tree, + new TreePath( + getPathToRoot( + treeModel.getChild( + curr, + numChild - 1), + 0))); + paintVerticalLine(g, tree, bounds.x + gap + 2, bounds.y + + bounds.height - 2, + lastChildBounds.y + lastChildBounds.height / 2); } } } /** - * Paints the renderer part of a row. The receiver should NOT modify clipBounds, - * or insets. + * Paints the renderer part of a row. The receiver should NOT modify + * clipBounds, or insets. * - * @param g - the graphics configuration - * @param clipBounds - - * @param insets - - * @param bounds - bounds of expand control - * @param path - path to draw control for - * @param row - row to draw control for - * @param isExpanded - is the row expanded - * @param hasBeenExpanded - has the row already been expanded - * @param isLeaf - is the path a leaf - */ - protected void paintRow(Graphics g, Rectangle clipBounds, - Insets insets, Rectangle bounds, - TreePath path, int row, + * @param g - + * the graphics configuration + * @param clipBounds - + * @param insets - + * @param bounds - + * bounds of expand control + * @param path - + * path to draw control for + * @param row - + * row to draw control for + * @param isExpanded - + * is the row expanded + * @param hasBeenExpanded - + * has the row already been expanded + * @param isLeaf - + * is the path a leaf + */ + protected void paintRow(Graphics g, Rectangle clipBounds, Insets insets, + Rectangle bounds, TreePath path, int row, boolean isExpanded, boolean hasBeenExpanded, boolean isLeaf) { boolean selected = tree.isPathSelected(path); boolean hasIcons = false; Object node = path.getLastPathComponent(); - + if (tree.isVisible(path)) { if (!validCachedPreferredSize) updateCachedPreferredSize(); - - - paintExpandControl(g, clipBounds, insets, bounds, path, row, isExpanded, hasBeenExpanded, isLeaf); - + + paintExpandControl(g, clipBounds, insets, bounds, path, row, + isExpanded, hasBeenExpanded, isLeaf); + if (row != 0) bounds.x += gap; bounds.width = preferredSize.width + bounds.x; - if (editingComponent != null && editingPath != null && isEditing(tree) && node.equals(editingPath.getLastPathComponent())) - { + { rendererPane.paintComponent(g, editingComponent.getParent(), null, bounds); } @@ -3622,9 +3661,12 @@ public class BasicTreeUI extends TreeUI TreeCellRenderer dtcr = tree.getCellRenderer(); if (dtcr == null) dtcr = createDefaultCellRenderer(); - + Component c = dtcr.getTreeCellRendererComponent(tree, node, - selected, isExpanded, isLeaf, row, tree.hasFocus()); + selected, + isExpanded, isLeaf, + row, + tree.hasFocus()); rendererPane.paintComponent(g, c, c.getParent(), bounds); } } @@ -3637,16 +3679,21 @@ public class BasicTreeUI extends TreeUI { // TODO: Implement this properly. } - + /** * Returns true if the expand (toggle) control should be drawn for the * specified row. * - * @param path - current path to check for. - * @param row - current row to check for. - * @param isExpanded - true if the path is expanded - * @param hasBeenExpanded - true if the path has been expanded already - * @param isLeaf - true if the row is a lead + * @param path - + * current path to check for. + * @param row - + * current row to check for. + * @param isExpanded - + * true if the path is expanded + * @param hasBeenExpanded - + * true if the path has been expanded already + * @param isLeaf - + * true if the row is a lead */ protected boolean shouldPaintExpandControl(TreePath path, int row, boolean isExpanded, @@ -3656,10 +3703,9 @@ public class BasicTreeUI extends TreeUI Object node = path.getLastPathComponent(); return (!isLeaf && getLevel(node) != 0 && hasControlIcons()); } - + /** - * Updates the cached current TreePath of all visible - * nodes in the tree. + * Updates the cached current TreePath of all visible nodes in the tree. */ void updateCurrentVisiblePath() { @@ -3667,19 +3713,22 @@ public class BasicTreeUI extends TreeUI return; Object next = treeModel.getRoot(); + if (next == null) + return; + TreePath rootPath = new TreePath(next); Rectangle bounds = getPathBounds(tree, rootPath); - + // If root is not a valid size to be visible, or is // not visible and the tree is expanded, then the next node acts // as the root - if ((bounds.width == 0 && bounds.height == 0) || (!isRootVisible() - && tree.isExpanded(new TreePath(next)))) + if ((bounds.width == 0 && bounds.height == 0) + || (!isRootVisible() && tree.isExpanded(new TreePath(next)))) { next = getNextNode(next); rootPath = new TreePath(next); } - + Object root = next; TreePath current = null; while (next != null) @@ -3688,7 +3737,7 @@ public class BasicTreeUI extends TreeUI current = rootPath; else current = current.pathByAddingChild(next); - + do { TreePath path = new TreePath(getPathToRoot(next, 0)); @@ -3712,19 +3761,23 @@ public class BasicTreeUI extends TreeUI } } } - while (next != null && - !tree.isVisible(new TreePath(getPathToRoot(next, 0)))); + while (next != null + && !tree.isVisible(new TreePath(getPathToRoot(next, 0)))); } currentVisiblePath = current; tree.setVisibleRowCount(getRowCount(tree)); - if (tree.getSelectionModel() != null && tree.getSelectionCount() == 0 && - currentVisiblePath != null) - selectPath(tree, new TreePath(getPathToRoot(currentVisiblePath. - getPathComponent(0), 0))); + if (tree.getSelectionModel() != null && tree.getSelectionCount() == 0 + && currentVisiblePath != null) + selectPath( + tree, + new TreePath( + getPathToRoot( + currentVisiblePath.getPathComponent(0), + 0))); } - + /** * Get next visible node in the currentVisiblePath. Package private for use in * inner classes. @@ -3743,8 +3796,8 @@ public class BasicTreeUI extends TreeUI while (i < nodes.length && !node.equals(nodes[i])) i++; // return the next node - if (i+1 < nodes.length) - return nodes[i+1]; + if (i + 1 < nodes.length) + return nodes[i + 1]; } return null; } diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalComboBoxUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalComboBoxUI.java index a43ee3c..0006b78 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalComboBoxUI.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalComboBoxUI.java @@ -313,4 +313,40 @@ public class MetalComboBoxUI extends BasicComboBoxUI d.height + insetsH + 1); } + /** + * Configures the editor for this combo box. + */ + public void configureEditor() + { + ComboBoxEditor cbe = comboBox.getEditor(); + if (cbe != null) + { + cbe.getEditorComponent().setFont(comboBox.getFont()); + cbe.setItem(comboBox.getSelectedItem()); + cbe.addActionListener(comboBox); + } + } + + /** + * Unconfigures the editor for this combo box. + */ + public void unconfigureEditor() + { + ComboBoxEditor cbe = comboBox.getEditor(); + if (cbe != null) + { + cbe.getEditorComponent().setFont(null); + cbe.setItem(null); + cbe.removeActionListener(comboBox); + } + } + + /** + * Lays out the ComboBox + */ + public void layoutComboBox(Container parent, + MetalComboBoxUI.MetalComboBoxLayoutManager manager) + { + manager.layoutContainer(parent); + } } diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalFileChooserUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalFileChooserUI.java index 3a2e1c1..967c40d 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalFileChooserUI.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalFileChooserUI.java @@ -38,39 +38,421 @@ exception statement from your version. */ package javax.swing.plaf.metal; +import java.awt.BorderLayout; import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.GridLayout; +import java.awt.Insets; +import java.awt.LayoutManager; +import java.awt.Rectangle; +import java.awt.Window; import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.text.NumberFormat; + import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; + import java.io.File; -import java.util.List; import javax.swing.AbstractAction; import javax.swing.AbstractListModel; +import javax.swing.ActionMap; +import javax.swing.BorderFactory; +import javax.swing.ButtonGroup; import javax.swing.ComboBoxModel; import javax.swing.DefaultListCellRenderer; +import javax.swing.Icon; +import javax.swing.JButton; +import javax.swing.JComboBox; import javax.swing.JComponent; +import javax.swing.JDialog; import javax.swing.JFileChooser; +import javax.swing.JLabel; import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.JTextField; +import javax.swing.JToggleButton; +import javax.swing.JViewport; +import javax.swing.ListModel; +import javax.swing.ListSelectionModel; +import javax.swing.SwingUtilities; import javax.swing.UIManager; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; import javax.swing.filechooser.FileFilter; import javax.swing.filechooser.FileSystemView; import javax.swing.filechooser.FileView; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicFileChooserUI; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.DefaultTableModel; + +import java.sql.Date; + +import java.text.DateFormat; + +import java.util.List; /** * A UI delegate for the {@link JFileChooser} component. This class is only * partially implemented and is not usable yet. */ -public class MetalFileChooserUI extends BasicFileChooserUI +public class MetalFileChooserUI + extends BasicFileChooserUI { + + /** + * A renderer for the files and directories in the file chooser table. + */ + class TableFileRenderer + extends DefaultTableCellRenderer + { + + /** + * Creates a new renderer. + */ + public TableFileRenderer() + { + super(); + } + + /** + * Returns a component that can render the specified value. + * + * @param table the table + * @param value the string value of the cell + * @param isSelected is the item selected? + * @param hasFocus does the item have the focus? + * @param row the row + * @param column the column + * + * @return The renderer. + */ + public Component getTableCellRendererComponent(JTable table, Object value, + boolean isSelected, boolean hasFocus, int row, int column) + { + if (column == 0) + { + FileView v = getFileView(getFileChooser()); + ListModel lm = fileList.getModel(); + if (row < lm.getSize()) + setIcon(v.getIcon((File) lm.getElementAt(row))); + } + else + setIcon(null); + + setText(value.toString()); + setOpaque(true); + setEnabled(table.isEnabled()); + setFont(fileList.getFont()); + + if (startEditing && column == 0 || !isSelected) + { + setBackground(table.getBackground()); + setForeground(table.getForeground()); + } + else + { + setBackground(table.getSelectionBackground()); + setForeground(table.getSelectionForeground()); + } + + if (hasFocus) + setBorder(UIManager.getBorder("Table.focusCellHighlightBorder")); + else + setBorder(noFocusBorder); + + return this; + } + } + + /** + * ActionListener for the list view. + */ + class ListViewActionListener implements ActionListener + { + + /** + * This method is invoked when an action occurs. + * + * @param e - + * the <code>ActionEvent</code> that occurred + */ + public void actionPerformed(ActionEvent e) + { + if (!listView) + { + int[] index = fileTable.getSelectedRows(); + listView = true; + JFileChooser fc = getFileChooser(); + fc.remove(fileTablePanel); + createList(fc); + + fileList.getSelectionModel().clearSelection(); + if (index.length > 0) + for (int i = 0; i < index.length; i++) + fileList.getSelectionModel().addSelectionInterval(index[i], index[i]); + + fc.add(fileListPanel, BorderLayout.CENTER); + fc.revalidate(); + fc.repaint(); + } + } + } + + /** + * ActionListener for the details view. + */ + class DetailViewActionListener implements ActionListener + { + + /** + * This method is invoked when an action occurs. + * + * @param e - + * the <code>ActionEvent</code> that occurred + */ + public void actionPerformed(ActionEvent e) + { + if (listView) + { + int[] index = fileList.getSelectedIndices(); + JFileChooser fc = getFileChooser(); + listView = false; + fc.remove(fileListPanel); + + if (fileTable == null) + createDetailsView(fc); + else + updateTable(); + + fileTable.getSelectionModel().clearSelection(); + if (index.length > 0) + { + for (int i = 0; i < index.length; i++) + fileTable.getSelectionModel().addSelectionInterval(index[i], index[i]); + } + + fc.add(fileTablePanel, BorderLayout.CENTER); + fc.revalidate(); + fc.repaint(); + } + } + } + + /** + * A property change listener. + */ + class MetalFileChooserPropertyChangeListener + implements PropertyChangeListener + { + /** + * Default constructor. + */ + public MetalFileChooserPropertyChangeListener() + { + } + + /** + * Handles a property change event. + * + * @param e the event. + */ + public void propertyChange(PropertyChangeEvent e) + { + JFileChooser filechooser = getFileChooser(); + + String n = e.getPropertyName(); + if (n.equals(JFileChooser.MULTI_SELECTION_ENABLED_CHANGED_PROPERTY)) + { + int mode = -1; + if (filechooser.isMultiSelectionEnabled()) + mode = ListSelectionModel.MULTIPLE_INTERVAL_SELECTION; + else + mode = ListSelectionModel.SINGLE_SELECTION; + + if (listView) + fileList.setSelectionMode(mode); + else + fileTable.setSelectionMode(mode); + } + else if (n.equals(JFileChooser.SELECTED_FILE_CHANGED_PROPERTY)) + { + File file = filechooser.getSelectedFile(); + + if (file != null + && filechooser.getDialogType() == JFileChooser.SAVE_DIALOG) + { + if (file.isDirectory() && filechooser.isTraversable(file)) + { + directoryLabel = look; + dirLabel.setText(directoryLabel); + filechooser.setApproveButtonText(openButtonText); + filechooser.setApproveButtonToolTipText(openButtonToolTipText); + } + else if (file.isFile()) + { + directoryLabel = save; + dirLabel.setText(directoryLabel); + filechooser.setApproveButtonText(saveButtonText); + filechooser.setApproveButtonToolTipText(saveButtonToolTipText); + } + } + + if (file == null) + setFileName(null); + else + setFileName(file.getName()); + int index = -1; + index = getModel().indexOf(file); + if (index >= 0) + { + if (listView) + { + fileList.setSelectedIndex(index); + fileList.ensureIndexIsVisible(index); + fileList.revalidate(); + fileList.repaint(); + } + else + { + fileTable.getSelectionModel().addSelectionInterval(index, index); + fileTable.scrollRectToVisible(fileTable.getCellRect(index, 0, true)); + fileTable.revalidate(); + fileTable.repaint(); + } + } + } + + else if (n.equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY)) + { + if (listView) + { + fileList.clearSelection(); + fileList.revalidate(); + fileList.repaint(); + } + else + { + fileTable.clearSelection(); + fileTable.revalidate(); + fileTable.repaint(); + } + + setDirectorySelected(false); + File currentDirectory = filechooser.getCurrentDirectory(); + setDirectory(currentDirectory); + boolean hasParent = (currentDirectory.getParentFile() != null); + getChangeToParentDirectoryAction().setEnabled(hasParent); + } + + else if (n.equals(JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY)) + { + filterModel.propertyChange(e); + } + else if (n.equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY)) + { + filterModel.propertyChange(e); + } + else if (n.equals(JFileChooser.DIALOG_TYPE_CHANGED_PROPERTY) + || n.equals(JFileChooser.DIALOG_TITLE_CHANGED_PROPERTY)) + { + Window owner = SwingUtilities.windowForComponent(filechooser); + if (owner instanceof JDialog) + ((JDialog) owner).setTitle(getDialogTitle(filechooser)); + approveButton.setText(getApproveButtonText(filechooser)); + approveButton.setToolTipText( + getApproveButtonToolTipText(filechooser)); + approveButton.setMnemonic(getApproveButtonMnemonic(filechooser)); + } + + else if (n.equals(JFileChooser.APPROVE_BUTTON_TEXT_CHANGED_PROPERTY)) + approveButton.setText(getApproveButtonText(filechooser)); + + else if (n.equals( + JFileChooser.APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY)) + approveButton.setToolTipText(getApproveButtonToolTipText(filechooser)); + + else if (n.equals(JFileChooser.APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY)) + approveButton.setMnemonic(getApproveButtonMnemonic(filechooser)); + + else if (n.equals( + JFileChooser.CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY)) + { + if (filechooser.getControlButtonsAreShown()) + { + topPanel.add(controls, BorderLayout.EAST); + } + else + topPanel.remove(controls); + topPanel.revalidate(); + topPanel.repaint(); + topPanel.doLayout(); + } + + else if (n.equals( + JFileChooser.ACCEPT_ALL_FILE_FILTER_USED_CHANGED_PROPERTY)) + { + if (filechooser.isAcceptAllFileFilterUsed()) + filechooser.addChoosableFileFilter( + getAcceptAllFileFilter(filechooser)); + else + filechooser.removeChoosableFileFilter( + getAcceptAllFileFilter(filechooser)); + } + + else if (n.equals(JFileChooser.ACCESSORY_CHANGED_PROPERTY)) + { + JComponent old = (JComponent) e.getOldValue(); + if (old != null) + getAccessoryPanel().remove(old); + JComponent newval = (JComponent) e.getNewValue(); + if (newval != null) + getAccessoryPanel().add(newval); + } + + if (n.equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY) + || n.equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY) + || n.equals(JFileChooser.FILE_HIDING_CHANGED_PROPERTY)) + { + // Remove editing component + if (fileTable != null) + fileTable.removeAll(); + if (fileList != null) + fileList.removeAll(); + startEditing = false; + + // Set text on button back to original. + if (filechooser.getDialogType() == JFileChooser.SAVE_DIALOG) + { + directoryLabel = save; + dirLabel.setText(directoryLabel); + filechooser.setApproveButtonText(saveButtonText); + filechooser.setApproveButtonToolTipText(saveButtonToolTipText); + } + + rescanCurrentDirectory(filechooser); + } + + filechooser.revalidate(); + filechooser.repaint(); + } + }; + /** * A combo box model containing the selected directory and all its parent * directories. */ - protected class DirectoryComboBoxModel extends AbstractListModel + protected class DirectoryComboBoxModel + extends AbstractListModel implements ComboBoxModel { /** Storage for the items in the model. */ @@ -161,7 +543,8 @@ public class MetalFileChooserUI extends BasicFileChooserUI /** * Handles changes to the selection in the directory combo box. */ - protected class DirectoryComboBoxAction extends AbstractAction + protected class DirectoryComboBoxAction + extends AbstractAction { /** * Creates a new action. @@ -184,9 +567,60 @@ public class MetalFileChooserUI extends BasicFileChooserUI } /** + * A renderer for the items in the directory combo box. + */ + class DirectoryComboBoxRenderer + extends DefaultListCellRenderer + { + /** + * Creates a new renderer. + */ + public DirectoryComboBoxRenderer(JFileChooser fc) + { + } + + /** + * Returns a component that can be used to paint the given value within + * the list. + * + * @param list the list. + * @param value the value (a {@link File}). + * @param index the item index. + * @param isSelected is the item selected? + * @param cellHasFocus does the list cell have focus? + * + * @return The list cell renderer. + */ + public Component getListCellRendererComponent(JList list, Object value, + int index, boolean isSelected, boolean cellHasFocus) + { + FileView fileView = getFileView(getFileChooser()); + File file = (File) value; + setIcon(fileView.getIcon(file)); + setText(fileView.getName(file)); + + if (isSelected) + { + setBackground(list.getSelectionBackground()); + setForeground(list.getSelectionForeground()); + } + else + { + setBackground(list.getBackground()); + setForeground(list.getForeground()); + } + + setEnabled(list.isEnabled()); + setFont(list.getFont()); + return this; + } + } + + /** * A renderer for the files and directories in the file chooser. */ - protected class FileRenderer extends DefaultListCellRenderer + protected class FileRenderer + extends DefaultListCellRenderer { /** @@ -213,8 +647,17 @@ public class MetalFileChooserUI extends BasicFileChooserUI { FileView v = getFileView(getFileChooser()); File f = (File) value; - setText(v.getName(f)); - setIcon(v.getIcon(f)); + if (f != null) + { + setText(v.getName(f)); + setIcon(v.getIcon(f)); + } + else + { + setText(""); + setIcon(null); + } + setOpaque(true); if (isSelected) { setBackground(list.getSelectionBackground()); @@ -249,7 +692,7 @@ public class MetalFileChooserUI extends BasicFileChooserUI protected FileFilter[] filters; /** The index of the selected file filter. */ - private int selectedIndex; + private Object selected; /** * Creates a new model. @@ -258,7 +701,7 @@ public class MetalFileChooserUI extends BasicFileChooserUI { filters = new FileFilter[1]; filters[0] = getAcceptAllFileFilter(getFileChooser()); - selectedIndex = 0; + selected = filters[0]; } /** @@ -270,11 +713,11 @@ public class MetalFileChooserUI extends BasicFileChooserUI { if (e.getPropertyName().equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY)) { - selectedIndex = -1; - FileFilter selected = (FileFilter) e.getNewValue(); - for (int i = 0; i < filters.length; i++) - if (filters[i].equals(selected)) - selectedIndex = i; + JFileChooser fc = getFileChooser(); + FileFilter[] choosableFilters = fc.getChoosableFileFilters(); + filters = choosableFilters; + fireContentsChanged(this, 0, filters.length); + selected = e.getNewValue(); fireContentsChanged(this, -1, -1); } else if (e.getPropertyName().equals( @@ -291,13 +734,15 @@ public class MetalFileChooserUI extends BasicFileChooserUI /** * Sets the selected filter. * - * @param filter the filter. + * @param filter the filter (<code>null</code> ignored). */ public void setSelectedItem(Object filter) { - // change the filter in the file chooser and let the property change - // event trigger the change to the selected item - getFileChooser().setFileFilter((FileFilter) filter); + if (filter != null) + { + selected = filter; + fireContentsChanged(this, -1, -1); + } } /** @@ -307,9 +752,7 @@ public class MetalFileChooserUI extends BasicFileChooserUI */ public Object getSelectedItem() { - if (selectedIndex >= 0) - return filters[selectedIndex]; - return null; + return selected; } /** @@ -339,7 +782,8 @@ public class MetalFileChooserUI extends BasicFileChooserUI /** * A renderer for the items in the file filter combo box. */ - public class FilterComboBoxRenderer extends DefaultListCellRenderer + public class FilterComboBoxRenderer + extends DefaultListCellRenderer { /** * Creates a new renderer. @@ -359,20 +803,488 @@ public class MetalFileChooserUI extends BasicFileChooserUI * @param isSelected is the item selected? * @param cellHasFocus does the list cell have focus? * - * @return A component. + * @return This component as the renderer. */ public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + super.getListCellRendererComponent(list, value, index, isSelected, + cellHasFocus); FileFilter filter = (FileFilter) value; - return super.getListCellRendererComponent(list, filter.getDescription(), - index, isSelected, cellHasFocus); + setText(filter.getDescription()); + return this; + } + } + + /** + * A listener for selection events in the file list. + * + * @see #createListSelectionListener(JFileChooser) + */ + class MetalFileChooserSelectionListener + implements ListSelectionListener + { + /** + * Creates a new <code>SelectionListener</code> object. + */ + protected MetalFileChooserSelectionListener() + { + // Do nothing here. + } + + /** + * Makes changes to different properties when + * a value has changed in the filechooser's selection. + * + * @param e - the list selection event that occured. + */ + public void valueChanged(ListSelectionEvent e) + { + File f = (File) fileList.getSelectedValue(); + if (f == null) + return; + JFileChooser filechooser = getFileChooser(); + if (! filechooser.isTraversable(f)) + filechooser.setSelectedFile(f); + else + filechooser.setSelectedFile(null); + } + } + + /** + * A mouse listener for the {@link JFileChooser}. + * This listener is used for editing filenames. + */ + protected class SingleClickListener + extends MouseAdapter + { + + /** Stores instance of the list */ + JList list; + + /** + * Stores the current file that is being edited. + * It is null if nothing is currently being edited. + */ + File editFile; + + /** The current file chooser. */ + JFileChooser fc; + + /** The last file selected. */ + Object lastSelected; + + /** The textfield used for editing. */ + JTextField editField; + + /** + * Creates a new listener. + * + * @param list the directory/file list. + */ + public SingleClickListener(JList list) + { + this.list = list; + editFile = null; + fc = getFileChooser(); + lastSelected = null; + startEditing = false; + } + + /** + * Receives notification of a mouse click event. + * + * @param e the event. + */ + public void mouseClicked(MouseEvent e) + { + if (e.getClickCount() == 1 && e.getButton() == MouseEvent.BUTTON1) + { + int index = list.locationToIndex(e.getPoint()); + File[] sf = fc.getSelectedFiles(); + if ((!fc.isMultiSelectionEnabled() || (sf != null && sf.length <= 1)) + && index >= 0 && !startEditing && list.isSelectedIndex(index)) + { + Object tmp = list.getModel().getElementAt(index); + if (lastSelected != null && lastSelected.equals(tmp)) + editFile(index); + lastSelected = tmp; + } + else + completeEditing(); + } + else + completeEditing(); + } + + /** + * Sets up the text editor for the current file. + * + * @param index - + * the current index of the item in the list to be edited. + */ + void editFile(int index) + { + Rectangle bounds = list.getCellBounds(index, index); + list.scrollRectToVisible(bounds); + editFile = (File) list.getModel().getElementAt(index); + if (editFile.canWrite()) + { + startEditing = true; + editField = new JTextField(editFile.getName()); + editField.addActionListener(new EditingActionListener()); + + Icon icon = getFileView(fc).getIcon(editFile); + if (icon != null) + { + int padding = icon.getIconWidth() + 4; + bounds.x += padding; + bounds.width -= padding; + } + editField.setBounds(bounds); + + list.add(editField); + + editField.requestFocus(); + editField.selectAll(); + } + else + completeEditing(); + list.repaint(); + } + + /** + * Completes the editing. + */ + void completeEditing() + { + if (editField != null && editFile != null) + { + String text = editField.getText(); + if (text != null && text != "" && !text.equals(fc.getName(editFile))) + if (editFile.renameTo + (fc.getFileSystemView().createFileObject + (fc.getCurrentDirectory(), text))) + rescanCurrentDirectory(fc); + list.remove(editField); + } + startEditing = false; + editFile = null; + lastSelected = null; + editField = null; + list.repaint(); + } + + /** + * ActionListener for the editing text field. + */ + class EditingActionListener implements ActionListener + { + + /** + * This method is invoked when an action occurs. + * + * @param e - + * the <code>ActionEvent</code> that occurred + */ + public void actionPerformed(ActionEvent e) + { + if (e.getActionCommand().equals("notify-field-accept")) + completeEditing(); + else if (editField != null) + { + list.remove(editField); + startEditing = false; + editFile = null; + lastSelected = null; + editField = null; + list.repaint(); + } + } } } + /** + * A mouse listener for the {@link JFileChooser}. + * This listener is used for the table + */ + private class TableClickListener extends MouseAdapter + { + + /** Stores instance of the table */ + JTable table; + + /** Stores instance of the file chooser */ + JFileChooser fc; + + /** The last selected file. */ + Object lastSelected = null; + + /** + * Stores the current file that is being edited. + * It is null if nothing is currently being edited. + */ + File editFile; + + /** The textfield used for editing. */ + JTextField editField; + + /** + * Creates a new listener. + * + * @param table + * the directory/file table + * @param fc + * the JFileChooser + */ + public TableClickListener(JTable table, JFileChooser fc) + { + this.table = table; + this.fc = fc; + lastSelected = fileList.getSelectedValue(); + setDirectorySelected(false); + startEditing = false; + editFile = null; + editField = null; + } + + /** + * Receives notification of a mouse click event. + * + * @param e + * the event. + */ + public void mouseClicked(MouseEvent e) + { + int row = table.getSelectedRow(); + Object selVal = fileList.getModel().getElementAt(row); + if (selVal == null) + return; + FileSystemView fsv = fc.getFileSystemView(); + if (e.getClickCount() == 1 && + selVal.equals(lastSelected) && + e.getButton() == MouseEvent.BUTTON1) + { + File[] sf = fc.getSelectedFiles(); + if ((!fc.isMultiSelectionEnabled() || (sf != null && sf.length <= 1)) + && !startEditing) + { + editFile = (File) selVal; + editFile(row); + } + } + else if (e.getClickCount() >= 2 && + selVal.equals(lastSelected)) + { + if (startEditing) + completeEditing(); + File f = fsv.createFileObject(lastSelected.toString()); + if (fc.isTraversable(f)) + { + fc.setCurrentDirectory(f); + fc.rescanCurrentDirectory(); + } + else + { + fc.setSelectedFile(f); + fc.approveSelection(); + closeDialog(); + } + } + else + { + if (startEditing) + completeEditing(); + String path = selVal.toString(); + File f = fsv.createFileObject(path); + fc.setSelectedFile(f); + if (fc.isTraversable(f)) + { + setDirectorySelected(true); + setDirectory(f); + } + else + { + setDirectorySelected(false); + setDirectory(null); + } + lastSelected = selVal; + if (f.isFile()) + setFileName(path.substring(path.lastIndexOf("/") + 1)); + else if (fc.getFileSelectionMode() == JFileChooser.DIRECTORIES_ONLY) + setFileName(path); + } + fileTable.repaint(); + } + + /** + * Sets up the text editor for the current file. + * + * @param row - + * the current row of the item in the list to be edited. + */ + void editFile(int row) + { + Rectangle bounds = table.getCellRect(row, 0, true); + table.scrollRectToVisible(bounds); + if (editFile.canWrite()) + { + startEditing = true; + editField = new JTextField(editFile.getName()); + editField.addActionListener(new EditingActionListener()); + + // Need to adjust y pos + bounds.y = row * table.getRowHeight(); + editField.setBounds(bounds); + + table.add(editField); + + editField.requestFocus(); + editField.selectAll(); + } + else + completeEditing(); + table.repaint(); + } + + /** + * Completes the editing. + */ + void completeEditing() + { + if (editField != null && editFile != null) + { + String text = editField.getText(); + if (text != null && text != "" && !text.equals(fc.getName(editFile))) + if (editFile.renameTo + (fc.getFileSystemView().createFileObject + (fc.getCurrentDirectory(), text))) + rescanCurrentDirectory(fc); + table.remove(editField); + } + startEditing = false; + editFile = null; + editField = null; + table.repaint(); + } + + /** + * ActionListener for the editing text field. + */ + class EditingActionListener implements ActionListener + { + + /** + * This method is invoked when an action occurs. + * + * @param e - + * the <code>ActionEvent</code> that occurred + */ + public void actionPerformed(ActionEvent e) + { + if (e.getActionCommand().equals("notify-field-accept")) + completeEditing(); + else if (editField != null) + { + table.remove(editField); + startEditing = false; + editFile = null; + editField = null; + table.repaint(); + } + } + } + + /** + * Closes the dialog. + */ + public void closeDialog() + { + Window owner = SwingUtilities.windowForComponent(fc); + if (owner instanceof JDialog) + ((JDialog) owner).dispose(); + } + } + + /** The text for a label describing the directory combo box. */ + private String directoryLabel; + + private JComboBox directoryComboBox; + /** The model for the directory combo box. */ DirectoryComboBoxModel directoryModel; + /** The text for a label describing the file text field. */ + private String fileLabel; + + /** The file name text field. */ + private JTextField fileTextField; + + /** The text for a label describing the filter combo box. */ + private String filterLabel; + + /** + * The top panel (contains the directory combo box and the control buttons). + */ + private JPanel topPanel; + + /** A panel containing the control buttons ('up', 'home' etc.). */ + private JPanel controls; + + /** + * The panel that contains the filename field and the filter combobox. + */ + private JPanel bottomPanel; + + /** + * The panel that contains the 'Open' (or 'Save') and 'Cancel' buttons. + */ + private JPanel buttonPanel; + + private JButton approveButton; + + /** The file list. */ + JList fileList; + + /** The file table. */ + JTable fileTable; + + /** The panel containing the file list. */ + JPanel fileListPanel; + + /** The panel containing the file table. */ + JPanel fileTablePanel; + + /** The filter combo box model. */ + private FilterComboBoxModel filterModel; + + /** The action map. */ + private ActionMap actionMap; + + /** True if currently in list view. */ + boolean listView; + + /** True if we can or have started editing a cell. */ + boolean startEditing; + + /** The scrollpane used for the table and list. */ + JScrollPane scrollPane; + + /** The text for the label when saving. */ + String save; + + /** The text for the label when opening a directory. */ + String look; + + /** The label for the file combo box. */ + JLabel dirLabel; + + /** Listeners. */ + ListSelectionListener listSelList; + MouseListener doubleClickList; + SingleClickListener singleClickList; + TableClickListener tableClickList; + /** * A factory method that returns a UI delegate for the specified * component. @@ -393,9 +1305,439 @@ public class MetalFileChooserUI extends BasicFileChooserUI public MetalFileChooserUI(JFileChooser filechooser) { super(filechooser); + bottomPanel = new JPanel(new GridLayout(3, 2)); + buttonPanel = new JPanel(); + } + + public void installUI(JComponent c) + { + super.installUI(c); + actionMap = createActionMap(); + } + + public void uninstallUI(JComponent c) + { + super.uninstallUI(c); + actionMap = null; + } + + /** + * Installs the sub-components of the file chooser. + * + * @param fc the file chooser component. + */ + public void installComponents(JFileChooser fc) + { + fc.setLayout(new BorderLayout()); + topPanel = new JPanel(new BorderLayout()); + dirLabel = new JLabel(directoryLabel); + topPanel.add(dirLabel, BorderLayout.WEST); + this.controls = new JPanel(); + addControlButtons(); + + JPanel dirPanel = new JPanel(new VerticalMidLayout()); + directoryModel = createDirectoryComboBoxModel(fc); + directoryComboBox = new JComboBox(directoryModel); + directoryComboBox.setRenderer(createDirectoryComboBoxRenderer(fc)); + dirPanel.add(directoryComboBox); + topPanel.add(dirPanel); + topPanel.add(controls, BorderLayout.EAST); + topPanel.setBorder(BorderFactory.createEmptyBorder(8, 8, 0, 8)); + fc.add(topPanel, BorderLayout.NORTH); + + JPanel list = createList(fc); + list.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8)); + fc.add(list, BorderLayout.CENTER); + + JPanel bottomPanel = getBottomPanel(); + filterModel = createFilterComboBoxModel(); + JComboBox fileFilterCombo = new JComboBox(filterModel); + fileFilterCombo.setRenderer(createFilterComboBoxRenderer()); + + fileTextField = new JTextField(); + JPanel fileNamePanel = new JPanel(new VerticalMidLayout()); + fileNamePanel.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 5)); + fileNamePanel.add(fileTextField); + JPanel row1 = new JPanel(new BorderLayout()); + row1.add(new JLabel(this.fileLabel), BorderLayout.WEST); + row1.add(fileNamePanel); + bottomPanel.add(row1); + + JPanel row2 = new JPanel(new BorderLayout()); + row2.add(new JLabel(this.filterLabel), BorderLayout.WEST); + row2.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5)); + row2.add(fileFilterCombo); + bottomPanel.add(row2); + JPanel buttonPanel = new JPanel(new ButtonLayout()); + + approveButton = new JButton(getApproveSelectionAction()); + approveButton.setText(getApproveButtonText(fc)); + approveButton.setToolTipText(getApproveButtonToolTipText(fc)); + approveButton.setMnemonic(getApproveButtonMnemonic(fc)); + buttonPanel.add(approveButton); + buttonPanel.setBorder(BorderFactory.createEmptyBorder(8, 0, 0, 0)); + + JButton cancelButton = new JButton(getCancelSelectionAction()); + cancelButton.setText(cancelButtonText); + cancelButton.setToolTipText(cancelButtonToolTipText); + cancelButton.setMnemonic(cancelButtonMnemonic); + buttonPanel.add(cancelButton); + bottomPanel.add(buttonPanel, BorderLayout.SOUTH); + bottomPanel.setBorder(BorderFactory.createEmptyBorder(0, 8, 8, 8)); + fc.add(bottomPanel, BorderLayout.SOUTH); + + fc.add(getAccessoryPanel(), BorderLayout.EAST); + } + + /** + * Uninstalls the components added by + * {@link #installComponents(JFileChooser)}. + * + * @param fc the file chooser. + */ + public void uninstallComponents(JFileChooser fc) + { + fc.remove(bottomPanel); + bottomPanel = null; + fc.remove(fileListPanel); + fc.remove(fileTablePanel); + fileTablePanel = null; + fileListPanel = null; + fc.remove(topPanel); + topPanel = null; + + directoryModel = null; + fileTextField = null; + directoryComboBox = null; + } + + /** + * Returns the panel that contains the 'Open' (or 'Save') and 'Cancel' + * buttons. + * + * @return The panel. + */ + protected JPanel getButtonPanel() + { + return buttonPanel; + } + + /** + * Creates and returns a new panel that will be used for the controls at + * the bottom of the file chooser. + * + * @return A new panel. + */ + protected JPanel getBottomPanel() + { + if (bottomPanel == null) + bottomPanel = new JPanel(new GridLayout(3, 2)); + return bottomPanel; + } + + /** + * Fetches localised strings for use by the labels and buttons on the + * file chooser. + * + * @param fc the file chooser. + */ + protected void installStrings(JFileChooser fc) + { + super.installStrings(fc); + look = "Look In: "; + save = "Save In: "; + if (fc.getDialogType() == JFileChooser.SAVE_DIALOG) + directoryLabel = save; + else + directoryLabel = look; + + fileLabel = "File Name: "; + filterLabel = "Files of Type: "; + + this.cancelButtonMnemonic = 0; + this.cancelButtonText = "Cancel"; + this.cancelButtonToolTipText = "Abort file chooser dialog"; + + this.directoryOpenButtonMnemonic = 0; + this.directoryOpenButtonText = "Open"; + this.directoryOpenButtonToolTipText = "Open selected directory"; + + this.helpButtonMnemonic = 0; + this.helpButtonText = "Help"; + this.helpButtonToolTipText = "Filechooser help"; + + this.openButtonMnemonic = 0; + this.openButtonText = "Open"; + this.openButtonToolTipText = "Open selected file"; + + this.saveButtonMnemonic = 0; + this.saveButtonText = "Save"; + this.saveButtonToolTipText = "Save selected file"; + + this.updateButtonMnemonic = 0; + this.updateButtonText = "Update"; + this.updateButtonToolTipText = "Update directory listing"; + } + + /** + * Installs the listeners required. + * + * @param fc the file chooser. + */ + protected void installListeners(JFileChooser fc) + { + directoryComboBox.setAction(new DirectoryComboBoxAction()); + fc.addPropertyChangeListener(filterModel); + listSelList = createListSelectionListener(fc); + doubleClickList = this.createDoubleClickListener(fc, fileList); + singleClickList = new SingleClickListener(fileList); + fileList.addListSelectionListener(listSelList); + fileList.addMouseListener(doubleClickList); + fileList.addMouseListener(singleClickList); + super.installListeners(fc); + } + + protected void uninstallListeners(JFileChooser fc) + { + super.uninstallListeners(fc); + fc.removePropertyChangeListener(filterModel); + directoryComboBox.setAction(null); + fileList.removeListSelectionListener(listSelList); + fileList.removeMouseListener(doubleClickList); + fileList.removeMouseListener(singleClickList); + + if (fileTable != null) + fileTable.removeMouseListener(tableClickList); + } + + protected ActionMap getActionMap() + { + if (actionMap == null) + actionMap = createActionMap(); + return actionMap; + } + + /** + * Creates and returns an action map. + * + * @return The action map. + */ + protected ActionMap createActionMap() + { + ActionMap map = new ActionMap(); + map.put("approveSelection", getApproveSelectionAction()); + map.put("cancelSelection", getCancelSelectionAction()); + map.put("Go Up", getChangeToParentDirectoryAction()); + return map; + } + + /** + * Creates a panel containing a list of files. + * + * @param fc the file chooser. + * + * @return A panel. + */ + protected JPanel createList(JFileChooser fc) + { + if (fileList == null) + { + fileListPanel = new JPanel(new BorderLayout()); + fileList = new JList(getModel()); + scrollPane = new JScrollPane(fileList); + scrollPane.setVerticalScrollBarPolicy + (JScrollPane.VERTICAL_SCROLLBAR_NEVER); + fileList.setLayoutOrientation(JList.VERTICAL_WRAP); + fileList.setCellRenderer(new FileRenderer()); + } + else + { + fileList.setModel(getModel()); + fileListPanel.removeAll(); + scrollPane.getViewport().setView(fileList); + } + fileListPanel.add(scrollPane); + + return fileListPanel; + } + + /** + * Creates a panel containing a table within a scroll pane. + * + * @param fc the file chooser. + * + * @return The details view. + */ + protected JPanel createDetailsView(JFileChooser fc) + { + fileTablePanel = new JPanel(new BorderLayout()); + + Object[] cols = new Object[] {"Name", "Size", "Modified"}; + Object[][] rows = new Object[fileList.getModel().getSize()][3]; + + fileTable = new JTable(new DefaultTableModel(rows, cols)); + + if (fc.isMultiSelectionEnabled()) + fileTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + else + fileTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + fileTable.setShowGrid(false); + fileTable.setColumnSelectionAllowed(false); + fileTable.setDefaultRenderer(Object.class, new TableFileRenderer()); + + tableClickList = new TableClickListener(fileTable, fc); + fileTable.addMouseListener(tableClickList); + + return updateTable(); + } + + /** + * Sets the values in the table, and puts it in the panel. + * + * @return the panel containing the table. + */ + JPanel updateTable() + { + DefaultTableModel mod = (DefaultTableModel) fileTable.getModel(); + ListModel lm = fileList.getModel(); + DateFormat dt = DateFormat.getDateTimeInstance(DateFormat.SHORT, + DateFormat.SHORT); + File curr = null; + int size = lm.getSize(); + int rc = mod.getRowCount(); + + // If there are not enough rows + for (int x = rc; x < size; x++) + mod.addRow(new Object[3]); + + for (int i = 0; i < size; i++) + { + curr = (File) lm.getElementAt(i); + fileTable.setValueAt(curr.getName(), i, 0); + fileTable.setValueAt(formatSize(curr.length()), i, 1); + fileTable.setValueAt(dt.format(new Date(curr.lastModified())), i, 2); + } + + // If there are too many rows + while (rc > size) + mod.removeRow(--rc); + + scrollPane.getViewport().setView(fileTable); + scrollPane.setColumnHeaderView(fileTable.getTableHeader()); + + fileTablePanel.removeAll(); + fileTablePanel.add(scrollPane); + + return fileTablePanel; + } + + /** + * Formats bytes into the appropriate size. + * + * @param bytes - + * the number of bytes to convert + * @return a string representation of the size + */ + private String formatSize(long bytes) + { + NumberFormat nf = NumberFormat.getNumberInstance(); + long mb = (long) Math.pow(2, 20); + long kb = (long) Math.pow(2, 10); + long gb = (long) Math.pow(2, 30); + double size = 0; + String id = ""; + + if ((bytes / gb) >= 1) + { + size = (double) bytes / (double) gb; + id = "GB"; + } + else if ((bytes / mb) >= 1) + { + size = (double) bytes / (double) mb; + id = "MB"; + } + else if ((bytes / kb) >= 1) + { + size = (double) bytes / (double) kb; + id = "KB"; + } + else + { + size = bytes; + id = "Bytes"; + } + + return nf.format(size) + " " + id; + } + /** + * Creates a listener that monitors selections in the directory/file list + * and keeps the {@link JFileChooser} component up to date. + * + * @param fc the file chooser. + * + * @return The listener. + * + * @see #installListeners(JFileChooser) + */ + public ListSelectionListener createListSelectionListener(JFileChooser fc) + { + return new MetalFileChooserSelectionListener(); + } + + /** + * Returns the preferred size for the file chooser component. + * + * @return The preferred size. + */ + public Dimension getPreferredSize(JComponent c) + { + Dimension tp = topPanel.getPreferredSize(); + Dimension bp = bottomPanel.getPreferredSize(); + Dimension fl = fileListPanel.getPreferredSize(); + return new Dimension(fl.width, tp.height + bp.height + fl.height); + } + + /** + * Returns the minimum size for the file chooser component. + * + * @return The minimum size. + */ + public Dimension getMinimumSize(JComponent c) + { + Dimension tp = topPanel.getMinimumSize(); + Dimension bp = bottomPanel.getMinimumSize(); + Dimension fl = fileListPanel.getMinimumSize(); + return new Dimension(fl.width, tp.height + bp.height + fl.height); } /** + * Returns the maximum size for the file chooser component. + * + * @return The maximum size. + */ + public Dimension getMaximumSize(JComponent c) + { + return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); + } + + /** + * Creates a property change listener that monitors the {@link JFileChooser} + * for property change events and updates the component display accordingly. + * + * @param fc the file chooser. + * + * @return The property change listener. + * + * @see #installListeners(JFileChooser) + */ + public PropertyChangeListener createPropertyChangeListener(JFileChooser fc) + { + return new MetalFileChooserPropertyChangeListener(); + } + + /** * Creates and returns a new instance of {@link DirectoryComboBoxModel}. * * @return A new instance of {@link DirectoryComboBoxModel}. @@ -407,6 +1749,20 @@ public class MetalFileChooserUI extends BasicFileChooserUI } /** + * Creates a new instance of the renderer used in the directory + * combo box. + * + * @param fc the file chooser. + * + * @return The renderer. + */ + protected DirectoryComboBoxRenderer createDirectoryComboBoxRenderer( + JFileChooser fc) + { + return new DirectoryComboBoxRenderer(fc); + } + + /** * Creates and returns a new instance of {@link FilterComboBoxModel}. * * @return A new instance of {@link FilterComboBoxModel}. @@ -427,4 +1783,297 @@ public class MetalFileChooserUI extends BasicFileChooserUI return new FilterComboBoxRenderer(); } + /** + * Adds the control buttons ('up', 'home' etc.) to the panel. + */ + protected void addControlButtons() + { + JButton upButton = new JButton(getChangeToParentDirectoryAction()); + upButton.setText(null); + upButton.setIcon(this.upFolderIcon); + upButton.setMargin(new Insets(0, 0, 0, 0)); + controls.add(upButton); + + JButton homeButton = new JButton(getGoHomeAction()); + homeButton.setText(null); + homeButton.setIcon(this.homeFolderIcon); + homeButton.setMargin(new Insets(0, 0, 0, 0)); + controls.add(homeButton); + + JButton newFolderButton = new JButton(getNewFolderAction()); + newFolderButton.setText(null); + newFolderButton.setIcon(this.newFolderIcon); + newFolderButton.setMargin(new Insets(0, 0, 0, 0)); + controls.add(newFolderButton); + + JToggleButton listButton = new JToggleButton(this.listViewIcon); + listButton.setMargin(new Insets(0, 0, 0, 0)); + listButton.addActionListener(new ListViewActionListener()); + listButton.setSelected(true); + listView = true; + controls.add(listButton); + + JToggleButton detailButton = new JToggleButton(this.detailsViewIcon); + detailButton.setMargin(new Insets(0, 0, 0, 0)); + detailButton.addActionListener(new DetailViewActionListener()); + detailButton.setSelected(false); + controls.add(detailButton); + + ButtonGroup buttonGroup = new ButtonGroup(); + buttonGroup.add(listButton); + buttonGroup.add(detailButton); + } + + /** + * Removes all the buttons from the control panel. + */ + protected void removeControlButtons() + { + controls.removeAll(); + controls.revalidate(); + controls.repaint(); + } + + /** + * Updates the current directory. + * + * @param the file chooser to update. + */ + public void rescanCurrentDirectory(JFileChooser fc) + { + directoryModel.setSelectedItem(fc.getCurrentDirectory()); + getModel().validateFileCache(); + if (!listView) + updateTable(); + else + createList(fc); + } + + /** + * Returns the file name in the text field. + * + * @return The file name. + */ + public String getFileName() + { + String result = null; + if (fileTextField != null) + result = fileTextField.getText(); + return result; + } + + /** + * Sets the file name in the text field. + * + * @param filename the file name. + */ + public void setFileName(String filename) + { + fileTextField.setText(filename); + } + + /** + * DOCUMENT ME!! + * + * @param e - DOCUMENT ME! + */ + public void valueChanged(ListSelectionEvent e) + { + // FIXME: Not sure what we should be doing here, if anything. + } + + /** + * Returns the approve button. + * + * @return The approve button. + */ + protected JButton getApproveButton(JFileChooser fc) + { + return approveButton; + } + + /** + * A layout manager that is used to arrange the subcomponents of the + * {@link JFileChooser}. + */ + class VerticalMidLayout implements LayoutManager + { + /** + * Performs the layout. + * + * @param parent the container. + */ + public void layoutContainer(Container parent) + { + int count = parent.getComponentCount(); + if (count > 0) + { + Insets insets = parent.getInsets(); + Component c = parent.getComponent(0); + Dimension prefSize = c.getPreferredSize(); + int h = parent.getHeight() - insets.top - insets.bottom; + int adj = Math.max(0, (h - prefSize.height) / 2); + c.setBounds(insets.left, insets.top + adj, parent.getWidth() + - insets.left - insets.right, + (int) Math.min(prefSize.getHeight(), h)); + } + } + + /** + * Returns the minimum layout size. + * + * @param parent the container. + * + * @return The minimum layout size. + */ + public Dimension minimumLayoutSize(Container parent) + { + return preferredLayoutSize(parent); + } + + /** + * Returns the preferred layout size. + * + * @param parent the container. + * + * @return The preferred layout size. + */ + public Dimension preferredLayoutSize(Container parent) + { + if (parent.getComponentCount() > 0) + { + return parent.getComponent(0).getPreferredSize(); + } + else return null; + } + + /** + * This layout manager does not need to track components, so this + * method does nothing. + * + * @param name the name the component is associated with. + * @param component the component. + */ + public void addLayoutComponent(String name, Component component) + { + // do nothing + } + + /** + * This layout manager does not need to track components, so this + * method does nothing. + * + * @param component the component. + */ + public void removeLayoutComponent(Component component) { + // do nothing + } + } + + /** + * A layout manager that is used to arrange buttons for the + * {@link JFileChooser}. + */ + class ButtonLayout implements LayoutManager + { + static final int GAP = 4; + + /** + * Performs the layout. + * + * @param parent the container. + */ + public void layoutContainer(Container parent) + { + int count = parent.getComponentCount(); + if (count > 0) + { + // first find the widest button + int maxW = 0; + for (int i = 0; i < count; i++) + { + Component c = parent.getComponent(i); + Dimension prefSize = c.getPreferredSize(); + maxW = Math.max(prefSize.width, maxW); + } + + // then position the buttons + Insets insets = parent.getInsets(); + int availableH = parent.getHeight() - insets.top - insets.bottom; + int currentX = parent.getWidth() - insets.right; + for (int i = count - 1; i >= 0; i--) + { + Component c = parent.getComponent(i); + Dimension prefSize = c.getPreferredSize(); + int adj = Math.max(0, (availableH - prefSize.height) / 2); + currentX = currentX - prefSize.width; + c.setBounds(currentX, insets.top + adj, prefSize.width, + (int) Math.min(prefSize.getHeight(), availableH)); + currentX = currentX - GAP; + } + } + } + + /** + * Returns the minimum layout size. + * + * @param parent the container. + * + * @return The minimum layout size. + */ + public Dimension minimumLayoutSize(Container parent) + { + return preferredLayoutSize(parent); + } + + /** + * Returns the preferred layout size. + * + * @param parent the container. + * + * @return The preferred layout size. + */ + public Dimension preferredLayoutSize(Container parent) + { + Insets insets = parent.getInsets(); + int maxW = 0; + int maxH = 0; + int count = parent.getComponentCount(); + if (count > 0) + { + for (int i = 0; i < count; i++) + { + Component c = parent.getComponent(i); + Dimension d = c.getPreferredSize(); + maxW = Math.max(d.width, maxW); + maxH = Math.max(d.height, maxH); + } + } + return new Dimension(maxW * count + GAP * (count - 1) + insets.left + + insets.right, maxH + insets.top + insets.bottom); + } + + /** + * This layout manager does not need to track components, so this + * method does nothing. + * + * @param name the name the component is associated with. + * @param component the component. + */ + public void addLayoutComponent(String name, Component component) + { + // do nothing + } + + /** + * This layout manager does not need to track components, so this + * method does nothing. + * + * @param component the component. + */ + public void removeLayoutComponent(Component component) { + // do nothing + } + } + } diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalIconFactory.java b/libjava/classpath/javax/swing/plaf/metal/MetalIconFactory.java index bcb86e6..0b644f3 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalIconFactory.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalIconFactory.java @@ -68,6 +68,12 @@ public class MetalIconFactory implements Serializable /** A constant representing "light". */ public static final boolean LIGHT = true; + + /** A shared instance of the MenuArrowIcon. */ + private static Icon menuArrow; + + /** A shared instance of the MenuItemArrowIcon. */ + private static Icon menuItemArrow; /** * An icon displayed for {@link JCheckBoxMenuItem} components. @@ -2467,4 +2473,102 @@ public class MetalIconFactory implements Serializable return treeHardDriveIcon; } + /** + * Returns a new instance of a 4 x 8 icon showing a small black triangle that + * points to the right. This is displayed in menu items that have a + * sub menu. + * + * @return The icon. + */ + public static Icon getMenuArrowIcon() + { + if (menuArrow == null) + menuArrow = new Icon() + { + public int getIconHeight() + { + return 8; + } + + public int getIconWidth() + { + return 4; + } + + public void paintIcon(Component c, Graphics g, int x, int y) + { + Color saved = g.getColor(); + g.setColor(Color.BLACK); + for (int i = 0; i < 4; i++) + g.drawLine(x + i, y + i, x + i, y + 7 - i); + g.setColor(saved); + } + }; + return menuArrow; + } + + /** + * Returns a new instance of a 4 x 8 icon showing a small black triangle that + * points to the right. This is displayed in menu items that have a sub menu. + * + * @return The icon. + */ + public static Icon getMenuItemArrowIcon() + { + if (menuItemArrow == null) + menuItemArrow = new Icon() + { + public int getIconHeight() + { + return 8; + } + + public int getIconWidth() + { + return 4; + } + + public void paintIcon(Component c, Graphics g, int x, int y) + { + Color saved = g.getColor(); + g.setColor(Color.BLACK); + for (int i = 0; i < 4; i++) + g.drawLine(x + i, y + i, x + i, y + 7 - i); + g.setColor(saved); + } + }; + return menuItemArrow; + } + + /** + * Returns a new instance of a 13 x 13 icon showing a small black check mark. + * + * @return The icon. + */ + public static Icon getMenuItemCheckIcon() + { + return new Icon() + { + public int getIconHeight() + { + return 13; + } + + public int getIconWidth() + { + return 13; + } + + public void paintIcon(Component c, Graphics g, int x, int y) + { + Color saved = g.getColor(); + g.setColor(Color.BLACK); + g.drawLine(3 + x, 5 + y, 3 + x, 9 + y); + g.drawLine(4 + x, 5 + y, 4 + x, 9 + y); + g.drawLine(5 + x, 7 + y, 9 + x, 3 + y); + g.drawLine(5 + x, 8 + y, 9 + x, 4 + y); + g.setColor(saved); + } + }; + } } diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalLookAndFeel.java b/libjava/classpath/javax/swing/plaf/metal/MetalLookAndFeel.java index da01937..c60b55c 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalLookAndFeel.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalLookAndFeel.java @@ -40,7 +40,6 @@ package javax.swing.plaf.metal; import java.awt.Color; import java.awt.Font; -import java.awt.Insets; import javax.swing.LookAndFeel; import javax.swing.UIDefaults; @@ -55,7 +54,17 @@ import javax.swing.plaf.basic.BasicLookAndFeel; /** * A custom look and feel that is designed to look similar across different - * operating systems. + * operating systems. To install this look and feel, add the following code + * (or something similar) near the start of your application:</p> + * <pre> + * try + * { + * UIManager.setLookAndFeel(new MetalLookAndFeel()); + * } + * catch (UnsupportedLookAndFeelException e) + * { + * e.printStackTrace(); + * }</pre> */ public class MetalLookAndFeel extends BasicLookAndFeel { @@ -72,8 +81,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public MetalLookAndFeel() { - if (theme == null) - createDefaultTheme(); + createDefaultTheme(); } /** @@ -81,7 +89,8 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ protected void createDefaultTheme() { - setCurrentTheme(new DefaultMetalTheme()); + if (theme == null) + setCurrentTheme(new DefaultMetalTheme()); } /** @@ -115,7 +124,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public String getDescription() { - return "Metal look and feel"; + return "The Java(tm) Look and Feel"; } /** @@ -125,7 +134,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public String getID() { - return "MetalLookAndFeel"; + return "Metal"; } /** @@ -135,7 +144,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public String getName() { - return "MetalLookAndFeel"; + return "Metal"; } public UIDefaults getDefaults() @@ -145,7 +154,8 @@ public class MetalLookAndFeel extends BasicLookAndFeel LAF_defaults = super.getDefaults(); // add custom theme entries to the table - theme.addCustomEntriesToTable(LAF_defaults); + if (theme != null) + theme.addCustomEntriesToTable(LAF_defaults); } // Returns the default values for this look and feel. @@ -159,7 +169,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getAcceleratorForeground() { - return theme.getAcceleratorForeground(); + if (theme != null) + return theme.getAcceleratorForeground(); + return null; } /** @@ -170,7 +182,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getAcceleratorSelectedForeground() { - return theme.getAcceleratorSelectedForeground(); + if (theme != null) + return theme.getAcceleratorSelectedForeground(); + return null; } /** @@ -180,7 +194,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getBlack() { - return theme.getBlack(); + if (theme != null) + return theme.getBlack(); + return null; } /** @@ -190,7 +206,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getControl() { - return theme.getControl(); + if (theme != null) + return theme.getControl(); + return null; } /** @@ -201,7 +219,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getControlDarkShadow() { - return theme.getControlDarkShadow(); + if (theme != null) + return theme.getControlDarkShadow(); + return null; } /** @@ -211,7 +231,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getControlDisabled() { - return theme.getControlDisabled(); + if (theme != null) + return theme.getControlDisabled(); + return null; } /** @@ -222,7 +244,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getControlHighlight() { - return theme.getControlHighlight(); + if (theme != null) + return theme.getControlHighlight(); + return null; } /** @@ -233,7 +257,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getControlInfo() { - return theme.getControlInfo(); + if (theme != null) + return theme.getControlInfo(); + return null; } /** @@ -244,7 +270,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getControlShadow() { - return theme.getControlShadow(); + if (theme != null) + return theme.getControlShadow(); + return null; } /** @@ -254,7 +282,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getControlTextColor() { - return theme.getControlTextColor(); + if (theme != null) + return theme.getControlTextColor(); + return null; } /** @@ -264,7 +294,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static FontUIResource getControlTextFont() { - return theme.getControlTextFont(); + if (theme != null) + return theme.getControlTextFont(); + return null; } /** @@ -275,7 +307,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getDesktopColor() { - return theme.getDesktopColor(); + if (theme != null) + return theme.getDesktopColor(); + return null; } /** @@ -286,7 +320,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getFocusColor() { - return theme.getFocusColor(); + if (theme != null) + return theme.getFocusColor(); + return null; } /** @@ -297,7 +333,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getHighlightedTextColor() { - return theme.getHighlightedTextColor(); + if (theme != null) + return theme.getHighlightedTextColor(); + return null; } /** @@ -308,7 +346,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getInactiveControlTextColor() { - return theme.getInactiveControlTextColor(); + if (theme != null) + return theme.getInactiveControlTextColor(); + return null; } /** @@ -319,7 +359,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getInactiveSystemTextColor() { - return theme.getInactiveSystemTextColor(); + if (theme != null) + return theme.getInactiveSystemTextColor(); + return null; } /** @@ -331,7 +373,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getMenuBackground() { - return theme.getMenuBackground(); + if (theme != null) + return theme.getMenuBackground(); + return null; } /** @@ -344,7 +388,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getMenuDisabledForeground() { - return theme.getMenuDisabledForeground(); + if (theme != null) + return theme.getMenuDisabledForeground(); + return null; } /** @@ -357,7 +403,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getMenuForeground() { - return theme.getMenuForeground(); + if (theme != null) + return theme.getMenuForeground(); + return null; } /** @@ -370,7 +418,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getMenuSelectedBackground() { - return theme.getMenuSelectedBackground(); + if (theme != null) + return theme.getMenuSelectedBackground(); + return null; } /** @@ -383,7 +433,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getMenuSelectedForeground() { - return theme.getMenuSelectedForeground(); + if (theme != null) + return theme.getMenuSelectedForeground(); + return null; } /** @@ -393,7 +445,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static FontUIResource getMenuTextFont() { - return theme.getMenuTextFont(); + if (theme != null) + return theme.getMenuTextFont(); + return null; } /** @@ -403,7 +457,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getPrimaryControl() { - return theme.getPrimaryControl(); + if (theme != null) + return theme.getPrimaryControl(); + return null; } /** @@ -414,7 +470,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getPrimaryControlDarkShadow() { - return theme.getPrimaryControlDarkShadow(); + if (theme != null) + return theme.getPrimaryControlDarkShadow(); + return null; } /** @@ -425,7 +483,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getPrimaryControlHighlight() { - return theme.getPrimaryControlHighlight(); + if (theme != null) + return theme.getPrimaryControlHighlight(); + return null; } /** @@ -436,7 +496,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getPrimaryControlInfo() { - return theme.getPrimaryControlInfo(); + if (theme != null) + return theme.getPrimaryControlInfo(); + return null; } /** @@ -447,7 +509,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getPrimaryControlShadow() { - return theme.getPrimaryControlShadow(); + if (theme != null) + return theme.getPrimaryControlShadow(); + return null; } /** @@ -457,7 +521,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getSeparatorBackground() { - return theme.getSeparatorBackground(); + if (theme != null) + return theme.getSeparatorBackground(); + return null; } /** @@ -467,7 +533,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getSeparatorForeground() { - return theme.getSeparatorForeground(); + if (theme != null) + return theme.getSeparatorForeground(); + return null; } /** @@ -477,7 +545,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static FontUIResource getSubTextFont() { - return theme.getSubTextFont(); + if (theme != null) + return theme.getSubTextFont(); + return null; } /** @@ -487,7 +557,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getSystemTextColor() { - return theme.getSystemTextColor(); + if (theme != null) + return theme.getSystemTextColor(); + return null; } /** @@ -497,7 +569,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static FontUIResource getSystemTextFont() { - return theme.getSystemTextFont(); + if (theme != null) + return theme.getSystemTextFont(); + return null; } /** @@ -507,7 +581,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getTextHighlightColor() { - return theme.getTextHighlightColor(); + if (theme != null) + return theme.getTextHighlightColor(); + return null; } /** @@ -517,7 +593,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getUserTextColor() { - return theme.getUserTextColor(); + if (theme != null) + return theme.getUserTextColor(); + return null; } /** @@ -527,7 +605,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static FontUIResource getUserTextFont() { - return theme.getUserTextFont(); + if (theme != null) + return theme.getUserTextFont(); + return null; } /** @@ -537,7 +617,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getWhite() { - return theme.getWhite(); + if (theme != null) + return theme.getWhite(); + return null; } /** @@ -547,7 +629,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getWindowBackground() { - return theme.getWindowBackground(); + if (theme != null) + return theme.getWindowBackground(); + return null; } /** @@ -557,7 +641,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getWindowTitleBackground() { - return theme.getWindowTitleBackground(); + if (theme != null) + return theme.getWindowTitleBackground(); + return null; } /** @@ -569,7 +655,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static FontUIResource getWindowTitleFont() { - return theme.getWindowTitleFont(); + if (theme != null) + return theme.getWindowTitleFont(); + return null; } /** @@ -579,7 +667,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getWindowTitleForeground() { - return theme.getWindowTitleForeground(); + if (theme != null) + return theme.getWindowTitleForeground(); + return null; } /** @@ -590,7 +680,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getWindowTitleInactiveBackground() { - return theme.getWindowTitleInactiveBackground(); + if (theme != null) + return theme.getWindowTitleInactiveBackground(); + return null; } /** @@ -601,7 +693,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel */ public static ColorUIResource getWindowTitleInactiveForeground() { - return theme.getWindowTitleInactiveForeground(); + if (theme != null) + return theme.getWindowTitleInactiveForeground(); + return null; } /** @@ -691,6 +785,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel "CheckBoxUI", "javax.swing.plaf.metal.MetalCheckBoxUI", "ComboBoxUI", "javax.swing.plaf.metal.MetalComboBoxUI", "DesktopIconUI", "javax.swing.plaf.metal.MetalDesktopIconUI", + "FileChooserUI", "javax.swing.plaf.metal.MetalFileChooserUI", "InternalFrameUI", "javax.swing.plaf.metal.MetalInternalFrameUI", "LabelUI", "javax.swing.plaf.metal.MetalLabelUI", "MenuBarUI", "javax.swing.plaf.metal.MetalMenuBarUI", @@ -841,7 +936,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel "EditorPane.background", getWindowBackground(), "EditorPane.caretForeground", getUserTextColor(), - "EditorPane.font", new FontUIResource("Dialog", Font.PLAIN, 12), + "EditorPane.font", new FontUIResource("Dialog", Font.BOLD, 12), "EditorPane.foreground", getUserTextColor(), "EditorPane.inactiveForeground", getInactiveSystemTextColor(), "EditorPane.selectionBackground", getTextHighlightColor(), @@ -858,6 +953,19 @@ public class MetalLookAndFeel extends BasicLookAndFeel "FormattedTextField.selectionBackground", getTextHighlightColor(), "FormattedTextField.selectionForeground", getHighlightedTextColor(), + "FileChooser.upFolderIcon", + MetalIconFactory.getFileChooserUpFolderIcon(), + "FileChooser.listViewIcon", + MetalIconFactory.getFileChooserListViewIcon(), + "FileChooser.newFolderIcon", + MetalIconFactory.getFileChooserNewFolderIcon(), + "FileChooser.homeFolderIcon", + MetalIconFactory.getFileChooserHomeFolderIcon(), + "FileChooser.detailsViewIcon", + MetalIconFactory.getFileChooserDetailViewIcon(), + "FileChooser.fileNameLabelMnemonic", new Integer(78), + "FileChooser.filesOfTypeLabelMnemonic",new Integer(84), + "FileChooser.lookInLabelMnemonic", new Integer(73), "FileView.computerIcon", MetalIconFactory.getTreeComputerIcon(), "FileView.directoryIcon", MetalIconFactory.getTreeFolderIcon(), "FileView.fileIcon", MetalIconFactory.getTreeLeafIcon(), @@ -875,15 +983,20 @@ public class MetalLookAndFeel extends BasicLookAndFeel "InternalFrame.icon", MetalIconFactory.getInternalFrameDefaultMenuIcon(), "InternalFrame.closeIcon", MetalIconFactory.getInternalFrameCloseIcon(16), + "InternalFrame.closeSound", "sounds/FrameClose.wav", "InternalFrame.inactiveTitleBackground", getWindowTitleInactiveBackground(), "InternalFrame.inactiveTitleForeground", getWindowTitleInactiveForeground(), "InternalFrame.maximizeIcon", MetalIconFactory.getInternalFrameMaximizeIcon(16), + "InternalFrame.maximizeSound", "sounds/FrameMaximize.wav", "InternalFrame.iconifyIcon", MetalIconFactory.getInternalFrameMinimizeIcon(16), + "InternalFrame.minimizeSound", "sounds/FrameMinimize.wav", "InternalFrame.paletteBorder", new MetalBorders.PaletteBorder(), "InternalFrame.paletteCloseIcon", new MetalIconFactory.PaletteCloseIcon(), "InternalFrame.paletteTitleHeight", new Integer(11), + "InternalFrame.restoreDownSound", "sounds/FrameRestoreDown.wav", + "InternalFrame.restoreUpSound", "sounds/FrameRestoreUp.wav", "Label.background", getControl(), "Label.disabledForeground", getInactiveSystemTextColor(), @@ -902,14 +1015,18 @@ public class MetalLookAndFeel extends BasicLookAndFeel "Menu.acceleratorFont", new FontUIResource("Dialog", Font.PLAIN, 10), "Menu.acceleratorForeground", getAcceleratorForeground(), "Menu.acceleratorSelectionForeground", getAcceleratorSelectedForeground(), + "Menu.arrowIcon", MetalIconFactory.getMenuArrowIcon(), "Menu.background", getMenuBackground(), "Menu.border", new MetalBorders.MenuItemBorder(), "Menu.borderPainted", Boolean.TRUE, + "MenuItem.commandSound", "sounds/MenuItemCommand.wav", "Menu.disabledForeground", getMenuDisabledForeground(), "Menu.font", getControlTextFont(), "Menu.foreground", getMenuForeground(), "Menu.selectionBackground", getMenuSelectedBackground(), "Menu.selectionForeground", getMenuSelectedForeground(), + "Menu.submenuPopupOffsetX", new Integer(-4), + "Menu.submenuPopupOffsetY", new Integer(-3), "MenuBar.background", getMenuBackground(), "MenuBar.border", new MetalBorders.MenuBarBorder(), @@ -918,11 +1035,14 @@ public class MetalLookAndFeel extends BasicLookAndFeel "MenuBar.highlight", getControlHighlight(), "MenuBar.shadow", getControlShadow(), + "MenuItem.acceleratorDelimiter", "-", "MenuItem.acceleratorFont", new FontUIResource("Dialog", Font.PLAIN, 10), "MenuItem.acceleratorForeground", getAcceleratorForeground(), "MenuItem.acceleratorSelectionForeground", getAcceleratorSelectedForeground(), + "MenuItem.arrowIcon", MetalIconFactory.getMenuItemArrowIcon(), "MenuItem.background", getMenuBackground(), "MenuItem.border", new MetalBorders.MenuItemBorder(), + "MenuItem.borderPainted", Boolean.TRUE, "MenuItem.disabledForeground", getMenuDisabledForeground(), "MenuItem.font", getControlTextFont(), "MenuItem.foreground", getMenuForeground(), @@ -930,6 +1050,10 @@ public class MetalLookAndFeel extends BasicLookAndFeel "MenuItem.selectionForeground", getMenuSelectedForeground(), "OptionPane.background", getControl(), + "OptionPane.errorSound", "sounds/OptionPaneError.wav", + "OptionPane.informationSound", "sounds/OptionPaneInformation.wav", + "OptionPane.questionSound", "sounds/OptionPaneQuestion.wav", + "OptionPane.warningSound", "sounds/OptionPaneWarning.wav", "OptionPane.errorDialog.border.background", new ColorUIResource(153, 51, 51), "OptionPane.errorDialog.titlePane.background", new ColorUIResource(255, 153, 153), "OptionPane.errorDialog.titlePane.foreground", new ColorUIResource(51, 0, 0), @@ -953,6 +1077,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel new BorderUIResource(MetalBorders.getTextFieldBorder()), "PasswordField.caretForeground", getUserTextColor(), "PasswordField.foreground", getUserTextColor(), + "PasswordField.font", new FontUIResource("Dialog", Font.PLAIN, 12), "PasswordField.inactiveBackground", getControl(), "PasswordField.inactiveForeground", getInactiveSystemTextColor(), "PasswordField.selectionBackground", getTextHighlightColor(), @@ -962,6 +1087,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel "PopupMenu.border", new MetalBorders.PopupMenuBorder(), "PopupMenu.font", new FontUIResource("Dialog", Font.BOLD, 12), "PopupMenu.foreground", getMenuForeground(), + "PopupMenu.popupSound", "sounds/PopupMenuPopup.wav", "ProgressBar.background", getControl(), "ProgressBar.border", new BorderUIResource.LineBorderUIResource(getControlDarkShadow(), 1), @@ -997,6 +1123,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel "RadioButtonMenuItem.borderPainted", Boolean.TRUE, "RadioButtonMenuItem.checkIcon", MetalIconFactory.getRadioButtonMenuItemIcon(), + "RadioButtonMenuItem.commandSound", "sounds/MenuItemCommand.wav", "RadioButtonMenuItem.disabledForeground", getMenuDisabledForeground(), "RadioButtonMenuItem.font", MetalLookAndFeel.getControlTextFont(), "RadioButtonMenuItem.foreground", getMenuForeground(), @@ -1006,6 +1133,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel "RadioButtonMenuItem.selectionForeground", MetalLookAndFeel.getMenuSelectedForeground(), + "ScrollBar.allowsAbsolutePositioning", Boolean.TRUE, "ScrollBar.background", getControl(), "ScrollBar.darkShadow", getControlDarkShadow(), "ScrollBar.foreground", getControl(), @@ -1041,6 +1169,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel "Slider.verticalThumbIcon", MetalIconFactory.getVerticalSliderThumbIcon(), + "Spinner.arrowButtonInsets", new InsetsUIResource(0, 0, 0, 0), "Spinner.background", getControl(), "Spinner.font", new FontUIResource("Dialog", Font.BOLD, 12), "Spinner.foreground", getControl(), @@ -1048,6 +1177,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel "SplitPane.background", getControl(), "SplitPane.darkShadow", getControlDarkShadow(), "SplitPane.dividerFocusColor", getPrimaryControl(), + "SplitPane.dividerSize", new Integer(10), "SplitPane.highlight", getControlHighlight(), "SplitPane.shadow", getControlShadow(), @@ -1150,6 +1280,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel "ToolTip.font", new FontUIResource("Dialog", Font.PLAIN, 12), "ToolTip.foreground", getPrimaryControlInfo(), "ToolTip.foregroundInactive", getControlDarkShadow(), + "ToolTip.hideAccelerator", Boolean.FALSE, "Tree.background", getWindowBackground(), "Tree.closedIcon", MetalIconFactory.getTreeFolderIcon(), diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalRadioButtonUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalRadioButtonUI.java index de71fe8..9fb960f 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalRadioButtonUI.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalRadioButtonUI.java @@ -176,7 +176,7 @@ public class MetalRadioButtonUI protected void paintFocus(Graphics g, Rectangle t, Dimension d) { g.setColor(focusColor); - g.drawRect(t.x - 1, t.y + 2, t.width + 2, t.height - 4); + g.drawRect(t.x - 1, t.y - 1, t.width + 2, t.height + 2); } } diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalScrollPaneUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalScrollPaneUI.java index d5bf175..ae14af3 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalScrollPaneUI.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalScrollPaneUI.java @@ -38,7 +38,10 @@ exception statement from your version. */ package javax.swing.plaf.metal; +import java.beans.PropertyChangeListener; + import javax.swing.JComponent; +import javax.swing.JScrollBar; import javax.swing.JScrollPane; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicScrollPaneUI; @@ -68,4 +71,89 @@ public class MetalScrollPaneUI { return new MetalScrollPaneUI(); } + + /** + * Configures the specified component appropriate for the look and feel. + * This method is invoked when the ComponentUI instance is being installed + * as the UI delegate on the specified component. This method should + * completely configure the component for the look and feel, + * including the following: + * 1. Install any default property values for color, fonts, borders, + * icons, opacity, etc. on the component. Whenever possible, property + * values initialized by the client program should not be overridden. + * 2. Install a LayoutManager on the component if necessary. + * 3. Create/add any required sub-components to the component. + * 4. Create/install event listeners on the component. + * 5. Create/install a PropertyChangeListener on the component in order + * to detect and respond to component property changes appropriately. + * 6. Install keyboard UI (mnemonics, traversal, etc.) on the component. + * 7. Initialize any appropriate instance data. + * + * @param c - the component to install the ui on + */ + public void installUI(JComponent c) + { + super.installUI(c); + JScrollBar hsb = scrollpane.getHorizontalScrollBar(); + hsb.putClientProperty(MetalScrollBarUI.FREE_STANDING_PROP, Boolean.FALSE); + JScrollBar vsb = scrollpane.getVerticalScrollBar(); + vsb.putClientProperty(MetalScrollBarUI.FREE_STANDING_PROP, Boolean.FALSE); + } + + /** + * Reverses configuration which was done on the specified component + * during installUI. This method is invoked when this UIComponent + * instance is being removed as the UI delegate for the specified + * component. This method should undo the configuration performed in + * installUI, being careful to leave the JComponent instance in a + * clean state (no extraneous listeners, look-and-feel-specific property + * objects, etc.). This should include the following: + * 1. Remove any UI-set borders from the component. + * 2. Remove any UI-set layout managers on the component. + * 3. Remove any UI-added sub-components from the component. + * 4. Remove any UI-added event/property listeners from the component. + * 5. Remove any UI-installed keyboard UI from the component. + * 6. Nullify any allocated instance data objects to allow for GC. + * + * @param c - the component to uninstall the ui on + */ + public void uninstallUI(JComponent c) + { + JScrollBar hsb = scrollpane.getHorizontalScrollBar(); + hsb.putClientProperty(MetalScrollBarUI.FREE_STANDING_PROP, null); + JScrollBar vsb = scrollpane.getVerticalScrollBar(); + vsb.putClientProperty(MetalScrollBarUI.FREE_STANDING_PROP, null); + super.uninstallUI(c); + } + + /** + * Installs listeners on scrollPane + * + * @param scrollPane - the component to install the listeners on + */ + public void installListeners(JScrollPane scrollPane) + { + super.installListeners(scrollPane); + } + + /** + * Uninstalls listeners on scrollPane + * + * @param scrollPane - the component to uninstall the listeners on + */ + public void uninstallListeners(JScrollPane scrollPane) + { + super.uninstallListeners(scrollPane); + } + + /** + * TODO + * + * @return TODO + */ + protected PropertyChangeListener createScrollBarSwapListener() + { + // FIXME: Anything else to do here? + return super.createPropertyChangeListener(); + } } diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalSplitPaneDivider.java b/libjava/classpath/javax/swing/plaf/metal/MetalSplitPaneDivider.java index 016e095..34a964c 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalSplitPaneDivider.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalSplitPaneDivider.java @@ -38,9 +38,16 @@ exception statement from your version. */ package javax.swing.plaf.metal; import java.awt.Color; +import java.awt.Component; +import java.awt.Container; import java.awt.Dimension; import java.awt.Graphics; +import java.awt.LayoutManager; +import java.awt.Point; +import javax.swing.JSplitPane; +import javax.swing.SwingConstants; +import javax.swing.plaf.basic.BasicArrowButton; import javax.swing.plaf.basic.BasicSplitPaneDivider; /** @@ -56,7 +63,13 @@ class MetalSplitPaneDivider extends BasicSplitPaneDivider /** The light color in the pattern. */ Color light; + + /** The JSplitPane the divider is on. */ + JSplitPane splitPane; + /** The split pane orientation. */ + int orientation; + /** * Creates a new instance of MetalSplitPaneDivider. * @@ -65,6 +78,9 @@ class MetalSplitPaneDivider extends BasicSplitPaneDivider public MetalSplitPaneDivider(MetalSplitPaneUI ui, Color light, Color dark) { super(ui); + setLayout(new MetalDividerLayout()); + this.splitPane = super.splitPane; + this.orientation = super.orientation; this.light = light; this.dark = dark; } @@ -76,9 +92,127 @@ class MetalSplitPaneDivider extends BasicSplitPaneDivider */ public void paint(Graphics g) { - //super.paint(g); Dimension s = getSize(); MetalUtils.fillMetalPattern(splitPane, g, 2, 2, s.width - 4, s.height - 4, light, dark); + if (splitPane.isOneTouchExpandable()) + { + ((BasicArrowButton) rightButton).paint(g); + ((BasicArrowButton) leftButton).paint(g); + } + } + + /** + * This helper class acts as the Layout Manager for the divider. + */ + public class MetalDividerLayout implements LayoutManager + { + /** The right button. */ + BasicArrowButton rb; + + /** The left button. */ + BasicArrowButton lb; + + /** + * Creates a new DividerLayout object. + */ + public MetalDividerLayout() + { + // Nothing to do here + } + + /** + * This method is called when a Component is added. + * + * @param string The constraints string. + * @param c The Component to add. + */ + public void addLayoutComponent(String string, Component c) + { + // Nothing to do here, constraints are set depending on + // orientation in layoutContainer + } + + /** + * This method is called to lay out the container. + * + * @param c The container to lay out. + */ + public void layoutContainer(Container c) + { + // The only components we care about setting up are the + // one touch buttons. + if (splitPane.isOneTouchExpandable()) + { + if (c.getComponentCount() == 2) + { + Component c1 = c.getComponent(0); + Component c2 = c.getComponent(1); + if ((c1 instanceof BasicArrowButton) + && (c2 instanceof BasicArrowButton)) + { + lb = ((BasicArrowButton) c1); + rb = ((BasicArrowButton) c2); + } + } + if (rb != null && lb != null) + { + Point p = getLocation(); + lb.setSize(lb.getPreferredSize()); + rb.setSize(rb.getPreferredSize()); + lb.setLocation(p.x, p.y); + + if (orientation == JSplitPane.HORIZONTAL_SPLIT) + { + rb.setDirection(SwingConstants.EAST); + lb.setDirection(SwingConstants.WEST); + rb.setLocation(p.x, p.y + lb.getHeight()); + } + else + { + rb.setDirection(SwingConstants.SOUTH); + lb.setDirection(SwingConstants.NORTH); + rb.setLocation(p.x + lb.getWidth(), p.y); + } + } + } + } + + /** + * This method returns the minimum layout size. + * + * @param c The container to calculate for. + * + * @return The minimum layout size. + */ + public Dimension minimumLayoutSize(Container c) + { + return preferredLayoutSize(c); + } + + /** + * This method returns the preferred layout size. + * + * @param c The container to calculate for. + * + * @return The preferred layout size. + */ + public Dimension preferredLayoutSize(Container c) + { + int dividerSize = getDividerSize(); + return new Dimension(dividerSize, dividerSize); + } + + /** + * This method is called when a component is removed. + * + * @param c The component to remove. + */ + public void removeLayoutComponent(Component c) + { + // Nothing to do here. If buttons are removed + // they will not be layed out when layoutContainer is + // called. + } } } diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalTabbedPaneUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalTabbedPaneUI.java index b1e02c7..c6c46ff 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalTabbedPaneUI.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalTabbedPaneUI.java @@ -38,11 +38,14 @@ exception statement from your version. */ package javax.swing.plaf.metal; +import java.awt.Color; import java.awt.Graphics; import java.awt.LayoutManager; +import java.awt.Rectangle; import javax.swing.JComponent; import javax.swing.JTabbedPane; +import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicTabbedPaneUI; @@ -101,6 +104,29 @@ public class MetalTabbedPaneUI extends BasicTabbedPaneUI } /** + * The minimum tab width. + */ + protected int minTabWidth; + + /** + * The color for the selected tab. + */ + protected Color selectColor; + + /** + * The color for a highlighted selected tab. + */ + protected Color selectHighlight; + + /** + * The background color used for the tab area. + */ + protected Color tabAreaBackground; + + /** The graphics to draw the highlight below the tab. */ + private Graphics hg; + + /** * Constructs a new instance of MetalTabbedPaneUI. */ public MetalTabbedPaneUI() @@ -175,6 +201,16 @@ public class MetalTabbedPaneUI extends BasicTabbedPaneUI protected void paintTopTabBorder(int tabIndex, Graphics g, int x, int y, int w, int h, int btm, int rght, boolean isSelected) { + int currentRun = getRunForTab(tabPane.getTabCount(), tabIndex); + if (shouldFillGap(currentRun, tabIndex, x, y)) + { + g.translate(x, y); + g.setColor(getColorForGap(currentRun, x, y)); + g.fillRect(1, 0, 5, 3); + g.fillRect(1, 3, 2, 2); + g.translate(-x, -y); + } + if (isSelected) { g.setColor(MetalLookAndFeel.getControlHighlight()); @@ -267,6 +303,16 @@ public class MetalTabbedPaneUI extends BasicTabbedPaneUI protected void paintBottomTabBorder(int tabIndex, Graphics g, int x, int y, int w, int h, int btm, int rght, boolean isSelected) { + int currentRun = getRunForTab(tabPane.getTabCount(), tabIndex); + if (shouldFillGap(currentRun, tabIndex, x, y)) + { + g.translate(x, y); + g.setColor(getColorForGap(currentRun, x, y)); + g.fillRect(1, h - 5, 3, 5); + g.fillRect(4, h - 2, 2, 2); + g.translate(-x, -y); + } + if (isSelected) { g.setColor(MetalLookAndFeel.getControlHighlight()); @@ -297,9 +343,16 @@ public class MetalTabbedPaneUI extends BasicTabbedPaneUI int tabIndex, int x, int y, int w, int h, boolean isSelected) { if (isSelected) - g.setColor(MetalLookAndFeel.getControl()); + g.setColor(UIManager.getColor("TabbedPane.selected")); else - g.setColor(MetalLookAndFeel.getControlShadow()); + { + // This is only present in the OceanTheme, so we must check if it + // is actually there + Color background = UIManager.getColor("TabbedPane.unselectedBackground"); + if (background == null) + background = UIManager.getColor("TabbedPane.background"); + g.setColor(background); + } int[] px, py; if (tabPlacement == TOP) { @@ -324,6 +377,8 @@ public class MetalTabbedPaneUI extends BasicTabbedPaneUI else throw new AssertionError("Unrecognised 'tabPlacement' argument."); g.fillPolygon(px, py, 5); + hg = g; + paintHighlightBelowTab(); } /** @@ -342,5 +397,94 @@ public class MetalTabbedPaneUI extends BasicTabbedPaneUI // (which is drawn at the very top for tabPlacement == TOP) return run < this.runCount - 1; } + + /** + * Installs the defaults for this UI. This method calls super.installDefaults + * and then loads the Metal specific defaults for TabbedPane. + */ + protected void installDefaults() + { + super.installDefaults(); + selectColor = UIManager.getColor("TabbedPane.selected"); + selectHighlight = UIManager.getColor("TabbedPane.selectHighlight"); + tabAreaBackground = UIManager.getColor("TabbedPane.tabAreaBackground"); + minTabWidth = 0; + } + /** + * Returns the color for the gap. + * + * @param currentRun - The current run to return the color for + * @param x - The x position of the current run + * @param y - The y position of the current run + * + * @return the color for the gap in the current run. + */ + protected Color getColorForGap(int currentRun, int x, int y) + { + int index = tabForCoordinate(tabPane, x, y); + int selected = tabPane.getSelectedIndex(); + if (selected == index) + return selectColor; + return tabAreaBackground; + } + + /** + * Returns true if the gap should be filled in. + * + * @param currentRun - The current run + * @param tabIndex - The current tab + * @param x - The x position of the tab + * @param y - The y position of the tab + * + * @return true if the gap at the current run should be filled + */ + protected boolean shouldFillGap(int currentRun, int tabIndex, int x, int y) + { + // As far as I can tell, the gap is never filled in. + return false; + } + + /** + * Paints the highlight below the tab, if there is one. + */ + protected void paintHighlightBelowTab() + { + int selected = tabPane.getSelectedIndex(); + int tabPlacement = tabPane.getTabPlacement(); + Rectangle bounds = getTabBounds(tabPane, selected); + + hg.setColor(selectColor); + int x = bounds.x; + int y = bounds.y; + int w = bounds.width; + int h = bounds.height; + + if (tabPlacement == TOP) + hg.fillRect(x, y + h - 2, w, 30); + else if (tabPlacement == LEFT) + hg.fillRect(x + w - 1, y, 20, h); + else if (tabPlacement == BOTTOM) + hg.fillRect(x, y - h + 2, w, 30); + else if (tabPlacement == RIGHT) + hg.fillRect(x - 18, y, 20, h); + else + throw new AssertionError("Unrecognised 'tabPlacement' argument."); + hg = null; + } + + /** + * Returns true if we should rotate the tab runs. + * + * @param tabPlacement - The current tab placement. + * @param selectedRun - The selected run. + * + * @return true if the tab runs should be rotated. + */ + protected boolean shouldRotateTabRuns(int tabPlacement, + int selectedRun) + { + // false because tab runs are not rotated in the MetalLookAndFeel + return false; + } } diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalTextFieldUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalTextFieldUI.java index 6984dae..30738b3 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalTextFieldUI.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalTextFieldUI.java @@ -38,6 +38,8 @@ exception statement from your version. */ package javax.swing.plaf.metal; +import java.beans.PropertyChangeEvent; + import javax.swing.JComponent; import javax.swing.JTextField; import javax.swing.plaf.ComponentUI; @@ -67,4 +69,14 @@ public class MetalTextFieldUI extends BasicTextFieldUI { return new MetalTextFieldUI(); } + + /** + * This method gets called when a bound property is changed on the associated + * JTextComponent. This is a hook which UI implementations may change to + * reflect how the UI displays bound properties of JTextComponent subclasses. + */ + public void propertyChange(PropertyChangeEvent evt) + { + super.propertyChange(evt); + } } diff --git a/libjava/classpath/javax/swing/plaf/metal/MetalToolBarUI.java b/libjava/classpath/javax/swing/plaf/metal/MetalToolBarUI.java index c5ca913..16e22ac 100644 --- a/libjava/classpath/javax/swing/plaf/metal/MetalToolBarUI.java +++ b/libjava/classpath/javax/swing/plaf/metal/MetalToolBarUI.java @@ -38,12 +38,16 @@ exception statement from your version. */ package javax.swing.plaf.metal; +import java.awt.Point; import java.awt.event.ContainerListener; +import java.awt.event.MouseEvent; + import java.beans.PropertyChangeListener; import javax.swing.JComponent; import javax.swing.JToolBar; import javax.swing.border.Border; +import javax.swing.event.MouseInputListener; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicToolBarUI; @@ -158,5 +162,67 @@ public class MetalToolBarUI extends BasicToolBarUI { return MetalBorders.getToolbarButtonBorder(); } - + + /** + * Sets the offset for the window used for dragging the toolbar. + * It is set as long as the window is not null (it has been installed). + */ + protected void setDragOffset(Point p) + { + if (dragWindow != null) + dragWindow.setOffset(p); + } + + /** + * Creates and returns an instance of MetalDockingListener. + * + * @return an instance of MetalDockingListener. + */ + protected MouseInputListener createDockingListener() + { + return new MetalDockingListener(toolBar); + } + + /** + * This is the MouseHandler class that allows the user to drag the JToolBar + * in and out of the parent and dock it if it can. + */ + protected class MetalDockingListener extends BasicToolBarUI.DockingListener + { + /** + * Creates a new DockingListener object. + * + * @param t The JToolBar this DockingListener is being used for. + */ + public MetalDockingListener(JToolBar t) + { + super(t); + } + + /** + * This method is called when the mouse is pressed in the JToolBar. If the + * press doesn't occur in a place where it causes the JToolBar to be + * dragged, it returns. Otherwise, it starts a drag session. + * + * @param e The MouseEvent. + */ + public void mousePressed(MouseEvent e) + { + super.mousePressed(e); + setDragOffset(new Point(e.getX(), e.getY())); + } + + /** + * This method is called when the mouse is dragged. It delegates the drag + * painting to the dragTo method. + * + * @param e The MouseEvent. + */ + public void mouseDragged(MouseEvent e) + { + // Does not do anything differently than dragging + // BasicToolBarUI.DockingListener + super.mouseDragged(e); + } + } } diff --git a/libjava/classpath/javax/swing/plaf/metal/OceanTheme.java b/libjava/classpath/javax/swing/plaf/metal/OceanTheme.java index f1886b1..d1fc4cf 100644 --- a/libjava/classpath/javax/swing/plaf/metal/OceanTheme.java +++ b/libjava/classpath/javax/swing/plaf/metal/OceanTheme.java @@ -238,6 +238,10 @@ public class OceanTheme extends DefaultMetalTheme {new Double(0.3), new Double(0.0), new ColorUIResource(221, 232, 243), new ColorUIResource(Color.WHITE), new ColorUIResource(184, 207, 229)})); + defaults.put("Button.rollover", Boolean.TRUE); + + defaults.put("TabbedPane.selected", new ColorUIResource(200, 221, 242)); + defaults.put("TabbedPane.unselectedBackground", SECONDARY3); } } diff --git a/libjava/classpath/javax/swing/table/DefaultTableCellRenderer.java b/libjava/classpath/javax/swing/table/DefaultTableCellRenderer.java index a187d74..233528c 100644 --- a/libjava/classpath/javax/swing/table/DefaultTableCellRenderer.java +++ b/libjava/classpath/javax/swing/table/DefaultTableCellRenderer.java @@ -181,7 +181,6 @@ public class DefaultTableCellRenderer extends JLabel else setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1)); - setEnabled(table.isEnabled()); setFont(table.getFont()); // If the current background is equal to the table's background, then we diff --git a/libjava/classpath/javax/swing/text/AbstractDocument.java b/libjava/classpath/javax/swing/text/AbstractDocument.java index a324425..c735388 100644 --- a/libjava/classpath/javax/swing/text/AbstractDocument.java +++ b/libjava/classpath/javax/swing/text/AbstractDocument.java @@ -541,6 +541,9 @@ public abstract class AbstractDocument implements Document, Serializable writeLock(); UndoableEdit undo = content.insertString(offset, text); + if (undo != null) + event.addEdit(undo); + insertUpdate(event, attributes); writeUnlock(); @@ -1326,7 +1329,14 @@ public abstract class AbstractDocument implements Document, Serializable */ public Object getAttribute(Object key) { - return attributes.getAttribute(key); + Object result = attributes.getAttribute(key); + if (result == null && element_parent != null) + { + AttributeSet parentSet = element_parent.getAttributes(); + if (parentSet != null) + result = parentSet.getAttribute(key); + } + return result; } /** @@ -1809,6 +1819,12 @@ public abstract class AbstractDocument implements Document, Serializable Hashtable changes; /** + * Indicates if this event has been modified or not. This is used to + * determine if this event is thrown. + */ + boolean modified; + + /** * Creates a new <code>DefaultDocumentEvent</code>. * * @param offset the starting offset of the change @@ -1822,6 +1838,7 @@ public abstract class AbstractDocument implements Document, Serializable this.length = length; this.type = type; changes = new Hashtable(); + modified = false; } /** @@ -1836,6 +1853,7 @@ public abstract class AbstractDocument implements Document, Serializable // XXX - Fully qualify ElementChange to work around gcj bug #2499. if (edit instanceof DocumentEvent.ElementChange) { + modified = true; DocumentEvent.ElementChange elEdit = (DocumentEvent.ElementChange) edit; changes.put(elEdit.getElement(), elEdit); @@ -1896,6 +1914,15 @@ public abstract class AbstractDocument implements Document, Serializable // XXX - Fully qualify ElementChange to work around gcj bug #2499. return (DocumentEvent.ElementChange) changes.get(elem); } + + /** + * Returns a String description of the change event. This returns the + * toString method of the Vector of edits. + */ + public String toString() + { + return edits.toString(); + } } /** diff --git a/libjava/classpath/javax/swing/text/ComponentView.java b/libjava/classpath/javax/swing/text/ComponentView.java index 830dda3..2846f8b 100644 --- a/libjava/classpath/javax/swing/text/ComponentView.java +++ b/libjava/classpath/javax/swing/text/ComponentView.java @@ -264,34 +264,4 @@ public class ComponentView extends View Element el = getElement(); return el.getStartOffset(); } - - /** - * Returns the document position that is (visually) nearest to the given - * document position <code>pos</code> in the given direction <code>d</code>. - * - * @param c the text component - * @param pos the document position - * @param b the bias for <code>pos</code> - * @param d the direction, must be either {@link SwingConstants#NORTH}, - * {@link SwingConstants#SOUTH}, {@link SwingConstants#WEST} or - * {@link SwingConstants#EAST} - * @param biasRet an array of {@link Position.Bias} that can hold at least - * one element, which is filled with the bias of the return position - * on method exit - * - * @return the document position that is (visually) nearest to the given - * document position <code>pos</code> in the given direction - * <code>d</code> - * - * @throws BadLocationException if <code>pos</code> is not a valid offset in - * the document model - */ - public int getNextVisualPositionFrom(JTextComponent c, int pos, - Position.Bias b, int d, - Position.Bias[] biasRet) - throws BadLocationException - { - // FIXME: Implement this method. - throw new AssertionError("Not yet implemented"); - } } diff --git a/libjava/classpath/javax/swing/text/CompositeView.java b/libjava/classpath/javax/swing/text/CompositeView.java index e6c2e4c..cd66452 100644 --- a/libjava/classpath/javax/swing/text/CompositeView.java +++ b/libjava/classpath/javax/swing/text/CompositeView.java @@ -661,34 +661,4 @@ public abstract class CompositeView { return false; } - - /** - * Returns the document position that is (visually) nearest to the given - * document position <code>pos</code> in the given direction <code>d</code>. - * - * @param c the text component - * @param pos the document position - * @param b the bias for <code>pos</code> - * @param d the direction, must be either {@link SwingConstants#NORTH}, - * {@link SwingConstants#SOUTH}, {@link SwingConstants#WEST} or - * {@link SwingConstants#EAST} - * @param biasRet an array of {@link Position.Bias} that can hold at least - * one element, which is filled with the bias of the return position - * on method exit - * - * @return the document position that is (visually) nearest to the given - * document position <code>pos</code> in the given direction - * <code>d</code> - * - * @throws BadLocationException if <code>pos</code> is not a valid offset in - * the document model - */ - public int getNextVisualPositionFrom(JTextComponent c, int pos, - Position.Bias b, int d, - Position.Bias[] biasRet) - throws BadLocationException - { - // TODO: Implement this properly. - throw new AssertionError("Not implemented yet."); - } } diff --git a/libjava/classpath/javax/swing/text/DefaultCaret.java b/libjava/classpath/javax/swing/text/DefaultCaret.java index 3ebeceb..776ef69 100644 --- a/libjava/classpath/javax/swing/text/DefaultCaret.java +++ b/libjava/classpath/javax/swing/text/DefaultCaret.java @@ -1,5 +1,5 @@ /* DefaultCaret.java -- - Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -430,18 +430,45 @@ public class DefaultCaret extends Rectangle */ public void focusGained(FocusEvent event) { - setVisible(true); + setVisible(true); + updateTimerStatus(); } /** * Sets the caret to <code>invisible</code>. - * + * * @param event the <code>FocusEvent</code> */ public void focusLost(FocusEvent event) { if (event.isTemporary() == false) - setVisible(false); + { + setVisible(false); + // Stop the blinker, if running. + if (blinkTimer != null && blinkTimer.isRunning()) + blinkTimer.stop(); + } + } + + /** + * Install (if not present) and start the timer, if the caret must blink. The + * caret does not blink if it is invisible, or the component is disabled or + * not editable. + */ + private void updateTimerStatus() + { + if (textComponent.isEnabled() && textComponent.isEditable()) + { + if (blinkTimer == null) + initBlinkTimer(); + if (!blinkTimer.isRunning()) + blinkTimer.start(); + } + else + { + if (blinkTimer != null) + blinkTimer.stop(); + } } /** @@ -641,8 +668,10 @@ public class DefaultCaret extends Rectangle } catch (BadLocationException e) { - assert false : "Unexpected bad caret location: " + dot; - return; + AssertionError ae; + ae = new AssertionError("Unexpected bad caret location: " + dot); + ae.initCause(e); + throw ae; } if (rect == null) @@ -802,9 +831,12 @@ public class DefaultCaret extends Rectangle public void setDot(int dot) { if (dot >= 0) - { + { + Document doc = textComponent.getDocument(); + if (doc != null) + this.dot = Math.min(dot, doc.getLength()); + this.dot = Math.max(this.dot, 0); this.mark = dot; - this.dot = dot; handleHighlight(); adjustVisibility(this); appear(); @@ -833,13 +865,17 @@ public class DefaultCaret extends Rectangle visible = true; Rectangle area = null; + int dot = getDot(); try { - area = getComponent().modelToView(getDot()); + area = getComponent().modelToView(dot); } - catch (BadLocationException ex) + catch (BadLocationException e) { - assert false : "Unexpected bad caret location: " + getDot(); + AssertionError ae; + ae = new AssertionError("Unexpected bad caret location: " + dot); + ae.initCause(e); + throw ae; } if (area != null) damage(area); @@ -870,26 +906,19 @@ public class DefaultCaret extends Rectangle if (v != visible) { visible = v; - if (visible) - if (textComponent.isEnabled() && textComponent.isEditable()) - { - if (blinkTimer == null) - initBlinkTimer(); - blinkTimer.start(); - } - else - { - if (blinkTimer != null) - blinkTimer.stop(); - } + updateTimerStatus(); Rectangle area = null; + int dot = getDot(); try { - area = getComponent().modelToView(getDot()); + area = getComponent().modelToView(dot); } - catch (BadLocationException ex) + catch (BadLocationException e) { - assert false: "Unexpected bad caret location: " + getDot(); + AssertionError ae; + ae = new AssertionError("Unexpected bad caret location: " + dot); + ae.initCause(e); + throw ae; } if (area != null) damage(area); diff --git a/libjava/classpath/javax/swing/text/DefaultEditorKit.java b/libjava/classpath/javax/swing/text/DefaultEditorKit.java index 3b3fc1f..88094b8 100644 --- a/libjava/classpath/javax/swing/text/DefaultEditorKit.java +++ b/libjava/classpath/javax/swing/text/DefaultEditorKit.java @@ -38,8 +38,10 @@ exception statement from your version. */ package javax.swing.text; +import java.awt.Point; import java.awt.Toolkit; import java.awt.event.ActionEvent; + import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; @@ -112,8 +114,7 @@ public class DefaultEditorKit extends EditorKit */ public void actionPerformed(ActionEvent event) { - // FIXME: Implement me. Tookit.getSystemClipboard should be used - // for that. + getTextComponent(event).copy(); } } @@ -144,8 +145,7 @@ public class DefaultEditorKit extends EditorKit */ public void actionPerformed(ActionEvent event) { - // FIXME: Implement me. Tookit.getSystemClipboard should be used - // for that. + getTextComponent(event).cut(); } } @@ -174,8 +174,7 @@ public class DefaultEditorKit extends EditorKit */ public void actionPerformed(ActionEvent event) { - // FIXME: Implement me. Tookit.getSystemClipboard should be used - // for that. + getTextComponent(event).paste(); } } @@ -216,19 +215,9 @@ public class DefaultEditorKit extends EditorKit return; JTextComponent t = getTextComponent(event); - if (t != null) - { - try - { - t.getDocument().insertString(t.getCaret().getDot(), - event.getActionCommand(), null); - } - catch (BadLocationException be) - { - // FIXME: we're not authorized to throw this.. swallow it? - } - } - } + if (t != null && t.isEnabled() && t.isEditable()) + t.replaceSelection(event.getActionCommand()); + } } /** @@ -309,7 +298,8 @@ public class DefaultEditorKit extends EditorKit */ public void actionPerformed(ActionEvent event) { - // FIXME: Implement this. + JTextComponent t = getTextComponent(event); + t.replaceSelection("\t"); } } @@ -710,6 +700,53 @@ public class DefaultEditorKit extends EditorKit new InsertContentAction(), new InsertTabAction(), new PasteAction(), + new TextAction(beginLineAction) + { + public void actionPerformed(ActionEvent event) + { + JTextComponent t = getTextComponent(event); + try + { + // TODO: There is a more efficent solution, but + // viewToModel doesn't work properly. + Point p = t.modelToView(t.getCaret().getDot()).getLocation(); + int cur = t.getCaretPosition(); + int y = p.y; + while (y == p.y && cur > 0) + y = t.modelToView(--cur).getLocation().y; + if (cur != 0) + cur++; + t.setCaretPosition(cur); + } + catch (BadLocationException ble) + { + // Do nothing here. + } + } + }, + new TextAction(endLineAction) + { + public void actionPerformed(ActionEvent event) + { + JTextComponent t = getTextComponent(event); + try + { + Point p = t.modelToView(t.getCaret().getDot()).getLocation(); + int cur = t.getCaretPosition(); + int y = p.y; + int length = t.getDocument().getLength(); + while (y == p.y && cur < length) + y = t.modelToView(++cur).getLocation().y; + if (cur != length) + cur--; + t.setCaretPosition(cur); + } + catch (BadLocationException ble) + { + // Nothing to do here + } + } + }, new TextAction(deleteNextCharAction) { public void actionPerformed(ActionEvent event) @@ -911,7 +948,7 @@ public class DefaultEditorKit extends EditorKit content.append("\n"); } - document.insertString(offset, content.toString(), + document.insertString(offset, content.substring(0, content.length() - 1), SimpleAttributeSet.EMPTY); } diff --git a/libjava/classpath/javax/swing/text/DefaultFormatter.java b/libjava/classpath/javax/swing/text/DefaultFormatter.java index f9e0f10..493699d 100644 --- a/libjava/classpath/javax/swing/text/DefaultFormatter.java +++ b/libjava/classpath/javax/swing/text/DefaultFormatter.java @@ -400,6 +400,8 @@ public class DefaultFormatter extends JFormattedTextField.AbstractFormatter public String valueToString(Object value) throws ParseException { + if (value == null) + return ""; return value.toString(); } diff --git a/libjava/classpath/javax/swing/text/DefaultFormatterFactory.java b/libjava/classpath/javax/swing/text/DefaultFormatterFactory.java new file mode 100644 index 0000000..84a1676 --- /dev/null +++ b/libjava/classpath/javax/swing/text/DefaultFormatterFactory.java @@ -0,0 +1,280 @@ +/* DefaultFormatterFactory.java -- FIXME: briefly describe file purpose + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.swing.text; + +import java.io.Serializable; + +import javax.swing.JFormattedTextField; +import javax.swing.JFormattedTextField.AbstractFormatter; +import javax.swing.JFormattedTextField.AbstractFormatterFactory; + +/** + * This class is Swing's only concrete implementation of + * JFormattedTextField.AbstractFormatterFactory. It holds several + * formatters and determines the best one to be used based on the + * passed-in value from the text field. + * + * @author Anthony Balkissoon abalkiss at redhat dot com + * @since 1.4 + */ +public class DefaultFormatterFactory extends AbstractFormatterFactory implements + Serializable +{ + /** + * The default formatter. + **/ + AbstractFormatter defaultFormatter; + + /** + * The formatter to use when the JFormattedTextField has focus and either the + * value isn't null or the value is null but no <code>nullFormatter</code> + * has been specified. + */ + AbstractFormatter editFormatter; + + /** + * The formatter to use when the JFormattedTextField doesn't havefocus and + * either the value isn't null or the value is null but no + * <code>nullFormatter</code> has been specified. + */ + AbstractFormatter displayFormatter; + + /** + * The formatter to use when the value of the JFormattedTextField is null. + */ + AbstractFormatter nullFormatter; + + /** + * Creates a DefaultFormatterFactory with no formatters + */ + public DefaultFormatterFactory() + { + // Nothing to be done here. + } + + /** + * Creates a new DefaultFormatterFactory with the specified formatters. + * @param defaultFormat the formatter to use if no other appropriate non-null + * formatted can be found. + */ + public DefaultFormatterFactory(AbstractFormatter defaultFormat) + { + defaultFormatter = defaultFormat; + } + + /** + * Creates a new DefaultFormatterFactory with the specified formatters. + * @param defaultFormat the formatter to use if no other appropriate non-null + * formatted can be found. + * @param displayFormat the formatter to use if the JFormattedTextField + * doesn't have focus and either the value is not null or the value is null + * but no <code>nullFormatter</code> has been specified. + */ + public DefaultFormatterFactory(AbstractFormatter defaultFormat, + AbstractFormatter displayFormat) + { + defaultFormatter = defaultFormat; + displayFormatter = displayFormat; + } + + /** + * Creates a new DefaultFormatterFactory with the specified formatters. + * @param defaultFormat the formatter to use if no other appropriate non-null + * formatted can be found. + * @param displayFormat the formatter to use if the JFormattedTextField + * doesn't have focus and either the value is not null or the value is null + * but no <code>nullFormatter</code> has been specified. + * @param editFormat the formatter to use if the JFormattedTextField has + * focus and either the value is not null or the value is null but not + * <code>nullFormatter</code> has been specified. + */ + public DefaultFormatterFactory(AbstractFormatter defaultFormat, + AbstractFormatter displayFormat, + AbstractFormatter editFormat) + { + defaultFormatter = defaultFormat; + displayFormatter = displayFormat; + editFormatter = editFormat; + } + + /** + * Creates a new DefaultFormatterFactory with the specified formatters. + * @param defaultFormat the formatter to use if no other appropriate non-null + * formatted can be found. + * @param displayFormat the formatter to use if the JFormattedTextField + * doesn't have focus and either the value is not null or the value is null + * but no <code>nullFormatter</code> has been specified. + * @param editFormat the formatter to use if the JFormattedTextField has + * focus and either the value is not null or the value is null but not + * <code>nullFormatter</code> has been specified. + * @param nullFormat the formatter to use when the value of the + * JFormattedTextField is null. + */ + public DefaultFormatterFactory(AbstractFormatter defaultFormat, + AbstractFormatter displayFormat, + AbstractFormatter editFormat, + AbstractFormatter nullFormat) + { + defaultFormatter = defaultFormat; + displayFormatter = displayFormat; + editFormatter = editFormat; + nullFormatter = nullFormat; + } + + /** + * Returns the formatted to be used if no other appropriate non-null + * formatter can be found. + * @return the formatted to be used if no other appropriate non-null + * formatter can be found. + */ + public AbstractFormatter getDefaultFormatter() + { + return defaultFormatter; + } + + /** + * Sets the formatted to be used if no other appropriate non-null formatter + * can be found. + * @param defaultFormatter the formatted to be used if no other appropriate + * non-null formatter can be found. + */ + public void setDefaultFormatter(AbstractFormatter defaultFormatter) + { + this.defaultFormatter = defaultFormatter; + } + + /** + * Gets the <code>displayFormatter</code>. This is the formatter to use if + * the JFormattedTextField is not being edited and either the value is not + * null or the value is null and no <code>nullFormatter<code> has been + * specified. + * @return the formatter to use if + * the JFormattedTextField is not being edited and either the value is not + * null or the value is null and no <code>nullFormatter<code> has been + * specified. + */ + public AbstractFormatter getDisplayFormatter() + { + return displayFormatter; + } + + /** + * Sets the <code>displayFormatter</code>. This is the formatter to use if + * the JFormattedTextField is not being edited and either the value is not + * null or the value is null and no <code>nullFormatter<code> has been + * specified. + * @param displayFormatter the formatter to use. + */ + public void setDisplayFormatter(AbstractFormatter displayFormatter) + { + this.displayFormatter = displayFormatter; + } + + /** + * Gets the <code>editFormatter</code>. This is the formatter to use if the + * JFormattedTextField is being edited and either the value is not null or + * the value is null and no <code>nullFormatter<code> has been specified. + * @return the formatter to use if the JFormattedTextField is being edited + * and the value is not null or the value is null but no nullFormatted has + * been specified. + */ + public AbstractFormatter getEditFormatter() + { + return editFormatter; + } + + /** + * Sets the <code>editFormatter</code>. This is the formatter to use if the + * JFormattedTextField is being edited and either the value is not null or + * the value is null and no <code>nullFormatter<code> has been specified. + * @param editFormatter the formatter to use. + */ + public void setEditFormatter(AbstractFormatter editFormatter) + { + this.editFormatter = editFormatter; + } + + /** + * Gets the formatter to use if the value of the JFormattedTextField is null. + * @return the formatter to use for null values. + */ + public AbstractFormatter getNullFormatter() + { + return nullFormatter; + } + + /** + * Sets the <code>nullFormatter</code>. This is the formatter to use if the + * value of the JFormattedTextField is null. + * @param nullFormatter the formatter to use for null values. + */ + public void setNullFormatter(AbstractFormatter nullFormatter) + { + this.nullFormatter = nullFormatter; + } + + /** + * Returns the appropriate formatter based on the state of + * <code>tf</code>. If <code>tf<code> is null we return null, otherwise + * we return one of the following: + * 1. Returns <code>nullFormatter</code> if <code>tf.getValue()</code> is + * null and <code>nullFormatter</code> is not. + * 2. Returns <code>editFormatter</code> if <code>tf.hasFocus()</code> is + * true and <code>editFormatter</code> is not null. + * 3. Returns <code>displayFormatter</code> if <code>tf.hasFocus()</code> is + * false and <code>displayFormatter</code> is not null. + * 4. Otherwise returns <code>defaultFormatter</code>. + */ + public AbstractFormatter getFormatter(JFormattedTextField tf) + { + if (tf == null) + return null; + + if (tf.getValue() == null && nullFormatter != null) + return nullFormatter; + + if (tf.hasFocus() && editFormatter != null) + return editFormatter; + + if (!tf.hasFocus() && displayFormatter != null) + return displayFormatter; + + return defaultFormatter; + } +} diff --git a/libjava/classpath/javax/swing/text/DefaultStyledDocument.java b/libjava/classpath/javax/swing/text/DefaultStyledDocument.java index eb56bb0..46b8225 100644 --- a/libjava/classpath/javax/swing/text/DefaultStyledDocument.java +++ b/libjava/classpath/javax/swing/text/DefaultStyledDocument.java @@ -42,11 +42,13 @@ import java.awt.Color; import java.awt.Font; import java.io.Serializable; import java.util.Enumeration; +import java.util.Stack; import java.util.Vector; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.event.DocumentEvent; +import javax.swing.event.UndoableEditEvent; import javax.swing.undo.AbstractUndoableEdit; import javax.swing.undo.UndoableEdit; @@ -365,7 +367,6 @@ public class DefaultStyledDocument extends AbstractDocument public String toString() { StringBuilder b = new StringBuilder(); - b.append('<'); switch (type) { case StartTagType: @@ -427,6 +428,29 @@ public class DefaultStyledDocument extends AbstractDocument /** Holds the length of structural changes. */ private int length; + + /** Holds the end offset for structural changes. **/ + private int endOffset; + + /** + * The number of inserted end tags. This is a counter which always gets + * incremented when an end tag is inserted. This is evaluated before + * content insertion to go up the element stack. + */ + private int numEndTags; + + /** + * The number of inserted start tags. This is a counter which always gets + * incremented when an end tag is inserted. This is evaluated before + * content insertion to go up the element stack. + */ + private int numStartTags; + + /** + * The current position in the element tree. This is used for bulk inserts + * using ElementSpecs. + */ + private Stack elementStack; /** * Holds fractured elements during insertion of end and start tags. @@ -450,6 +474,7 @@ public class DefaultStyledDocument extends AbstractDocument public ElementBuffer(Element root) { this.root = root; + elementStack = new Stack(); } /** @@ -463,6 +488,85 @@ public class DefaultStyledDocument extends AbstractDocument } /** + * Updates the element structure of the document in response to removal of + * content. It removes the affected {@link Element}s from the document + * structure. + * + * This method sets some internal parameters and delegates the work + * to {@link #removeUpdate}. + * + * @param offs the offset from which content is remove + * @param len the length of the removed content + * @param ev the document event that records the changes + */ + public void remove(int offs, int len, DefaultDocumentEvent ev) + { + offset = offs; + length = len; + documentEvent = ev; + removeUpdate(); + } + + /** + * Updates the element structure of the document in response to removal of + * content. It removes the affected {@link Element}s from the document + * structure. + */ + protected void removeUpdate() + { + int startParagraph = root.getElementIndex(offset); + int endParagraph = root.getElementIndex(offset + length); + Element[] empty = new Element[0]; + int removeStart = -1; + int removeEnd = -1; + for (int i = startParagraph; i < endParagraph; i++) + { + Element paragraph = root.getElement(i); + int contentStart = paragraph.getElementIndex(offset); + int contentEnd = paragraph.getElementIndex(offset + length); + if (contentStart == paragraph.getStartOffset() + && contentEnd == paragraph.getEndOffset()) + { + // In this case we only need to remove the whole paragraph. We + // do this in one go after this loop and only record the indices + // here. + if (removeStart == -1) + { + removeStart = i; + removeEnd = i; + } + else + removeEnd = i; + } + else + { + // In this case we remove a couple of child elements from this + // paragraph. + int removeLen = contentEnd - contentStart; + Element[] removed = new Element[removeLen]; + for (int j = contentStart; j < contentEnd; j++) + removed[j] = paragraph.getElement(j); + ((BranchElement) paragraph).replace(contentStart, removeLen, + empty); + documentEvent.addEdit(new ElementEdit(paragraph, contentStart, + removed, empty)); + } + } + // Now we remove paragraphs from the root that have been tagged for + // removal. + if (removeStart != -1) + { + int removeLen = removeEnd - removeStart; + Element[] removed = new Element[removeLen]; + for (int i = removeStart; i < removeEnd; i++) + removed[i] = root.getElement(i); + ((BranchElement) root).replace(removeStart, removeLen, empty); + documentEvent.addEdit(new ElementEdit(root, removeStart, removed, + empty)); + } + } + + /** * Modifies the element structure so that the specified interval starts * and ends at an element boundary. Content and paragraph elements * are split and created as necessary. @@ -493,11 +597,50 @@ public class DefaultStyledDocument extends AbstractDocument { // Split up the element at the start offset if necessary. Element el = getCharacterElement(offset); - split(el, offset); + Element[] res = split(el, offset, 0); + BranchElement par = (BranchElement) el.getParentElement(); + if (res[1] != null) + { + int index = par.getElementIndex(offset); + Element[] removed; + Element[] added; + if (res[0] == null) + { + removed = new Element[0]; + added = new Element[]{ res[1] }; + index++; + } + else + { + removed = new Element[]{ el }; + added = new Element[]{ res[0], res[1] }; + } + par.replace(index, removed.length, added); + addEdit(par, index, removed, added); + } int endOffset = offset + length; el = getCharacterElement(endOffset); - split(el, endOffset); + res = split(el, endOffset, 0); + par = (BranchElement) el.getParentElement(); + if (res[1] != null) + { + int index = par.getElementIndex(offset); + Element[] removed; + Element[] added; + if (res[1] == null) + { + removed = new Element[0]; + added = new Element[]{ res[1] }; + } + else + { + removed = new Element[]{ el }; + added = new Element[]{ res[0], res[1] }; + } + par.replace(index, removed.length, added); + addEdit(par, index, removed, added); + } } /** @@ -505,42 +648,96 @@ public class DefaultStyledDocument extends AbstractDocument * * @param el the Element to possibly split * @param offset the offset at which to possibly split + * @param space the amount of space to create between the splitted parts + * + * @return An array of elements which represent the split result. This + * array has two elements, the two parts of the split. The first + * element might be null, which means that the element which should + * be splitted can remain in place. The second element might also + * be null, which means that the offset is already at an element + * boundary and the element doesn't need to be splitted. + * */ - void split(Element el, int offset) + private Element[] split(Element el, int offset, int space) { - if (el instanceof AbstractElement) + // If we are at an element boundary, then return an empty array. + if ((offset == el.getStartOffset() || offset == el.getEndOffset()) + && space == 0 && el.isLeaf()) + return new Element[2]; + + // If the element is an instance of BranchElement, then we recursivly + // call this method to perform the split. + Element[] res = new Element[2]; + if (el instanceof BranchElement) { - AbstractElement ael = (AbstractElement) el; - int startOffset = ael.getStartOffset(); - int endOffset = ael.getEndOffset(); - int len = endOffset - startOffset; - if (startOffset != offset && endOffset != offset) + int index = el.getElementIndex(offset); + Element child = el.getElement(index); + Element[] result = split(child, offset, space); + Element[] removed; + Element[] added; + Element[] newAdded; + + int count = el.getElementCount(); + if (!(result[1] == null)) { - Element paragraph = ael.getParentElement(); - if (paragraph instanceof BranchElement) + // This is the case when we can keep the first element. + if (result[0] == null) { - BranchElement par = (BranchElement) paragraph; - Element child1 = createLeafElement(par, ael, startOffset, - offset); - Element child2 = createLeafElement(par, ael, offset, - endOffset); - int index = par.getElementIndex(startOffset); - Element[] add = new Element[]{ child1, child2 }; - par.replace(index, 1, add); - documentEvent.addEdit(new ElementEdit(par, index, - new Element[]{ el }, - add)); + removed = new Element[count - index - 1]; + newAdded = new Element[count - index - 1]; + added = new Element[]{}; } + // This is the case when we may not keep the first element. else - throw new AssertionError("paragraph elements are expected to " - + "be instances of " - + "javax.swing.text.AbstractDocument.BranchElement"); + { + removed = new Element[count - index]; + newAdded = new Element[count - index]; + added = new Element[]{result[0]}; + } + newAdded[0] = result[1]; + for (int i = index; i < count; i++) + { + Element el2 = el.getElement(i); + int ind = i - count + removed.length; + removed[ind] = el2; + if (ind != 0) + newAdded[ind] = el2; + } + + ((BranchElement) el).replace(index, removed.length, added); + addEdit(el, index, removed, added); + BranchElement newPar = + (BranchElement) createBranchElement(el.getParentElement(), + el.getAttributes()); + newPar.replace(0, 0, newAdded); + res = new Element[]{ null, newPar }; + } + else + { + removed = new Element[count - index]; + for (int i = index; i < count; ++i) + removed[i - index] = el.getElement(i); + added = new Element[0]; + ((BranchElement) el).replace(index, removed.length, + added); + addEdit(el, index, removed, added); + BranchElement newPar = + (BranchElement) createBranchElement(el.getParentElement(), + el.getAttributes()); + newPar.replace(0, 0, removed); + res = new Element[]{ null, newPar }; } } - else - throw new AssertionError("content elements are expected to be " - + "instances of " - + "javax.swing.text.AbstractDocument.AbstractElement"); + else if (el instanceof LeafElement) + { + BranchElement par = (BranchElement) el.getParentElement(); + Element el1 = createLeafElement(par, el.getAttributes(), + el.getStartOffset(), offset); + Element el2 = createLeafElement(par, el.getAttributes(), + offset + space, el.getEndOffset()); + res = new Element[]{ el1, el2 }; + } + return res; } /** @@ -560,9 +757,18 @@ public class DefaultStyledDocument extends AbstractDocument public void insert(int offset, int length, ElementSpec[] data, DefaultDocumentEvent ev) { + if (length == 0) + return; this.offset = offset; this.length = length; + this.endOffset = offset + length; documentEvent = ev; + // Push the root and the paragraph at offset onto the element stack. + elementStack.clear(); + elementStack.push(root); + elementStack.push(root.getElement(root.getElementIndex(offset))); + numEndTags = 0; + numStartTags = 0; insertUpdate(data); } @@ -573,202 +779,348 @@ public class DefaultStyledDocument extends AbstractDocument * {@link #insert}. * * @param data the element specifications for the elements to be inserte - */ + */ protected void insertUpdate(ElementSpec[] data) { + if (data[0].getType() == ElementSpec.EndTagType) + { + // fracture deepest child here + BranchElement paragraph = (BranchElement) elementStack.peek(); + Element curr = paragraph.getParentElement(); + int index = curr.getElementIndex(offset); + while (!curr.isLeaf()) + { + index = curr.getElementIndex(offset); + curr = curr.getElement(index); + } + Element parent = curr.getParentElement(); + Element newEl1 = createLeafElement(parent, + curr.getAttributes(), + curr.getStartOffset(), offset); + Element grandParent = parent.getParentElement(); + BranchElement nextBranch = + (BranchElement) grandParent.getElement + (grandParent.getElementIndex(parent.getEndOffset())); + Element firstLeaf = nextBranch.getElement(0); + while (!firstLeaf.isLeaf()) + { + firstLeaf = firstLeaf.getElement(0); + } + BranchElement parent2 = (BranchElement) firstLeaf.getParentElement(); + Element newEl2 = + createLeafElement(parent2, + firstLeaf.getAttributes(), + offset, firstLeaf.getEndOffset()); + parent2.replace(0, 1, new Element[] { newEl2 }); + + + ((BranchElement) parent). + replace(index, 1, new Element[] { newEl1 }); + } + for (int i = 0; i < data.length; i++) { + BranchElement paragraph = (BranchElement) elementStack.peek(); switch (data[i].getType()) { case ElementSpec.StartTagType: - insertStartTag(data[i]); + switch (data[i].getDirection()) + { + case ElementSpec.JoinFractureDirection: + insertFracture(data[i]); + break; + case ElementSpec.JoinNextDirection: + int index = paragraph.getElementIndex(offset); + elementStack.push(paragraph.getElement(index)); + break; + case ElementSpec.OriginateDirection: + Element current = (Element) elementStack.peek(); + Element newParagraph = + insertParagraph((BranchElement) current, offset); + elementStack.push(newParagraph); + break; + default: + break; + } break; case ElementSpec.EndTagType: - insertEndTag(data[i]); + elementStack.pop(); break; - default: + case ElementSpec.ContentType: insertContentTag(data[i]); break; } } + endEdit(); } /** - * Insert a new paragraph after the paragraph at the current position. - * - * @param tag the element spec that describes the element to be inserted + * Finishes an insertion by possibly evaluating the outstanding start and + * end tags. However, this is only performed if the event has received any + * modifications. + */ + private void endEdit() + { + if (documentEvent.modified) + prepareContentInsertion(); + } + + /** + * Evaluates the number of inserted end tags and performs the corresponding + * structural changes. */ - void insertStartTag(ElementSpec tag) + private void prepareContentInsertion() { - BranchElement root = (BranchElement) getDefaultRootElement(); - int index = root.getElementIndex(offset); - if (index == -1) - index = 0; - - BranchElement newParagraph = - (BranchElement) createBranchElement(root, tag.getAttributes()); - newParagraph.setResolveParent(getStyle(StyleContext.DEFAULT_STYLE)); - - // Add new paragraph into document structure. - Element[] added = new Element[]{newParagraph}; - root.replace(index + 1, 0, added); - ElementEdit edit = new ElementEdit(root, index + 1, new Element[0], - added); - documentEvent.addEdit(edit); - - // Maybe add fractured elements. - if (tag.getDirection() == ElementSpec.JoinFractureDirection) + while (numEndTags > 0) + { + elementStack.pop(); + numEndTags--; + } + + while (numStartTags > 0) { - Element[] newFracture = new Element[fracture.length]; - for (int i = 0; i < fracture.length; i++) + Element current = (Element) elementStack.peek(); + Element newParagraph = + insertParagraph((BranchElement) current, offset); + elementStack.push(newParagraph); + numStartTags--; + } + } + + private Element insertParagraph(BranchElement par, int offset) + { + Element current = par.getElement(par.getElementIndex(offset)); + Element[] res = split(current, offset, 0); + int index = par.getElementIndex(offset); + Element ret; + if (res[1] != null) + { + Element[] removed; + Element[] added; + if (res[0] == null) { - Element oldLeaf = fracture[i]; - Element newLeaf = createLeafElement(newParagraph, - oldLeaf.getAttributes(), - oldLeaf.getStartOffset(), - oldLeaf.getEndOffset()); - newFracture[i] = newLeaf; + removed = new Element[0]; + if (res[1] instanceof BranchElement) + { + added = new Element[]{ res[1] }; + ret = res[1]; + } + else + { + ret = createBranchElement(par, null); + added = new Element[]{ ret, res[1] }; + } + index++; + } + else + { + removed = new Element[]{ current }; + if (res[1] instanceof BranchElement) + { + ret = res[1]; + added = new Element[]{ res[0], res[1] }; + } + else + { + ret = createBranchElement(par, null); + added = new Element[]{ res[0], ret, res[1] }; + } } - newParagraph.replace(0, 0, newFracture); - edit = new ElementEdit(newParagraph, 0, new Element[0], - fracture); - documentEvent.addEdit(edit); - fracture = new Element[0]; + par.replace(index, removed.length, added); + addEdit(par, index, removed, added); } + else + { + ret = createBranchElement(par, null); + Element[] added = new Element[]{ ret }; + par.replace(index, 0, added); + addEdit(par, index, new Element[0], added); + } + return ret; } - + /** - * Inserts an end tag into the document structure. This cuts of the - * current paragraph element, possibly fracturing it's child elements. - * The fractured elements are saved so that they can be joined later - * with a new paragraph element. + * Inserts a fracture into the document structure. + * + * @param tag - the element spec. */ - void insertEndTag(ElementSpec tag) + private void insertFracture(ElementSpec tag) { - BranchElement root = (BranchElement) getDefaultRootElement(); - int parIndex = root.getElementIndex(offset); - BranchElement paragraph = (BranchElement) root.getElement(parIndex); - - int index = paragraph.getElementIndex(offset); - LeafElement content = (LeafElement) paragraph.getElement(index); - // We might have to split the element at offset. - split(content, offset); - index = paragraph.getElementIndex(offset); - - int count = paragraph.getElementCount(); - // Store fractured elements. - fracture = new Element[count - index]; - for (int i = index; i < count; ++i) - fracture[i - index] = paragraph.getElement(i); - - // Delete fractured elements. - paragraph.replace(index, count - index, new Element[0]); - - // Add this action to the document event. - ElementEdit edit = new ElementEdit(paragraph, index, fracture, - new Element[0]); - documentEvent.addEdit(edit); + // This is the parent of the paragraph about to be fractured. We will + // create a new child of this parent. + BranchElement parent = (BranchElement) elementStack.peek(); + int parentIndex = parent.getElementIndex(offset); + + // This is the old paragraph. We must remove all its children that + // occur after offset and move them to a new paragraph. We must + // also recreate its child that occurs at offset to have the proper + // end offset. The remainder of this child will also go in the new + // paragraph. + BranchElement previous = (BranchElement) parent.getElement(parentIndex); + + // This is the new paragraph. + BranchElement newBranch = + (BranchElement) createBranchElement(parent, previous.getAttributes()); + + + // The steps we must take to properly fracture are: + // 1. Recreate the LeafElement at offset to have the correct end offset. + // 2. Create a new LeafElement with the remainder of the LeafElement in + // #1 ==> this is whatever was in that LeafElement to the right of the + // inserted newline. + // 3. Find the paragraph at offset and remove all its children that + // occur _after_ offset. These will be moved to the newly created + // paragraph. + // 4. Move the LeafElement created in #2 and all the LeafElements removed + // in #3 to the newly created paragraph. + // 5. Add the new paragraph to the parent. + int previousIndex = previous.getElementIndex(offset); + int numReplaced = previous.getElementCount() - previousIndex; + Element previousLeaf = previous.getElement(previousIndex); + AttributeSet prevLeafAtts = previous.getAttributes(); + + // This recreates the child at offset to have the proper end offset. + // (Step 1). + Element newPreviousLeaf = + createLeafElement(previous, + prevLeafAtts, previousLeaf.getStartOffset(), + offset); + // This creates the new child, which is the remainder of the old child. + // (Step 2). + + Element firstLeafInNewBranch = + createLeafElement(newBranch, prevLeafAtts, + offset, previousLeaf.getEndOffset()); + + // Now we move the new LeafElement and all the old children that occurred + // after the offset to the new paragraph. (Step 4). + Element[] newLeaves = new Element[numReplaced]; + newLeaves[0] = firstLeafInNewBranch; + for (int i = 1; i < numReplaced; i++) + newLeaves[i] = previous.getElement(previousIndex + i); + newBranch.replace(0, 0, newLeaves); + addEdit(newBranch, 0, null, newLeaves); + + // Now we remove the children after the offset from the previous + // paragraph. (Step 3). + int removeSize = previous.getElementCount() - previousIndex; + Element[] add = new Element[] { newPreviousLeaf }; + Element[] remove = new Element[removeSize]; + for (int j = 0; j < removeSize; j++) + remove[j] = previous.getElement(previousIndex + j); + previous.replace(previousIndex, removeSize, add); + addEdit(previous, previousIndex, remove, add); + + // Finally we add the new paragraph to the parent. (Step 5). + Element[] nb = new Element[] { newBranch }; + int index = parentIndex + 1; + parent.replace(index, 0, nb); + addEdit(parent, index, null, nb); } - + /** * Inserts a content element into the document structure. - * + * * @param tag the element spec */ - void insertContentTag(ElementSpec tag) + private void insertContentTag(ElementSpec tag) { + prepareContentInsertion(); int len = tag.getLength(); int dir = tag.getDirection(); + AttributeSet tagAtts = tag.getAttributes(); if (dir == ElementSpec.JoinPreviousDirection) { - Element prev = getCharacterElement(offset); - BranchElement prevParent = (BranchElement) prev.getParentElement(); - Element join = createLeafElement(prevParent, tag.getAttributes(), - prev.getStartOffset(), - Math.max(prev.getEndOffset(), - offset + len)); - int ind = prevParent.getElementIndex(offset); - if (ind == -1) - ind = 0; - Element[] add = new Element[]{join}; - prevParent.replace(ind, 1, add); - - // Add this action to the document event. - ElementEdit edit = new ElementEdit(prevParent, ind, - new Element[]{prev}, add); - documentEvent.addEdit(edit); + // The mauve tests to this class show that a JoinPrevious insertion + // does not add any edits to the document event. To me this means + // that nothing is done here. The previous element naturally should + // expand so that it covers the new characters. } else if (dir == ElementSpec.JoinNextDirection) { - Element next = getCharacterElement(offset + len); - BranchElement nextParent = (BranchElement) next.getParentElement(); - Element join = createLeafElement(nextParent, tag.getAttributes(), - offset, - next.getEndOffset()); - int ind = nextParent.getElementIndex(offset + len); - if (ind == -1) - ind = 0; - Element[] add = new Element[]{join}; - nextParent.replace(ind, 1, add); - - // Add this action to the document event. - ElementEdit edit = new ElementEdit(nextParent, ind, - new Element[]{next}, add); - documentEvent.addEdit(edit); + // FIXME: + // Have to handle JoinNext differently depending on whether + // or not it comes after a fracture. If comes after a fracture, + // the insertFracture method takes care of everything and nothing + // needs to be done here. Otherwise, we need to adjust the + // Element structure. For now, I check if the elementStack's + // top Element is the immediate parent of the LeafElement at + // offset - if so, we did not come immediately after a + // fracture. This seems awkward and should probably be improved. + // We may be doing too much in insertFracture because we are + // adjusting the offsets, the correct thing to do may be to + // create a new branch element and push it on to element stack + // and then this method here can be more general. + + BranchElement paragraph = (BranchElement) elementStack.peek(); + int index = paragraph.getElementIndex(offset); + Element target = paragraph.getElement(index); + if (target.isLeaf() && paragraph.getElementCount() > (index + 1)) + { + Element next = paragraph.getElement(index + 1); + Element newEl1 = createLeafElement(paragraph, + target.getAttributes(), + target.getStartOffset(), + offset); + Element newEl2 = createLeafElement(paragraph, + next.getAttributes(), offset, + next.getEndOffset()); + Element[] add = new Element[] { newEl1, newEl2 }; + paragraph.replace (index, 2, add); + addEdit(paragraph, index, new Element[] { target, next }, add); + } } - else + else if (dir == ElementSpec.OriginateDirection) { - BranchElement par = (BranchElement) getParagraphElement(offset); - - int ind = par.getElementIndex(offset); - - // Make room for the element. - // Cut previous element. - Element prev = par.getElement(ind); - if (prev != null && prev.getStartOffset() < offset) + BranchElement paragraph = (BranchElement) elementStack.peek(); + int index = paragraph.getElementIndex(offset); + Element current = paragraph.getElement(index); + + Element[] added; + Element[] removed = new Element[] {current}; + Element[] splitRes = split(current, offset, length); + if (splitRes[0] == null) { - Element cutPrev = createLeafElement(par, prev.getAttributes(), - prev.getStartOffset(), - offset); - Element[] remove = new Element[]{prev}; - Element[] add = new Element[]{cutPrev}; - if (prev.getEndOffset() > offset + len) - { - Element rem = createLeafElement(par, prev.getAttributes(), - offset + len, - prev.getEndOffset()); - add = new Element[]{cutPrev, rem}; - } - - par.replace(ind, 1, add); - documentEvent.addEdit(new ElementEdit(par, ind, remove, add)); - ind++; + added = new Element[2]; + added[0] = createLeafElement(paragraph, tagAtts, + offset, endOffset); + added[1] = splitRes[1]; + removed = new Element[0]; + index++; } - // ind now points to the next element. - - // Cut next element if necessary. - Element next = par.getElement(ind); - if (next != null && next.getStartOffset() < offset + len) + else if (current.getStartOffset() == offset) + { + // This is if the new insertion happens immediately before + // the <code>current</code> Element. In this case there are 2 + // resulting Elements. + added = new Element[2]; + added[0] = createLeafElement(paragraph, tagAtts, offset, + endOffset); + added[1] = splitRes[1]; + } + else if (current.getEndOffset() == endOffset) { - Element cutNext = createLeafElement(par, next.getAttributes(), - offset + len, - next.getEndOffset()); - Element[] remove = new Element[]{next}; - Element[] add = new Element[]{cutNext}; - par.replace(ind, 1, add); - documentEvent.addEdit(new ElementEdit(par, ind, remove, - add)); + // This is if the new insertion happens right at the end of + // the <code>current</code> Element. In this case there are + // 2 resulting Elements. + added = new Element[2]; + added[0] = splitRes[0]; + added[1] = createLeafElement(paragraph, tagAtts, offset, + endOffset); } - - // Insert new element. - Element newEl = createLeafElement(par, tag.getAttributes(), - offset, offset + len); - Element[] added = new Element[]{newEl}; - par.replace(ind, 0, added); - // Add this action to the document event. - ElementEdit edit = new ElementEdit(par, ind, new Element[0], - added); - documentEvent.addEdit(edit); + else + { + // This is if the new insertion is in the middle of the + // <code>current</code> Element. In this case + // there will be 3 resulting Elements. + added = new Element[3]; + added[0] = splitRes[0]; + added[1] = createLeafElement(paragraph, tagAtts, offset, + endOffset); + added[2] = splitRes[1]; + } + paragraph.replace(index, removed.length, added); + addEdit(paragraph, index, removed, added); } offset += len; } @@ -800,6 +1152,79 @@ public class DefaultStyledDocument extends AbstractDocument result.replace(0, 0, children); return result; } + + /** + * Adds an ElementChange for a given element modification to the document + * event. If there already is an ElementChange registered for this element, + * this method tries to merge the ElementChanges together. However, this + * is only possible if the indices of the new and old ElementChange are + * equal. + * + * @param e the element + * @param i the index of the change + * @param removed the removed elements, or <code>null</code> + * @param added the added elements, or <code>null</code> + */ + private void addEdit(Element e, int i, Element[] removed, Element[] added) + { + // Perform sanity check first. + DocumentEvent.ElementChange ec = documentEvent.getChange(e); + + // Merge the existing stuff with the new stuff. + Element[] oldAdded = ec == null ? null: ec.getChildrenAdded(); + Element[] newAdded; + if (oldAdded != null && added != null) + { + if (ec.getIndex() <= i) + { + int index = i - ec.getIndex(); + // Merge adds together. + newAdded = new Element[oldAdded.length + added.length]; + System.arraycopy(oldAdded, 0, newAdded, 0, index); + System.arraycopy(added, 0, newAdded, index, added.length); + System.arraycopy(oldAdded, index, newAdded, index + added.length, + oldAdded.length - index); + i = ec.getIndex(); + } + else + throw new AssertionError("Not yet implemented case."); + } + else if (added != null) + newAdded = added; + else if (oldAdded != null) + newAdded = oldAdded; + else + newAdded = new Element[0]; + + Element[] oldRemoved = ec == null ? null: ec.getChildrenRemoved(); + Element[] newRemoved; + if (oldRemoved != null && removed != null) + { + if (ec.getIndex() <= i) + { + int index = i - ec.getIndex(); + // Merge removes together. + newRemoved = new Element[oldRemoved.length + removed.length]; + System.arraycopy(oldAdded, 0, newRemoved, 0, index); + System.arraycopy(removed, 0, newRemoved, index, removed.length); + System.arraycopy(oldRemoved, index, newRemoved, + index + removed.length, + oldRemoved.length - index); + i = ec.getIndex(); + } + else + throw new AssertionError("Not yet implemented case."); + } + else if (removed != null) + newRemoved = removed; + else if (oldRemoved != null) + newRemoved = oldRemoved; + else + newRemoved = new Element[0]; + + // Replace the existing edit for the element with the merged. + documentEvent.addEdit(new ElementEdit(e, i, newRemoved, newAdded)); + } } /** @@ -824,7 +1249,7 @@ public class DefaultStyledDocument extends AbstractDocument */ public String getName() { - return "section"; + return SectionElementName; } } @@ -945,9 +1370,7 @@ public class DefaultStyledDocument extends AbstractDocument // Use createBranchElement() and createLeafElement instead. SectionElement section = new SectionElement(); - BranchElement paragraph = - (BranchElement) createBranchElement(section, null); - paragraph.setResolveParent(getStyle(StyleContext.DEFAULT_STYLE)); + BranchElement paragraph = new BranchElement(section, null); tmp = new Element[1]; tmp[0] = paragraph; section.replace(0, 0, tmp); @@ -1043,7 +1466,11 @@ public class DefaultStyledDocument extends AbstractDocument { Element paragraph = getParagraphElement(position); AttributeSet attributes = paragraph.getAttributes(); - return (Style) attributes.getResolveParent(); + AttributeSet a = attributes.getResolveParent(); + // If the resolve parent is not of type Style, we return null. + if (a instanceof Style) + return (Style) a; + return null; } /** @@ -1112,50 +1539,54 @@ public class DefaultStyledDocument extends AbstractDocument AttributeSet attributes, boolean replace) { - DefaultDocumentEvent ev = - new DefaultDocumentEvent(offset, length, - DocumentEvent.EventType.CHANGE); - - // Modify the element structure so that the interval begins at an element - // start and ends at an element end. - buffer.change(offset, length, ev); - - Element root = getDefaultRootElement(); - // Visit all paragraph elements within the specified interval - int paragraphCount = root.getElementCount(); - for (int pindex = 0; pindex < paragraphCount; pindex++) + // Exit early if length is 0, so no DocumentEvent is created or fired. + if (length == 0) + return; + try { - Element paragraph = root.getElement(pindex); - // Skip paragraphs that lie outside the interval. - if ((paragraph.getStartOffset() > offset + length) - || (paragraph.getEndOffset() < offset)) - continue; - - // Visit content elements within this paragraph - int contentCount = paragraph.getElementCount(); - for (int cindex = 0; cindex < contentCount; cindex++) + // Must obtain a write lock for this method. writeLock() and + // writeUnlock() should always be in try/finally block to make + // sure that locking happens in a balanced manner. + writeLock(); + DefaultDocumentEvent ev = + new DefaultDocumentEvent( + offset, + length, + DocumentEvent.EventType.CHANGE); + + // Modify the element structure so that the interval begins at an + // element + // start and ends at an element end. + buffer.change(offset, length, ev); + + Element root = getDefaultRootElement(); + // Visit all paragraph elements within the specified interval + int end = offset + length; + Element curr; + for (int pos = offset; pos < end; ) { - Element content = paragraph.getElement(cindex); - // Skip content that lies outside the interval. - if ((content.getStartOffset() > offset + length) - || (content.getEndOffset() < offset)) - continue; - - if (content instanceof AbstractElement) - { - AbstractElement el = (AbstractElement) content; - if (replace) - el.removeAttributes(el); - el.addAttributes(attributes); - } - else - throw new AssertionError("content elements are expected to be" - + "instances of " - + "javax.swing.text.AbstractDocument.AbstractElement"); + // Get the CharacterElement at offset pos. + curr = getCharacterElement(pos); + if (pos == curr.getEndOffset()) + break; + + MutableAttributeSet a = (MutableAttributeSet) curr.getAttributes(); + ev.addEdit(new AttributeUndoableEdit(curr, attributes, replace)); + // If replace is true, remove all the old attributes. + if (replace) + a.removeAttributes(a); + // Add all the new attributes. + a.addAttributes(attributes); + // Increment pos so we can check the next CharacterElement. + pos = curr.getEndOffset(); } + fireChangedUpdate(ev); + fireUndoableEditUpdate(new UndoableEditEvent(this, ev)); + } + finally + { + writeUnlock(); } - - fireChangedUpdate(ev); } /** @@ -1167,14 +1598,36 @@ public class DefaultStyledDocument extends AbstractDocument public void setLogicalStyle(int position, Style style) { Element el = getParagraphElement(position); - if (el instanceof AbstractElement) - { - AbstractElement ael = (AbstractElement) el; - ael.setResolveParent(style); - } - else - throw new AssertionError("paragraph elements are expected to be" - + "instances of javax.swing.text.AbstractDocument.AbstractElement"); + // getParagraphElement doesn't return null but subclasses might so + // we check for null here. + if (el == null) + return; + try + { + writeLock(); + if (el instanceof AbstractElement) + { + AbstractElement ael = (AbstractElement) el; + ael.setResolveParent(style); + int start = el.getStartOffset(); + int end = el.getEndOffset(); + DefaultDocumentEvent ev = + new DefaultDocumentEvent ( + start, + end - start, + DocumentEvent.EventType.CHANGE); + // FIXME: Add an UndoableEdit to this event and fire it. + fireChangedUpdate(ev); + } + else + throw new + AssertionError("paragraph elements are expected to be" + + "instances of AbstractDocument.AbstractElement"); + } + finally + { + writeUnlock(); + } } /** @@ -1190,15 +1643,47 @@ public class DefaultStyledDocument extends AbstractDocument AttributeSet attributes, boolean replace) { - int index = offset; - while (index < offset + length) + try + { + // Must obtain a write lock for this method. writeLock() and + // writeUnlock() should always be in try/finally blocks to make + // sure that locking occurs in a balanced manner. + writeLock(); + + // Create a DocumentEvent to use for changedUpdate(). + DefaultDocumentEvent ev = + new DefaultDocumentEvent ( + offset, + length, + DocumentEvent.EventType.CHANGE); + + // Have to iterate through all the _paragraph_ elements that are + // contained or partially contained in the interval + // (offset, offset + length). + Element rootElement = getDefaultRootElement(); + int startElement = rootElement.getElementIndex(offset); + int endElement = rootElement.getElementIndex(offset + length - 1); + if (endElement < startElement) + endElement = startElement; + + for (int i = startElement; i <= endElement; i++) + { + Element par = rootElement.getElement(i); + MutableAttributeSet a = (MutableAttributeSet) par.getAttributes(); + // Add the change to the DocumentEvent. + ev.addEdit(new AttributeUndoableEdit(par, attributes, replace)); + // If replace is true remove the old attributes. + if (replace) + a.removeAttributes(a); + // Add the new attributes. + a.addAttributes(attributes); + } + fireChangedUpdate(ev); + fireUndoableEditUpdate(new UndoableEditEvent(this, ev)); + } + finally { - AbstractElement par = (AbstractElement) getParagraphElement(index); - AttributeContext ctx = getAttributeContext(); - if (replace) - par.removeAttributes(par); - par.addAttributes(attributes); - index = par.getElementCount(); + writeUnlock(); } } @@ -1212,9 +1697,14 @@ public class DefaultStyledDocument extends AbstractDocument protected void insertUpdate(DefaultDocumentEvent ev, AttributeSet attr) { super.insertUpdate(ev, attr); + // If the attribute set is null, use an empty attribute set. + if (attr == null) + attr = SimpleAttributeSet.EMPTY; int offset = ev.getOffset(); int length = ev.getLength(); int endOffset = offset + length; + AttributeSet paragraphAttributes = + getParagraphElement(endOffset).getAttributes(); Segment txt = new Segment(); try { @@ -1229,66 +1719,141 @@ public class DefaultStyledDocument extends AbstractDocument int len = 0; Vector specs = new Vector(); - + ElementSpec finalStartTag = null; + short finalStartDirection = ElementSpec.OriginateDirection; + boolean prevCharWasNewline = false; Element prev = getCharacterElement(offset); - Element next = getCharacterElement(endOffset); + Element next = getCharacterElement(endOffset); + Element prevParagraph = getParagraphElement(offset); + Element paragraph = getParagraphElement(endOffset); + + int segmentEnd = txt.offset + txt.count; + + // Check to see if we're inserting immediately after a newline. + if (offset > 0) + { + try + { + String s = getText(offset - 1, 1); + if (s.equals("\n")) + { + finalStartDirection = + handleInsertAfterNewline(specs, offset, endOffset, + prevParagraph, + paragraph, + paragraphAttributes); + + prevCharWasNewline = true; + // Find the final start tag from the ones just created. + for (int i = 0; i < specs.size(); i++) + if (((ElementSpec) specs.get(i)).getType() + == ElementSpec.StartTagType) + finalStartTag = (ElementSpec)specs.get(i); + } + } + catch (BadLocationException ble) + { + // This shouldn't happen. + AssertionError ae = new AssertionError(); + ae.initCause(ble); + throw ae; + } + } - for (int i = offset; i < endOffset; ++i) + + for (int i = txt.offset; i < segmentEnd; ++i) { len++; if (txt.array[i] == '\n') { - ElementSpec spec = new ElementSpec(attr, ElementSpec.ContentType, - len); - - // If we are at the last index, then check if we could probably be - // joined with the next element. - if (i == endOffset - 1) - { - if (next.getAttributes().isEqual(attr)) - spec.setDirection(ElementSpec.JoinNextDirection); - } - // If we are at the first new element, then check if it could be - // joined with the previous element. - else if (specs.size() == 0) - { - if (prev.getAttributes().isEqual(attr)) - spec.setDirection(ElementSpec.JoinPreviousDirection); - } - - specs.add(spec); + // Add the ElementSpec for the content. + specs.add(new ElementSpec(attr, ElementSpec.ContentType, len)); // Add ElementSpecs for the newline. - ElementSpec endTag = new ElementSpec(null, ElementSpec.EndTagType); - specs.add(endTag); - ElementSpec startTag = new ElementSpec(null, + specs.add(new ElementSpec(null, ElementSpec.EndTagType)); + finalStartTag = new ElementSpec(paragraphAttributes, ElementSpec.StartTagType); - startTag.setDirection(ElementSpec.JoinFractureDirection); - specs.add(startTag); - + specs.add(finalStartTag); len = 0; - offset += len; } } // Create last element if last character hasn't been a newline. - if (len > 0) + if (len > 0) + specs.add(new ElementSpec(attr, ElementSpec.ContentType, len)); + + // Set the direction of the last spec of type StartTagType. + // If we are inserting after a newline then this value comes from + // handleInsertAfterNewline. + if (finalStartTag != null) + { + if (prevCharWasNewline) + finalStartTag.setDirection(finalStartDirection); + else if (prevParagraph.getEndOffset() != endOffset) + { + try + { + String last = getText(endOffset - 1, 1); + if (!last.equals("\n")) + finalStartTag.setDirection(ElementSpec.JoinFractureDirection); + } + catch (BadLocationException ble) + { + // This shouldn't happen. + AssertionError ae = new AssertionError(); + ae.initCause(ble); + throw ae; + } + } + else + { + // If there is an element AFTER this one, then set the + // direction to JoinNextDirection. + Element parent = prevParagraph.getParentElement(); + int index = parent.getElementIndex(offset); + if (index + 1 < parent.getElementCount() + && !parent.getElement(index + 1).isLeaf()) + finalStartTag.setDirection(ElementSpec.JoinNextDirection); + } + } + + // If we are at the last index, then check if we could probably be + // joined with the next element. + // This means: + // - we must be a ContentTag + // - if there is a next Element, we must have the same attributes + // - if there is no next Element, but one will be created, + // we must have the same attributes as the higher-level run. + ElementSpec last = (ElementSpec) specs.lastElement(); + if (last.getType() == ElementSpec.ContentType) { - ElementSpec spec = new ElementSpec(attr, ElementSpec.ContentType, len); - // If we are at the first new element, then check if it could be - // joined with the previous element. - if (specs.size() == 0) + Element currentRun = + prevParagraph.getElement(prevParagraph.getElementIndex(offset)); + if (currentRun.getEndOffset() == endOffset) { - if (prev.getAttributes().isEqual(attr)) - spec.setDirection(ElementSpec.JoinPreviousDirection); + if (endOffset < getLength() && next.getAttributes().isEqual(attr) + && last.getType() == ElementSpec.ContentType) + last.setDirection(ElementSpec.JoinNextDirection); + } + else + { + if (finalStartTag != null + && finalStartTag.getDirection() == + ElementSpec.JoinFractureDirection + && currentRun.getAttributes().isEqual(attr)) + { + last.setDirection(ElementSpec.JoinNextDirection); + } } - // Check if we could probably be joined with the next element. - else if (next.getAttributes().isEqual(attr)) - spec.setDirection(ElementSpec.JoinNextDirection); - - specs.add(spec); } - + + // If we are at the first new element, then check if it could be + // joined with the previous element. + ElementSpec first = (ElementSpec) specs.firstElement(); + if (prev.getAttributes().isEqual(attr) + && first.getType() == ElementSpec.ContentType) + first.setDirection(ElementSpec.JoinPreviousDirection); + ElementSpec[] elSpecs = (ElementSpec[]) specs.toArray(new ElementSpec[specs.size()]); @@ -1296,6 +1861,47 @@ public class DefaultStyledDocument extends AbstractDocument } /** + * A helper method to set up the ElementSpec buffer for the special + * case of an insertion occurring immediately after a newline. + * @param specs the ElementSpec buffer to initialize. + */ + short handleInsertAfterNewline(Vector specs, int offset, int endOffset, + Element prevParagraph, Element paragraph, + AttributeSet a) + { + if (prevParagraph.getParentElement() == paragraph.getParentElement()) + { + specs.add(new ElementSpec(a, ElementSpec.EndTagType)); + specs.add(new ElementSpec(a, ElementSpec.StartTagType)); + if (prevParagraph.getEndOffset() != endOffset) + return ElementSpec.JoinFractureDirection; + // If there is an Element after this one, use JoinNextDirection. + Element parent = paragraph.getParentElement(); + if (parent.getElementCount() > parent.getElementIndex(offset) + 1) + return ElementSpec.JoinNextDirection; + } + else + { + // TODO: What to do here? + } + return ElementSpec.OriginateDirection; + } + + /** + * Updates the document structure in response to text removal. This is + * forwarded to the {@link ElementBuffer} of this document. Any changes to + * the document structure are added to the specified document event and + * sent to registered listeners. + * + * @param ev the document event that records the changes to the document + */ + protected void removeUpdate(DefaultDocumentEvent ev) + { + super.removeUpdate(ev); + buffer.remove(ev.getOffset(), ev.getLength(), ev); + } + + /** * Returns an enumeration of all style names. * * @return an enumeration of all style names @@ -1316,6 +1922,35 @@ public class DefaultStyledDocument extends AbstractDocument // Nothing to do here. This is intended to be overridden by subclasses. } + void printElements (Element start, int pad) + { + for (int i = 0; i < pad; i++) + System.out.print(" "); + if (pad == 0) + System.out.println ("ROOT ELEMENT ("+start.getStartOffset()+", "+start.getEndOffset()+")"); + else if (start instanceof AbstractDocument.BranchElement) + System.out.println ("BranchElement ("+start.getStartOffset()+", "+start.getEndOffset()+")"); + else + { + { + try + { + System.out.println ("LeafElement ("+start.getStartOffset()+", " + + start.getEndOffset()+"): "+ + start.getDocument(). + getText(start.getStartOffset(), + start.getEndOffset() - + start.getStartOffset())); + } + catch (BadLocationException ble) + { + } + } + } + for (int i = 0; i < start.getElementCount(); i ++) + printElements (start.getElement(i), pad+3); + } + /** * Inserts a bulk of structured content at once. * @@ -1325,36 +1960,53 @@ public class DefaultStyledDocument extends AbstractDocument protected void insert(int offset, ElementSpec[] data) throws BadLocationException { - writeLock(); - // First we insert the content. - int index = offset; - for (int i = 0; i < data.length; i++) + if (data == null || data.length == 0) + return; + try { - ElementSpec spec = data[i]; - if (spec.getArray() != null && spec.getLength() > 0) + // writeLock() and writeUnlock() should always be in a try/finally + // block so that locking balance is guaranteed even if some + // exception is thrown. + writeLock(); + + // First we collect the content to be inserted. + StringBuffer contentBuffer = new StringBuffer(); + for (int i = 0; i < data.length; i++) { - String insertString = new String(spec.getArray(), spec.getOffset(), - spec.getLength()); - content.insertString(index, insertString); + // Collect all inserts into one so we can get the correct + // ElementEdit + ElementSpec spec = data[i]; + if (spec.getArray() != null && spec.getLength() > 0) + contentBuffer.append(spec.getArray(), spec.getOffset(), + spec.getLength()); } - index += spec.getLength(); + + int length = contentBuffer.length(); + + // If there was no content inserted then exit early. + if (length == 0) + return; + + UndoableEdit edit = content.insertString(offset, + contentBuffer.toString()); + + // Create the DocumentEvent with the ElementEdit added + DefaultDocumentEvent ev = + new DefaultDocumentEvent(offset, + length, + DocumentEvent.EventType.INSERT); + ev.addEdit(edit); + + // Finally we must update the document structure and fire the insert + // update event. + buffer.insert(offset, length, data, ev); + fireInsertUpdate(ev); + fireUndoableEditUpdate(new UndoableEditEvent(this, ev)); } - // Update the view structure. - DefaultDocumentEvent ev = new DefaultDocumentEvent(offset, index - offset, - DocumentEvent.EventType.INSERT); - for (int i = 0; i < data.length; i++) + finally { - ElementSpec spec = data[i]; - AttributeSet atts = spec.getAttributes(); - if (atts != null) - insertUpdate(ev, atts); + writeUnlock(); } - - // Finally we must update the document structure and fire the insert update - // event. - buffer.insert(offset, index - offset, data, ev); - fireInsertUpdate(ev); - writeUnlock(); } /** @@ -1382,4 +2034,9 @@ public class DefaultStyledDocument extends AbstractDocument throw err; } } + + static boolean attributeSetsAreSame (AttributeSet a, AttributeSet b) + { + return (a == null && b == null) || (a != null && a.isEqual(b)); + } } diff --git a/libjava/classpath/javax/swing/text/FlowView.java b/libjava/classpath/javax/swing/text/FlowView.java index 765f515..6d4b9cd 100644 --- a/libjava/classpath/javax/swing/text/FlowView.java +++ b/libjava/classpath/javax/swing/text/FlowView.java @@ -396,37 +396,6 @@ public abstract class FlowView extends BoxView throw new AssertionError("This method must not be called in " + "LogicalView."); } - - /** - * Returns the document position that is (visually) nearest to the given - * document position <code>pos</code> in the given direction <code>d</code>. - * - * @param c the text component - * @param pos the document position - * @param b the bias for <code>pos</code> - * @param d the direction, must be either {@link SwingConstants#NORTH}, - * {@link SwingConstants#SOUTH}, {@link SwingConstants#WEST} or - * {@link SwingConstants#EAST} - * @param biasRet an array of {@link Position.Bias} that can hold at least - * one element, which is filled with the bias of the return position - * on method exit - * - * @return the document position that is (visually) nearest to the given - * document position <code>pos</code> in the given direction - * <code>d</code> - * - * @throws BadLocationException if <code>pos</code> is not a valid offset in - * the document model - */ - public int getNextVisualPositionFrom(JTextComponent c, int pos, - Position.Bias b, int d, - Position.Bias[] biasRet) - throws BadLocationException - { - assert false : "getNextVisualPositionFrom() must not be called in " - + "LogicalView"; - return 0; - } } /** diff --git a/libjava/classpath/javax/swing/text/GapContent.java b/libjava/classpath/javax/swing/text/GapContent.java index 4c65de0..80dcfa5 100644 --- a/libjava/classpath/javax/swing/text/GapContent.java +++ b/libjava/classpath/javax/swing/text/GapContent.java @@ -64,6 +64,7 @@ import javax.swing.undo.UndoableEdit; public class GapContent implements AbstractDocument.Content, Serializable { + /** * A {@link Position} implementation for <code>GapContent</code>. */ @@ -100,15 +101,15 @@ public class GapContent public int compareTo(Object o) { if (o instanceof Integer) - { - int otherMark = ((Integer) o).intValue(); - return mark - otherMark; - } + { + int otherMark = ((Integer) o).intValue(); + return mark - otherMark; + } else - { - GapContentPosition other = (GapContentPosition) o; - return mark - other.mark; - } + { + GapContentPosition other = (GapContentPosition) o; + return mark - other.mark; + } } /** @@ -122,7 +123,6 @@ public class GapContent assert mark <= gapStart || mark >= gapEnd : "mark: " + mark + ", gapStart: " + gapStart + ", gapEnd: " + gapEnd; - if (mark <= gapStart) return mark; else @@ -130,11 +130,11 @@ public class GapContent } } - class UndoInsertString extends AbstractUndoableEdit + class InsertUndo extends AbstractUndoableEdit { public int where, length; String text; - public UndoInsertString(int start, int len) + public InsertUndo(int start, int len) { where = start; length = len; @@ -316,7 +316,7 @@ public class GapContent replace(where, 0, str.toCharArray(), strLen); - return new UndoInsertString(where, strLen); + return new InsertUndo(where, strLen); } /** @@ -449,7 +449,7 @@ public class GapContent // We store the actual array index in the GapContentPosition. The real // offset is then calculated in the GapContentPosition. int mark = offset; - if (offset > gapStart) + if (offset >= gapStart) mark += gapEnd - gapStart; GapContentPosition pos = new GapContentPosition(mark); @@ -584,8 +584,9 @@ public class GapContent { if (gapStart != position) shiftGap(position); + // Remove content - if (rmSize > 0) + if (rmSize > 0) shiftGapEndUp(gapEnd + rmSize); // If gap is too small, enlarge the gap. @@ -644,6 +645,13 @@ public class GapContent new GapContentPosition(offset)); if (index1 < 0) index1 = -(index1 + 1); + + // Search the first index with the specified offset. The binarySearch does + // not necessarily find the first one. + while (index1 > 0 + && ((GapContentPosition) positions.get(index1 - 1)).mark == offset) + index1--; + for (ListIterator i = positions.listIterator(index1); i.hasNext();) { GapContentPosition p = (GapContentPosition) i.next(); @@ -672,6 +680,13 @@ public class GapContent new GapContentPosition(offset)); if (index1 < 0) index1 = -(index1 + 1); + + // Search the first index with the specified offset. The binarySearch does + // not necessarily find the first one. + while (index1 > 0 + && ((GapContentPosition) positions.get(index1 - 1)).mark == offset) + index1--; + for (ListIterator i = positions.listIterator(index1); i.hasNext();) { GapContentPosition p = (GapContentPosition) i.next(); @@ -700,6 +715,12 @@ public class GapContent new GapContentPosition(offset)); if (index1 < 0) index1 = -(index1 + 1); + + // Search the first index with the specified offset. The binarySearch does + // not necessarily find the first one. + while (index1 > 0 + && ((GapContentPosition) positions.get(index1 - 1)).mark == offset) + index1--; for (ListIterator i = positions.listIterator(index1); i.hasNext();) { GapContentPosition p = (GapContentPosition) i.next(); diff --git a/libjava/classpath/javax/swing/text/GlyphView.java b/libjava/classpath/javax/swing/text/GlyphView.java index d3dd75e..47deb50 100644 --- a/libjava/classpath/javax/swing/text/GlyphView.java +++ b/libjava/classpath/javax/swing/text/GlyphView.java @@ -1057,34 +1057,4 @@ public class GlyphView extends View implements TabableView, Cloneable return painter.getNextVisualPositionFrom(this, pos, bias, a, direction, biasRet); } - - /** - * Returns the document position that is (visually) nearest to the given - * document position <code>pos</code> in the given direction <code>d</code>. - * - * @param c the text component - * @param pos the document position - * @param b the bias for <code>pos</code> - * @param d the direction, must be either {@link SwingConstants#NORTH}, - * {@link SwingConstants#SOUTH}, {@link SwingConstants#WEST} or - * {@link SwingConstants#EAST} - * @param biasRet an array of {@link Position.Bias} that can hold at least - * one element, which is filled with the bias of the return position - * on method exit - * - * @return the document position that is (visually) nearest to the given - * document position <code>pos</code> in the given direction - * <code>d</code> - * - * @throws BadLocationException if <code>pos</code> is not a valid offset in - * the document model - */ - public int getNextVisualPositionFrom(JTextComponent c, int pos, - Position.Bias b, int d, - Position.Bias[] biasRet) - throws BadLocationException - { - // TODO: Implement this properly. - throw new AssertionError("Not implemented yet."); - } } diff --git a/libjava/classpath/javax/swing/text/IconView.java b/libjava/classpath/javax/swing/text/IconView.java index 86c27dd..af2581a 100644 --- a/libjava/classpath/javax/swing/text/IconView.java +++ b/libjava/classpath/javax/swing/text/IconView.java @@ -158,34 +158,4 @@ public class IconView return el.getStartOffset(); } - /** - * Returns the document position that is (visually) nearest to the given - * document position <code>pos</code> in the given direction <code>d</code>. - * - * @param c the text component - * @param pos the document position - * @param b the bias for <code>pos</code> - * @param d the direction, must be either {@link SwingConstants#NORTH}, - * {@link SwingConstants#SOUTH}, {@link SwingConstants#WEST} or - * {@link SwingConstants#EAST} - * @param biasRet an array of {@link Position.Bias} that can hold at least - * one element, which is filled with the bias of the return position - * on method exit - * - * @return the document position that is (visually) nearest to the given - * document position <code>pos</code> in the given direction - * <code>d</code> - * - * @throws BadLocationException if <code>pos</code> is not a valid offset in - * the document model - */ - public int getNextVisualPositionFrom(JTextComponent c, int pos, - Position.Bias b, int d, - Position.Bias[] biasRet) - throws BadLocationException - { - // TODO: Implement this properly. - throw new AssertionError("Not implemented yet."); - } - } diff --git a/libjava/classpath/javax/swing/text/InternationalFormatter.java b/libjava/classpath/javax/swing/text/InternationalFormatter.java index 86300a7..ba3cffa 100644 --- a/libjava/classpath/javax/swing/text/InternationalFormatter.java +++ b/libjava/classpath/javax/swing/text/InternationalFormatter.java @@ -78,6 +78,8 @@ public class InternationalFormatter minimum = null; maximum = null; format = null; + setCommitsOnValidEdit(false); + setOverwriteMode(false); } /** @@ -226,6 +228,8 @@ public class InternationalFormatter public String valueToString(Object value) throws ParseException { + if (value == null) + return ""; if (format != null) return format.format(value); else diff --git a/libjava/classpath/javax/swing/text/JTextComponent.java b/libjava/classpath/javax/swing/text/JTextComponent.java index 83966bb..afa1f24 100644 --- a/libjava/classpath/javax/swing/text/JTextComponent.java +++ b/libjava/classpath/javax/swing/text/JTextComponent.java @@ -380,12 +380,18 @@ public abstract class JTextComponent extends JComponent public KeyStroke[] allKeys() { KeyStroke[] superKeys = super.allKeys(); - KeyStroke[] mapKeys = map.getBoundKeyStrokes(); - KeyStroke[] bothKeys = new KeyStroke[superKeys.length + mapKeys.length]; - for (int i = 0; i < superKeys.length; ++i) + KeyStroke[] mapKeys = map.getBoundKeyStrokes(); + int skl = 0; + int mkl = 0; + if (superKeys != null) + skl = superKeys.length; + if (mapKeys != null) + mkl = mapKeys.length; + KeyStroke[] bothKeys = new KeyStroke[skl + mkl]; + for (int i = 0; i < skl; ++i) bothKeys[i] = superKeys[i]; - for (int i = 0; i < mapKeys.length; ++i) - bothKeys[i + superKeys.length] = mapKeys[i]; + for (int i = 0; i < mkl; ++i) + bothKeys[i + skl] = mapKeys[i]; return bothKeys; } } @@ -864,7 +870,7 @@ public abstract class JTextComponent extends JComponent Hashtable acts = new Hashtable(actions.length); for (int i = 0; i < actions.length; ++i) acts.put(actions[i].getValue(Action.NAME), actions[i]); - for (int i = 0; i < bindings.length; ++i) + for (int i = 0; i < bindings.length; ++i) if (acts.containsKey(bindings[i].actionName)) map.addActionForKeyStroke(bindings[i].key, (Action) acts.get(bindings[i].actionName)); } @@ -906,33 +912,16 @@ public abstract class JTextComponent extends JComponent public JTextComponent() { Keymap defkeymap = getKeymap(DEFAULT_KEYMAP); - boolean creatingKeymap = false; if (defkeymap == null) { defkeymap = addKeymap(DEFAULT_KEYMAP, null); defkeymap.setDefaultAction(new DefaultEditorKit.DefaultKeyTypedAction()); - creatingKeymap = true; } setFocusable(true); setEditable(true); enableEvents(AWTEvent.KEY_EVENT_MASK); updateUI(); - - // need to do this after updateUI() - if (creatingKeymap) - loadKeymap(defkeymap, - new KeyBinding[] { - new KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), - DefaultEditorKit.backwardAction), - new KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), - DefaultEditorKit.forwardAction), - new KeyBinding(KeyStroke.getKeyStroke("typed \b"), - DefaultEditorKit.deletePrevCharAction), - new KeyBinding(KeyStroke.getKeyStroke("typed \u007f"), - DefaultEditorKit.deleteNextCharAction) - }, - getActions()); } public void setDocument(Document newDoc) diff --git a/libjava/classpath/javax/swing/text/MaskFormatter.java b/libjava/classpath/javax/swing/text/MaskFormatter.java new file mode 100644 index 0000000..d12b9ea --- /dev/null +++ b/libjava/classpath/javax/swing/text/MaskFormatter.java @@ -0,0 +1,583 @@ +/* MaskFormatter.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.swing.text; + +import java.text.ParseException; + +import javax.swing.JFormattedTextField; + +/** + * @author Anthony Balkissoon abalkiss at redhat dot com + * + */ +public class MaskFormatter extends DefaultFormatter +{ + // The declaration of the valid mask characters + private static final char NUM_CHAR = '#'; + private static final char ESCAPE_CHAR = '\''; + private static final char UPPERCASE_CHAR = 'U'; + private static final char LOWERCASE_CHAR = 'L'; + private static final char ALPHANUM_CHAR = 'A'; + private static final char LETTER_CHAR = '?'; + private static final char ANYTHING_CHAR = '*'; + private static final char HEX_CHAR = 'H'; + + /** The mask for this MaskFormatter **/ + private String mask; + + /** + * A String made up of the characters that are not valid for input for + * this MaskFormatter. + */ + private String invalidChars; + + /** + * A String made up of the characters that are valid for input for + * this MaskFormatter. + */ + private String validChars; + + /** A String used in place of missing chracters if the value does not + * completely fill in the spaces in the mask. + */ + private String placeHolder; + + /** A character used in place of missing characters if the value does + * not completely fill in the spaces in the mask. + */ + private char placeHolderChar = ' '; + + /** + * Whether or not stringToValue should return literal characters in the mask. + */ + private boolean valueContainsLiteralCharacters = true; + + /** A String used for easy access to valid HEX characters **/ + private static String hexString = "0123456789abcdefABCDEF"; + + /** An int to hold the length of the mask, accounting for escaped characters **/ + int maskLength = 0; + + public MaskFormatter () + { + // Override super's default behaviour, in MaskFormatter the default + // is not to allow invalid values + setAllowsInvalid(false); + } + + /** + * Creates a MaskFormatter with the specified mask. + * @specnote doesn't actually throw a ParseException although it + * is declared to do so + * @param mask + * @throws java.text.ParseException + */ + public MaskFormatter (String mask) throws java.text.ParseException + { + // Override super's default behaviour, in MaskFormatter the default + // is not to allow invalid values + setAllowsInvalid(false); + setMask (mask); + } + + /** + * Returns the mask used in this MaskFormatter. + * @return the mask used in this MaskFormatter. + */ + public String getMask() + { + return mask; + } + + /** + * Returns a String containing the characters that are not valid for input + * for this MaskFormatter. + * @return a String containing the invalid characters. + */ + public String getInvalidCharacters() + { + return invalidChars; + } + + /** + * Sets characters that are not valid for input. If + * <code>invalidCharacters</code> is non-null then no characters contained + * in it will be allowed to be input. + * + * @param invalidCharacters the String specifying invalid characters. + */ + public void setInvalidCharacters (String invalidCharacters) + { + this.invalidChars = invalidCharacters; + } + + /** + * Returns a String containing the characters that are valid for input + * for this MaskFormatter. + * @return a String containing the valid characters. + */ + public String getValidCharacters() + { + return validChars; + } + + /** + * Sets characters that are valid for input. If + * <code>validCharacters</code> is non-null then no characters that are + * not contained in it will be allowed to be input. + * + * @param validCharacters the String specifying valid characters. + */ + public void setValidCharacters (String validCharacters) + { + this.validChars = validCharacters; + } + + /** + * Returns the place holder String that is used in place of missing + * characters when the value doesn't completely fill in the spaces + * in the mask. + * @return the place holder String. + */ + public String getPlaceholder() + { + return placeHolder; + } + + /** + * Sets the string to use if the value does not completely fill in the mask. + * If this is null, the place holder character will be used instead. + * @param placeholder the String to use if the value doesn't completely + * fill in the mask. + */ + public void setPlaceholder (String placeholder) + { + this.placeHolder = placeholder; + } + + /** + * Returns the character used in place of missing characters when the + * value doesn't completely fill the mask. + * @return the place holder character + */ + public char getPlaceholderCharacter() + { + return placeHolderChar; + } + + /** + * Sets the char to use if the value does not completely fill in the mask. + * This is only used if the place holder String has not been set or does + * not completely fill in the mask. + * @param placeholder the char to use if the value doesn't completely + * fill in the mask. + */ + public void setPlaceholderCharacter (char placeholder) + { + this.placeHolderChar = placeholder; + } + + /** + * Returns true if stringToValue should return the literal + * characters in the mask. + * @return true if stringToValue should return the literal + * characters in the mask + */ + public boolean getValueContainsLiteralCharacters() + { + return valueContainsLiteralCharacters; + } + + /** + * Determines whether stringToValue will return literal characters or not. + * @param containsLiteralChars if true, stringToValue will return the + * literal characters in the mask, otherwise it will not. + */ + public void setValueContainsLiteralCharacters (boolean containsLiteralChars) + { + this.valueContainsLiteralCharacters = containsLiteralChars; + } + + /** + * Sets the mask for this MaskFormatter. + * @specnote doesn't actually throw a ParseException even though it is + * declared to do so + * @param mask the new mask for this MaskFormatter + * @throws ParseException if <code>mask</code> is not valid. + */ + public void setMask (String mask) throws ParseException + { + this.mask = mask; + + // Update the cached maskLength. + int end = mask.length() - 1; + maskLength = 0; + for (int i = 0; i <= end; i++) + { + // Handle escape characters properly - they don't add to the maskLength + // but 2 escape characters in a row is really one escape character and + // one literal single quote, so that does add 1 to the maskLength. + if (mask.charAt(i) == '\'') + { + // Escape characters at the end of the mask don't do anything. + if (i != end) + maskLength++; + i++; + } + else + maskLength++; + } + } + + /** + * Installs this MaskFormatter on the JFormattedTextField. + * Invokes valueToString to convert the current value from the + * JFormattedTextField to a String, then installs the Actions from + * getActions, the DocumentFilter from getDocumentFilter, and the + * NavigationFilter from getNavigationFilter. + * + * If valueToString throws a ParseException, this method sets the text + * to an empty String and marks the JFormattedTextField as invalid. + */ + public void install (JFormattedTextField ftf) + { + super.install(ftf); + if (ftf != null) + { + try + { + valueToString(ftf.getValue()); + } + catch (ParseException pe) + { + // Set the text to an empty String and mark the JFormattedTextField + // as invalid. + ftf.setText(""); + setEditValid(false); + } + } + } + + /** + * Parses the text using the mask, valid characters, and invalid characters + * to determine the appropriate Object to return. This strips the literal + * characters if necessary and invokes super.stringToValue. If the paramter + * is invalid for the current mask and valid/invalid character sets this + * method will throw a ParseException. + * + * @param value the String to parse + * @throws ParseException if value doesn't match the mask and valid/invalid + * character sets + */ + public Object stringToValue (String value) throws ParseException + { + int vLength = value.length(); + + // For value to be a valid it must be the same length as the mask + // note this doesn't take into account symbols that occupy more than + // one character, this is something we may possibly need to fix. + if (maskLength != vLength) + throw new ParseException ("stringToValue passed invalid value", vLength); + + // Check if the value is valid according to the mask and valid/invalid + // sets. + try + { + convertValue(value, false); + } + catch (ParseException pe) + { + throw new ParseException("stringToValue passed invalid value", + pe.getErrorOffset()); + } + + if (!getValueContainsLiteralCharacters()) + value = stripLiterals(value); + return super.stringToValue(value); + } + + /** + * Strips the literal characters from the given String. + * @param value the String to strip + * @return the stripped String + */ + String stripLiterals(String value) + { + StringBuffer result = new StringBuffer(); + for (int i = 0; i < value.length(); i++) + { + // Only append the characters that don't correspond to literal + // characters in the mask. + switch (mask.charAt(i)) + { + case NUM_CHAR: + case UPPERCASE_CHAR: + case LOWERCASE_CHAR: + case ALPHANUM_CHAR: + case LETTER_CHAR: + case HEX_CHAR: + case ANYTHING_CHAR: + result.append(value.charAt(i)); + break; + default: + } + } + return result.toString(); + } + + /** + * Returns a String representation of the Object value based on the mask. + * + * @param value the value to convert + * @throws ParseException if value is invalid for this mask and valid/invalid + * character sets + */ + public String valueToString (Object value) throws ParseException + { + String result = super.valueToString(value); + int rLength = result.length(); + + // If value is longer than the mask, truncate it. Note we may need to + // account for symbols that are more than one character long. + if (rLength > maskLength) + result = result.substring(0, maskLength); + + // Verify the validity and convert to upper/lowercase as needed. + result = convertValue(result, true); + if (rLength < maskLength) + return pad(result, rLength); + return result; + } + + /** + * This method takes in a String and runs it through the mask to make + * sure that it is valid. If <code>convert</code> is true, it also + * converts letters to upper/lowercase as required by the mask. + * @param value the String to convert + * @param convert true if we should convert letters to upper/lowercase + * @return the converted String + * @throws ParseException if the given String isn't valid for the mask + */ + String convertValue(String value, boolean convert) throws ParseException + { + StringBuffer result = new StringBuffer(value); + char markChar; + char resultChar; + boolean literal; + + // this boolean is specifically to avoid calling the isCharValid method + // when neither invalidChars or validChars has been set + boolean checkCharSets = (invalidChars != null || validChars != null); + + for (int i = 0, j = 0; i < value.length(); i++, j++) + { + literal = false; + resultChar = result.charAt(i); + // This switch block on the mask character checks that the character + // within <code>value</code> at that point is valid according to the + // mask and also converts to upper/lowercase as needed. + switch (mask.charAt(j)) + { + case NUM_CHAR: + if (!Character.isDigit(resultChar)) + throw new ParseException("Number expected", i); + break; + case UPPERCASE_CHAR: + if (!Character.isLetter(resultChar)) + throw new ParseException("Letter expected", i); + if (convert) + result.setCharAt(i, Character.toUpperCase(resultChar)); + break; + case LOWERCASE_CHAR: + if (!Character.isLetter(resultChar)) + throw new ParseException("Letter expected", i); + if (convert) + result.setCharAt(i, Character.toLowerCase(resultChar)); + break; + case ALPHANUM_CHAR: + if (!Character.isLetterOrDigit(resultChar)) + throw new ParseException("Letter or number expected", i); + break; + case LETTER_CHAR: + if (!Character.isLetter(resultChar)) + throw new ParseException("Letter expected", i); + break; + case HEX_CHAR: + if (hexString.indexOf(resultChar) == -1) + throw new ParseException("Hexadecimal character expected", i); + break; + case ANYTHING_CHAR: + break; + case ESCAPE_CHAR: + // Escape character, check the next character to make sure that + // the literals match + j++; + literal = true; + if (resultChar != mask.charAt(j)) + throw new ParseException ("Invalid character: "+resultChar, i); + break; + default: + literal = true; + if (!getValueContainsLiteralCharacters() && convert) + throw new ParseException ("Invalid character: "+resultChar, i); + else if (resultChar != mask.charAt(j)) + throw new ParseException ("Invalid character: "+resultChar, i); + } + // If necessary, check if the character is valid. + if (!literal && checkCharSets && !isCharValid(resultChar)) + throw new ParseException("invalid character: "+resultChar, i); + + } + return result.toString(); + } + + /** + * Convenience method used by many other methods to check if a character is + * valid according to the mask, the validChars, and the invalidChars. To + * be valid a character must: + * 1. be allowed by the mask + * 2. be present in any non-null validChars String + * 3. not be present in any non-null invalidChars String + * @param testChar the character to test + * @return true if the character is valid + */ + boolean isCharValid(char testChar) + { + char lower = Character.toLowerCase(testChar); + char upper = Character.toUpperCase(testChar); + // If validChars isn't null, the character must appear in it. + if (validChars != null) + if (validChars.indexOf(lower) == -1 && validChars.indexOf(upper) == -1) + return false; + // If invalidChars isn't null, the character must not appear in it. + if (invalidChars != null) + if (invalidChars.indexOf(lower) != -1 + || invalidChars.indexOf(upper) != -1) + return false; + return true; + } + + /** + * Pads the value with literals, the placeholder String and/or placeholder + * character as appropriate. + * @param value the value to pad + * @param currLength the current length of the value + * @return the padded String + */ + String pad (String value, int currLength) + { + StringBuffer result = new StringBuffer(value); + int index = currLength; + while (result.length() < maskLength) + { + // The character used to pad may be a literal, a character from the + // place holder string, or the place holder character. getPadCharAt + // will find the proper one for us. + result.append (getPadCharAt(index)); + index++; + } + return result.toString(); + } + + /** + * Returns the character with which to pad the value at the given index + * position. If the mask has a literal at this position, this is returned + * otherwise if the place holder string is initialized and is longer than + * <code>i</code> characters then the character at position <code>i</code> + * from this String is returned. Else, the place holder character is + * returned. + * @param i the index at which we want to pad the value + * @return the character with which we should pad the value + */ + char getPadCharAt(int i) + { + boolean escaped = false; + int target = i; + char maskChar; + int holderLength = placeHolder == null ? -1 : placeHolder.length(); + // We must iterate through the mask from the beginning, because the given + // index doesn't account for escaped characters. For example, with the + // mask "1A'A''A1" index 2 refers to the literalized A, not to the + // single quotation. + for (int n = 0; n < mask.length(); n++) + { + maskChar = mask.charAt(n); + if (maskChar == ESCAPE_CHAR && !escaped) + { + target++; + escaped = true; + } + else if (escaped == true) + { + // Check if target == n which means we've come to the character + // we want to return and since it is a literal (because escaped + // is true), we return it. + if (target == n) + return maskChar; + escaped = false; + } + if (target == n) + { + // We've come to the character we want to return. It wasn't + // escaped so if it isn't a literal we should return either + // the character from place holder string or the place holder + // character, depending on whether or not the place holder + // string is long enough. + switch (maskChar) + { + case NUM_CHAR: + case UPPERCASE_CHAR: + case LOWERCASE_CHAR: + case ALPHANUM_CHAR: + case LETTER_CHAR: + case HEX_CHAR: + case ANYTHING_CHAR: + if (holderLength > i) + return placeHolder.charAt(i); + else + return placeHolderChar; + default: + return maskChar; + } + } + } + // This shouldn't happen + throw new AssertionError("MaskFormatter.getMaskCharAt failed"); + } +} diff --git a/libjava/classpath/javax/swing/text/NumberFormatter.java b/libjava/classpath/javax/swing/text/NumberFormatter.java new file mode 100644 index 0000000..a858ff4 --- /dev/null +++ b/libjava/classpath/javax/swing/text/NumberFormatter.java @@ -0,0 +1,86 @@ +/* NumberFormatter.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.swing.text; + +import java.text.Format; +import java.text.NumberFormat; + +/** + * <code>NumberFormatter</code> is an {@link InternationalFormatter} + * that implements value to string and string to value conversion via + * an instance of {@link NumberFormat}. + * + * @author Anthony Balkissoon abalkiss at redhat dot com + * @since 1.4 + */ +public class NumberFormatter extends InternationalFormatter +{ + + /** + * Creates a NumberFormatter with the default NumberFormat from + * NumberFormat.getNumberInstance(). + */ + public NumberFormatter () + { + this (NumberFormat.getNumberInstance()); + } + + /** + * Creates a NumberFormatter with the specified NumberFormat. + * @param format the NumberFormat to use for this NumberFormatter. + */ + public NumberFormatter (NumberFormat format) + { + super(format); + setFormat(format); + } + + /** + * Sets the NumberFormat that this NumberFormatter will use to determine + * legal values for editing and displaying. + * + * @param format the Format to use to determine legal values. + */ + public void setFormat (Format format) + { + // TODO: This should be different from the super implementation + // but I don't yet know how. + super.setFormat(format); + } +} diff --git a/libjava/classpath/javax/swing/text/PasswordView.java b/libjava/classpath/javax/swing/text/PasswordView.java index c3aa66c..e54331c5 100644 --- a/libjava/classpath/javax/swing/text/PasswordView.java +++ b/libjava/classpath/javax/swing/text/PasswordView.java @@ -41,6 +41,7 @@ package javax.swing.text; import java.awt.Color; import java.awt.FontMetrics; import java.awt.Graphics; +import java.awt.Rectangle; import java.awt.Shape; import javax.swing.JPasswordField; @@ -211,7 +212,10 @@ public class PasswordView /** * Provides a mapping from the document model coordinate space to the * coordinate space of the view mapped to it. - * + * + * This method is overridden to provide a correct mapping with respect to the + * echo char and not to the real content. + * * @param pos - the position to convert >= 0 * @param a - the allocated region to render into * @param b - typesafe enumeration to indicate bias to a position in the model. @@ -222,7 +226,35 @@ public class PasswordView public Shape modelToView(int pos, Shape a, Position.Bias b) throws BadLocationException { - return super.modelToView(pos, a, b); + Shape newAlloc = adjustAllocation(a); + + // Ensure metrics are up-to-date. + updateMetrics(); + + // Get rectangle of the line containing position. + int lineIndex = getElement().getElementIndex(pos); + Rectangle rect = lineToRect(newAlloc, lineIndex); + + // Get the rectangle for position. + Element line = getElement().getElement(lineIndex); + int lineStart = line.getStartOffset(); + Segment segment = getLineBuffer(); + segment.array = new char[pos - lineStart]; + char echoChar = getEchoChar(); + for (int i = 0; i < segment.array.length; ++i) + segment.array[i] = echoChar; + segment.offset = 0; + segment.count = segment.array.length; + + int xoffset = Utilities.getTabbedTextWidth(segment, metrics, rect.x, + this, lineStart); + + // Calc the real rectangle. + rect.x += xoffset; + rect.width = 1; + rect.height = metrics.getHeight(); + + return rect; } /** @@ -239,6 +271,8 @@ public class PasswordView */ public int viewToModel(float fx, float fy, Shape a, Position.Bias[] bias) { + // FIXME: This only provides a view->model mapping for the real text + // content and does not respect the echo char. return super.viewToModel(fx, fy, a, bias); } } diff --git a/libjava/classpath/javax/swing/text/PlainDocument.java b/libjava/classpath/javax/swing/text/PlainDocument.java index 0c00a06..2200cae 100644 --- a/libjava/classpath/javax/swing/text/PlainDocument.java +++ b/libjava/classpath/javax/swing/text/PlainDocument.java @@ -113,6 +113,46 @@ public class PlainDocument extends AbstractDocument int elementIndex = rootElement.getElementIndex(offset); Element firstElement = rootElement.getElement(elementIndex); + // If we're inserting immediately after a newline we have to fix the + // Element structure. + if (offset > 0) + { + try + { + String s = getText(offset - 1, 1); + if (s.equals("\n")) + { + int newEl2EndOffset = end; + boolean replaceNext = false; + if (rootElement.getElementCount() > elementIndex + 1) + { + replaceNext = true; + newEl2EndOffset = + rootElement.getElement(elementIndex + 1).getEndOffset(); + } + Element newEl1 = + createLeafElement(rootElement, firstElement.getAttributes(), + firstElement.getStartOffset(), offset); + Element newEl2 = + createLeafElement (rootElement, firstElement.getAttributes(), + offset, newEl2EndOffset); + if (replaceNext) + rootElement.replace(elementIndex, 2, new Element[] { newEl1, newEl2 }); + else + rootElement.replace(elementIndex, 1, new Element[] { newEl1, newEl2 }); + firstElement = newEl2; + elementIndex ++; + } + } + catch (BadLocationException ble) + { + // This shouldn't happen. + AssertionError ae = new AssertionError(); + ae.initCause(ble); + throw ae; + } + } + // added and removed are Element arrays used to add an ElementEdit // to the DocumentEvent if there were entire lines added or removed. Element[] removed = new Element[1]; diff --git a/libjava/classpath/javax/swing/text/PlainView.java b/libjava/classpath/javax/swing/text/PlainView.java index 9f5ee8ad..a318ee7 100644 --- a/libjava/classpath/javax/swing/text/PlainView.java +++ b/libjava/classpath/javax/swing/text/PlainView.java @@ -185,7 +185,6 @@ public class PlainView extends View implements TabExpander JTextComponent textComponent = (JTextComponent) getContainer(); - g.setFont(textComponent.getFont()); selectedColor = textComponent.getSelectedTextColor(); unselectedColor = textComponent.getForeground(); disabledColor = textComponent.getDisabledTextColor(); @@ -513,7 +512,8 @@ public class PlainView extends View implements TabExpander else { Rectangle repaintRec = rec0.union(rec1); - host.repaint(); + host.repaint(repaintRec.x, repaintRec.y, repaintRec.width, + repaintRec.height); } } @@ -530,35 +530,5 @@ public class PlainView extends View implements TabExpander lineBuffer = new Segment(); return lineBuffer; } - - /** - * Returns the document position that is (visually) nearest to the given - * document position <code>pos</code> in the given direction <code>d</code>. - * - * @param c the text component - * @param pos the document position - * @param b the bias for <code>pos</code> - * @param d the direction, must be either {@link SwingConstants#NORTH}, - * {@link SwingConstants#SOUTH}, {@link SwingConstants#WEST} or - * {@link SwingConstants#EAST} - * @param biasRet an array of {@link Position.Bias} that can hold at least - * one element, which is filled with the bias of the return position - * on method exit - * - * @return the document position that is (visually) nearest to the given - * document position <code>pos</code> in the given direction - * <code>d</code> - * - * @throws BadLocationException if <code>pos</code> is not a valid offset in - * the document model - */ - public int getNextVisualPositionFrom(JTextComponent c, int pos, - Position.Bias b, int d, - Position.Bias[] biasRet) - throws BadLocationException - { - // TODO: Implement this properly. - throw new AssertionError("Not implemented yet."); - } } diff --git a/libjava/classpath/javax/swing/text/StyleContext.java b/libjava/classpath/javax/swing/text/StyleContext.java index 6c4e2994..dabc0ba 100644 --- a/libjava/classpath/javax/swing/text/StyleContext.java +++ b/libjava/classpath/javax/swing/text/StyleContext.java @@ -362,9 +362,8 @@ public class StyleContext public boolean isEqual(AttributeSet attr) { - return attr != null - && attr.containsAttributes(this) - && this.containsAttributes(attr); + return getAttributeCount() == attr.getAttributeCount() + && this.containsAttributes(attr); } public String toString() diff --git a/libjava/classpath/javax/swing/text/StyledEditorKit.java b/libjava/classpath/javax/swing/text/StyledEditorKit.java index e71f992..c4eef44 100644 --- a/libjava/classpath/javax/swing/text/StyledEditorKit.java +++ b/libjava/classpath/javax/swing/text/StyledEditorKit.java @@ -67,7 +67,7 @@ public class StyledEditorKit extends DefaultEditorKit */ public UnderlineAction() { - super("TODO"); // TODO: Figure out name for this action. + super("font-underline"); } /** @@ -97,7 +97,7 @@ public class StyledEditorKit extends DefaultEditorKit */ public ItalicAction() { - super("TODO"); // TODO: Figure out correct name of this Action. + super("font-italic"); } /** @@ -127,7 +127,7 @@ public class StyledEditorKit extends DefaultEditorKit */ public BoldAction() { - super("TODO"); // TODO: Figure out correct name of this Action. + super("font-bold"); } /** @@ -585,8 +585,26 @@ public class StyledEditorKit extends DefaultEditorKit public Action[] getActions() { Action[] actions1 = super.getActions(); - Action[] myActions = new Action[] { new BoldAction(), new ItalicAction(), - new UnderlineAction() }; + Action[] myActions = new Action[] { + new FontSizeAction("font-size-8", 8), + new FontSizeAction("font-size-10", 10), + new FontSizeAction("font-size-12", 12), + new FontSizeAction("font-size-14", 14), + new FontSizeAction("font-size-16", 16), + new FontSizeAction("font-size-18", 18), + new FontSizeAction("font-size-24", 24), + new FontSizeAction("font-size-36", 36), + new FontSizeAction("font-size-48", 48), + new FontFamilyAction("font-family-Serif", "Serif"), + new FontFamilyAction("font-family-Monospaced", "Monospaced"), + new FontFamilyAction("font-family-SansSerif", "SansSerif"), + new AlignmentAction("left-justify", StyleConstants.ALIGN_LEFT), + new AlignmentAction("center-justify", StyleConstants.ALIGN_CENTER), + new AlignmentAction("right-justify", StyleConstants.ALIGN_RIGHT), + new BoldAction(), + new ItalicAction(), + new UnderlineAction() + }; return TextAction.augmentList(actions1, myActions); } @@ -696,9 +714,8 @@ public class StyledEditorKit extends DefaultEditorKit protected void createInputAttributes(Element element, MutableAttributeSet set) { - AttributeSet atts = element.getAttributes(); - set.removeAttributes(set); // FIXME: Filter out component, icon and element name attributes. - set.addAttributes(atts); + set.removeAttributes(set); + set.addAttributes(element.getAttributes()); } } diff --git a/libjava/classpath/javax/swing/text/TableView.java b/libjava/classpath/javax/swing/text/TableView.java new file mode 100644 index 0000000..d3113b8 --- /dev/null +++ b/libjava/classpath/javax/swing/text/TableView.java @@ -0,0 +1,465 @@ +/* TableView.java -- A view impl for tables inside styled text + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.swing.text; + +import java.awt.Rectangle; +import java.awt.Shape; + +import javax.swing.SizeRequirements; +import javax.swing.event.DocumentEvent; + +/** + * A {@link View} implementation for rendering tables inside styled text. + * Tables are rendered as vertical boxes (see {@link BoxView}). These boxes + * have a number of child views, which are the rows of the table. These are + * horizontal boxes containing the actuall cells of the table. These cells + * can be arbitrary view implementations and are fetched via the + * {@link ViewFactory} returned by {@link View#getViewFactory}. + * + * @author Roman Kennke (kennke@aicas.com) + */ +public class TableView + extends BoxView +{ + + /** + * A view implementation that renders a row of a <code>TableView</code>. + * This is implemented as a horizontal box that contains the actual cells + * of the table. + * + * @author Roman Kennke (kennke@aicas.com) + */ + public class TableRow + extends BoxView + { + /** + * Creates a new instance of <code>TableRow</code>. + * + * @param el the element for which to create a row view + */ + public TableRow(Element el) + { + super(el, X_AXIS); + } + + /** + * Replaces some child views with a new set of child views. This is + * implemented to call the superclass behaviour and invalidates the row + * grid so that rows and columns will be recalculated. + * + * @param offset the start offset at which to replace views + * @param length the number of views to remove + * @param views the new set of views + */ + public void replace(int offset, int length, View[] views) + { + super.replace(offset, length, views); + layoutChanged(X_AXIS); + } + + /** + * Lays out the box's child views along the major axis. This is + * reimplemented so that the child views all have the width of their + * column. + * + * @param targetSpan the total span of the view + * @param axis the axis that is laid out + * @param offsets an array that holds the offsets of the child views after + * this method returned + * @param spans an array that holds the spans of the child views after this + * method returned + */ + protected void layoutMajorAxis(int targetSpan, int axis, int[] offsets, + int[] spans) + { + // TODO: Maybe prepare columnSpans and columnOffsets. + + // Some sanity checks. If these preconditions are not met, then the + // following code will not work. Also, there must be something + // seriously wrong then. + assert(offsets.length == columnOffsets.length); + assert(spans.length == columnSpans.length); + assert(offsets.length == spans.length); + for (int i = 0; i < offsets.length; ++i) + { + offsets[i] = columnOffsets[i]; + spans[i] = columnSpans[i]; + } + } + + /** + * Lays out the box's child views along the minor axis (the orthogonal axis + * to the major axis). This is reimplemented to call the super behaviour + * and then adjust the span of the child views that span multiple rows. + * + * @param targetSpan the total span of the view + * @param axis the axis that is laid out + * @param offsets an array that holds the offsets of the child views after + * this method returned + * @param spans an array that holds the spans of the child views after this + * method returned + */ + protected void layoutMinorAxis(int targetSpan, int axis, int[] offsets, + int[] spans) + { + // FIXME: Figure out how to fetch the row heights from the TableView's + // element. + super.layoutMajorAxis(targetSpan, axis, offsets, spans); + } + + /** + * Determines the resizeability of this view along the specified axis. + * + * @param axis the axis of which to fetch the resizability + * + * @return the resize weight or <= 0 if this view is not resizable + * + * @throws IllegalArgumentException when an illegal axis is specified + */ + public int getResizeWeight(int axis) + { + // TODO: Figure out if this is ok. I would think so, but better test + // this. + return 0; + } + + /** + * Returns the child view that represents the specified position in the + * model. This is reimplemented because in this view we do not necessarily + * have a one to one mapping of child elements to child views. + * + * @param pos the model position for which to query the view + * @param a the allocation of this view + * + * @return the view that corresponds to the specified model position or + * <code>null</code> if there is none + */ + protected View getViewAtPosition(int pos, Rectangle a) + { + // FIXME: Do not call super here. Instead walk through the child views + // and look for a range that contains the given position. + return super.getViewAtPosition(pos, a); + } + } + + /** + * This class is deprecated and not used anymore. Table cells are + * rendered by an arbitrary <code>View</code> implementation. + * + * @author Roman Kennke (kennke@aicas.com) + * + * @deprecated Table cells are now rendered by an arbitrary <code>View</code> + * implementation. + */ + public class TableCell + extends BoxView + { + + /** + * The row number of this cell. + */ + private int row; + + /** + * The column number of this cell. + */ + private int column; + + /** + * Creates a new instance. + * + * @param el the element + * + * @deprecated Table cells are now rendered by an arbitrary + * <code>View</code> implementation. + */ + public TableCell(Element el) + { + super(el, X_AXIS); + } + + /** + * Returns the number of columns that this cell spans. + * + * @return the number of columns that this cell spans + * + * @deprecated Table cells are now rendered by an arbitrary + * <code>View</code> implementation. + */ + public int getColumnCount() + { + // TODO: Figure out if this is right. However, this is not so important + // since this class isn't used anyway (except maybe be application code + // that still uses this deprecated class). + return 1; + } + + /** + * Returns the number of rows that this cell spans. + * + * @return the number of rows that this cell spans + * + * @deprecated Table cells are now rendered by an arbitrary + * <code>View</code> implementation. + */ + public int getRowCount() + { + // TODO: Figure out if this is right. However, this is not so important + // since this class isn't used anyway (except maybe be application code + // that still uses this deprecated class). + return 1; + } + + /** + * Sets the grid location of this table cell. + * + * @param r the row of this cell + * @param c the column of this cell + * + * @deprecated Table cells are now rendered by an arbitrary + * <code>View</code> implementation. + */ + public void setGridLocation(int r, int c) + { + row = r; + column = c; + } + + /** + * Returns the row number of this cell. + * + * @return the row number of this cell + * + * @deprecated Table cells are now rendered by an arbitrary + * <code>View</code> implementation. + */ + public int getGridRow() + { + return row; + } + + /** + * Returns the column number of this cell. + * + * @return the column number of this cell + * + * @deprecated Table cells are now rendered by an arbitrary + * <code>View</code> implementation. + */ + public int getGridColumn() + { + return column; + } + } + + /** + * The offsets of the columns of this table. Package private to avoid + * synthetic accessor methods. + */ + int[] columnOffsets; + + /** + * The spans of the columns of this table. Package private to avoid + * synthetic accessor methods. + */ + int[] columnSpans; + + /** + * The size requirements of the columns. + */ + private SizeRequirements[] columnRequirements; + + /** + * Creates a new instance of <code>TableView</code>. + * + * @param el the element for which to create a table view + */ + public TableView(Element el) + { + super(el, Y_AXIS); + int numChildren = el.getElementCount(); + View[] rows = new View[numChildren]; + for (int i = 0; i < numChildren; ++i) + { + Element rowEl = el.getElement(i); + TableRow rowView = createTableRow(rowEl); + rows[i] = rowView; + } + replace(0, 0, rows); + } + + /** + * Replaces a number of child views with a set of new child views. This is + * implemented to call the superclass behaviour and invalidate the layout. + * + * @param offset the offset at which to replace child views + * @param length the number of child views to remove + * @param views the new set of views + */ + public void replace(int offset, int length, View[] views) + { + super.replace(offset, length, views); + layoutChanged(Y_AXIS); + } + + /** + * Creates a view for a table row. + * + * @param el the element that represents the table row + * + * @return a view for rendering the table row + */ + protected TableRow createTableRow(Element el) + { + return new TableRow(el); + } + + /** + * Creates a view for a table cell. This method is deprecated and not used + * anymore. + * + * @param el the element that represents the table cell + * + * @return a view for rendering the table cell + * + * @deprecated Table cells are now rendered by an arbitrary + * <code>View</code> implementation. + */ + protected TableCell createTableCell(Element el) + { + return new TableCell(el); + } + + protected void forwardUpdate(DocumentEvent.ElementChange ec, DocumentEvent e, + Shape a, ViewFactory vf) + { + // TODO: Figure out what to do here. + } + + /** + * Lays out the columns to fit within the specified target span. + * + * @param targetSpan the total span for the columns + * @param offsets an array that holds the offsets of the columns when this + * method returns + * @param spans an array that holds the spans of the columns when this method + * returns + * @param reqs the size requirements for each column + */ + protected void layoutColumns(int targetSpan, int[] offsets, int spans[], + SizeRequirements[] reqs) + { + // TODO: Figure out what exactly to do here. + } + + /** + * Lays out the child views along the minor axis of the table (that is the + * horizontal axis). This is implemented to call {@link #layoutColumns} to + * layout the column layout of this table, and then forward to the superclass + * to actually lay out the rows. + * + * @param targetSpan the available span along the minor (horizontal) axis + * @param axis the axis + * @param offsets an array that holds the offsets of the columns when this + * method returns + * @param spans an array that holds the spans of the columns when this method + * returns + */ + protected void layoutMinorAxis(int targetSpan, int axis, int[] offsets, + int[] spans) + { + // TODO: Prepare size requirements for the columns. + layoutColumns(targetSpan, columnOffsets, columnSpans, columnRequirements); + super.layoutMinorAxis(targetSpan, axis, offsets, spans); + } + + /** + * Calculates the requirements of this view for the minor (== horizontal) + * axis. + * + * This is reimplemented to calculate the requirements as the sum of the + * size requirements of the columns. + * + * @param axis the axis + * @param req the size requirements object to use, if <code>null</code> a new + * one will be created + */ + protected SizeRequirements calculateMinorAxisRequirements(int axis, + SizeRequirements req) + { + // TODO: Maybe prepare columnRequirements. + SizeRequirements res = req; + if (res == null) + res = new SizeRequirements(); + else + { + res.alignment = 0.5f; + res.maximum = 0; + res.minimum = 0; + res.preferred = 0; + } + + for (int i = 0; i < columnRequirements.length; ++i) + { + res.minimum += columnRequirements[i].minimum; + res.preferred += columnRequirements[i].preferred; + res.maximum += columnRequirements[i].maximum; + // TODO: Do we have to handle alignment somehow? + } + return res; + } + + /** + * Returns the child view that represents the specified position in the + * model. This is reimplemented because in this view we do not necessarily + * have a one to one mapping of child elements to child views. + * + * @param pos the model position for which to query the view + * @param a the allocation of this view + * + * @return the view that corresponds to the specified model position or + * <code>null</code> if there is none + */ + protected View getViewAtPosition(int pos, Rectangle a) + { + // FIXME: Do not call super here. Instead walk through the child views + // and look for a range that contains the given position. + return super.getViewAtPosition(pos, a); + } +} diff --git a/libjava/classpath/javax/swing/text/Utilities.java b/libjava/classpath/javax/swing/text/Utilities.java index 7830b2f..1adc8ff 100644 --- a/libjava/classpath/javax/swing/text/Utilities.java +++ b/libjava/classpath/javax/swing/text/Utilities.java @@ -45,6 +45,7 @@ import java.awt.Rectangle; import java.text.BreakIterator; import javax.swing.SwingConstants; +import javax.swing.SwingUtilities; /** * A set of utilities to deal with text. This is used by several other classes @@ -573,10 +574,11 @@ public class Utilities View rootView = c.getUI().getRootView(c); Rectangle r = c.modelToView(offset); int offs = c.viewToModel(new Point(x, r.y)); - int pos = rootView.getNextVisualPositionFrom(c, offs, - Position.Bias.Forward, - SwingConstants.NORTH, - new Position.Bias[1]); + int pos = rootView.getNextVisualPositionFrom(offs, + Position.Bias.Forward, + SwingUtilities.calculateInnerArea(c, null), + SwingConstants.NORTH, + new Position.Bias[1]); return pos; } @@ -599,10 +601,11 @@ public class Utilities View rootView = c.getUI().getRootView(c); Rectangle r = c.modelToView(offset); int offs = c.viewToModel(new Point(x, r.y)); - int pos = rootView.getNextVisualPositionFrom(c, offs, - Position.Bias.Forward, - SwingConstants.SOUTH, - new Position.Bias[1]); + int pos = rootView.getNextVisualPositionFrom(offs, + Position.Bias.Forward, + SwingUtilities.calculateInnerArea(c, null), + SwingConstants.SOUTH, + new Position.Bias[1]); return pos; } } diff --git a/libjava/classpath/javax/swing/text/View.java b/libjava/classpath/javax/swing/text/View.java index daab347..b835842 100644 --- a/libjava/classpath/javax/swing/text/View.java +++ b/libjava/classpath/javax/swing/text/View.java @@ -447,9 +447,11 @@ public abstract class View implements SwingConstants protected void updateLayout(DocumentEvent.ElementChange ec, DocumentEvent ev, Shape shape) { - Rectangle b = shape.getBounds(); - if (ec != null) - preferenceChanged(this, true, true); + if (ec != null && shape != null) + preferenceChanged(null, true, true); + Container c = getContainer(); + if (c != null) + c.repaint(); } /** @@ -599,9 +601,9 @@ public abstract class View implements SwingConstants * Returns the document position that is (visually) nearest to the given * document position <code>pos</code> in the given direction <code>d</code>. * - * @param c the text component * @param pos the document position * @param b the bias for <code>pos</code> + * @param a the allocation for this view * @param d the direction, must be either {@link SwingConstants#NORTH}, * {@link SwingConstants#SOUTH}, {@link SwingConstants#WEST} or * {@link SwingConstants#EAST} @@ -615,9 +617,31 @@ public abstract class View implements SwingConstants * * @throws BadLocationException if <code>pos</code> is not a valid offset in * the document model + * @throws IllegalArgumentException if <code>d</code> is not a valid direction */ - public abstract int getNextVisualPositionFrom(JTextComponent c, int pos, - Position.Bias b, int d, - Position.Bias[] biasRet) - throws BadLocationException; + public int getNextVisualPositionFrom(int pos, Position.Bias b, + Shape a, int d, + Position.Bias[] biasRet) + throws BadLocationException + { + int ret = pos; + switch (d) + { + case WEST: + ret = pos - 1; + break; + case EAST: + ret = pos + 1; + break; + case NORTH: + // TODO: Implement this + break; + case SOUTH: + // TODO: Implement this + break; + default: + throw new IllegalArgumentException("Illegal value for d"); + } + return ret; + } } diff --git a/libjava/classpath/javax/swing/text/WrappedPlainView.java b/libjava/classpath/javax/swing/text/WrappedPlainView.java index b03399d..baba343 100644 --- a/libjava/classpath/javax/swing/text/WrappedPlainView.java +++ b/libjava/classpath/javax/swing/text/WrappedPlainView.java @@ -620,36 +620,6 @@ public class WrappedPlainView extends BoxView implements TabExpander currLineStart = currLineEnd; } } - - /** - * Returns the document position that is (visually) nearest to the given - * document position <code>pos</code> in the given direction <code>d</code>. - * - * @param c the text component - * @param pos the document position - * @param b the bias for <code>pos</code> - * @param d the direction, must be either {@link SwingConstants#NORTH}, - * {@link SwingConstants#SOUTH}, {@link SwingConstants#WEST} or - * {@link SwingConstants#EAST} - * @param biasRet an array of {@link Position.Bias} that can hold at least - * one element, which is filled with the bias of the return position - * on method exit - * - * @return the document position that is (visually) nearest to the given - * document position <code>pos</code> in the given direction - * <code>d</code> - * - * @throws BadLocationException if <code>pos</code> is not a valid offset - * in the document model - */ - public int getNextVisualPositionFrom(JTextComponent c, int pos, - Position.Bias b, int d, - Position.Bias[] biasRet) - throws BadLocationException - { - // TODO: Implement this properly. - throw new AssertionError("Not implemented yet."); - } /** * This method is called from insertUpdate and removeUpdate. diff --git a/libjava/classpath/javax/swing/text/html/BlockView.java b/libjava/classpath/javax/swing/text/html/BlockView.java new file mode 100644 index 0000000..6274e7b --- /dev/null +++ b/libjava/classpath/javax/swing/text/html/BlockView.java @@ -0,0 +1,301 @@ +/* BlockView.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.swing.text.html; + +import java.awt.Graphics; +import java.awt.Rectangle; +import java.awt.Shape; + +import javax.swing.SizeRequirements; +import javax.swing.event.DocumentEvent; +import javax.swing.text.AttributeSet; +import javax.swing.text.BoxView; +import javax.swing.text.Element; +import javax.swing.text.View; +import javax.swing.text.ViewFactory; + +/** + * @author Lillian Angel <langel@redhat.com> + */ +public class BlockView extends BoxView +{ + + /** + * Creates a new view that represents an html box. + * This can be used for a number of elements. + * + * @param elem - the element to create a view for + * @param axis - either View.X_AXIS or View.Y_AXIS + */ + public BlockView(Element elem, int axis) + { + super(elem, axis); + } + + /** + * Creates the parent view for this. It is called before + * any other methods, if the parent view is working properly. + * Implemented to forward to the superclass and call + * setPropertiesFromAttributes to set the paragraph + * properties. + * + * @param parent - the new parent, or null if the view + * is being removed from a parent it was added to. + */ + public void setParent(View parent) + { + super.setParent(parent); + + if (parent != null) + setPropertiesFromAttributes(); + } + + /** + * Calculates the requirements along the major axis. + * This is implemented to call the superclass and then + * adjust it if the CSS width or height attribute is specified + * and applicable. + * + * @param axis - the axis to check the requirements for. + * @param r - the SizeRequirements. If null, one is created. + * @return the new SizeRequirements object. + */ + protected SizeRequirements calculateMajorAxisRequirements(int axis, + SizeRequirements r) + { + SizeRequirements sr = super.calculateMajorAxisRequirements(axis, r); + // FIXME: adjust it if the CSS width or height attribute is specified + // and applicable + return sr; + } + + /** + * Calculates the requirements along the minor axis. + * This is implemented to call the superclass and then + * adjust it if the CSS width or height attribute is specified + * and applicable. + * + * @param axis - the axis to check the requirements for. + * @param r - the SizeRequirements. If null, one is created. + * @return the new SizeRequirements object. + */ + protected SizeRequirements calculateMinorAxisRequirements(int axis, + SizeRequirements r) + { + SizeRequirements sr = super.calculateMinorAxisRequirements(axis, r); + // FIXME: adjust it if the CSS width or height attribute is specified + // and applicable. + return sr; + } + + /** + * Lays out the box along the minor axis (the axis that is + * perpendicular to the axis that it represents). The results + * of the layout are placed in the given arrays which are + * the allocations to the children along the minor axis. + * + * @param targetSpan - the total span given to the view, also + * used to layout the children. + * @param axis - the minor axis + * @param offsets - the offsets from the origin of the view for + * all the child views. This is a return value and is filled in by this + * function. + * @param spans - the span of each child view. This is a return value and is + * filled in by this function. + */ + protected void layoutMinorAxis(int targetSpan, int axis, + int[] offsets, int[] spans) + { + // FIXME: Not implemented. + super.layoutMinorAxis(targetSpan, axis, offsets, spans); + } + + /** + * Paints using the given graphics configuration and shape. + * This delegates to the css box painter to paint the + * border and background prior to the interior. + * + * @param g - Graphics configuration + * @param a - the Shape to render into. + */ + public void paint(Graphics g, Shape a) + { + Rectangle rect = (Rectangle) a; + // FIXME: not fully implemented + getStyleSheet().getBoxPainter(getAttributes()).paint(g, rect.x, rect.y, + rect.width, + rect.height, this); + super.paint(g, a); + } + + /** + * Fetches the attributes to use when painting. + * + * @return the attributes of this model. + */ + public AttributeSet getAttributes() + { + return getStyleSheet().getViewAttributes(this); + } + + /** + * Gets the resize weight. + * + * @param axis - the axis to get the resize weight for. + * @return the resize weight. + * @throws IllegalArgumentException - for an invalid axis + */ + public int getResizeWeight(int axis) throws IllegalArgumentException + { + // Can't resize the Y_AXIS + if (axis == Y_AXIS) + return 0; + if (axis == X_AXIS) + return 1; + throw new IllegalArgumentException("Invalid Axis"); + } + + /** + * Gets the alignment. + * + * @param axis - the axis to get the alignment for. + * @return the alignment. + */ + public float getAlignment(int axis) + { + if (axis == X_AXIS) + return 0.0F; + if (axis == Y_AXIS) + { + if (getViewCount() == 0) + return 0.0F; + float prefHeight = getPreferredSpan(Y_AXIS); + float firstRowHeight = getView(0).getPreferredSpan(Y_AXIS); + return (firstRowHeight / 2.F) / prefHeight; + } + throw new IllegalArgumentException("Invalid Axis"); + } + + /** + * Gives notification from the document that attributes were + * changed in a location that this view is responsible for. + * + * @param ev - the change information + * @param a - the current shape of the view + * @param f - the factory to use to rebuild if the view has children. + */ + public void changedUpdate(DocumentEvent ev, + Shape a, ViewFactory f) + { + super.changedUpdate(ev, a, f); + + // If more elements were added, then need to set the properties for them + int currPos = ev.getOffset(); + if (currPos <= getStartOffset() && (currPos + ev.getLength()) >= getEndOffset()) + setPropertiesFromAttributes(); + } + + /** + * Determines the preferred span along the axis. + * + * @param axis - the view to get the preferred span for. + * @return the span the view would like to be painted into >=0/ + * The view is usually told to paint into the span that is returned, + * although the parent may choose to resize or break the view. + * @throws IllegalArgumentException - for an invalid axis + */ + public float getPreferredSpan(int axis) throws IllegalArgumentException + { + if (axis == X_AXIS || axis == Y_AXIS) + return super.getPreferredSpan(axis); + throw new IllegalArgumentException("Invalid Axis"); + } + + /** + * Determines the minimum span along the axis. + * + * @param axis - the axis to get the minimum span for. + * @return the span the view would like to be painted into >=0/ + * The view is usually told to paint into the span that is returned, + * although the parent may choose to resize or break the view. + * @throws IllegalArgumentException - for an invalid axis + */ + public float getMinimumSpan(int axis) throws IllegalArgumentException + { + if (axis == X_AXIS || axis == Y_AXIS) + return super.getMinimumSpan(axis); + throw new IllegalArgumentException("Invalid Axis"); + } + + /** + * Determines the maximum span along the axis. + * + * @param axis - the axis to get the maximum span for. + * @return the span the view would like to be painted into >=0/ + * The view is usually told to paint into the span that is returned, + * although the parent may choose to resize or break the view. + * @throws IllegalArgumentException - for an invalid axis + */ + public float getMaximumSpan(int axis) throws IllegalArgumentException + { + if (axis == X_AXIS || axis == Y_AXIS) + return super.getMaximumSpan(axis); + throw new IllegalArgumentException("Invalid Axis"); + } + + /** + * Updates any cached values that come from attributes. + */ + protected void setPropertiesFromAttributes() + { + // FIXME: Not implemented (need to use StyleSheet). + } + + /** + * Gets the default style sheet. + * + * @return the style sheet + */ + protected StyleSheet getStyleSheet() + { + StyleSheet styleSheet = new StyleSheet(); + styleSheet.importStyleSheet(getClass().getResource(HTMLEditorKit.DEFAULT_CSS)); + return styleSheet; + } +} diff --git a/libjava/classpath/javax/swing/text/html/CSS.java b/libjava/classpath/javax/swing/text/html/CSS.java index 029ad26..c248e75 100644 --- a/libjava/classpath/javax/swing/text/html/CSS.java +++ b/libjava/classpath/javax/swing/text/html/CSS.java @@ -37,6 +37,7 @@ exception statement from your version. */ package javax.swing.text.html; +import java.io.Serializable; import java.util.HashMap; /** @@ -46,7 +47,7 @@ import java.util.HashMap; * * @author Roman Kennke (kennke@aicas.com) */ -public class CSS +public class CSS implements Serializable { /** * Returns an array of all CSS attributes. diff --git a/libjava/classpath/javax/swing/text/html/CSSParser.java b/libjava/classpath/javax/swing/text/html/CSSParser.java new file mode 100644 index 0000000..0bf76eb --- /dev/null +++ b/libjava/classpath/javax/swing/text/html/CSSParser.java @@ -0,0 +1,568 @@ +/* CSSParser.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.swing.text.html; + +import java.io.*; + +/** + * Parses a CSS document. This works by way of a delegate that implements the + * CSSParserCallback interface. The delegate is notified of the following + * events: + * - Import statement: handleImport + * - Selectors handleSelector. This is invoked for each string. For example if + * the Reader contained p, bar , a {}, the delegate would be notified 4 times, + * for 'p,' 'bar' ',' and 'a'. + * - When a rule starts, startRule + * - Properties in the rule via the handleProperty. This + * is invoked one per property/value key, eg font size: foo;, would cause the + * delegate to be notified once with a value of 'font size'. + * - Values in the rule via the handleValue, this is notified for the total value. + * - When a rule ends, endRule + * + * @author Lillian Angel (langel@redhat.com) + */ +class CSSParser +{ + + /** + * Receives all information about the CSS document structure while parsing it. + * The methods are invoked by parser. + */ + static interface CSSParserCallback + { + /** + * Handles the import statment in the document. + * + * @param imp - the import string + */ + public abstract void handleImport(String imp); + + /** + * Called when the start of a rule is encountered. + */ + public abstract void startRule(); + + /** + * Called when the end of a rule is encountered. + */ + public abstract void endRule(); + + /** + * Handles the selector of a rule. + * + * @param selector - the selector in the rule + */ + public abstract void handleSelector(String selector); + + /** + * Handles the properties in the document. + * + * @param property - the property in the document. + */ + public abstract void handleProperty(String property); + + /** + * Handles the values in the document. + * + * @param value - the value to handle. + */ + public abstract void handleValue(String value); + + } + + /** + * The identifier of the rule. + */ + private static final int IDENTIFIER = 1; + + /** + * The open bracket. + */ + private static final int BRACKET_OPEN = 2; + + /** + * The close bracket. + */ + private static final int BRACKET_CLOSE = 3; + + /** + * The open brace. + */ + private static final int BRACE_OPEN = 4; + + /** + * The close brace. + */ + private static final int BRACE_CLOSE = 5; + + /** + * The open parentheses. + */ + private static final int PAREN_OPEN = 6; + + /** + * The close parentheses. + */ + private static final int PAREN_CLOSE = 7; + + /** + * The end of the document. + */ + private static final int END = -1; + + /** + * The character mapping in the document. + */ + // FIXME: What is this used for? + private static final char[] charMapping = null; + + /** + * Set to true if one character has been read ahead. + */ + private boolean didPushChar; + + /** + * The read ahead character. + */ + private int pushedChar; + + /** + * Temporary place to hold identifiers. + */ + private StringBuffer unitBuffer; + + /** + * Used to indicate blocks. + */ + private int[] unitStack; + + /** + * Number of valid blocks. + */ + private int stackCount; + + /** + * Holds the incoming CSS rules. + */ + private Reader reader; + + /** + * Set to true when the first non @ rule is encountered. + */ + private boolean encounteredRuleSet; + + /** + * The call back used to parse. + */ + private CSSParser.CSSParserCallback callback; + + /** + * nextToken() inserts the string here. + */ + private char[] tokenBuffer; + + /** + * Current number of chars in tokenBufferLength. + */ + private int tokenBufferLength; + + /** + * Set to true if any whitespace is read. + */ + private boolean readWS; + + /** + * Constructor + */ + CSSParser() + { + unitBuffer = new StringBuffer(); + tokenBuffer = new char[10]; + } + + /** + * Appends a character to the token buffer. + * + * @param c - the character to append + */ + private void append(char c) + { + if (tokenBuffer.length >= tokenBufferLength) + { + char[] temp = new char[tokenBufferLength * 2]; + if (tokenBuffer != null) + System.arraycopy(tokenBuffer, 0, temp, 0, tokenBufferLength); + + temp[tokenBufferLength] = c; + tokenBuffer = temp; + } + else + tokenBuffer[tokenBufferLength] = c; + tokenBufferLength++; + } + + /** + * Fetches the next token. + * + * @param c - the character to fetch. + * @return the location + * @throws IOException - any i/o error encountered while reading + */ + private int nextToken(char c) throws IOException + { + readWS = false; + int next = readWS(); + + switch (next) + { + case '\"': + if (tokenBufferLength > 0) + tokenBufferLength--; + return IDENTIFIER; + case '\'': + if (tokenBufferLength > 0) + tokenBufferLength--; + return IDENTIFIER; + case '(': + return PAREN_OPEN; + case ')': + return PAREN_CLOSE; + case '{': + return BRACE_OPEN; + case '}': + return BRACE_CLOSE; + case '[': + return BRACKET_OPEN; + case ']': + return BRACKET_CLOSE; + case -1: + return END; + default: + pushChar(next); + getIdentifier(c); + return IDENTIFIER; + } + } + + /** + * Reads a character from the stream. + * + * @return the number of characters read or -1 if end of stream is reached. + * @throws IOException - any i/o encountered while reading + */ + private int readChar() throws IOException + { + if (didPushChar) + { + didPushChar = false; + return pushedChar; + } + return reader.read(); + } + + /** + * Parses the the contents of the reader using the + * callback. + * + * @param reader - the reader to read from + * @param callback - the callback instance + * @param parsingDeclaration - true if parsing a declaration + * @throws IOException - any i/o error from the reader + */ + void parse(Reader reader, CSSParser.CSSParserCallback callback, + boolean parsingDeclaration) + throws IOException + { + this.reader = reader; + this.callback = callback; + + try + { + if (!parsingDeclaration) + while(getNextStatement()); + else + parseDeclarationBlock(); + } + catch (IOException ioe) + { + // Nothing to do here. + } + } + + /** + * Skips any white space, returning the character after the white space. + * + * @return the character after the whitespace + * @throws IOException - any i/o error from the reader + */ + private int readWS() throws IOException + { + int next = readChar(); + while (Character.isWhitespace((char) next)) + { + readWS = true; + int tempNext = readChar(); + if (tempNext == END) + return next; + next = tempNext; + } + + // Its all whitespace + return END; + } + + /** + * Gets the next statement, returning false if the end is reached. + * A statement is either an At-rule, or a ruleset. + * + * @return false if the end is reached + * @throws IOException - any i/o error from the reader + */ + private boolean getNextStatement() throws IOException + { + int c = nextToken((char) 0); + switch (c) + { + case PAREN_OPEN: + case BRACE_OPEN: + case BRACKET_OPEN: + parseTillClosed(c); + break; + case BRACKET_CLOSE: + case BRACE_CLOSE: + case PAREN_CLOSE: + throw new IOException("Not a proper statement."); + case IDENTIFIER: + if (tokenBuffer[0] == ('@')) + parseAtRule(); + else + parseRuleSet(); + break; + case END: + return false; + } + return true; + } + + /** + * Parses an @ rule, stopping at a matching brace pair, or ;. + * + * @throws IOException - any i/o error from the reader + */ + private void parseAtRule() throws IOException + { + // An At-Rule begins with the "@" character followed immediately by a keyword. + // Following the keyword separated by a space is an At-rule statement appropriate + // to the At-keyword used. If the At-Rule is a simple declarative statement + // (charset, import, fontdef), it is terminated by a semi-colon (";".) + // If the At-Rule is a conditional or informative statement (media, page, font-face), + // it is followed by optional arguments and then a style declaration block inside matching + // curly braces ("{", "}".) At-Rules are sometimes nestable, depending on the context. + // If any part of an At-Rule is not understood, it should be ignored. + + // FIXME: Not Implemented + // call handleimport + } + + /** + * Parses the next rule set, which is a selector followed by a declaration + * block. + * + * @throws IOException - any i/o error from the reader + */ + private void parseRuleSet() throws IOException + { + // call parseDeclarationBlock + // call parse selectors + // call parse identifiers + // call startrule/endrule + // FIXME: Not Implemented + } + + /** + * Parses a set of selectors, returning false if the end of the stream is + * reached. + * + * @return false if the end of stream is reached + * @throws IOException - any i/o error from the reader + */ + private boolean parseSelectors() throws IOException + { + // FIXME: Not Implemented + // call handleselector + return false; + } + + /** + * Parses a declaration block. Which a number of declarations followed by a + * })]. + * + * @throws IOException - any i/o error from the reader + */ + private void parseDeclarationBlock() throws IOException + { + // call parseDeclaration + // FIXME: Not Implemented + } + + /** + * Parses a single declaration, which is an identifier a : and another identifier. + * This returns the last token seen. + * + * @returns the last token + * @throws IOException - any i/o error from the reader + */ + private int parseDeclaration() throws IOException + { + // call handleValue + // FIXME: Not Implemented + return 0; + } + + /** + * Parses identifiers until c is encountered, returning the ending token, + * which will be IDENTIFIER if c is found. + * + * @param c - the stop character + * @param wantsBlocks - true if blocks are wanted + * @return the ending token + * @throws IOException - any i/o error from the reader + */ + private int parseIdentifiers(char c, boolean wantsBlocks) throws IOException + { + // FIXME: Not implemented + // call handleproperty? + return 0; + } + + /** + * Parses till a matching block close is encountered. This is only appropriate + * to be called at the top level (no nesting). + * + * @param i - FIXME + * @throws IOException - any i/o error from the reader + */ + private void parseTillClosed(int i) throws IOException + { + // FIXME: Not Implemented + } + + /** + * Gets an identifier, returning true if the length of the string is greater + * than 0, stopping when c, whitespace, or one of {}()[] is hit. + * + * @param c - the stop character + * @return returns true if the length of the string > 0 + * @throws IOException - any i/o error from the reader + */ + private boolean getIdentifier(char c) throws IOException + { + // FIXME: Not Implemented + return false; + } + + /** + * Reads till c is encountered, escaping characters as necessary. + * + * @param c - the stop character + * @throws IOException - any i/o error from the reader + */ + private void readTill(char c) throws IOException + { + // FIXME: Not Implemented + } + + /** + * Parses a comment block. + * + * @throws IOException - any i/o error from the reader + */ + private void readComment() throws IOException + { + // Should ignore comments. Read until end of comment. + // FIXME: Not implemented + } + + /** + * Called when a block start is encountered ({[. + * + * @param start of block + */ + private void startBlock(int start) + { + // FIXME: Not Implemented + } + + /** + * Called when an end block is encountered )]} + * + * @param end of block + */ + private void endBlock(int end) + { + // FIXME: Not Implemented + } + + /** + * Checks if currently in a block. + * + * @return true if currently in a block. + */ + private boolean inBlock() + { + // FIXME: Not Implemented + return false; + } + + /** + * Supports one character look ahead, this will throw if called twice in a row. + * + * @param c - the character to push. + * @throws IOException - if called twice in a row + */ + private void pushChar(int c) throws IOException + { + if (didPushChar) + throw new IOException("pushChar called twice."); + didPushChar = true; + pushedChar = c; + } +} + +
\ No newline at end of file diff --git a/libjava/classpath/javax/swing/text/html/HTMLDocument.java b/libjava/classpath/javax/swing/text/html/HTMLDocument.java index d048a04..5b2452b 100644 --- a/libjava/classpath/javax/swing/text/html/HTMLDocument.java +++ b/libjava/classpath/javax/swing/text/html/HTMLDocument.java @@ -40,17 +40,32 @@ package javax.swing.text.html; import java.net.URL; +import java.io.IOException; + +import java.util.HashMap; +import java.util.Stack; +import java.util.Vector; + +import javax.swing.event.DocumentEvent; +import javax.swing.event.UndoableEditEvent; import javax.swing.text.AbstractDocument; import javax.swing.text.AttributeSet; +import javax.swing.text.BadLocationException; import javax.swing.text.DefaultStyledDocument; import javax.swing.text.Element; import javax.swing.text.ElementIterator; +import javax.swing.text.GapContent; +import javax.swing.text.MutableAttributeSet; +import javax.swing.text.SimpleAttributeSet; +import javax.swing.text.StyleConstants; import javax.swing.text.html.HTML.Tag; /** - * TODO: This class is not yet completetely implemented. - * + * TODO: Add more comments here + * * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + * @author Anthony Balkissoon (abalkiss@redhat.com) + * @author Lillian Angel (langel@redhat.com) */ public class HTMLDocument extends DefaultStyledDocument { @@ -60,6 +75,195 @@ public class HTMLDocument extends DefaultStyledDocument public static final String AdditionalComments = "AdditionalComments"; URL baseURL = null; boolean preservesUnknownTags = true; + int tokenThreshold = Integer.MAX_VALUE; + HTMLEditorKit.Parser parser; + StyleSheet styleSheet; + AbstractDocument.Content content; + + /** + * Constructs an HTML document using the default buffer size and a default + * StyleSheet. + */ + public HTMLDocument() + { + this(null); + } + + /** + * Constructs an HTML document with the default content storage + * implementation and the specified style/attribute storage mechanism. + * + * @param styles - the style sheet + */ + public HTMLDocument(StyleSheet styles) + { + this(new GapContent(BUFFER_SIZE_DEFAULT), styles); + } + + /** + * Constructs an HTML document with the given content storage implementation + * and the given style/attribute storage mechanism. + * + * @param c - the document's content + * @param styles - the style sheet + */ + public HTMLDocument(AbstractDocument.Content c, StyleSheet styles) + { + this.content = c; + if (styles == null) + { + styles = new StyleSheet(); + styles.importStyleSheet(getClass().getResource(HTMLEditorKit. + DEFAULT_CSS)); + } + this.styleSheet = styles; + } + + /** + * Gets the style sheet with the document display rules (CSS) that were specified + * in the HTML document. + * + * @return - the style sheet + */ + public StyleSheet getStyleSheet() + { + return styleSheet; + } + + /** + * Replaces the contents of the document with the given element specifications. + * This is called before insert if the loading is done in bursts. This is the + * only method called if loading the document entirely in one burst. + * + * @param data - the date that replaces the content of the document + */ + protected void create(DefaultStyledDocument.ElementSpec[] data) + { + // FIXME: Not implemented + System.out.println("create not implemented"); + super.create(data); + } + + /** + * This method creates a root element for the new document. + * + * @return the new default root + */ + protected AbstractDocument.AbstractElement createDefaultRoot() + { + // FIXME: Not implemented + System.out.println("createDefaultRoot not implemented"); + return super.createDefaultRoot(); + } + + /** + * This method returns an HTMLDocument.RunElement object attached to + * parent representing a run of text from p0 to p1. The run has + * attributes described by a. + * + * @param parent - the parent element + * @param a - the attributes for the element + * @param p0 - the beginning of the range >= 0 + * @param p1 - the end of the range >= p0 + * @return the new element + */ + protected Element createLeafElement(Element parent, AttributeSet a, int p0, + int p1) + { + // FIXME: Not implemented + System.out.println("createLeafElement not implemented"); + return super.createLeafElement(parent, a, p0, p1); + } + + /** This method returns an HTMLDocument.BlockElement object representing the + * attribute set a and attached to parent. + * + * @param parent - the parent element + * @param a - the attributes for the element + * @return the new element + */ + protected Element createBranchElement(Element parent, AttributeSet a) + { + // FIXME: Not implemented + System.out.println("createBranchElement not implemented"); + return super.createBranchElement(parent, a); + } + + /** + * Inserts new elements in bulk. This is how elements get created in the + * document. The parsing determines what structure is needed and creates the + * specification as a set of tokens that describe the edit while leaving the + * document free of a write-lock. This method can then be called in bursts by + * the reader to acquire a write-lock for a shorter duration (i.e. while the + * document is actually being altered). + * + * @param offset - the starting offset + * @param data - the element data + * @throws BadLocationException - if the given position does not + * represent a valid location in the associated document. + */ + protected void insert(int offset, DefaultStyledDocument.ElementSpec[] data) + throws BadLocationException + { + super.insert(offset, data); + } + + /** + * Updates document structure as a result of text insertion. This will happen + * within a write lock. This implementation simply parses the inserted content + * for line breaks and builds up a set of instructions for the element buffer. + * + * @param chng - a description of the document change + * @param attr - the attributes + */ + protected void insertUpdate(AbstractDocument.DefaultDocumentEvent chng, + AttributeSet attr) + { + // FIXME: Not implemented + System.out.println("insertUpdate not implemented"); + super.insertUpdate(chng, attr); + } + + /** + * Returns the parser used by this HTMLDocument to insert HTML. + * + * @return the parser used by this HTMLDocument to insert HTML. + */ + public HTMLEditorKit.Parser getParser() + { + return parser; + } + + /** + * Sets the parser used by this HTMLDocument to insert HTML. + * + * @param p the parser to use + */ + public void setParser (HTMLEditorKit.Parser p) + { + parser = p; + } + /** + * Sets the number of tokens to buffer before trying to display the + * Document. + * + * @param n the number of tokens to buffer + */ + public void setTokenThreshold (int n) + { + tokenThreshold = n; + } + + /** + * Returns the number of tokens that are buffered before the document + * is rendered. + * + * @return the number of tokens buffered + */ + public int getTokenThreshold () + { + return tokenThreshold; + } /** * Returns the location against which to resolve relative URLs. @@ -79,7 +283,7 @@ public class HTMLDocument extends DefaultStyledDocument public void setBase(URL u) { baseURL = u; - //TODO: also set the base of the StyleSheet + styleSheet.setBase(u); } /** @@ -259,10 +463,1133 @@ public class HTMLDocument extends DefaultStyledDocument return null; } + /** + * Gets the name of the element. + * + * @return the name of the element if it exists, null otherwise. + */ public String getName() { - //FIXME: this is supposed to do something different from the super class - return super.getName(); + return (String) getAttribute(StyleConstants.NameAttribute); + } + } + + /** + * RunElement represents a section of text that has a set of + * HTML character level attributes assigned to it. + */ + public class RunElement extends AbstractDocument.LeafElement + { + + /** + * Constructs an element that has no children. It represents content + * within the document. + * + * @param parent - parent of this + * @param a - elements attributes + * @param start - the start offset >= 0 + * @param end - the end offset + */ + public RunElement(Element parent, AttributeSet a, int start, int end) + { + super(parent, a, start, end); + } + + /** + * Gets the name of the element. + * + * @return the name of the element if it exists, null otherwise. + */ + public String getName() + { + return (String) getAttribute(StyleConstants.NameAttribute); + } + + /** + * Gets the resolving parent. HTML attributes do not inherit at the + * model level, so this method returns null. + * + * @return null + */ + public AttributeSet getResolveParent() + { + return null; + } + } + + /** + * A reader to load an HTMLDocument with HTML structure. + * + * @author Anthony Balkissoon abalkiss at redhat dot com + */ + public class HTMLReader extends HTMLEditorKit.ParserCallback + { + /** Holds the current character attribute set **/ + protected MutableAttributeSet charAttr = new SimpleAttributeSet(); + + protected Vector parseBuffer = new Vector(); + + /** A stack for character attribute sets **/ + Stack charAttrStack = new Stack(); + + /** A mapping between HTML.Tag objects and the actions that handle them **/ + HashMap tagToAction; + + /** Tells us whether we've received the '</html>' tag yet **/ + boolean endHTMLEncountered = false; + + /** Variables related to the constructor with explicit insertTag **/ + int popDepth, pushDepth, offset; + HTML.Tag insertTag; + boolean insertTagEncountered = false; + + /** A temporary variable that helps with the printing out of debug information **/ + boolean debug = false; + + void print (String line) + { + if (debug) + System.out.println (line); + } + + public class TagAction + { + /** + * This method is called when a start tag is seen for one of the types + * of tags associated with this Action. By default this does nothing. + */ + public void start(HTML.Tag t, MutableAttributeSet a) + { + // Nothing to do here. + } + + /** + * Called when an end tag is seen for one of the types of tags associated + * with this Action. By default does nothing. + */ + public void end(HTML.Tag t) + { + // Nothing to do here. + } + } + + public class BlockAction extends TagAction + { + /** + * This method is called when a start tag is seen for one of the types + * of tags associated with this Action. + */ + public void start(HTML.Tag t, MutableAttributeSet a) + { + // Tell the parse buffer to open a new block for this tag. + blockOpen(t, a); + } + + /** + * Called when an end tag is seen for one of the types of tags associated + * with this Action. + */ + public void end(HTML.Tag t) + { + // Tell the parse buffer to close this block. + blockClose(t); + } + } + + public class CharacterAction extends TagAction + { + /** + * This method is called when a start tag is seen for one of the types + * of tags associated with this Action. + */ + public void start(HTML.Tag t, MutableAttributeSet a) + { + // Put the old attribute set on the stack. + pushCharacterStyle(); + + // And create the new one by adding the attributes in <code>a</code>. + if (a != null) + charAttr.addAttribute(t, a.copyAttributes()); + } + + /** + * Called when an end tag is seen for one of the types of tags associated + * with this Action. + */ + public void end(HTML.Tag t) + { + popCharacterStyle(); + } + } + + public class FormAction extends SpecialAction + { + /** + * This method is called when a start tag is seen for one of the types + * of tags associated with this Action. + */ + public void start(HTML.Tag t, MutableAttributeSet a) + { + // FIXME: Implement. + print ("FormAction.start not implemented"); + } + + /** + * Called when an end tag is seen for one of the types of tags associated + * with this Action. + */ + public void end(HTML.Tag t) + { + // FIXME: Implement. + print ("FormAction.end not implemented"); + } + } + + public class HiddenAction extends TagAction + { + /** + * This method is called when a start tag is seen for one of the types + * of tags associated with this Action. + */ + public void start(HTML.Tag t, MutableAttributeSet a) + { + // FIXME: Implement. + print ("HiddenAction.start not implemented"); + } + + /** + * Called when an end tag is seen for one of the types of tags associated + * with this Action. + */ + public void end(HTML.Tag t) + { + // FIXME: Implement. + print ("HiddenAction.end not implemented"); + } + } + + public class IsindexAction extends TagAction + { + /** + * This method is called when a start tag is seen for one of the types + * of tags associated with this Action. + */ + public void start(HTML.Tag t, MutableAttributeSet a) + { + // FIXME: Implement. + print ("IsindexAction.start not implemented"); + } + + /** + * Called when an end tag is seen for one of the types of tags associated + * with this Action. + */ + public void end(HTML.Tag t) + { + // FIXME: Implement. + print ("IsindexAction.end not implemented"); + } + } + + public class ParagraphAction extends BlockAction + { + /** + * This method is called when a start tag is seen for one of the types + * of tags associated with this Action. + */ + public void start(HTML.Tag t, MutableAttributeSet a) + { + // FIXME: Implement. + print ("ParagraphAction.start not implemented"); + } + + /** + * Called when an end tag is seen for one of the types of tags associated + * with this Action. + */ + public void end(HTML.Tag t) + { + // FIXME: Implement. + print ("ParagraphAction.end not implemented"); + } + } + + public class PreAction extends BlockAction + { + /** + * This method is called when a start tag is seen for one of the types + * of tags associated with this Action. + */ + public void start(HTML.Tag t, MutableAttributeSet a) + { + // FIXME: Implement. + print ("PreAction.start not implemented"); + } + + /** + * Called when an end tag is seen for one of the types of tags associated + * with this Action. + */ + public void end(HTML.Tag t) + { + // FIXME: Implement. + print ("PreAction.end not implemented"); + } + } + + public class SpecialAction extends TagAction + { + /** + * This method is called when a start tag is seen for one of the types + * of tags associated with this Action. + */ + public void start(HTML.Tag t, MutableAttributeSet a) + { + // FIXME: Implement. + print ("SpecialAction.start not implemented"); + } + + /** + * Called when an end tag is seen for one of the types of tags associated + * with this Action. + */ + public void end(HTML.Tag t) + { + // FIXME: Implement. + print ("SpecialAction.end not implemented"); + } + } + + class AreaAction extends TagAction + { + /** + * This method is called when a start tag is seen for one of the types + * of tags associated with this Action. + */ + public void start(HTML.Tag t, MutableAttributeSet a) + { + // FIXME: Implement. + print ("AreaAction.start not implemented"); + } + + /** + * Called when an end tag is seen for one of the types of tags associated + * with this Action. + */ + public void end(HTML.Tag t) + { + // FIXME: Implement. + print ("AreaAction.end not implemented"); + } + } + + class BaseAction extends TagAction + { + /** + * This method is called when a start tag is seen for one of the types + * of tags associated with this Action. + */ + public void start(HTML.Tag t, MutableAttributeSet a) + { + // FIXME: Implement. + print ("BaseAction.start not implemented"); + } + + /** + * Called when an end tag is seen for one of the types of tags associated + * with this Action. + */ + public void end(HTML.Tag t) + { + // FIXME: Implement. + print ("BaseAction.end not implemented"); + } + } + + class HeadAction extends BlockAction + { + /** + * This method is called when a start tag is seen for one of the types + * of tags associated with this Action. + */ + public void start(HTML.Tag t, MutableAttributeSet a) + { + // FIXME: Implement. + print ("HeadAction.start not implemented: "+t); + super.start(t, a); + } + + /** + * Called when an end tag is seen for one of the types of tags associated + * with this Action. + */ + public void end(HTML.Tag t) + { + // FIXME: Implement. + print ("HeadAction.end not implemented: "+t); + super.end(t); + } + } + + class LinkAction extends TagAction + { + /** + * This method is called when a start tag is seen for one of the types + * of tags associated with this Action. + */ + public void start(HTML.Tag t, MutableAttributeSet a) + { + // FIXME: Implement. + print ("LinkAction.start not implemented"); + } + + /** + * Called when an end tag is seen for one of the types of tags associated + * with this Action. + */ + public void end(HTML.Tag t) + { + // FIXME: Implement. + print ("LinkAction.end not implemented"); + } + } + + class MapAction extends TagAction + { + /** + * This method is called when a start tag is seen for one of the types + * of tags associated with this Action. + */ + public void start(HTML.Tag t, MutableAttributeSet a) + { + // FIXME: Implement. + print ("MapAction.start not implemented"); + } + + /** + * Called when an end tag is seen for one of the types of tags associated + * with this Action. + */ + public void end(HTML.Tag t) + { + // FIXME: Implement. + print ("MapAction.end not implemented"); + } + } + + class MetaAction extends TagAction + { + /** + * This method is called when a start tag is seen for one of the types + * of tags associated with this Action. + */ + public void start(HTML.Tag t, MutableAttributeSet a) + { + // FIXME: Implement. + print ("MetaAction.start not implemented"); + } + + /** + * Called when an end tag is seen for one of the types of tags associated + * with this Action. + */ + public void end(HTML.Tag t) + { + // FIXME: Implement. + print ("MetaAction.end not implemented"); + } + } + + class StyleAction extends TagAction + { + /** + * This method is called when a start tag is seen for one of the types + * of tags associated with this Action. + */ + public void start(HTML.Tag t, MutableAttributeSet a) + { + // FIXME: Implement. + print ("StyleAction.start not implemented"); + } + + /** + * Called when an end tag is seen for one of the types of tags associated + * with this Action. + */ + public void end(HTML.Tag t) + { + // FIXME: Implement. + print ("StyleAction.end not implemented"); + } + } + + class TitleAction extends TagAction + { + /** + * This method is called when a start tag is seen for one of the types + * of tags associated with this Action. + */ + public void start(HTML.Tag t, MutableAttributeSet a) + { + // FIXME: Implement. + print ("TitleAction.start not implemented"); + } + + /** + * Called when an end tag is seen for one of the types of tags associated + * with this Action. + */ + public void end(HTML.Tag t) + { + // FIXME: Implement. + print ("TitleAction.end not implemented"); + } + } + + public HTMLReader(int offset) + { + this (offset, 0, 0, null); + } + + public HTMLReader(int offset, int popDepth, int pushDepth, + HTML.Tag insertTag) + { + print ("HTMLReader created with pop: "+popDepth + + " push: "+pushDepth + " offset: "+offset + + " tag: "+insertTag); + this.insertTag = insertTag; + this.offset = offset; + this.popDepth = popDepth; + this.pushDepth = pushDepth; + initTags(); + } + + void initTags() + { + tagToAction = new HashMap(72); + CharacterAction characterAction = new CharacterAction(); + HiddenAction hiddenAction = new HiddenAction(); + AreaAction areaAction = new AreaAction(); + BaseAction baseAction = new BaseAction(); + BlockAction blockAction = new BlockAction(); + SpecialAction specialAction = new SpecialAction(); + ParagraphAction paragraphAction = new ParagraphAction(); + HeadAction headAction = new HeadAction(); + FormAction formAction = new FormAction(); + IsindexAction isindexAction = new IsindexAction(); + LinkAction linkAction = new LinkAction(); + MapAction mapAction = new MapAction(); + PreAction preAction = new PreAction(); + MetaAction metaAction = new MetaAction(); + StyleAction styleAction = new StyleAction(); + TitleAction titleAction = new TitleAction(); + + + tagToAction.put(HTML.Tag.A, characterAction); + tagToAction.put(HTML.Tag.ADDRESS, characterAction); + tagToAction.put(HTML.Tag.APPLET, hiddenAction); + tagToAction.put(HTML.Tag.AREA, areaAction); + tagToAction.put(HTML.Tag.B, characterAction); + tagToAction.put(HTML.Tag.BASE, baseAction); + tagToAction.put(HTML.Tag.BASEFONT, characterAction); + tagToAction.put(HTML.Tag.BIG, characterAction); + tagToAction.put(HTML.Tag.BLOCKQUOTE, blockAction); + tagToAction.put(HTML.Tag.BODY, blockAction); + tagToAction.put(HTML.Tag.BR, specialAction); + tagToAction.put(HTML.Tag.CAPTION, blockAction); + tagToAction.put(HTML.Tag.CENTER, blockAction); + tagToAction.put(HTML.Tag.CITE, characterAction); + tagToAction.put(HTML.Tag.CODE, characterAction); + tagToAction.put(HTML.Tag.DD, blockAction); + tagToAction.put(HTML.Tag.DFN, characterAction); + tagToAction.put(HTML.Tag.DIR, blockAction); + tagToAction.put(HTML.Tag.DIV, blockAction); + tagToAction.put(HTML.Tag.DL, blockAction); + tagToAction.put(HTML.Tag.DT, paragraphAction); + tagToAction.put(HTML.Tag.EM, characterAction); + tagToAction.put(HTML.Tag.FONT, characterAction); + tagToAction.put(HTML.Tag.FORM, blockAction); + tagToAction.put(HTML.Tag.FRAME, specialAction); + tagToAction.put(HTML.Tag.FRAMESET, blockAction); + tagToAction.put(HTML.Tag.H1, paragraphAction); + tagToAction.put(HTML.Tag.H2, paragraphAction); + tagToAction.put(HTML.Tag.H3, paragraphAction); + tagToAction.put(HTML.Tag.H4, paragraphAction); + tagToAction.put(HTML.Tag.H5, paragraphAction); + tagToAction.put(HTML.Tag.H6, paragraphAction); + tagToAction.put(HTML.Tag.HEAD, headAction); + tagToAction.put(HTML.Tag.HR, specialAction); + tagToAction.put(HTML.Tag.HTML, blockAction); + tagToAction.put(HTML.Tag.I, characterAction); + tagToAction.put(HTML.Tag.IMG, specialAction); + tagToAction.put(HTML.Tag.INPUT, formAction); + tagToAction.put(HTML.Tag.ISINDEX, isindexAction); + tagToAction.put(HTML.Tag.KBD, characterAction); + tagToAction.put(HTML.Tag.LI, blockAction); + tagToAction.put(HTML.Tag.LINK, linkAction); + tagToAction.put(HTML.Tag.MAP, mapAction); + tagToAction.put(HTML.Tag.MENU, blockAction); + tagToAction.put(HTML.Tag.META, metaAction); + tagToAction.put(HTML.Tag.NOFRAMES, blockAction); + tagToAction.put(HTML.Tag.OBJECT, specialAction); + tagToAction.put(HTML.Tag.OL, blockAction); + tagToAction.put(HTML.Tag.OPTION, formAction); + tagToAction.put(HTML.Tag.P, paragraphAction); + tagToAction.put(HTML.Tag.PARAM, hiddenAction); + tagToAction.put(HTML.Tag.PRE, preAction); + tagToAction.put(HTML.Tag.SAMP, characterAction); + tagToAction.put(HTML.Tag.SCRIPT, hiddenAction); + tagToAction.put(HTML.Tag.SELECT, formAction); + tagToAction.put(HTML.Tag.SMALL, characterAction); + tagToAction.put(HTML.Tag.STRIKE, characterAction); + tagToAction.put(HTML.Tag.S, characterAction); + tagToAction.put(HTML.Tag.STRONG, characterAction); + tagToAction.put(HTML.Tag.STYLE, styleAction); + tagToAction.put(HTML.Tag.SUB, characterAction); + tagToAction.put(HTML.Tag.SUP, characterAction); + tagToAction.put(HTML.Tag.TABLE, blockAction); + tagToAction.put(HTML.Tag.TD, blockAction); + tagToAction.put(HTML.Tag.TEXTAREA, formAction); + tagToAction.put(HTML.Tag.TH, blockAction); + tagToAction.put(HTML.Tag.TITLE, titleAction); + tagToAction.put(HTML.Tag.TR, blockAction); + tagToAction.put(HTML.Tag.TT, characterAction); + tagToAction.put(HTML.Tag.U, characterAction); + tagToAction.put(HTML.Tag.UL, blockAction); + tagToAction.put(HTML.Tag.VAR, characterAction); + } + + /** + * Pushes the current character style onto the stack. + * + */ + protected void pushCharacterStyle() + { + charAttrStack.push(charAttr); + } + + /** + * Pops a character style off of the stack and uses it as the + * current character style. + * + */ + protected void popCharacterStyle() + { + if (!charAttrStack.isEmpty()) + charAttr = (MutableAttributeSet) charAttrStack.pop(); + } + + /** + * Registers a given tag with a given Action. All of the well-known tags + * are registered by default, but this method can change their behaviour + * or add support for custom or currently unsupported tags. + * + * @param t the Tag to register + * @param a the Action for the Tag + */ + protected void registerTag(HTML.Tag t, HTMLDocument.HTMLReader.TagAction a) + { + tagToAction.put (t, a); + } + + /** + * This is the last method called on the HTMLReader, allowing any pending + * changes to be flushed to the HTMLDocument. + */ + public void flush() throws BadLocationException + { + DefaultStyledDocument.ElementSpec[] elements; + elements = new DefaultStyledDocument.ElementSpec[parseBuffer.size()]; + parseBuffer.copyInto(elements); + parseBuffer.removeAllElements(); + insert(offset, elements); + offset += HTMLDocument.this.getLength() - offset; + } + + /** + * This method is called by the parser to indicate a block of + * text was encountered. Should insert the text appropriately. + * + * @param data the text that was inserted + * @param pos the position at which the text was inserted + */ + public void handleText(char[] data, int pos) + { + if (data != null && data.length > 0) + addContent(data, 0, data.length); + } + + /** + * This method is called by the parser and should route the call to + * the proper handler for the tag. + * + * @param t the HTML.Tag + * @param a the attribute set + * @param pos the position at which the tag was encountered + */ + public void handleStartTag(HTML.Tag t, MutableAttributeSet a, int pos) + { + // Don't call the Action if we've already seen </html>. + if (endHTMLEncountered) + return; + + TagAction action = (TagAction) tagToAction.get(t); + if (action != null) + action.start(t, a); + } + + /** + * This method called by parser to handle a comment block. + * + * @param data the comment + * @param pos the position at which the comment was encountered + */ + public void handleComment(char[] data, int pos) + { + // Don't call the Action if we've already seen </html>. + if (endHTMLEncountered) + return; + + TagAction action = (TagAction) tagToAction.get(HTML.Tag.COMMENT); + if (action != null) + { + action.start(HTML.Tag.COMMENT, new SimpleAttributeSet()); + action.end (HTML.Tag.COMMENT); + } + } + + /** + * This method is called by the parser and should route the call to + * the proper handler for the tag. + * + * @param t the HTML.Tag + * @param pos the position at which the tag was encountered + */ + public void handleEndTag(HTML.Tag t, int pos) + { + // Don't call the Action if we've already seen </html>. + if (endHTMLEncountered) + return; + + // If this is the </html> tag we need to stop calling the Actions + if (t == HTML.Tag.HTML) + endHTMLEncountered = true; + + TagAction action = (TagAction) tagToAction.get(t); + if (action != null) + action.end(t); + } + + /** + * This is a callback from the parser that should be routed to the + * appropriate handler for the tag. + * + * @param t the HTML.Tag that was encountered + * @param a the attribute set + * @param pos the position at which the tag was encountered + */ + public void handleSimpleTag(HTML.Tag t, MutableAttributeSet a, int pos) + { + // Don't call the Action if we've already seen </html>. + if (endHTMLEncountered) + return; + + TagAction action = (TagAction) tagToAction.get (t); + if (action != null) + { + action.start(t, a); + action.end(t); + } + } + + /** + * This is invoked after the stream has been parsed but before it has been + * flushed. + * + * @param eol one of \n, \r, or \r\n, whichever was encountered the most in + * parsing the stream + * @since 1.3 + */ + public void handleEndOfLineString(String eol) + { + // FIXME: Implement. + print ("HTMLReader.handleEndOfLineString not implemented yet"); + } + + /** + * Adds the given text to the textarea document. Called only when we are + * within a textarea. + * + * @param data the text to add to the textarea + */ + protected void textAreaContent(char[] data) + { + // FIXME: Implement. + print ("HTMLReader.textAreaContent not implemented yet"); + } + + /** + * Adds the given text that was encountered in a <PRE> element. + * + * @param data the text + */ + protected void preContent(char[] data) + { + // FIXME: Implement + print ("HTMLReader.preContent not implemented yet"); + } + + /** + * Instructs the parse buffer to create a block element with the given + * attributes. + * + * @param t the tag that requires opening a new block + * @param attr the attribute set for the new block + */ + protected void blockOpen(HTML.Tag t, MutableAttributeSet attr) + { + printBuffer(); + DefaultStyledDocument.ElementSpec element; + element = new DefaultStyledDocument.ElementSpec(attr.copyAttributes(), + DefaultStyledDocument.ElementSpec.StartTagType); + parseBuffer.addElement(element); + printBuffer(); + } + + /** + * Instructs the parse buffer to close the block element associated with + * the given HTML.Tag + * + * @param t the HTML.Tag that is closing its block + */ + protected void blockClose(HTML.Tag t) + { + printBuffer(); + DefaultStyledDocument.ElementSpec element; + element = new DefaultStyledDocument.ElementSpec(null, + DefaultStyledDocument.ElementSpec.EndTagType); + parseBuffer.addElement(element); + printBuffer(); } + + /** + * Adds text to the appropriate context using the current character + * attribute set. + * + * @param data the text to add + * @param offs the offset at which to add it + * @param length the length of the text to add + */ + protected void addContent(char[] data, int offs, int length) + { + addContent(data, offs, length, true); + } + + /** + * Adds text to the appropriate context using the current character + * attribute set, and possibly generating an IMPLIED Tag if necessary. + * + * @param data the text to add + * @param offs the offset at which to add it + * @param length the length of the text to add + * @param generateImpliedPIfNecessary whether or not we should generate + * an HTML.Tag.IMPLIED tag if necessary + */ + protected void addContent(char[] data, int offs, int length, + boolean generateImpliedPIfNecessary) + { + // Copy the attribute set, don't use the same object because + // it may change + AttributeSet attributes = null; + if (charAttr != null) + attributes = charAttr.copyAttributes(); + + DefaultStyledDocument.ElementSpec element; + element = new DefaultStyledDocument.ElementSpec(attributes, + DefaultStyledDocument.ElementSpec.ContentType, + data, offs, length); + + printBuffer(); + // Add the element to the buffer + parseBuffer.addElement(element); + printBuffer(); + + if (parseBuffer.size() > HTMLDocument.this.getTokenThreshold()) + { + try + { + flush(); + } + catch (BadLocationException ble) + { + // TODO: what to do here? + } + } + } + + /** + * Adds content that is specified in the attribute set. + * + * @param t the HTML.Tag + * @param a the attribute set specifying the special content + */ + protected void addSpecialElement(HTML.Tag t, MutableAttributeSet a) + { + // FIXME: Implement + print ("HTMLReader.addSpecialElement not implemented yet"); + } + + void printBuffer() + { + print ("\n*********BUFFER**********"); + for (int i = 0; i < parseBuffer.size(); i ++) + print (" "+parseBuffer.get(i)); + print ("***************************"); + } + } + + /** + * Gets the reader for the parser to use when loading the document with HTML. + * + * @param pos - the starting position + * @return - the reader + */ + public HTMLEditorKit.ParserCallback getReader(int pos) + { + return new HTMLReader(pos); + } + + /** + * Gets the reader for the parser to use when loading the document with HTML. + * + * @param pos - the starting position + * @param popDepth - the number of EndTagTypes to generate before inserting + * @param pushDepth - the number of StartTagTypes with a direction + * of JoinNextDirection that should be generated before inserting, + * but after the end tags have been generated. + * @param insertTag - the first tag to start inserting into document + * @return - the reader + */ + public HTMLEditorKit.ParserCallback getReader(int pos, + int popDepth, + int pushDepth, + HTML.Tag insertTag) + { + return new HTMLReader(pos, popDepth, pushDepth, insertTag); + } + + /** + * Gets the child element that contains the attribute with the value or null. + * Not thread-safe. + * + * @param e - the element to begin search at + * @param attribute - the desired attribute + * @param value - the desired value + * @return the element found with the attribute and value specified or null + * if it is not found. + */ + public Element getElement(Element e, Object attribute, Object value) + { + if (e != null) + { + if (e.getAttributes().containsAttribute(attribute, value)) + return e; + + int count = e.getElementCount(); + for (int j = 0; j < count; j++) + { + Element child = e.getElement(j); + if (child.getAttributes().containsAttribute(attribute, value)) + return child; + + Element grandChild = getElement(child, attribute, value); + if (grandChild != null) + return grandChild; + } + } + return null; + } + + /** + * Returns the element that has the given id Attribute. If it is not found, + * null is returned. This method works on an Attribute, not a character tag. + * This is not thread-safe. + * + * @param attrId - the Attribute id to look for + * @return the element that has the given id. + */ + public Element getElement(String attrId) + { + Element root = getDefaultRootElement(); + return getElement(root, HTML.getAttributeKey(attrId) , attrId); + } + + /** + * Replaces the children of the given element with the contents of + * the string. The document must have an HTMLEditorKit.Parser set. + * This will be seen as at least two events, n inserts followed by a remove. + * + * @param elem - the brance element whose children will be replaced + * @param htmlText - the string to be parsed and assigned to element. + * @throws BadLocationException + * @throws IOException + * @throws IllegalArgumentException - if elem is a leaf + * @throws IllegalStateException - if an HTMLEditorKit.Parser has not been set + */ + public void setInnerHTML(Element elem, String htmlText) + throws BadLocationException, IOException + { + if (elem.isLeaf()) + throw new IllegalArgumentException("Element is a leaf"); + if (parser == null) + throw new IllegalStateException("Parser has not been set"); + // FIXME: Not implemented fully, use InsertHTML* in HTMLEditorKit? + System.out.println("setInnerHTML not implemented"); + } + + /** + * Replaces the given element in the parent with the string. When replacing + * a leaf, this will attempt to make sure there is a newline present if one is + * needed. This may result in an additional element being inserted. + * This will be seen as at least two events, n inserts followed by a remove. + * The HTMLEditorKit.Parser must be set. + * + * @param elem - the branch element whose parent will be replaced + * @param htmlText - the string to be parsed and assigned to elem + * @throws BadLocationException + * @throws IOException + * @throws IllegalStateException - if parser is not set + */ + public void setOuterHTML(Element elem, String htmlText) + throws BadLocationException, IOException + { + if (parser == null) + throw new IllegalStateException("Parser has not been set"); + // FIXME: Not implemented fully, use InsertHTML* in HTMLEditorKit? + System.out.println("setOuterHTML not implemented"); + } + + /** + * Inserts the string before the start of the given element. + * The parser must be set. + * + * @param elem - the element to be the root for the new text. + * @param htmlText - the string to be parsed and assigned to elem + * @throws BadLocationException + * @throws IOException + * @throws IllegalStateException - if parser has not been set + */ + public void insertBeforeStart(Element elem, String htmlText) + throws BadLocationException, IOException + { + if (parser == null) + throw new IllegalStateException("Parser has not been set"); + // FIXME: Not implemented fully, use InsertHTML* in HTMLEditorKit? + System.out.println("insertBeforeStart not implemented"); + } + + /** + * Inserts the string at the end of the element. If elem's children + * are leaves, and the character at elem.getEndOffset() - 1 is a newline, + * then it will be inserted before the newline. The parser must be set. + * + * @param elem - the element to be the root for the new text + * @param htmlText - the text to insert + * @throws BadLocationException + * @throws IOException + * @throws IllegalStateException - if parser is not set + */ + public void insertBeforeEnd(Element elem, String htmlText) + throws BadLocationException, IOException + { + if (parser == null) + throw new IllegalStateException("Parser has not been set"); + // FIXME: Not implemented fully, use InsertHTML* in HTMLEditorKit? + System.out.println("insertBeforeEnd not implemented"); + } + + /** + * Inserts the string after the end of the given element. + * The parser must be set. + * + * @param elem - the element to be the root for the new text + * @param htmlText - the text to insert + * @throws BadLocationException + * @throws IOException + * @throws IllegalStateException - if parser is not set + */ + public void insertAfterEnd(Element elem, String htmlText) + throws BadLocationException, IOException + { + if (parser == null) + throw new IllegalStateException("Parser has not been set"); + // FIXME: Not implemented fully, use InsertHTML* in HTMLEditorKit? + System.out.println("insertAfterEnd not implemented"); + } + + /** + * Inserts the string at the start of the element. + * The parser must be set. + * + * @param elem - the element to be the root for the new text + * @param htmlText - the text to insert + * @throws BadLocationException + * @throws IOException + * @throws IllegalStateException - if parser is not set + */ + public void insertAfterStart(Element elem, String htmlText) + throws BadLocationException, IOException + { + if (parser == null) + throw new IllegalStateException("Parser has not been set"); + // FIXME: Not implemented fully, use InsertHTML* in HTMLEditorKit? + System.out.println("insertAfterStart not implemented"); + } + + /** + * This method sets the attributes associated with the paragraph containing + * offset. If replace is false, s is merged with existing attributes. The + * length argument determines how many characters are affected by the new + * attributes. This is often the entire paragraph. + * + * @param offset - + * the offset into the paragraph (must be at least 0) + * @param length - + * the number of characters affected (must be at least 0) + * @param s - + * the attributes + * @param replace - + * whether to replace existing attributes, or merge them + */ + public void setParagraphAttributes(int offset, int length, AttributeSet s, + boolean replace) + { + // FIXME: Not implemented. + System.out.println("setParagraphAttributes not implemented"); + super.setParagraphAttributes(offset, length, s, replace); + } + + /** + * This method flags a change in the document. + * + * @param e - the Document event + */ + protected void fireChangedUpdate(DocumentEvent e) + { + // FIXME: Not implemented. + System.out.println("fireChangedUpdate not implemented"); + super.fireChangedUpdate(e); + } + + /** + * This method fires an event intended to be caught by Undo listeners. It + * simply calls the super version inherited from DefaultStyledDocument. With + * this method, an HTML editor could easily provide undo support. + * + * @param e - the UndoableEditEvent + */ + protected void fireUndoableEditUpdate(UndoableEditEvent e) + { + super.fireUndoableEditUpdate(e); } } diff --git a/libjava/classpath/javax/swing/text/html/HTMLEditorKit.java b/libjava/classpath/javax/swing/text/html/HTMLEditorKit.java index 5189c77..1ef9768 100644 --- a/libjava/classpath/javax/swing/text/html/HTMLEditorKit.java +++ b/libjava/classpath/javax/swing/text/html/HTMLEditorKit.java @@ -38,28 +38,563 @@ exception statement from your version. */ package javax.swing.text.html; + +import java.awt.event.ActionEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionListener; +import java.awt.Cursor; + import java.io.IOException; import java.io.Reader; import java.io.Serializable; +import java.io.StringReader; +import java.io.Writer; +import javax.accessibility.Accessible; +import javax.accessibility.AccessibleContext; + +import javax.swing.Action; +import javax.swing.JEditorPane; +import javax.swing.text.AbstractDocument; import javax.swing.text.BadLocationException; +import javax.swing.text.BoxView; +import javax.swing.text.ComponentView; import javax.swing.text.Document; +import javax.swing.text.EditorKit; +import javax.swing.text.Element; +import javax.swing.text.IconView; +import javax.swing.text.LabelView; import javax.swing.text.MutableAttributeSet; +import javax.swing.text.ParagraphView; +import javax.swing.text.StyleConstants; +import javax.swing.text.StyleContext; import javax.swing.text.StyledEditorKit; +import javax.swing.text.TextAction; +import javax.swing.text.View; +import javax.swing.text.ViewFactory; import javax.swing.text.html.parser.ParserDelegator; /** - * This class is NOT implemented. This file currently holds only - * declarations of the two enclosing classes, necessary for testing - * the implemented javax.swing.text.html.parser package. - * - * @author No authorship is taken, implement the class and be! - * TODO: replace this header after implementing the class. + * @author Lillian Angel (langel at redhat dot com) */ public class HTMLEditorKit extends StyledEditorKit - implements Serializable, Cloneable + implements Serializable, Cloneable, Accessible { + + /** + * Fires the hyperlink events on the associated component + * when needed. + */ + public static class LinkController + extends MouseAdapter + implements MouseMotionListener, Serializable + { + + /** + * Constructor + */ + public LinkController() + { + super(); + } + + /** + * Dispatched when the mouse is clicked. If the component + * is read-only, then the clicked event is used to drive an + * attempt to follow the reference specified by a link + * + * @param e - the mouse event + */ + public void mouseClicked(MouseEvent e) + { + /* + These MouseInputAdapter methods generate mouse appropriate events around + hyperlinks (entering, exiting, and activating). + */ + // FIXME: Not implemented. + } + + /** + * Dispatched when the mouse is dragged on a component. + * + * @param e - the mouse event. + */ + public void mouseDragged(MouseEvent e) + { + /* + These MouseInputAdapter methods generate mouse appropriate events around + hyperlinks (entering, exiting, and activating). + */ + // FIXME: Not implemented. + } + + /** + * Dispatched when the mouse cursor has moved into the component. + * + * @param e - the mouse event. + */ + public void mouseMoved(MouseEvent e) + { + /* + These MouseInputAdapter methods generate mouse appropriate events around + hyperlinks (entering, exiting, and activating). + */ + // FIXME: Not implemented. + } + + /** + * If the given position represents a link, then linkActivated is called + * on the JEditorPane. Implemented to forward to the method with the same + * name, but pos == editor == -1. + * + * @param pos - the position + * @param editor - the editor pane + */ + protected void activateLink(int pos, + JEditorPane editor) + { + /* + This method creates and fires a HyperlinkEvent if the document is an + instance of HTMLDocument and the href tag of the link is not null. + */ + // FIXME: Not implemented. + } + } + + /** + * This class is used to insert a string of HTML into an existing + * document. At least 2 HTML.Tags need to be supplied. The first Tag (parentTag) + * identifies the parent in the document to add the elements to. The second, (addTag), + * identifies that the first tag should be added to the document as seen in the string. + * The parser will generate all appropriate (opening/closing tags_ even if they are not + * in the HTML string passed in. + */ + public static class InsertHTMLTextAction + extends HTMLTextAction + { + + /** + * Tag in HTML to start adding tags from. + */ + protected HTML.Tag addTag; + + /** + * Alternate tag in HTML to start adding tags from if parentTag is + * not found and alternateParentTag is not found. + */ + protected HTML.Tag alternateAddTag; + + /** + * Alternate tag to check if parentTag is not found. + */ + protected HTML.Tag alternateParentTag; + + /** + * HTML to insert. + */ + protected String html; + + /** + * Tag to check for in the document. + */ + protected HTML.Tag parentTag; + + /** + * Initializes all fields. + * + * @param name - the name of the document. + * @param html - the html to insert + * @param parentTag - the parent tag to check for + * @param addTag - the tag to start adding from + */ + public InsertHTMLTextAction(String name, String html, + HTML.Tag parentTag, HTML.Tag addTag) + { + this(name, html, parentTag, addTag, null, null); + } + + /** + * Initializes all fields and calls super + * + * @param name - the name of the document. + * @param html - the html to insert + * @param parentTag - the parent tag to check for + * @param addTag - the tag to start adding from + * @param alternateParentTag - the alternate parent tag + * @param alternateAddTag - the alternate add tag + */ + public InsertHTMLTextAction(String name, String html, HTML.Tag parentTag, + HTML.Tag addTag, HTML.Tag alternateParentTag, + HTML.Tag alternateAddTag) + { + super(name); + // Fields are for easy access when the action is applied to an actual + // document. + this.html = html; + this.parentTag = parentTag; + this.addTag = addTag; + this.alternateParentTag = alternateParentTag; + this.alternateAddTag = alternateAddTag; + } + + /** + * HTMLEditorKit.insertHTML is called. If an exception is + * thrown, it is wrapped in a RuntimeException and thrown. + * + * @param editor - the editor to use to get the editorkit + * @param doc - + * the Document to insert the HTML into. + * @param offset - + * where to begin inserting the HTML. + * @param html - + * the String to insert + * @param popDepth - + * the number of ElementSpec.EndTagTypes to generate before + * inserting + * @param pushDepth - + * the number of ElementSpec.StartTagTypes with a direction of + * ElementSpec.JoinNextDirection that should be generated before + * @param addTag - + * the first tag to start inserting into document + */ + protected void insertHTML(JEditorPane editor, HTMLDocument doc, int offset, + String html, int popDepth, int pushDepth, + HTML.Tag addTag) + { + try + { + super.getHTMLEditorKit(editor).insertHTML(doc, offset, html, + popDepth, pushDepth, addTag); + } + catch (IOException e) + { + throw (RuntimeException) new RuntimeException("Parser is null.").initCause(e); + } + catch (BadLocationException ex) + { + throw (RuntimeException) new RuntimeException("BadLocationException: " + + offset).initCause(ex); + } + } + + /** + * Invoked when inserting at a boundary. Determines the number of pops, + * and then the number of pushes that need to be performed. The it calls + * insertHTML. + * + * @param editor - + * the editor to use to get the editorkit + * @param doc - + * the Document to insert the HTML into. + * @param offset - + * where to begin inserting the HTML. + * @param insertElement - + * the element to insert + * @param html - + * the html to insert + * @param parentTag - + * the parent tag + * @param addTag - + * the first tag + */ + protected void insertAtBoundary(JEditorPane editor, + HTMLDocument doc, int offset, + Element insertElement, + String html, HTML.Tag parentTag, + HTML.Tag addTag) + { + /* + As its name implies, this protected method is used when HTML is inserted at a + boundary. (A boundary in this case is an offset in doc that exactly matches the + beginning offset of the parentTag.) It performs the extra work required to keep + the tag stack in shape and then calls insertHTML(). The editor and doc argu- + ments are the editor pane and document where the HTML should go. The offset + argument represents the cursor location or selection start in doc. The insert- + Element and parentTag arguments are used to calculate the proper number of + tag pops and pushes before inserting the HTML (via html and addTag, which are + passed directly to insertHTML()). + */ + // FIXME: not implemented + } + + /** + * Invoked when inserting at a boundary. Determines the number of pops, + * and then the number of pushes that need to be performed. The it calls + * insertHTML. + * + * @param editor - the editor to use to get the editorkit + * @param doc - + * the Document to insert the HTML into. + * @param offset - + * where to begin inserting the HTML. + * @param insertElement - the element to insert + * @param html - the html to insert + * @param parentTag - the parent tag + * @param addTag - the first tag + * + * @deprecated as of v1.3, use insertAtBoundary + */ + protected void insertAtBoundry(JEditorPane editor, + HTMLDocument doc, + int offset, Element insertElement, + String html, HTML.Tag parentTag, + HTML.Tag addTag) + { + insertAtBoundary(editor, doc, offset, insertElement, + html, parentTag, addTag); + } + + /** + * Inserts the HTML. + * + * @param ae - the action performed + */ + public void actionPerformed(ActionEvent ae) + { + Object source = ae.getSource(); + if (source instanceof JEditorPane) + { + JEditorPane pane = ((JEditorPane) source); + Document d = pane.getDocument(); + if (d instanceof HTMLDocument) + insertHTML(pane, (HTMLDocument) d, 0, html, 0, 0, addTag); + // FIXME: is this correct parameters? + } + // FIXME: else not implemented + } + } + + /** + * Abstract Action class that helps inserting HTML into an existing document. + */ + public abstract static class HTMLTextAction + extends StyledEditorKit.StyledTextAction + { + + /** + * Constructor + */ + public HTMLTextAction(String name) + { + super(name); + } + + /** + * Gets the HTMLDocument from the JEditorPane. + * + * @param e - the editor pane + * @return the html document. + */ + protected HTMLDocument getHTMLDocument(JEditorPane e) + { + Document d = e.getDocument(); + if (d instanceof HTMLDocument) + return (HTMLDocument) d; + throw new IllegalArgumentException("Document is not a HTMLDocument."); + } + + /** + * Gets the HTMLEditorKit + * + * @param e - the JEditorPane to get the HTMLEditorKit from. + * @return the HTMLEditorKit + */ + protected HTMLEditorKit getHTMLEditorKit(JEditorPane e) + { + EditorKit d = e.getEditorKit(); + if (d instanceof HTMLEditorKit) + return (HTMLEditorKit) d; + throw new IllegalArgumentException("EditorKit is not a HTMLEditorKit."); + } + + /** + * Returns an array of Elements that contain the offset. + * The first elements corresponds to the roots of the doc. + * + * @param doc - the document to get the Elements from. + * @param offset - the offset the Elements must contain + * @return an array of all the elements containing the offset. + */ + protected Element[] getElementsAt(HTMLDocument doc, + int offset) + { + return getElementsAt(doc.getDefaultRootElement(), offset, 0); + } + + /** + * Helper function to get all elements using recursion. + */ + private Element[] getElementsAt(Element root, int offset, int depth) + { + Element[] elements = null; + if (root != null) + { + if (root.isLeaf()) + { + elements = new Element[depth + 1]; + elements[depth] = root; + return elements; + } + elements = getElementsAt(root.getElement(root.getElementIndex(offset)), + offset, depth + 1); + elements[depth] = root; + } + return elements; + } + + /** + * Returns the number of elements, starting at the deepest point, needed + * to get an element representing tag. -1 if no elements are found, 0 if + * the parent of the leaf at offset represents the tag. + * + * @param doc - + * the document to search + * @param offset - + * the offset to check + * @param tag - + * the tag to look for + * @return - the number of elements needed to get an element representing + * tag. + */ + protected int elementCountToTag(HTMLDocument doc, + int offset, HTML.Tag tag) + { + Element root = doc.getDefaultRootElement(); + int num = -1; + Element next = root.getElement(root.getElementIndex(offset)); + + while (!next.isLeaf()) + { + num++; + if (next.getAttributes(). + getAttribute(StyleConstants.NameAttribute).equals(tag)) + return num; + next = next.getElement(next.getElementIndex(offset)); + } + return num; + } + + /** + * Gets the deepest element at offset with the + * matching tag. + * + * @param doc - the document to search + * @param offset - the offset to check for + * @param tag - the tag to match + * @return - the element that is found, null if not found. + */ + protected Element findElementMatchingTag(HTMLDocument doc, + int offset, HTML.Tag tag) + { + Element element = doc.getDefaultRootElement(); + Element tagElement = null; + + while (element != null) + { + Object otag = element.getAttributes().getAttribute( + StyleConstants.NameAttribute); + if (otag instanceof HTML.Tag && otag.equals(tag)) + tagElement = element; + element = element.getElement(element.getElementIndex(offset)); + } + + return tagElement; + } + } + + /** + * A {@link ViewFactory} that is able to create {@link View}s for + * the <code>Element</code>s that are supported. + */ + public static class HTMLFactory + implements ViewFactory + { + + /** + * Constructor + */ + public HTMLFactory() + { + // Do Nothing here. + } + + /** + * Creates a {@link View} for the specified <code>Element</code>. + * + * @param element the <code>Element</code> to create a <code>View</code> + * for + * @return the <code>View</code> for the specified <code>Element</code> + * or <code>null</code> if the type of <code>element</code> is + * not supported + */ + public View create(Element element) + { + View view = null; + Object attr = element.getAttributes().getAttribute( + StyleConstants.NameAttribute); + if (attr instanceof HTML.Tag) + { + HTML.Tag tag = (HTML.Tag) attr; + + if (tag.equals(HTML.Tag.IMPLIED) || tag.equals(HTML.Tag.P) + || tag.equals(HTML.Tag.H1) || tag.equals(HTML.Tag.H2) + || tag.equals(HTML.Tag.H3) || tag.equals(HTML.Tag.H4) + || tag.equals(HTML.Tag.H5) || tag.equals(HTML.Tag.H6) + || tag.equals(HTML.Tag.DT)) + view = new ParagraphView(element); + else if (tag.equals(HTML.Tag.LI) || tag.equals(HTML.Tag.DL) + || tag.equals(HTML.Tag.DD) || tag.equals(HTML.Tag.BODY) + || tag.equals(HTML.Tag.HTML) || tag.equals(HTML.Tag.CENTER) + || tag.equals(HTML.Tag.DIV) + || tag.equals(HTML.Tag.BLOCKQUOTE) + || tag.equals(HTML.Tag.PRE)) + view = new BlockView(element, View.Y_AXIS); + + // FIXME: Uncomment when the views have been implemented + /* else if (tag.equals(HTML.Tag.CONTENT)) + view = new InlineView(element); + else if (tag.equals(HTML.Tag.MENU) || tag.equals(HTML.Tag.DIR) + || tag.equals(HTML.Tag.UL) || tag.equals(HTML.Tag.OL)) + view = new ListView(element); + else if (tag.equals(HTML.Tag.IMG)) + view = new ImageView(element); + else if (tag.equals(HTML.Tag.HR)) + view = new HRuleView(element); + else if (tag.equals(HTML.Tag.BR)) + view = new BRView(element); + else if (tag.equals(HTML.Tag.TABLE)) + view = new TableView(element); + else if (tag.equals(HTML.Tag.INPUT) || tag.equals(HTML.Tag.SELECT) + || tag.equals(HTML.Tag.TEXTAREA)) + view = new FormView(element); + else if (tag.equals(HTML.Tag.OBJECT)) + view = new ObjectView(element); + else if (tag.equals(HTML.Tag.FRAMESET)) + view = new FrameSetView(element); + else if (tag.equals(HTML.Tag.FRAME)) + view = new FrameView(element); */ + } + + if (view == null) + { + String name = element.getName(); + if (name.equals(AbstractDocument.ContentElementName)) + view = new LabelView(element); + else if (name.equals(AbstractDocument.ParagraphElementName)) + view = new ParagraphView(element); + else if (name.equals(AbstractDocument.SectionElementName)) + view = new BoxView(element, View.Y_AXIS); + else if (name.equals(StyleConstants.ComponentElementName)) + view = new ComponentView(element); + else if (name.equals(StyleConstants.IconElementName)) + view = new IconView(element); + } + return view; + } + } + /** * The abstract HTML parser declaration. */ @@ -76,9 +611,7 @@ public class HTMLEditorKit * @throws IOException, normally if the reader throws one. */ public abstract void parse(Reader reader, ParserCallback callback, - boolean ignoreCharSet - ) - throws IOException; + boolean ignoreCharSet) throws IOException; } /** @@ -96,11 +629,19 @@ public class HTMLEditorKit public static final Object IMPLIED = "_implied_"; /** + * Constructor + */ + public ParserCallback() + { + // Nothing to do here. + } + + /** * The parser calls this method after it finishes parsing the document. */ public void flush() throws BadLocationException { - // TODO: What to do here, if anything? + // Nothing to do here. } /** @@ -110,7 +651,7 @@ public class HTMLEditorKit */ public void handleComment(char[] comment, int position) { - // TODO: What to do here, if anything? + // Nothing to do here. } /** @@ -121,7 +662,7 @@ public class HTMLEditorKit */ public void handleEndOfLineString(String end_of_line) { - // TODO: What to do here, if anything? + // Nothing to do here. } /** @@ -133,7 +674,7 @@ public class HTMLEditorKit */ public void handleEndTag(HTML.Tag tag, int position) { - // TODO: What to do here, if anything? + // Nothing to do here. } /** @@ -144,7 +685,7 @@ public class HTMLEditorKit */ public void handleError(String message, int position) { - // TODO: What to do here, if anything? + // Nothing to do here. } /** @@ -157,7 +698,7 @@ public class HTMLEditorKit public void handleSimpleTag(HTML.Tag tag, MutableAttributeSet attributes, int position) { - // TODO: What to do here, if anything? + // Nothing to do here. } /** @@ -168,10 +709,9 @@ public class HTMLEditorKit * @param position The tag position in the text being parsed */ public void handleStartTag(HTML.Tag tag, MutableAttributeSet attributes, - int position - ) + int position) { - // TODO: What to do here, if anything? + // Nothing to do here. } /** @@ -181,7 +721,7 @@ public class HTMLEditorKit */ public void handleText(char[] text, int position) { - // TODO: What to do here, if anything? + // Nothing to do here. } } @@ -255,7 +795,83 @@ public class HTMLEditorKit * The "ident paragraph right" action. */ public static final String PARA_INDENT_RIGHT = "html-para-indent-right"; - + + /** + * Actions for HTML + */ + private static final Action[] defaultActions = { + // FIXME: Add default actions for html + }; + + /** + * The current style sheet. + */ + StyleSheet styleSheet; + + /** + * The ViewFactory for HTMLFactory. + */ + HTMLFactory viewFactory; + + /** + * The Cursor for links. + */ + Cursor linkCursor; + + /** + * The default cursor. + */ + Cursor defaultCursor; + + /** + * The parser. + */ + Parser parser; + + /** + * The mouse listener used for links. + */ + LinkController mouseListener; + + /** + * Style context for this editor. + */ + StyleContext styleContext; + + /** The content type */ + String contentType = "text/html"; + + /** The input attributes defined by default.css */ + MutableAttributeSet inputAttributes; + + /** The editor pane used. */ + JEditorPane editorPane; + + /** + * Constructs an HTMLEditorKit, creates a StyleContext, and loads the style sheet. + */ + public HTMLEditorKit() + { + super(); + styleContext = new StyleContext(); + styleSheet = new StyleSheet(); + styleSheet.importStyleSheet(getClass().getResource(DEFAULT_CSS)); + // FIXME: Set inputAttributes with default.css + } + + /** + * Gets a factory suitable for producing views of any + * models that are produced by this kit. + * + * @return the view factory suitable for producing views. + */ + public ViewFactory getViewFactory() + { + if (viewFactory == null) + viewFactory = new HTMLFactory(); + return viewFactory; + } + /** * Create a text storage model for this type of editor. * @@ -263,18 +879,297 @@ public class HTMLEditorKit */ public Document createDefaultDocument() { - HTMLDocument document = new HTMLDocument(); + HTMLDocument document = new HTMLDocument(getStyleSheet()); + document.setParser(getParser()); return document; } /** * Get the parser that this editor kit uses for reading HTML streams. This * method can be overridden to use the alternative parser. - * + * * @return the HTML parser (by default, {@link ParserDelegator}). */ protected Parser getParser() { - return new ParserDelegator(); + if (parser == null) + parser = new ParserDelegator(); + return parser; + } + + /** + * Inserts HTML into an existing document. + * + * @param doc - the Document to insert the HTML into. + * @param offset - where to begin inserting the HTML. + * @param html - the String to insert + * @param popDepth - the number of ElementSpec.EndTagTypes + * to generate before inserting + * @param pushDepth - the number of ElementSpec.StartTagTypes + * with a direction of ElementSpec.JoinNextDirection that + * should be generated before + * @param insertTag - the first tag to start inserting into document + * @throws IOException - on any I/O error + * @throws BadLocationException - if pos represents an invalid location + * within the document + */ + public void insertHTML(HTMLDocument doc, int offset, String html, + int popDepth, int pushDepth, HTML.Tag insertTag) + throws BadLocationException, IOException + { + Parser parser = getParser(); + if (offset < 0 || offset > doc.getLength()) + throw new BadLocationException("Bad location", offset); + if (parser == null) + throw new IOException("Parser is null."); + + ParserCallback pc = ((HTMLDocument) doc).getReader + (offset, popDepth, pushDepth, insertTag); + + // FIXME: What should ignoreCharSet be set to? + + // parser.parse inserts html into the buffer + parser.parse(new StringReader(html), pc, false); + pc.flush(); + } + + /** + * Inserts content from the given stream. Inserting HTML into a non-empty + * document must be inside the body Element, if you do not insert into + * the body an exception will be thrown. When inserting into a non-empty + * document all tags outside of the body (head, title) will be dropped. + * + * @param in - the stream to read from + * @param doc - the destination for the insertion + * @param pos - the location in the document to place the content + * @throws IOException - on any I/O error + * @throws BadLocationException - if pos represents an invalid location + * within the document + */ + public void read(Reader in, Document doc, int pos) throws IOException, + BadLocationException + { + if (doc instanceof HTMLDocument) + { + Parser parser = getParser(); + if (pos < 0 || pos > doc.getLength()) + throw new BadLocationException("Bad location", pos); + if (parser == null) + throw new IOException("Parser is null."); + + HTMLDocument hd = ((HTMLDocument) doc); + hd.setBase(editorPane.getPage()); + ParserCallback pc = hd.getReader(pos); + + // FIXME: What should ignoreCharSet be set to? + + // parser.parse inserts html into the buffer + parser.parse(in, pc, false); + pc.flush(); + } + else + // read in DefaultEditorKit is called. + // the string is inserted in the document as usual. + super.read(in, doc, pos); + } + + /** + * Writes content from a document to the given stream in + * an appropriate format. + * + * @param out - the stream to write to + * @param doc - the source for the write + * @param pos - the location in the document to get the content. + * @param len - the amount to write out + * @throws IOException - on any I/O error + * @throws BadLocationException - if pos represents an invalid location + * within the document + */ + public void write(Writer out, Document doc, int pos, int len) + throws IOException, BadLocationException + { + if (doc instanceof HTMLDocument) + { + // FIXME: Not implemented. Use HTMLWriter. + out.write(doc.getText(pos, len)); + } + else + super.write(out, doc, pos, len); + } + + /** + * Gets the content type that the kit supports. + * This kit supports the type text/html. + * + * @returns the content type supported. + */ + public String getContentType() + { + return contentType; + } + + /** + * Creates a copy of the editor kit. + * + * @return a copy of this. + */ + public Object clone() + { + // FIXME: Need to clone all fields + return (HTMLEditorKit) super.clone(); + } + + /** + * Copies the key/values in elements AttributeSet into set. + * This does not copy component, icon, or element names attributes. + * This is called anytime the caret moves over a different location. + * + * @param element - the element to create the input attributes for. + * @param set - the set to copy the values into. + */ + protected void createInputAttributes(Element element, + MutableAttributeSet set) + { + set.removeAttributes(set); + set.addAttributes(element.getAttributes()); + // FIXME: Not fully implemented. + } + + /** + * Called when this is installed into the JEditorPane. + * + * @param c - the JEditorPane installed into. + */ + public void install(JEditorPane c) + { + super.install(c); + mouseListener = new LinkController(); + c.addMouseListener(mouseListener); + editorPane = c; + // FIXME: need to set up hyperlinklistener object + } + + /** + * Called when the this is removed from the JEditorPane. + * It unregisters any listeners. + * + * @param c - the JEditorPane being removed from. + */ + public void deinstall(JEditorPane c) + { + super.deinstall(c); + c.removeMouseListener(mouseListener); + mouseListener = null; + editorPane = null; + } + + /** + * Gets the AccessibleContext associated with this. + * + * @return the AccessibleContext for this. + */ + public AccessibleContext getAccessibleContext() + { + // FIXME: Should return an instance of + // javax.swing.text.html.AccessibleHTML$RootHTMLAccessibleContext + // Not implemented yet. + return null; + } + + /** + * Gets the action list. This list is supported by the superclass + * augmented by the collection of actions defined locally for style + * operations. + * + * @return an array of all the actions + */ + public Action[] getActions() + { + return TextAction.augmentList(super.getActions(), defaultActions); + } + + /** + * Returns the default cursor. + * + * @return the default cursor + */ + public Cursor getDefaultCursor() + { + if (defaultCursor == null) + defaultCursor = Cursor.getDefaultCursor(); + return defaultCursor; + } + + /** + * Returns the cursor for links. + * + * @return the cursor for links. + */ + public Cursor getLinkCursor() + { + if (linkCursor == null) + linkCursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR); + return linkCursor; + } + + /** + * Sets the Cursor for links. + * + * @param cursor - the new cursor for links. + */ + public void setLinkCursor(Cursor cursor) + { + linkCursor = cursor; + } + + /** + * Sets the default cursor. + * + * @param cursor - the new default cursor. + */ + public void setDefaultCursor(Cursor cursor) + { + defaultCursor = cursor; + } + + /** + * Gets the input attributes used for the styled editing actions. + * + * @return the attribute set + */ + public MutableAttributeSet getInputAttributes() + { + return inputAttributes; + } + + /** + * Get the set of styles currently being used to render the HTML elements. + * By default the resource specified by DEFAULT_CSS gets loaded, and is + * shared by all HTMLEditorKit instances. + * + * @return the style sheet. + */ + public StyleSheet getStyleSheet() + { + if (styleSheet == null) + { + styleSheet = new StyleSheet(); + styleSheet.importStyleSheet(getClass().getResource(DEFAULT_CSS)); + } + return styleSheet; + } + + /** + * Set the set of styles to be used to render the various HTML elements. + * These styles are specified in terms of CSS specifications. Each document + * produced by the kit will have a copy of the sheet which it can add the + * document specific styles to. By default, the StyleSheet specified is shared + * by all HTMLEditorKit instances. + * + * @param s - the new style sheet + */ + public void setStyleSheet(StyleSheet s) + { + styleSheet = s; } -}
\ No newline at end of file +} diff --git a/libjava/classpath/javax/swing/text/html/StyleSheet.java b/libjava/classpath/javax/swing/text/html/StyleSheet.java new file mode 100644 index 0000000..2466a28 --- /dev/null +++ b/libjava/classpath/javax/swing/text/html/StyleSheet.java @@ -0,0 +1,937 @@ +/* StyleSheet.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.swing.text.html; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics; + +import java.io.IOException; +import java.io.Reader; +import java.io.Serializable; +import java.io.StringReader; + +import java.net.MalformedURLException; +import java.net.URL; + +import java.util.Enumeration; +import java.util.Vector; + +import javax.swing.text.AttributeSet; +import javax.swing.text.Element; +import javax.swing.text.MutableAttributeSet; +import javax.swing.text.SimpleAttributeSet; +import javax.swing.text.Style; +import javax.swing.text.StyleContext; +import javax.swing.text.View; + + +/** + * This class adds support for defining the visual characteristics of HTML views + * being rendered. This enables views to be customized by a look-and-feel, mulitple + * views over the same model can be rendered differently. Each EditorPane has its + * own StyleSheet, but by default one sheet will be shared by all of the HTMLEditorKit + * instances. An HTMLDocument can also have a StyleSheet, which holds specific CSS + * specs. + * + * In order for Views to store less state and therefore be more lightweight, + * the StyleSheet can act as a factory for painters that handle some of the + * rendering tasks. Since the StyleSheet may be used by views over multiple + * documents the HTML attributes don't effect the selector being used. + * + * The rules are stored as named styles, and other information is stored to + * translate the context of an element to a rule. + * + * @author Lillian Angel (langel@redhat.com) + */ +public class StyleSheet extends StyleContext +{ + + /** The base URL */ + URL base; + + /** Base font size (int) */ + int baseFontSize; + + /** The style sheets stored. */ + StyleSheet[] styleSheet; + + /** + * Constructs a StyleSheet. + */ + public StyleSheet() + { + super(); + baseFontSize = 4; // Default font size from CSS + } + + /** + * Gets the style used to render the given tag. The element represents the tag + * and can be used to determine the nesting, where the attributes will differ + * if there is nesting inside of elements. + * + * @param t - the tag to translate to visual attributes + * @param e - the element representing the tag + * @return the set of CSS attributes to use to render the tag. + */ + public Style getRule(HTML.Tag t, Element e) + { + // FIXME: Not implemented. + return null; + } + + /** + * Gets the rule that best matches the selector. selector is a space + * separated String of element names. The attributes of the returned + * Style will change as rules are added and removed. + * + * @param selector - the element names separated by spaces + * @return the set of CSS attributes to use to render + */ + public Style getRule(String selector) + { + // FIXME: Not implemented. + return null; + } + + /** + * Adds a set if rules to the sheet. The rules are expected to be in valid + * CSS format. This is called as a result of parsing a <style> tag + * + * @param rule - the rule to add to the sheet + */ + public void addRule(String rule) + { + CssParser cp = new CssParser(); + try + { + cp.parse(base, new StringReader(rule), false, false); + } + catch (IOException io) + { + // Do nothing here. + } + } + + /** + * Translates a CSS declaration into an AttributeSet. This is called + * as a result of encountering an HTML style attribute. + * + * @param decl - the declaration to get + * @return the AttributeSet representing the declaration + */ + public AttributeSet getDeclaration(String decl) + { + if (decl == null) + return SimpleAttributeSet.EMPTY; + // FIXME: Not implemented. + return null; + } + + /** + * Loads a set of rules that have been specified in terms of CSS grammar. + * If there are any conflicts with existing rules, the new rule is added. + * + * @param in - the stream to read the CSS grammar from. + * @param ref - the reference URL. It is the location of the stream, it may + * be null. All relative URLs specified in the stream will be based upon this + * parameter. + * @throws IOException - For any IO error while reading + */ + public void loadRules(Reader in, URL ref) throws IOException + { + CssParser cp = new CssParser(); + cp.parse(ref, in, false, false); + } + + /** + * Gets a set of attributes to use in the view. This is a set of + * attributes that can be used for View.getAttributes + * + * @param v - the view to get the set for + * @return the AttributeSet to use in the view. + */ + public AttributeSet getViewAttributes(View v) + { + // FIXME: Not implemented. + return null; + } + + /** + * Removes a style previously added. + * + * @param nm - the name of the style to remove + */ + public void removeStyle(String nm) + { + // FIXME: Not implemented. + super.removeStyle(nm); + } + + /** + * Adds the rules from ss to those of the receiver. ss's rules will + * override the old rules. An added StyleSheet will never override the rules + * of the receiving style sheet. + * + * @param ss - the new StyleSheet. + */ + public void addStyleSheet(StyleSheet ss) + { + if (styleSheet == null) + styleSheet = new StyleSheet[] {ss}; + else + System.arraycopy(new StyleSheet[] {ss}, 0, styleSheet, + styleSheet.length, 1); + } + + /** + * Removes ss from those of the receiver + * + * @param ss - the StyleSheet to remove. + */ + public void removeStyleSheet(StyleSheet ss) + { + if (styleSheet.length == 1 && styleSheet[0].equals(ss)) + styleSheet = null; + else + { + for (int i = 0; i < styleSheet.length; i++) + { + StyleSheet curr = styleSheet[i]; + if (curr.equals(ss)) + { + StyleSheet[] tmp = new StyleSheet[styleSheet.length - 1]; + if (i != 0 && i != (styleSheet.length - 1)) + { + System.arraycopy(styleSheet, 0, tmp, 0, i); + System.arraycopy(styleSheet, i + 1, tmp, i, + styleSheet.length - i - 1); + } + else if (i == 0) + System.arraycopy(styleSheet, 1, tmp, 0, styleSheet.length - 1); + else + System.arraycopy(styleSheet, 0, tmp, 0, styleSheet.length - 1); + + styleSheet = tmp; + break; + } + } + } + } + + /** + * Returns an array of the linked StyleSheets. May return null. + * + * @return - An array of the linked StyleSheets. + */ + public StyleSheet[] getStyleSheets() + { + return styleSheet; + } + + /** + * Imports a style sheet from the url. The rules are directly added to the + * receiver. + * + * @param url - the URL to import the StyleSheet from. + */ + public void importStyleSheet(URL url) + { + // FIXME: Not implemented + } + + /** + * Sets the base url. All import statements that are relative, will be + * relative to base. + * + * @param base - + * the base URL. + */ + public void setBase(URL base) + { + this.base = base; + } + + /** + * Gets the base url. + * + * @return - the base + */ + public URL getBase() + { + return base; + } + + /** + * Adds a CSS attribute to the given set. + * + * @param attr - the attribute set + * @param key - the attribute to add + * @param value - the value of the key + */ + public void addCSSAttribute(MutableAttributeSet attr, CSS.Attribute key, + String value) + { + attr.addAttribute(key, value); + } + + /** + * Adds a CSS attribute to the given set. + * This method parses the value argument from HTML based on key. + * Returns true if it finds a valid value for the given key, + * and false otherwise. + * + * @param attr - the attribute set + * @param key - the attribute to add + * @param value - the value of the key + * @return true if a valid value was found. + */ + public boolean addCSSAttributeFromHTML(MutableAttributeSet attr, CSS.Attribute key, + String value) + { + // FIXME: Need to parse value from HTML based on key. + attr.addAttribute(key, value); + return attr.containsAttribute(key, value); + } + + /** + * Converts a set of HTML attributes to an equivalent set of CSS attributes. + * + * @param htmlAttrSet - the set containing the HTML attributes. + * @return the set of CSS attributes + */ + public AttributeSet translateHTMLToCSS(AttributeSet htmlAttrSet) + { + // FIXME: Not implemented. + return null; + } + + /** + * Adds an attribute to the given set and returns a new set. This is implemented + * to convert StyleConstants attributes to CSS before forwarding them to the superclass. + * The StyleConstants attribute do not have corresponding CSS entry, the attribute + * is stored (but will likely not be used). + * + * @param old - the old set + * @param key - the non-null attribute key + * @param value - the attribute value + * @return the updated set + */ + public AttributeSet addAttribute(AttributeSet old, Object key, + Object value) + { + // FIXME: Not implemented. + return super.addAttribute(old, key, value); + } + + /** + * Adds a set of attributes to the element. If any of these attributes are + * StyleConstants, they will be converted to CSS before forwarding to the + * superclass. + * + * @param old - the old set + * @param attr - the attributes to add + * @return the updated attribute set + */ + public AttributeSet addAttributes(AttributeSet old, AttributeSet attr) + { + // FIXME: Not implemented. + return super.addAttributes(old, attr); + } + + /** + * Removes an attribute from the set. If the attribute is a + * StyleConstants, it will be converted to CSS before forwarding to the + * superclass. + * + * @param old - the old set + * @param key - the non-null attribute key + * @return the updated set + */ + public AttributeSet removeAttribute(AttributeSet old, Object key) + { + // FIXME: Not implemented. + return super.removeAttribute(old, key); + } + + /** + * Removes an attribute from the set. If any of the attributes are + * StyleConstants, they will be converted to CSS before forwarding to the + * superclass. + * + * @param old - the old set + * @param attrs - the attributes to remove + * @return the updated set + */ + public AttributeSet removeAttributes(AttributeSet old, AttributeSet attrs) + { + // FIXME: Not implemented. + return super.removeAttributes(old, attrs); + } + + /** + * Removes a set of attributes for the element. If any of the attributes is a + * StyleConstants, they will be converted to CSS before forwarding to the + * superclass. + * + * @param old - the old attribute set + * @param names - the attribute names + * @return the update attribute set + */ + public AttributeSet removeAttributes(AttributeSet old, Enumeration names) + { + // FIXME: Not implemented. + return super.removeAttributes(old, names); + } + + /** + * Creates a compact set of attributes that might be shared. This is a hook + * for subclasses that want to change the behaviour of SmallAttributeSet. + * + * @param a - the set of attributes to be represented in the compact form. + * @return the set of attributes created + */ + protected StyleContext.SmallAttributeSet createSmallAttributeSet(AttributeSet a) + { + return super.createSmallAttributeSet(a); + } + + /** + * Creates a large set of attributes. This set is not shared. This is a hook + * for subclasses that want to change the behaviour of the larger attribute + * storage format. + * + * @param a - the set of attributes to be represented in the larger form. + * @return the large set of attributes. + */ + protected MutableAttributeSet createLargeAttributeSet(AttributeSet a) + { + return super.createLargeAttributeSet(a); + } + + /** + * Gets the font to use for the given set. + * + * @param a - the set to get the font for. + * @return the font for the set + */ + public Font getFont(AttributeSet a) + { + return super.getFont(a); + } + + /** + * Takes a set of attributes and turns it into a foreground + * color specification. This is used to specify things like, brigher, more hue + * etc. + * + * @param a - the set to get the foreground color for + * @return the foreground color for the set + */ + public Color getForeground(AttributeSet a) + { + return super.getForeground(a); + } + + /** + * Takes a set of attributes and turns it into a background + * color specification. This is used to specify things like, brigher, more hue + * etc. + * + * @param a - the set to get the background color for + * @return the background color for the set + */ + public Color getBackground(AttributeSet a) + { + return super.getBackground(a); + } + + /** + * Gets the box formatter to use for the given set of CSS attributes. + * + * @param a - the given set + * @return the box formatter + */ + public BoxPainter getBoxPainter(AttributeSet a) + { + return new BoxPainter(a); + } + + /** + * Gets the list formatter to use for the given set of CSS attributes. + * + * @param a - the given set + * @return the list formatter + */ + public ListPainter getListPainter(AttributeSet a) + { + return new ListPainter(a); + } + + /** + * Sets the base font size between 1 and 7. + * + * @param sz - the new font size for the base. + */ + public void setBaseFontSize(int sz) + { + if (sz <= 7 && sz >= 1) + baseFontSize = sz; + } + + /** + * Sets the base font size from the String. It can either identify + * a specific font size (between 1 and 7) or identify a relative + * font size such as +1 or -2. + * + * @param size - the new font size as a String. + */ + public void setBaseFontSize(String size) + { + size.trim(); + int temp = 0; + try + { + if (size.length() == 2) + { + int i = new Integer(size.substring(1)).intValue(); + if (size.startsWith("+")) + temp = baseFontSize + i; + else if (size.startsWith("-")) + temp = baseFontSize - i; + } + else if (size.length() == 1) + temp = new Integer(size.substring(0)).intValue(); + + if (temp <= 7 && temp >= 1) + baseFontSize = temp; + } + catch (NumberFormatException nfe) + { + // Do nothing here + } + } + + /** + * TODO + * + * @param pt - TODO + * @return TODO + */ + public static int getIndexOfSize(float pt) + { + // FIXME: Not implemented. + return 0; + } + + /** + * Gets the point size, given a size index. + * + * @param index - the size index + * @return the point size. + */ + public float getPointSize(int index) + { + // FIXME: Not implemented. + return 0; + } + + /** + * Given the string of the size, returns the point size value. + * + * @param size - the string representation of the size. + * @return - the point size value. + */ + public float getPointSize(String size) + { + // FIXME: Not implemented. + return 0; + } + + /** + * Converst a color string to a color. If it is not found, null is returned. + * + * @param color - the color string such as "RED" or "#NNNNNN" + * @return the Color, or null if not found. + */ + public Color stringToColor(String color) + { + color = color.toLowerCase(); + if (color.equals("black") || color.equals("#000000")) + return Color.BLACK; + else if (color.equals("aqua") || color.equals("#00FFFF")) + return new Color(127, 255, 212); + else if (color.equals("gray") || color.equals("#808080")) + return Color.GRAY; + else if (color.equals("navy") || color.equals("#000080")) + return new Color(0, 0, 128); + else if (color.equals("silver") || color.equals("#C0C0C0")) + return Color.LIGHT_GRAY; + else if (color.equals("green") || color.equals("#008000")) + return Color.GREEN; + else if (color.equals("olive") || color.equals("#808000")) + return new Color(128, 128, 0); + else if (color.equals("teal") || color.equals("#008080")) + return new Color(0, 128, 128); + else if (color.equals("blue") || color.equals("#0000FF")) + return Color.BLUE; + else if (color.equals("lime") || color.equals("#00FF00")) + return new Color(0, 255, 0); + else if (color.equals("purple") || color.equals("#800080")) + return new Color(128, 0, 128); + else if (color.equals("white") || color.equals("#FFFFFF")) + return Color.WHITE; + else if (color.equals("fuchsia") || color.equals("#FF00FF")) + return Color.MAGENTA; + else if (color.equals("maroon") || color.equals("#800000")) + return new Color(128, 0, 0); + else if (color.equals("Red") || color.equals("#FF0000")) + return Color.RED; + else if (color.equals("Yellow") || color.equals("#FFFF00")) + return Color.YELLOW; + return null; + } + + /** + * This class carries out some of the duties of CSS formatting. This enables views + * to present the CSS formatting while not knowing how the CSS values are cached. + * + * This object is reponsible for the insets of a View and making sure + * the background is maintained according to the CSS attributes. + * + * @author Lillian Angel (langel@redhat.com) + */ + public static class BoxPainter extends Object implements Serializable + { + + /** + * Attribute set for painter + */ + AttributeSet as; + + /** + * Package-private constructor. + * + * @param as - AttributeSet for painter + */ + BoxPainter(AttributeSet as) + { + this.as = as; + } + + /** + * Gets the inset needed on a given side to account for the margin, border + * and padding. + * + * @param size - the size of the box to get the inset for. View.TOP, View.LEFT, + * View.BOTTOM or View.RIGHT. + * @param v - the view making the request. This is used to get the AttributeSet, + * amd may be used to resolve percentage arguments. + * @return the inset + * @throws IllegalArgumentException - for an invalid direction. + */ + public float getInset(int size, View v) + { + // FIXME: Not implemented. + return 0; + } + + /** + * Paints the CSS box according to the attributes given. This should + * paint the border, padding and background. + * + * @param g - the graphics configuration + * @param x - the x coordinate + * @param y - the y coordinate + * @param w - the width of the allocated area + * @param h - the height of the allocated area + * @param v - the view making the request + */ + public void paint(Graphics g, float x, float y, float w, float h, View v) + { + // FIXME: Not implemented. + } + } + + /** + * This class carries out some of the CSS list formatting duties. Implementations + * of this class enable views to present the CSS formatting while not knowing anything + * about how the CSS values are being cached. + * + * @author Lillian Angel (langel@redhat.com) + */ + public static class ListPainter extends Object implements Serializable + { + + /** + * Attribute set for painter + */ + AttributeSet as; + + /** + * Package-private constructor. + * + * @param as - AttributeSet for painter + */ + ListPainter(AttributeSet as) + { + this.as = as; + } + + /** + * Paints the CSS list decoration according to the attributes given. + * + * @param g - the graphics configuration + * @param x - the x coordinate + * @param y - the y coordinate + * @param w - the width of the allocated area + * @param h - the height of the allocated area + * @param v - the view making the request + * @param item - the list item to be painted >=0. + */ + public void paint(Graphics g, float x, float y, float w, float h, View v, + int item) + { + // FIXME: Not implemented. + } + } + + /** + * The parser callback for the CSSParser. + */ + class CssParser implements CSSParser.CSSParserCallback + { + /** + * A vector of all the selectors. + * Each element is an array of all the selector tokens + * in a single rule. + */ + Vector selectors; + + /** A vector of all the selector tokens in a rule. */ + Vector selectorTokens; + + /** Name of the current property. */ + String propertyName; + + /** The set of CSS declarations */ + MutableAttributeSet declaration; + + /** + * True if parsing a declaration, that is the Reader will not + * contain a selector. + */ + boolean parsingDeclaration; + + /** True if the attributes are coming from a linked/imported style. */ + boolean isLink; + + /** The base URL */ + URL base; + + /** The parser */ + CSSParser parser; + + /** + * Constructor + */ + CssParser() + { + selectors = new Vector(); + selectorTokens = new Vector(); + parser = new CSSParser(); + base = StyleSheet.this.base; + declaration = new SimpleAttributeSet(); + } + + /** + * Parses the passed in CSS declaration into an AttributeSet. + * + * @param s - the declaration + * @return the set of attributes containing the property and value. + */ + public AttributeSet parseDeclaration(String s) + { + try + { + return parseDeclaration(new StringReader(s)); + } + catch (IOException e) + { + // Do nothing here. + } + return null; + } + + /** + * Parses the passed in CSS declaration into an AttributeSet. + * + * @param r - the reader + * @return the attribute set + * @throws IOException from the reader + */ + public AttributeSet parseDeclaration(Reader r) throws IOException + { + parse(base, r, true, false); + return declaration; + } + + /** + * Parse the given CSS stream + * + * @param base - the url + * @param r - the reader + * @param parseDec - True if parsing a declaration + * @param isLink - True if parsing a link + */ + public void parse(URL base, Reader r, boolean parseDec, boolean isLink) throws IOException + { + parsingDeclaration = parseDec; + this.isLink = isLink; + this.base = base; + + // flush out all storage + propertyName = null; + selectors.clear(); + selectorTokens.clear(); + declaration.removeAttributes(declaration); + + parser.parse(r, this, parseDec); + } + + /** + * Invoked when a valid @import is encountered, + * will call importStyleSheet if a MalformedURLException + * is not thrown in creating the URL. + * + * @param s - the string after @import + */ + public void handleImport(String s) + { + if (s != null) + { + try + { + if (s.startsWith("url(") && s.endsWith(")")) + s = s.substring(4, s.length() - 1); + if (s.indexOf("\"") >= 0) + s = s.replaceAll("\"",""); + + URL url = new URL(s); + if (url == null && base != null) + url = new URL(base, s); + + importStyleSheet(url); + } + catch (MalformedURLException e) + { + // Do nothing here. + } + } + } + + /** + * A selector has been encountered. + * + * @param s - a selector (e.g. P or UL or even P,) + */ + public void handleSelector(String s) + { + if (s.endsWith(",")) + s = s.substring(0, s.length() - 1); + + selectorTokens.addElement(s); + addSelector(); + } + + /** + * Invoked when the start of a rule is encountered. + */ + public void startRule() + { + addSelector(); + } + + /** + * Invoked when a property name is encountered. + * + * @param s - the property + */ + public void handleProperty(String s) + { + propertyName = s; + } + + /** + * Invoked when a property value is encountered. + * + * @param s - the value + */ + public void handleValue(String s) + { + // call addCSSAttribute + // FIXME: Not implemented + } + + /** + * Invoked when the end of a rule is encountered. + */ + public void endRule() + { + // FIXME: Not implemented + // add rules + propertyName = null; + } + + /** + * Adds the selector to the vector. + */ + private void addSelector() + { + int length = selectorTokens.size(); + if (length > 0) + { + Object[] sel = new Object[length]; + System.arraycopy(selectorTokens.toArray(), 0, sel, 0, length); + selectors.add(sel); + selectorTokens.clear(); + } + } + } +} diff --git a/libjava/classpath/javax/swing/text/html/default.css b/libjava/classpath/javax/swing/text/html/default.css new file mode 100644 index 0000000..f2a44f8 --- /dev/null +++ b/libjava/classpath/javax/swing/text/html/default.css @@ -0,0 +1,378 @@ +/* default.css -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +nobr { + white-space: nowrap; +} + +ol { + margin-right: 50px; + margin-top: 10px; + margin-left: 50px; + margin-bottom: 10px; + list-style-type: decimal; +} + +u { + text-decoration: underline; +} + +s { + text-decoration: line-through; +} + +p { + margin-top: 15px; +} + +dd p { + margin-left: 0px; + margin-top: 0px; + margin-bottom: 0px; +} + +ol li p { + margin-top: 0px; + margin-bottom: 0px; +} + + +address { + font-style: italic; + color: blue; +} + +i { + font-style: italic; +} + +h6 { + margin-top: 10px; + font-size: xx-small; + font-weight: bold; + margin-bottom: 10px; +} + +h5 { + margin-top: 10px; + font-size: x-small; + font-weight: bold; + margin-bottom: 10px; +} + +h4 { + margin-top: 10px; + font-size: small; + font-weight: bold; + margin-bottom: 10px; +} + +h3 { + margin-top: 10px; + font-size: medium; + font-weight: bold; + margin-bottom: 10px; +} + +dir li p { + margin-top: 0px; + margin-bottom: 0px; +} + +h2 { + margin-top: 10px; + font-size: large; + font-weight: bold; + margin-bottom: 10px; +} + +b { + font-weight: bold; +} + +h1 { + margin-top: 10px; + font-size: x-large; + font-weight: bold; + margin-bottom: 10px; +} + +caption { + text-align: center; + caption-side: top; +} + +a { + text-decoration: underline; + color: blue; +} + +ul li ul li ul li { + margin-left: 0px; + margin-top: 0px; + margin-bottom: 0px; +} + +menu { + margin-right: 40px; + margin-top: 10px; + margin-left: 40px; + margin-bottom: 10px; +} + +menu li p { + margin-top: 0px; + margin-bottom: 0px; +} + +sup { + vertical-align: super; +} + +body { + margin-right: 0px; + margin-left: 0px; + font-family: Serif; + font-size: 14pt; + font-weight: normal; + color: black; +} + +ul li ul li ul { + margin-right: 25px; + margin-left: 25px; + list-style-type: square; +} + +blockquote { + margin-right: 35px; + margin-left: 35px; + margin-top: 5px; + margin-bottom: 5px; +} + +samp { + font-family: Monospaced; + font-size: small; +} + +cite { + font-style: italic; +} + +sub { + vertical-align: sub; +} + +em { + font-style: italic; +} + +ul li p { + margin-top: 0px; + margin-bottom: 0px; +} + +ul li ul li { + margin-right: 0px; + margin-left: 0px; + margin-top: 0px; + margin-bottom: 0px; +} + +var { + font-style: italic; + font-weight: bold; +} + +table { + border-color: Gray; + border-style: outset; +} + +dfn { + font-style: italic; +} + +menu li { + margin-right: 0px; + margin-left: 0px; + margin-top: 0px; + margin-bottom: 0px; +} + +strong { + font-weight: bold; +} + +ul { + margin-right: 50px; + margin-top: 10px; + margin-left: 50px; + margin-bottom: 10px; + list-style-type: disc; +} + +center { + text-align: center; +} + +ul li ul { + margin-right: 25px; + margin-left: 25px; + list-style-type: circle; +} + +kbd { + font-family: Monospaced; + font-size: small; +} + +dir li { + margin-right: 0px; + margin-left: 0px; + margin-top: 0px; + margin-bottom: 0px; +} + +ul li menu { + margin-right: 25px; + margin-left: 25px; + list-style-type: circle; +} + +dt { + margin-top: 0px; + margin-bottom: 0px; +} + +ol li { + margin-right: 0px; + margin-left: 0px; + margin-top: 0px; + margin-bottom: 0px; +} + +li p { + margin-top: 0px; + margin-bottom: 0px; +} + +default { +} + +strike { + text-decoration: line-through; +} + +dl { + margin-left: 0px; + margin-top: 10px; + margin-bottom: 10px; +} + +tt { + font-family: Monospaced; +} + +ul li { + margin-right: 0px; + margin-left: 0px; + margin-top: 0px; + margin-bottom: 0px; +} + +dir { + margin-right: 40px; + margin-top: 10px; + margin-left: 40px; + margin-bottom: 10px; +} + +tr { + text-align: left; +} + +pre p { + margin-top: 0px; +} + +dd { + margin-right: 40px; + margin-top: 0px; + margin-left: 40px; + margin-bottom: 0px; +} + +th { + padding-bottom: 3px; + text-align: center; + padding-top: 3px; + padding-right: 3px; + padding-left: 3px; + font-weight: bold; + border-color: Gray; + border-style: inset; +} + +pre { + margin-top: 5px; + font-family: Monospaced; + margin-bottom: 5px; +} + +td { + padding-bottom: 3px; + padding-top: 3px; + padding-right: 3px; + padding-left: 3px; + border-color: Gray; + border-style: inset; +} + +code { + font-family: Monospaced; + font-size: small; +} + +small { + font-size: x-small; +} + +big { + font-size: x-large; +} diff --git a/libjava/classpath/javax/swing/tree/DefaultTreeModel.java b/libjava/classpath/javax/swing/tree/DefaultTreeModel.java index 5cf8098..818f548 100644 --- a/libjava/classpath/javax/swing/tree/DefaultTreeModel.java +++ b/libjava/classpath/javax/swing/tree/DefaultTreeModel.java @@ -148,12 +148,6 @@ public class DefaultTreeModel */ public void setRoot(TreeNode root) { - // Sanity Check - if (root == null) - { - throw new IllegalArgumentException("null root"); - } - // Set new root this.root = root; } diff --git a/libjava/classpath/javax/swing/tree/DefaultTreeSelectionModel.java b/libjava/classpath/javax/swing/tree/DefaultTreeSelectionModel.java index 75b76a9..de27dad 100644 --- a/libjava/classpath/javax/swing/tree/DefaultTreeSelectionModel.java +++ b/libjava/classpath/javax/swing/tree/DefaultTreeSelectionModel.java @@ -116,7 +116,7 @@ public class DefaultTreeSelectionModel */ public DefaultTreeSelectionModel() { - setSelectionMode(SINGLE_TREE_SELECTION); + setSelectionMode(DISCONTIGUOUS_TREE_SELECTION); listenerList = new EventListenerList(); } diff --git a/libjava/classpath/javax/xml/namespace/QName.java b/libjava/classpath/javax/xml/namespace/QName.java index 19700b3..edc6678 100644 --- a/libjava/classpath/javax/xml/namespace/QName.java +++ b/libjava/classpath/javax/xml/namespace/QName.java @@ -1,5 +1,5 @@ /* QName.java - An XML qualified name. - Copyright (C) 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2004,2005,2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -67,16 +67,17 @@ public class QName implements Serializable public QName(String namespaceURI, String localPart, String prefix) { if (namespaceURI == null) - { - namespaceURI = XMLConstants.NULL_NS_URI; - } + namespaceURI = XMLConstants.NULL_NS_URI; if (localPart == null) - { - throw new IllegalArgumentException(); - } + throw new IllegalArgumentException(); if (prefix == null) + prefix = XMLConstants.DEFAULT_NS_PREFIX; + else { - prefix = XMLConstants.DEFAULT_NS_PREFIX; + if (XMLConstants.XML_NS_PREFIX.equals(prefix)) + namespaceURI = XMLConstants.XML_NS_URI; + else if (XMLConstants.XMLNS_ATTRIBUTE.equals(prefix)) + namespaceURI = XMLConstants.XMLNS_ATTRIBUTE_NS_URI; } this.namespaceURI = namespaceURI; this.localPart = localPart; @@ -151,9 +152,7 @@ public class QName implements Serializable if (start != -1) { if (end < start) - { - throw new IllegalArgumentException(qNameAsString); - } + throw new IllegalArgumentException(qNameAsString); namespaceUri = qNameAsString.substring(start + 1, end); qNameAsString = qNameAsString.substring(end + 1); } diff --git a/libjava/classpath/javax/xml/parsers/SAXParserFactory.java b/libjava/classpath/javax/xml/parsers/SAXParserFactory.java index 8a89fdd..549fe4b 100644 --- a/libjava/classpath/javax/xml/parsers/SAXParserFactory.java +++ b/libjava/classpath/javax/xml/parsers/SAXParserFactory.java @@ -115,7 +115,7 @@ public abstract class SAXParserFactory } } while (className == null && count < 3); - return new gnu.xml.aelfred2.JAXPFactory(); + return new gnu.xml.stream.SAXParserFactory(); } private static String getFactoryClassName(ClassLoader loader, int attempt) |