Re: [cp-patches] RFA: List.java
Tania's email is currently broken but after talking to her, this patch is now commited. 2006-07-28 Anthony Balkissoon [EMAIL PROTECTED] * java/awt/List.java: Committed following patch from Tania. Initialized private variable visibleIndex to -1. (addItem(String, int)): If string is null, set to empty string. If int -1, set to -1. (delItem): If the item to be deleted was selected, select the next item in the list. (delItems): Checks are not necessary and all indices in selected should be deleted. (select): Update selected. (deselect): Update selected. --Tony On Thu, 2006-07-27 at 17:55 -0400, Anthony Balkissoon wrote: On Thu, 2006-07-27 at 17:05 -0400, Anthony Balkissoon wrote: A couple of things to check first: - getSelectedIndex() should probably return -1 if no items are selected, not 0. Correct, it should return -1, the patch that Tania submitted did return -1, the branch if (selected == null) return 0 was never taken because selected was initialized in the constructor and not set to null anywhere. It could potentially be null if the peer returns null for getSelectedIndexes() and in this case -1 should still be returned so I removed that if statement. - in delItem, if the last item is deleted, but it was selected, it looks like an ArrayIndexOutOfBoundsException will be thrown Actually, no. If there are 3 items and the third one (index 2) is selected, and then delItem(2) is called, isSelected(2) still returns true. This doesn't throw any exceptions. getItem(2) will throw an exception but isSelected(2) should still return true. I augmented the Mauve tests to show this. - what happens in select() if multiple mode is false and another index is already selected? should be call deselect() here? The way it is now seems to be fine, initializing a new int array. All of these things should also be tested when there IS a peer present. For instance, in select(), if a peer is present, we call peer.select(). I wonder if we should return at this point or continue on with the method. These tests need to be written. The patch attached is essentially Tania's patch, with the aforementioned removal of an if statement and also with one small performance tweak in the select() method when multipleMode is false. I'll leave this for Tania to comment on and commit. --Tony Index: java/awt/List.java === RCS file: /cvsroot/classpath/classpath/java/awt/List.java,v retrieving revision 1.28 diff -u -r1.28 List.java --- java/awt/List.java 13 Jul 2006 17:30:24 - 1.28 +++ java/awt/List.java 28 Jul 2006 15:13:38 - @@ -108,7 +108,7 @@ * @serial An index value used by codemakeVisible()/code and * codegetVisibleIndex/code. */ -private int visibleIndex; +private int visibleIndex = -1; // The list of ItemListeners for this object. private ItemListener item_listeners; @@ -116,7 +116,6 @@ // The list of ActionListeners for this object. private ActionListener action_listeners; - /*/ /* @@ -176,6 +175,7 @@ if (GraphicsEnvironment.isHeadless()) throw new HeadlessException (); + } /*/ @@ -314,12 +314,13 @@ */ public void setMultipleSelections(boolean multipleMode) -{ +{ this.multipleMode = multipleMode; ListPeer peer = (ListPeer) getPeer (); if (peer != null) peer.setMultipleMode (multipleMode); + } /*/ @@ -519,6 +520,12 @@ public void addItem(String item, int index) { + if (item == null) +item = ; + + if (index -1) +index = -1; + if ((index == -1) || (index = items.size ())) items.addElement (item); else @@ -543,7 +550,17 @@ public void delItem(int index) throws IllegalArgumentException { + boolean selected = false; + if (isSelected(index)) +{ + selected = true; + deselect(index); +} + items.removeElementAt (index); + + if (selected) +select(index); ListPeer peer = (ListPeer) getPeer (); if (peer != null) @@ -580,15 +597,6 @@ public synchronized void delItems(int start, int end) throws IllegalArgumentException { - if ((start 0) || (start = items.size())) -throw new IllegalArgumentException(Bad list start index value: + start); - - if ((start 0) || (start = items.size())) -throw new IllegalArgumentException(Bad list start index value: + start); - - if (start end) -throw new IllegalArgumentException(Start is greater than end!); - // We must run the loop in reverse direction. for (int i = end; i = start; --i) items.removeElementAt (i); @@ -644,6 +652,8 @@ ListPeer peer = (ListPeer) getPeer (); if (peer != null) peer.removeAll
Re: [cp-patches] RFA: List.java
A couple of things to check first: - getSelectedIndex() should probably return -1 if no items are selected, not 0. - in delItem, if the last item is deleted, but it was selected, it looks like an ArrayIndexOutOfBoundsException will be thrown - what happens in select() if multiple mode is false and another index is already selected? should be call deselect() here? I'll test out the patch and maybe write some more tests for this stuff. --Tony On Wed, 2006-07-26 at 10:53 -0400, Tania Bento wrote: Hey, This patch now makes a few of harmony's test suites now pass on classpath. The main problem was that 'selected' was not being updated in a couple of necessary methods. I have also committed some mauve tests (gnu.testlet.java.awt.List.testSelected.java). The other minor modifications were also based on harmony's test suites. If someone could kindly review this patch and approve and/or comment on it, that would be great. Thanks. Tania 2006-07-26 Tania Bento [EMAIL PROTECTED] * java/awt/List.java Initialized private variable visibleIndex to -1. (addItem(String, int)): If string is null, it should be set to the empty string. (addItem(String, int)): If int -1, it should be set to -1. (delItem): If the item to be deleted was selected, the next item on the list automatically is selected. (delItems): Checks are not necessarily and all indices in selected should be deleted. (getSelectedIndex): If selected == null, 0 should be returned. (select): Updated selected. (deselect): Updated selected.
Re: [cp-patches] RFA: List.java
On Thu, 2006-07-27 at 17:05 -0400, Anthony Balkissoon wrote: A couple of things to check first: - getSelectedIndex() should probably return -1 if no items are selected, not 0. Correct, it should return -1, the patch that Tania submitted did return -1, the branch if (selected == null) return 0 was never taken because selected was initialized in the constructor and not set to null anywhere. It could potentially be null if the peer returns null for getSelectedIndexes() and in this case -1 should still be returned so I removed that if statement. - in delItem, if the last item is deleted, but it was selected, it looks like an ArrayIndexOutOfBoundsException will be thrown Actually, no. If there are 3 items and the third one (index 2) is selected, and then delItem(2) is called, isSelected(2) still returns true. This doesn't throw any exceptions. getItem(2) will throw an exception but isSelected(2) should still return true. I augmented the Mauve tests to show this. - what happens in select() if multiple mode is false and another index is already selected? should be call deselect() here? The way it is now seems to be fine, initializing a new int array. All of these things should also be tested when there IS a peer present. For instance, in select(), if a peer is present, we call peer.select(). I wonder if we should return at this point or continue on with the method. These tests need to be written. The patch attached is essentially Tania's patch, with the aforementioned removal of an if statement and also with one small performance tweak in the select() method when multipleMode is false. I'll leave this for Tania to comment on and commit. --Tony Index: java/awt/List.java === RCS file: /cvsroot/classpath/classpath/java/awt/List.java,v retrieving revision 1.28 diff -u -r1.28 List.java --- java/awt/List.java 13 Jul 2006 17:30:24 - 1.28 +++ java/awt/List.java 27 Jul 2006 21:46:45 - @@ -108,7 +108,7 @@ * @serial An index value used by codemakeVisible()/code and * codegetVisibleIndex/code. */ -private int visibleIndex; +private int visibleIndex = -1; // The list of ItemListeners for this object. private ItemListener item_listeners; @@ -116,7 +116,6 @@ // The list of ActionListeners for this object. private ActionListener action_listeners; - /*/ /* @@ -176,6 +175,7 @@ if (GraphicsEnvironment.isHeadless()) throw new HeadlessException (); + } /*/ @@ -314,12 +314,13 @@ */ public void setMultipleSelections(boolean multipleMode) -{ +{ this.multipleMode = multipleMode; ListPeer peer = (ListPeer) getPeer (); if (peer != null) peer.setMultipleMode (multipleMode); + } /*/ @@ -519,6 +520,12 @@ public void addItem(String item, int index) { + if (item == null) +item = ; + + if (index -1) +index = -1; + if ((index == -1) || (index = items.size ())) items.addElement (item); else @@ -543,7 +550,17 @@ public void delItem(int index) throws IllegalArgumentException { + boolean selected = false; + if (isSelected(index)) +{ + selected = true; + deselect(index); +} + items.removeElementAt (index); + + if (selected) +select(index); ListPeer peer = (ListPeer) getPeer (); if (peer != null) @@ -580,15 +597,6 @@ public synchronized void delItems(int start, int end) throws IllegalArgumentException { - if ((start 0) || (start = items.size())) -throw new IllegalArgumentException(Bad list start index value: + start); - - if ((start 0) || (start = items.size())) -throw new IllegalArgumentException(Bad list start index value: + start); - - if (start end) -throw new IllegalArgumentException(Start is greater than end!); - // We must run the loop in reverse direction. for (int i = end; i = start; --i) items.removeElementAt (i); @@ -644,6 +652,8 @@ ListPeer peer = (ListPeer) getPeer (); if (peer != null) peer.removeAll (); + + selected = new int[0]; } /*/ @@ -695,6 +705,7 @@ if (selected == null || selected.length != 1) return -1; + return selected[0]; } @@ -713,7 +724,8 @@ { ListPeer l = (ListPeer) peer; selected = l.getSelectedIndexes (); -} +} + return selected; } @@ -862,13 +874,32 @@ * * @param index The index of the item to select. */ -public synchronized void -select(int index) -{ - ListPeer lp = (ListPeer)getPeer(); - if (lp != null) -lp.select(index); -} + public synchronized void select(int index) + { +ListPeer lp = (ListPeer) getPeer(); +if (lp != null) + lp.select(index); + +boolean
[cp-patches] FYI: JTable fixlet
While testing Mauve exception handling I tried to generate a NPE using JTable.columnAtPoint but found that Classpath was gracefully ignoring null argument while Sun was throwing the NPE I wanted. So I removed the != null check. 2006-03-21 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/JTable.java: (columnAtPoint): Removed the null check, this method should throw a NPE if the argument is null. --Tony === RCS file: /cvsroot/classpath/classpath/javax/swing/JTable.java,v retrieving revision 1.89 diff -u -r1.89 JTable.java --- javax/swing/JTable.java 20 Mar 2006 11:26:04 - 1.89 +++ javax/swing/JTable.java 21 Mar 2006 18:40:07 - @@ -1946,21 +1946,18 @@ */ public int columnAtPoint(Point point) { -if (point != null) - { -int ncols = getColumnCount(); -Dimension gap = getIntercellSpacing(); -TableColumnModel cols = getColumnModel(); -int x = point.x; +int ncols = getColumnCount(); +Dimension gap = getIntercellSpacing(); +TableColumnModel cols = getColumnModel(); +int x = point.x; -for (int i = 0; i ncols; ++i) - { -int width = cols.getColumn(i).getWidth() -+ (gap == null ? 0 : gap.width); -if (0 = x x width) - return i; -x -= width; - } +for (int i = 0; i ncols; ++i) + { +int width = cols.getColumn(i).getWidth() ++ (gap == null ? 0 : gap.width); +if (0 = x x width) + return i; +x -= width; } return -1; } @@ -1969,8 +1966,7 @@ * Returns index of the row that contains specified point or -1 if this table * doesn't contain this point. * - * @param point - * point to identify the row + * @param point point to identify the row * @return index of the row that contains specified point or -1 if this table * doesn't contain this point. */
[cp-patches] FYI: Updated header comment in Character.java
Updated the comment because it made reference to the old Unicode 3 support instead of the new Unicode 4 support. 2006-03-16 Anthony Balkissoon [EMAIL PROTECTED] * java/lang/Character.java: Updated header comment. --Tony
Re: [cp-patches] FYI: Updated header comment in Character.java
Forgot the patch, here it is. On Thu, 2006-03-16 at 13:53 -0500, Anthony Balkissoon wrote: Updated the comment because it made reference to the old Unicode 3 support instead of the new Unicode 4 support. 2006-03-16 Anthony Balkissoon [EMAIL PROTECTED] * java/lang/Character.java: Updated header comment. --Tony ? include/gnu_java_net_PlainDatagramSocketImpl.h ? include/gnu_java_net_PlainSocketImpl.h Index: java/lang/Character.java === RCS file: /cvsroot/classpath/classpath/java/lang/Character.java,v retrieving revision 1.45 diff -u -r1.45 Character.java --- java/lang/Character.java 15 Feb 2006 23:00:38 - 1.45 +++ java/lang/Character.java 16 Mar 2006 18:51:41 - @@ -47,7 +47,7 @@ /** * Wrapper class for the primitive char data type. In addition, this class * allows one to retrieve property information and perform transformations - * on the 57,707 defined characters in the Unicode Standard, Version 3.0.0. + * on the defined characters in the Unicode Standard, Version 4.0.0. * java.lang.Character is designed to be very dynamic, and as such, it * retrieves information on the Unicode character set from a separate * database, gnu.java.lang.CharData, which can be easily upgraded. @@ -55,7 +55,7 @@ * pFor predicates, boundaries are used to describe * the set of characters for which the method will return true. * This syntax uses fairly normal regular expression notation. - * See 5.13 of the Unicode Standard, Version 3.0, for the + * See 5.13 of the Unicode Standard, Version 4.0, for the * boundary specification. * * pSee a href=http://www.unicode.org;http://www.unicode.org/a
[cp-patches] FYI: missing StringBuilder methods
I implemented the missing methods in StringBuilder. 2006-03-02 Anthony Balkissoon [EMAIL PROTECTED] * java/lang/StringBuilder.java: (codePointAt): New method. (codePointBefore): Likewise. (codePointCount): Likewise. (trimToSize): Likewise. --Tony ? include/gnu_java_net_PlainDatagramSocketImpl.h ? include/gnu_java_net_PlainSocketImpl.h Index: java/lang/StringBuilder.java === RCS file: /cvsroot/classpath/classpath/java/lang/StringBuilder.java,v retrieving revision 1.6 diff -u -r1.6 StringBuilder.java --- java/lang/StringBuilder.java 24 Oct 2005 23:58:21 - 1.6 +++ java/lang/StringBuilder.java 2 Mar 2006 20:17:17 - @@ -1006,4 +1006,65 @@ return false; return true; } + + /** + * Get the code point at the specified index. This is like #charAt(int), + * but if the character is the start of a surrogate pair, and the + * following character completes the pair, then the corresponding + * supplementary code point is returned. + * @param index the index of the codepoint to get, starting at 0 + * @return the codepoint at the specified index + * @throws IndexOutOfBoundsException if index is negative or gt;= length() + * @since 1.5 + */ + public int codePointAt(int index) + { +return Character.codePointAt(value, index, count); + } + +/** + * Get the code point before the specified index. This is like + * #codePointAt(int), but checks the characters at codeindex-1/code and + * codeindex-2/code to see if they form a supplementary code point. + * @param index the index just past the codepoint to get, starting at 0 + * @return the codepoint at the specified index + * @throws IndexOutOfBoundsException if index is negative or gt;= length() + * @since 1.5 + */ + public int codePointBefore(int index) + { +// Character.codePointBefore() doesn't perform this check. We +// could use the CharSequence overload, but this is just as easy. +if (index = count) + throw new IndexOutOfBoundsException(); +return Character.codePointBefore(value, index, 1); + } + + /** + * Returns the number of Unicode code points in the specified sub sequence. + * Surrogate pairs count as one code point. + * @param beginIndex the start of the subarray + * @param endIndex the index after the last char in the subarray + * @return the number of code points + * @throws IndexOutOfBoundsException if beginIndex is less than zero or + * greater than endIndex or if endIndex is greater than the length of this + * StringBuilder + */ + public int codePointCount(int beginIndex,int endIndex) + { +if (beginIndex 0 || beginIndex endIndex || endIndex count) + throw new IndexOutOfBoundsException(invalid indices: + beginIndex + + , + endIndex); +return Character.codePointCount(value, beginIndex, endIndex - beginIndex); + } + + public void trimToSize() + { +if (count value.length) + { +char[] newValue = new char[count]; +System.arraycopy(value, 0, newValue, 0, count); +value = newValue; + } + } }
[cp-patches] [generics] BigDecimal conversion methods
Wrote the conversion methods longValueExact, intValueExact, byteValueExact, and shortValueExact. This required a fix in precision() because very large numbers weren't handled properly. 2006-03-01 Anthony Balkissoon [EMAIL PROTECTED] * java/math/BigDecimal.java: (precision): Fixed overflow problem with large numbers. (longValueExact): New method. (intValueExact): Likewise. (byteValueExact): Likewise. (shortValueExact): Likewise. --Tony Index: java/math/BigDecimal.java === RCS file: /cvsroot/classpath/classpath/java/math/BigDecimal.java,v retrieving revision 1.17.2.15 diff -u -r1.17.2.15 BigDecimal.java --- java/math/BigDecimal.java 1 Mar 2006 17:04:22 - 1.17.2.15 +++ java/math/BigDecimal.java 1 Mar 2006 20:12:46 - @@ -1023,13 +1023,11 @@ { if (precision == 0) { -precision = numDigitsInLong(intVal.longValue()); -// If numDigitsInLong returns 19 then we use numDigitsInBigInteger -// to determine if there are actually more than 19 digits in intVal. -if (precision == 19) +if (intVal.compareTo(BigInteger.TEN.pow(18)) == 1) precision = numDigitsInBigInteger(intVal); - } - +else + precision = numDigitsInLong(intVal.longValue()); + } return precision; } @@ -1051,7 +1049,7 @@ /** * This method determines the number of digits in the long value l. - * @param l the long value + * @param l1 the long value * @return the number of digits in l */ private static int numDigitsInLong(long l1) @@ -1536,4 +1534,79 @@ { return new BigDecimal(BigInteger.ONE, scale); } + + /** + * Converts this BigDecimal to a long value. + * @return the long value + * @throws ArithmeticException if rounding occurs or if overflow occurs + * @since 1.5 + */ + public long longValueExact() + { +// Set scale will throw an exception if rounding occurs. +BigDecimal temp = setScale(0, ROUND_UNNECESSARY); +BigInteger tempVal = temp.intVal; +// Check for overflow. +long result = intVal.longValue(); +if (tempVal.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) 1 +|| (result 0 signum() == 1) || (result 0 signum() == -1)) + throw new ArithmeticException(this BigDecimal is too + +large to fit into the return type); + +return intVal.longValue(); + } + + /** + * Converts this BigDecimal into an int by first calling longValueExact + * and then checking that the codelong/code returned from that + * method fits into an codeint/code. + * @return an int whose value is codethis/code + * @throws ArithmeticException if this BigDecimal has a fractional part + * or is too large to fit into an int. + * @since 1.5 + */ + public int intValueExact() + { +long temp = longValueExact(); +int result = (int)temp; +if (result != temp) + throw new ArithmeticException (this BigDecimal cannot fit into an int); +return result; + } + + /** + * Converts this BigDecimal into a byte by first calling longValueExact + * and then checking that the codelong/code returned from that + * method fits into a codebyte/code. + * @return a byte whose value is codethis/code + * @throws ArithmeticException if this BigDecimal has a fractional part + * or is too large to fit into a byte. + * @since 1.5 + */ + public byte byteValueExact() + { +long temp = longValueExact(); +byte result = (byte)temp; +if (result != temp) + throw new ArithmeticException (this BigDecimal cannot fit into a byte); +return result; + } + + /** + * Converts this BigDecimal into a short by first calling longValueExact + * and then checking that the codelong/code returned from that + * method fits into a codeshort/code. + * @return a short whose value is codethis/code + * @throws ArithmeticException if this BigDecimal has a fractional part + * or is too large to fit into a short. + * @since 1.5 + */ + public short shortValueExact() + { +long temp = longValueExact(); +short result = (short)temp; +if (result != temp) + throw new ArithmeticException (this BigDecimal cannot fit into a short); +return result; + } }
[cp-patches] FYI: updated NEWS file
I added a line about Unicode 4.0.0 support to the NEWS file. 2006-02-28 Anthony Balkissoon [EMAIL PROTECTED] * NEWS: Added line about Unicode 4.0.0 support. --Tony ? include/gnu_java_net_PlainDatagramSocketImpl.h ? include/gnu_java_net_PlainSocketImpl.h Index: NEWS === RCS file: /cvsroot/classpath/classpath/NEWS,v retrieving revision 1.114 diff -u -r1.114 NEWS --- NEWS 24 Feb 2006 12:49:44 - 1.114 +++ NEWS 28 Feb 2006 16:14:58 - @@ -7,6 +7,8 @@ `java.security.' `javax.crypto,' and `javax.net.ssl' packages, and are service providers implementing the underlying algorithms. +* Unicode 4.0.0 is supported. + * The new folder tools includes GIOP and RMI stub and tie source code generators, IOR parser and both transient and persistent GIOP naming services.
[cp-patches] FYI: BigInteger serialization fixes PR 26333
I submitted the patch written by Rafael Teixeira: http://developer.classpath.org/pipermail/classpath-patches/2006-February/000473.html that fixes BigInteger serialization. 2006-02-28 Anthony Balkissoon [EMAIL PROTECTED] * java/math/BigInteger.java: Committed patch by Rafael: developer.classpath.org/pipermail/classpath-patches/ 2006-February/000473.html (signum): Return early 0 if words == null and ival == 0. (readObject): Handle special case of magnitude.length or signum being 0. (writeObject): If signum is zero return a zero-sized byte[]. --Tony ? patch.diff ? include/gnu_java_net_PlainDatagramSocketImpl.h ? include/gnu_java_net_PlainSocketImpl.h Index: java/math/BigInteger.java === RCS file: /cvsroot/classpath/classpath/java/math/BigInteger.java,v retrieving revision 1.26 diff -u -r1.26 BigInteger.java --- java/math/BigInteger.java 21 Sep 2005 17:00:33 - 1.26 +++ java/math/BigInteger.java 28 Feb 2006 17:59:13 - @@ -356,9 +356,9 @@ public int signum() { -int top = words == null ? ival : words[ival-1]; -if (top == 0 words == null) +if (ival == 0 words == null) return 0; +int top = words == null ? ival : words[ival-1]; return top 0 ? -1 : 1; } @@ -2227,17 +2227,25 @@ throws IOException, ClassNotFoundException { s.defaultReadObject(); -words = byteArrayToIntArray(magnitude, signum 0 ? -1 : 0); -BigInteger result = make(words, words.length); -this.ival = result.ival; -this.words = result.words; +if (magnitude.length == 0 || signum == 0) + { +this.ival = 0; +this.words = null; + } +else + { +words = byteArrayToIntArray(magnitude, signum 0 ? -1 : 0); +BigInteger result = make(words, words.length); +this.ival = result.ival; +this.words = result.words; + } } private void writeObject(ObjectOutputStream s) throws IOException, ClassNotFoundException { signum = signum(); -magnitude = toByteArray(); +magnitude = signum == 0 ? new byte[0] : toByteArray(); s.defaultWriteObject(); } }
[cp-patches] [generics] BigDecimal fix and 4 new methods
More BD stuff. 2006-02-28 Anthony Balkissoon [EMAIL PROTECTED] * java/math/BigDecimal.java: (divide(BigDecimal, int, RoundingMode)): New method. (divide(BigDecimal, RoundingMode)): Likewise. (divide(BigDecimal, int, int)): Removed incorrect throwing of exception when the new scale is 0. (setScale(int, RoundingMode)): New method. (ulp): Likewise. --Tony Index: java/math/BigDecimal.java === RCS file: /cvsroot/classpath/classpath/java/math/BigDecimal.java,v retrieving revision 1.17.2.13 diff -u -r1.17.2.13 BigDecimal.java --- java/math/BigDecimal.java 27 Feb 2006 21:35:15 - 1.17.2.13 +++ java/math/BigDecimal.java 28 Feb 2006 20:28:12 - @@ -670,7 +670,38 @@ { return divide (val, scale, roundingMode); } + + /** + * Returns a BigDecimal whose value is (this / val), with the specified scale + * and rounding according to the RoundingMode + * @param val the divisor + * @param scale the scale of the BigDecimal returned + * @param roundingMode the rounding mode to use + * @return a BigDecimal whose value is approximately (this / val) + * @throws ArithmeticException if divisor is zero or the rounding mode is + * UNNECESSARY but the specified scale cannot represent the value exactly + * @since 1.5 + */ + public BigDecimal divide(BigDecimal val, + int scale, RoundingMode roundingMode) + { +return divide (val, scale, roundingMode.ordinal()); + } + /** + * Returns a BigDecimal whose value is (this / val) rounded according to the + * RoundingMode + * @param val the divisor + * @param roundingMode the rounding mode to use + * @return a BigDecimal whose value is approximately (this / val) + * @throws ArithmeticException if divisor is zero or the rounding mode is + * UNNECESSARY but the specified scale cannot represent the value exactly + */ + public BigDecimal divide (BigDecimal val, RoundingMode roundingMode) + { +return divide (val, scale, roundingMode.ordinal()); + } + public BigDecimal divide(BigDecimal val, int newScale, int roundingMode) throws ArithmeticException, IllegalArgumentException { @@ -678,9 +709,6 @@ throw new IllegalArgumentException(illegal rounding mode: + roundingMode); -if (newScale 0) - throw new ArithmeticException (scale is negative: + newScale); - if (intVal.signum () == 0) // handle special case of 0.0/0.0 return newScale == 0 ? ZERO : new BigDecimal (ZERO.intVal, newScale); @@ -1346,6 +1374,23 @@ } /** + * Returns a BigDecimal whose value is the same as this BigDecimal but whose + * representation has a scale of codenewScale/code. If the scale is + * reduced then rounding may occur, according to the RoundingMode. + * @param newScale + * @param roundingMode + * @return a BigDecimal whose scale is as given, whose value is + * codethis/code with possible rounding + * @throws ArithmeticException if the rounding mode is UNNECESSARY but + * rounding is required + * @since 1.5 + */ + public BigDecimal setScale(int newScale, RoundingMode roundingMode) + { +return setScale(newScale, roundingMode.ordinal()); + } + + /** * Returns a new BigDecimal constructed from the BigDecimal(String) * constructor using the Double.toString(double) method to obtain * the String. @@ -1419,4 +1464,15 @@ result = result.round(mc); return result; } + + /** + * Returns the size of a unit in the last place of this BigDecimal. This + * returns a BigDecimal with [unscaledValue, scale] = [1, this.scale()]. + * @return the size of a unit in the last place of codethis/code. + * @since 1.5 + */ + public BigDecimal ulp() + { +return new BigDecimal(BigInteger.ONE, scale); + } }
[cp-patches] [generics] BigDecimal stuff again
Some more missing stuff from the BigDecimal class. This spans 2 commits because the first time I forgot the ChangeLog entry. 2006-02-27 Anthony Balkissoon [EMAIL PROTECTED] * java/math/BigDecimal.java: Added @throws clause to constructors. (mathContext): Removed this unneeded field. (BigDecimal(int, MathContext)): New constructor. (BigDecimal(BigInteger, int, MathContext)): Likewise. (multiply(BigDecimal, MathContext)): New method. (negate(MathContext)): Likewise. (plus(MathContext)): Likewise. (numDigitsInLong): Fixed to properly handle negatives. --Tony Index: java/math/BigDecimal.java === RCS file: /cvsroot/classpath/classpath/java/math/BigDecimal.java,v retrieving revision 1.17.2.11 diff -u -r1.17.2.11 BigDecimal.java --- java/math/BigDecimal.java 24 Feb 2006 21:48:07 - 1.17.2.11 +++ java/math/BigDecimal.java 27 Feb 2006 19:42:03 - @@ -41,7 +41,6 @@ { private BigInteger intVal; private int scale; - private MathContext mathContext; private int precision = 0; private static final long serialVersionUID = 6108874887143696463L; @@ -88,6 +87,27 @@ } /** + * Constructs a BigDecimal using the BigDecimal(int) constructor and then + * rounds according to the MathContext. + * @param val the value for the initial (unrounded) BigDecimal + * @param mc the MathContext specifying the rounding + * @throws ArithmeticException if the result is inexact but the rounding type + * is RoundingMode.UNNECESSARY + * @since 1.5 + */ + public BigDecimal (int val, MathContext mc) + { +this (val); +if (mc.getPrecision() != 0) + { +BigDecimal result = this.round(mc); +this.intVal = result.intVal; +this.scale = result.scale; +this.precision = result.precision; + } + } + + /** * Constructs a new BigDecimal whose unscaled value is val and whose * scale is zero. * @param val the value of the new BigDecimal @@ -103,6 +123,8 @@ * and then rounds according to the MathContext. * @param val the long from which we create the initial BigDecimal * @param mc the MathContext that specifies the rounding behaviour + * @throws ArithmeticException if the result is inexact but the rounding type + * is RoundingMode.UNNECESSARY * @since 1.5 */ public BigDecimal (long val, MathContext mc) @@ -124,7 +146,9 @@ * the number of digits in num, then rounding is necessary. * @param num the unscaledValue, before rounding * @param mc the MathContext that specifies the precision - * @since 1.5 + * @throws ArithmeticException if the result is inexact but the rounding type + * is RoundingMode.UNNECESSARY + * * @since 1.5 */ public BigDecimal (BigInteger num, MathContext mc) { @@ -144,6 +168,8 @@ * according to the MathContext mc. * @param val the String from which we construct the initial BigDecimal * @param mc the MathContext that specifies the rounding + * @throws ArithmeticException if the result is inexact but the rounding type + * is RoundingMode.UNNECESSARY * @since 1.5 */ public BigDecimal (String val, MathContext mc) @@ -179,12 +205,36 @@ this.intVal = num; this.scale = scale; } + + /** + * Constructs a BigDecimal using the BigDecimal(BigInteger, int) + * constructor and then rounds according to the MathContext. + * @param num the unscaled value of the unrounded BigDecimal + * @param scale the scale of the unrounded BigDecimal + * @param mc the MathContext specifying the rounding + * @throws ArithmeticException if the result is inexact but the rounding type + * is RoundingMode.UNNECESSARY + * @since 1.5 + */ + public BigDecimal (BigInteger num, int scale, MathContext mc) + { +this (num, scale); +if (mc.getPrecision() != 0) + { +BigDecimal result = this.round(mc); +this.intVal = result.intVal; +this.scale = result.scale; +this.precision = result.precision; + } + } /** * Constructs a BigDecimal in the same way as BigDecimal(double) and then * rounds according to the MathContext. * @param num the double from which the initial BigDecimal is created * @param mc the MathContext that specifies the rounding behaviour + * @throws ArithmeticException if the result is inexact but the rounding type + * is RoundingMode.UNNECESSARY * @since 1.5 */ public BigDecimal (double num, MathContext mc) @@ -569,6 +619,21 @@ { return new BigDecimal (intVal.multiply (val.intVal), scale + val.scale); } + + /** + * Returns a BigDecimal whose value is (this x val) before it is rounded + * according to the MathContext mc. + * @param val the multiplicand + * @param mc the MathContext for rounding + * @return a new BigDecimal with value approximately (this x val) + * @throws ArithmeticException
[cp-patches] [generics] some BigDecimal fixes and new methods
More stuff. Sorry for not sending this BigDecimal stuff all at once but my test cases are small and I prefer to get the stuff committed once its been tested. Also helps me use JAPI to determine what needs to be done. 2006-02-27 Anthony Balkissoon [EMAIL PROTECTED] * java/math/BigDecimal.java: Replaced occurences of BigInteger.valueOf with BigInteger.ZERO, BigInteger.ONE, BigInteger.TEN where appropriate. (add(BigDecimal, MathContext)): New method. (subtract(BigDecimal, MathContext)): Likewise. (precision): Fixed to correctly handle BigIntegers with more than 19 digits. (pow(int, MathContext)): New method. --Tony Index: java/math/BigDecimal.java === RCS file: /cvsroot/classpath/classpath/java/math/BigDecimal.java,v retrieving revision 1.17.2.12 diff -u -r1.17.2.12 BigDecimal.java --- java/math/BigDecimal.java 27 Feb 2006 19:49:07 - 1.17.2.12 +++ java/math/BigDecimal.java 27 Feb 2006 21:31:00 - @@ -49,21 +49,21 @@ * @since 1.5 */ public static final BigDecimal ZERO = -new BigDecimal (BigInteger.valueOf (0), 0); +new BigDecimal (BigInteger.ZERO, 0); /** * The constant one as a BigDecimal with scale zero. * @since 1.5 */ public static final BigDecimal ONE = -new BigDecimal (BigInteger.valueOf (1), 0); +new BigDecimal (BigInteger.ONE, 0); /** * The constant ten as a BigDecimal with scale zero. * @since 1.5 */ public static final BigDecimal TEN = -new BigDecimal (BigInteger.valueOf (10), 0); +new BigDecimal (BigInteger.TEN, 0); public static final int ROUND_UP = 0; public static final int ROUND_DOWN = 1; @@ -603,18 +603,48 @@ BigInteger op1 = intVal; BigInteger op2 = val.intVal; if (scale val.scale) - op1 = op1.multiply (BigInteger.valueOf (10).pow (val.scale - scale)); + op1 = op1.multiply (BigInteger.TEN.pow (val.scale - scale)); else if (scale val.scale) - op2 = op2.multiply (BigInteger.valueOf (10).pow (scale - val.scale)); + op2 = op2.multiply (BigInteger.TEN.pow (scale - val.scale)); return new BigDecimal (op1.add (op2), Math.max (scale, val.scale)); } + + /** + * Returns a BigDecimal whose value is found first by calling the + * method add(val) and then by rounding according to the MathContext mc. + * @param val the augend + * @param mc the MathContext for rounding + * @throws ArithmeticException if the value is inexact but the rounding is + * RoundingMode.UNNECESSARY + * @return codethis/code + codeval/code, rounded if need be + * @since 1.5 + */ + public BigDecimal add (BigDecimal val, MathContext mc) + { +return add(val).round(mc); + } public BigDecimal subtract (BigDecimal val) { return this.add(val.negate()); } + /** + * Returns a BigDecimal whose value is found first by calling the + * method subtract(val) and then by rounding according to the MathContext mc. + * @param val the subtrahend + * @param mc the MathContext for rounding + * @throws ArithmeticException if the value is inexact but the rounding is + * RoundingMode.UNNECESSARY + * @return codethis/code - codeval/code, rounded if need be + * @since 1.5 + */ + public BigDecimal subtract (BigDecimal val, MathContext mc) + { +return subtract(val).round(mc); + } + public BigDecimal multiply (BigDecimal val) { return new BigDecimal (intVal.multiply (val.intVal), scale + val.scale); @@ -661,11 +691,11 @@ { // Effectively increase the scale of val to avoid an // ArithmeticException for a negative power. -valIntVal = valIntVal.multiply (BigInteger.valueOf (10).pow (-power)); +valIntVal = valIntVal.multiply (BigInteger.TEN.pow (-power)); power = 0; } -BigInteger dividend = intVal.multiply (BigInteger.valueOf (10).pow (power)); +BigInteger dividend = intVal.multiply (BigInteger.TEN.pow (power)); BigInteger parts[] = dividend.divideAndRemainder (valIntVal); @@ -674,7 +704,7 @@ return new BigDecimal (unrounded, newScale); if (roundingMode == ROUND_UNNECESSARY) - throw new ArithmeticException (newScale is not large enough); + throw new ArithmeticException (Rounding necessary); int sign = intVal.signum () * valIntVal.signum (); @@ -726,9 +756,9 @@ return intVal.compareTo (val.intVal); BigInteger thisParts[] = - intVal.divideAndRemainder (BigInteger.valueOf (10).pow (scale)); + intVal.divideAndRemainder (BigInteger.TEN.pow (scale)); BigInteger valParts[] = - val.intVal.divideAndRemainder (BigInteger.valueOf (10).pow (val.scale)); + val.intVal.divideAndRemainder (BigInteger.TEN.pow (val.scale)); int compare; if ((compare = thisParts[0].compareTo (valParts[0])) != 0) @@ -737,15 +767,15 @@ // quotients are the same, so compare remainders // remove
[cp-patches] [generics] (even) more BigDecimal methods
Fixed a problem with toBigInteger, it was crashing when the scale was negative. Also wrote the new methods toBigIntegerExact and stripTrailingZeros. 2006-02-24 Anthony Balkissoon [EMAIL PROTECTED] * java/math/BigDecimal.java (toBigInteger): Fixed problem where this method couldn't handle negative values for scale. (toBigIntegerExact): New method. (stripTrailingZeros): Likewise. --Tony Index: java/math/BigDecimal.java === RCS file: /cvsroot/classpath/classpath/java/math/BigDecimal.java,v retrieving revision 1.17.2.9 diff -u -r1.17.2.9 BigDecimal.java --- java/math/BigDecimal.java 23 Feb 2006 22:39:04 - 1.17.2.9 +++ java/math/BigDecimal.java 24 Feb 2006 19:43:16 - @@ -1017,16 +1017,78 @@ return sb.toString(); } + /** + * Converts this BigDecimal to a BigInteger. Any fractional part will + * be discarded. + * @return a BigDecimal whose value is equal to floor[this] + */ public BigInteger toBigInteger () { -return scale == 0 ? intVal : - intVal.divide (BigInteger.valueOf (10).pow (scale)); +// If scale 0 then we must divide, if scale 0 then we must multiply, +// and if scale is zero then we just return intVal; +if (scale 0) + return intVal.divide (BigInteger.valueOf (10).pow (scale)); +else if (scale 0) + return intVal.multiply(BigInteger.valueOf(10).pow(-scale)); +return intVal; + } + + /** + * Converts this BigDecimal into a BigInteger, throwing an + * ArithmeticException if the conversion is not exact. + * @return a BigInteger whose value is equal to the value of this BigDecimal + * @since 1.5 + */ + public BigInteger toBigIntegerExact() + { +if (scale 0) + { +// If we have to divide, we must check if the result is exact. +BigInteger[] result = + intVal.divideAndRemainder(BigInteger.valueOf(10).pow(scale)); +if (result[1].equals(BigInteger.ZERO)) + return result[0]; +throw new ArithmeticException(No exact BigInteger representation); + } +else if (scale 0) + // If we're multiplying instead, then we needn't check for exactness. + return intVal.multiply(BigInteger.valueOf(10).pow(-scale)); +// If the scale is zero we can simply return intVal. +return intVal; } public int intValue () { return toBigInteger ().intValue (); } + + /** + * Returns a BigDecimal which is numerically equal to this BigDecimal but + * with no trailing zeros in the representation. For example, if this + * BigDecimal has [unscaledValue, scale] = [6313000, 4] this method returns + * a BigDecimal with [unscaledValue, scale] = [6313, 1]. As another + * example, [12400, -2] would become [124, -4]. + * @return a numerically equal BigDecimal with no trailing zeros + */ + public BigDecimal stripTrailingZeros() + { +String intValStr = intVal.toString(); +int newScale = scale; +int pointer = intValStr.length() - 1; +// This loop adjusts pointer which will be used to give us the substring +// of intValStr to use in our new BigDecimal, and also accordingly +// adjusts the scale of our new BigDecimal. +while (intValStr.charAt(pointer) == '0') + { +pointer --; +newScale --; + } +// Create a new BigDecimal with the appropriate substring and then +// set its scale. +BigDecimal result = new BigDecimal(intValStr.substring(0, pointer + 1)); +result.scale = newScale; +return result; + } public long longValue () {
[cp-patches] [generics] (still) more BigDecimal methods
I tested the rounding methods and made a fix to the round() method. Satisfied with this I implemented several constructors that required rounding facilities and the abs(MathContext) method that also required rounding. 2006-02-24 Anthony Balkissoon [EMAIL PROTECTED] * java/math/BigDecimal.java: (BigDecimal(long, MathContext)): New constructor. (BigDecimal(BigInteger, MathContext)): Likewise. (BigDecimal(String, MathContext)): Likewise. (BigDecimal(double, MathContext)): Likewise. (round): Fixed a typo where the precision field was used instead of a call to the precision method, and also store the new precision in the returned BigDecimal. (abs(MathContext)): New method. --Tony Index: java/math/BigDecimal.java === RCS file: /cvsroot/classpath/classpath/java/math/BigDecimal.java,v retrieving revision 1.17.2.10 diff -u -r1.17.2.10 BigDecimal.java --- java/math/BigDecimal.java 24 Feb 2006 19:44:30 - 1.17.2.10 +++ java/math/BigDecimal.java 24 Feb 2006 21:45:04 - @@ -99,6 +99,66 @@ } /** + * Constructs a BigDecimal from the long in the same way as BigDecimal(long) + * and then rounds according to the MathContext. + * @param val the long from which we create the initial BigDecimal + * @param mc the MathContext that specifies the rounding behaviour + * @since 1.5 + */ + public BigDecimal (long val, MathContext mc) + { +this(val); +if (mc.getPrecision() != 0) + { +BigDecimal result = this.round(mc); +this.intVal = result.intVal; +this.scale = result.scale; +this.precision = result.precision; + } + } + + /** + * Constructs a BigDecimal whose value is given by num rounded according to + * mc. Since num is already a BigInteger, the rounding refers only to the + * precision setting in mc, if mc.getPrecision() returns an int lower than + * the number of digits in num, then rounding is necessary. + * @param num the unscaledValue, before rounding + * @param mc the MathContext that specifies the precision + * @since 1.5 + */ + public BigDecimal (BigInteger num, MathContext mc) + { +this (num, 0); +if (mc.getPrecision() != 0) + { +BigDecimal result = this.round(mc); +this.intVal = result.intVal; +this.scale = result.scale; +this.precision = result.precision; + } + } + + /** + * Constructs a BigDecimal from the String val according to the same + * rules as the BigDecimal(String) constructor and then rounds + * according to the MathContext mc. + * @param val the String from which we construct the initial BigDecimal + * @param mc the MathContext that specifies the rounding + * @since 1.5 + */ + public BigDecimal (String val, MathContext mc) + { +this (val); +if (mc.getPrecision() != 0) + { +BigDecimal result = this.round(mc); +this.intVal = result.intVal; +this.scale = result.scale; +this.precision = result.precision; + } + } + + /** * Constructs a BigDecimal whose unscaled value is num and whose * scale is zero. * @param num the value of the new BigDecimal @@ -120,6 +180,25 @@ this.scale = scale; } + /** + * Constructs a BigDecimal in the same way as BigDecimal(double) and then + * rounds according to the MathContext. + * @param num the double from which the initial BigDecimal is created + * @param mc the MathContext that specifies the rounding behaviour + * @since 1.5 + */ + public BigDecimal (double num, MathContext mc) + { +this (num); +if (mc.getPrecision() != 0) + { +BigDecimal result = this.round(mc); +this.intVal = result.intVal; +this.scale = result.scale; +this.precision = result.precision; + } + } + public BigDecimal (double num) throws NumberFormatException { if (Double.isInfinite (num) || Double.isNaN (num)) @@ -703,7 +782,7 @@ public BigDecimal round(MathContext mc) { int mcPrecision = mc.getPrecision(); -int numToChop = precision - mcPrecision; +int numToChop = precision() - mcPrecision; // If mc specifies not to chop any digits or if we've already chopped // enough digits (say by using a MathContext in the constructor for this // BigDecimal) then just return this. @@ -716,6 +795,7 @@ new BigDecimal(BigInteger.valueOf((long)Math.pow(10, numToChop))); BigDecimal rounded = divide(div, scale, mc.getRoundingMode().ordinal()); rounded.scale -= numToChop; +rounded.precision = mcPrecision; return rounded; } @@ -1161,5 +1241,16 @@ return result; } - + /** + * Returns a BigDecimal whose value is the absolute value of this BigDecimal + * with rounding according to the given MathContext. + * @param mc the MathContext + * @return the new BigDecimal + */ + public
[cp-patches] [generics] more BigDecimal stuff
I wrote the 'scaleByPowerOfTen' method and when testing it noticed that the toString method wasn't behaving as specified, so I fixed it and added the comments explaining how it should behave. 2006-02-23 Anthony Balkissoon [EMAIL PROTECTED] * java/math/BigDecimal.java: (toString): Rewrote this method to behave as specified. Added API comments to explain behaviour. (scaleByPowerOfTen): New method. --Tony Index: java/math/BigDecimal.java === RCS file: /sources/classpath/classpath/java/math/BigDecimal.java,v retrieving revision 1.17.2.7 diff -u -r1.17.2.7 BigDecimal.java --- java/math/BigDecimal.java 22 Feb 2006 21:56:44 - 1.17.2.7 +++ java/math/BigDecimal.java 23 Feb 2006 18:51:53 - @@ -783,37 +783,82 @@ // 18 or 19 digits. return (l 100L) ? 18 : 19; } - - public String toString () + + /** + * Returns the String representation of this BigDecimal, using scientific + * notation if necessary. The following steps are taken to generate + * the result: + * + * 1. the BigInteger unscaledValue's toString method is called and if + * codescale == 0code is returned. + * 2. an codeint adjExp/code is created which is equal to the negation + * of codescale/code plus the number of digits in the unscaled value, + * minus one. + * 3. if codescale = 0 adjExp = -6/code then we represent this + * BigDecimal without scientific notation. A decimal is added if the + * scale is positive and zeros are prepended as necessary. + * 4. if scale is negative or adjExp is less than -6 we use scientific + * notation. If the unscaled value has more than one digit, a decimal + * as inserted after the first digit, the character 'E' is appended + * and adjExp is appended. + */ + public String toString() { +// bigStr is the String representation of the unscaled value. If +// scale is zero we simply return this. String bigStr = intVal.toString(); -if (scale == 0) +if (scale == 0) return bigStr; -boolean negative = (bigStr.charAt(0) == '-'); +// This is the adjusted exponent described above. +int adjExp = -scale + (numDigitsInLong(intVal.longValue()) - 1); +StringBuilder val = new StringBuilder(); -int point = bigStr.length() - scale - (negative ? 1 : 0); - -StringBuffer sb = new StringBuffer(bigStr.length() + 2 + - (point = 0 ? (-point + 1) : 0)); -if (point = 0) +if (scale = 0 adjExp = -6) { -if (negative) - sb.append('-'); -sb.append('0').append('.'); -while (point 0) +// Convert to character form without scientific notation. +boolean negative = (bigStr.charAt(0) == '-'); +int point = bigStr.length() - scale - (negative ? 1 : 0); +if (point = 0) + { +// Zeros need to be prepended to the StringBuilder. +if (negative) + val.append('-'); +// Prepend a '0' and a '.' and then as many more '0's as necessary. +val.append('0').append('.'); +while (point 0) + { +val.append('0'); +point++; + } +// Append the unscaled value. +val.append(bigStr.substring(negative ? 1 : 0)); + } +else { -sb.append('0'); -point++; +// No zeros need to be prepended so the String is simply the +// unscaled value with the decimal point inserted. +val.append(bigStr); +val.insert(point + (negative ? 1 : 0), '.'); } -sb.append(bigStr.substring(negative ? 1 : 0)); } else { - sb.append(bigStr); - sb.insert(point + (negative ? 1 : 0), '.'); +// We must use scientific notation to represent this BigDecimal. +val.append(bigStr); +// If there is more than one digit in the unscaled value we put a +// decimal after the first digit. +if (bigStr.length() 1) + val.insert(1, '.'); +// And then append 'E' and the exponent - adjExp. +val.append('E'); +if (adjExp 0) + val.append('-'); +else + val.append('+'); +val.append(adjExp); } -return sb.toString(); +return val.toString(); } public BigInteger toBigInteger () @@ -868,4 +913,18 @@ throw new NumberFormatException(argument cannot be NaN or infinite.); return new BigDecimal(Double.toString(val)); } + + /** + * Returns a BigDecimal whose numerical value is the numerical value + * of this BigDecimal multiplied by 10 to the power of coden/code. + * @param n the power of ten + * @return the new BigDecimal + * @since 1.5 + */ + public BigDecimal scaleByPowerOfTen(int n) + { +BigDecimal result = new BigDecimal(intVal, scale - n); +result.precision
[cp-patches] [generics] more BigDecimal methods
ChangeLog says it all. 2006-02-23 Anthony Balkissoon [EMAIL PROTECTED] * java/math/BigDecimal.java: (toString): Fixed a problem where the negative sign was being displayed twice in the exponent. (toEngineeringString): New method. (toPlainString): Likewise. (pow): Likewise. --Tony Index: java/math/BigDecimal.java === RCS file: /cvsroot/classpath/classpath/java/math/BigDecimal.java,v retrieving revision 1.17.2.8 diff -u -r1.17.2.8 BigDecimal.java --- java/math/BigDecimal.java 23 Feb 2006 18:54:51 - 1.17.2.8 +++ java/math/BigDecimal.java 23 Feb 2006 22:36:15 - @@ -850,17 +850,173 @@ // decimal after the first digit. if (bigStr.length() 1) val.insert(1, '.'); -// And then append 'E' and the exponent - adjExp. +// And then append 'E' and the exponent (adjExp). val.append('E'); -if (adjExp 0) - val.append('-'); -else +if (adjExp = 0) val.append('+'); val.append(adjExp); } return val.toString(); } + /** + * Returns the String representation of this BigDecimal, using engineering + * notation if necessary. This is similar to toString() but when exponents + * are used the exponent is made to be a multiple of 3 such that the integer + * part is between 1 and 999. + * + * @return a String representation of this BigDecimal in engineering notation + * @since 1.5 + */ + public String toEngineeringString() + { +// bigStr is the String representation of the unscaled value. If +// scale is zero we simply return this. +String bigStr = intVal.toString(); +if (scale == 0) + return bigStr; + +// This is the adjusted exponent described above. +int adjExp = -scale + (numDigitsInLong(intVal.longValue()) - 1); +StringBuilder val = new StringBuilder(); + +if (scale = 0 adjExp = -6) + { +// Convert to character form without scientific notation. +boolean negative = (bigStr.charAt(0) == '-'); +int point = bigStr.length() - scale - (negative ? 1 : 0); +if (point = 0) + { +// Zeros need to be prepended to the StringBuilder. +if (negative) + val.append('-'); +// Prepend a '0' and a '.' and then as many more '0's as necessary. +val.append('0').append('.'); +while (point 0) + { +val.append('0'); +point++; + } +// Append the unscaled value. +val.append(bigStr.substring(negative ? 1 : 0)); + } +else + { +// No zeros need to be prepended so the String is simply the +// unscaled value with the decimal point inserted. +val.append(bigStr); +val.insert(point + (negative ? 1 : 0), '.'); + } + } +else + { +// We must use scientific notation to represent this BigDecimal. +// The exponent must be a multiple of 3 and the integer part +// must be between 1 and 999. +val.append(bigStr); +int zeros = adjExp % 3; +int dot = 1; +if (adjExp 0) + { +// If the exponent is positive we just move the decimal to the +// right and decrease the exponent until it is a multiple of 3. +dot += zeros; +adjExp -= zeros; + } +else + { +// If the exponent is negative then we move the dot to the right +// and decrease the exponent (increase its magnitude) until +// it is a multiple of 3. Note that this is not adjExp -= zeros +// because the mod operator doesn't give us the distance to the +// correct multiple of 3. (-5 mod 3) is -2 but the distance from +// -5 to the correct multiple of 3 (-6) is 1, not 2. +if (zeros == -2) + { +dot += 1; +adjExp -= 1; + } +else if (zeros == -1) + { +dot += 2; +adjExp -= 2; + } + } + +// Either we have to append zeros because, for example, 1.1E+5 should +// be 110E+3, or we just have to put the decimal in the right place. +if (dot val.length()) + { +while (dot val.length()) + val.append('0'); + } +else if (bigStr.length() dot) + val.insert(dot, '.'); + +// And then append 'E' and the exponent (adjExp). +val.append('E'); +if (adjExp = 0) + val.append('+'); +val.append(adjExp); + } +return val.toString(); + } + + /** + * Returns a String representation of this BigDecimal without using + * scientific notation. This is how
[cp-patches] [generics] New BigDecimal constructors
I added some of the missing constructors in BigDecimal and fixed a small problem with one of the old ones. The BigDecimal(char[], int, int) constructor is the meat of this patch, which I adapted from the BigDecimal(String) constructor but fixed some problems and commented thoroughly. More BigDecimal stuff to follow, the rounding is still yet untested. 2006-02-22 Anthony Balkissoon [EMAIL PROTECTED] * java/math/BigDecimal.java: (BigDecimal(char[], int, int, MathContext)): New constructor. (BigDecimal(char[], MathContext)): Likewise. (BigDecimal(char[])): Likewise. (BigDecimal(char[], int, int)): Likewise. (BigDecimal(String)): Fixed handling of exponent and scale. --Tony Index: java/math/BigDecimal.java === RCS file: /cvsroot/classpath/classpath/java/math/BigDecimal.java,v retrieving revision 1.17.2.6 diff -u -r1.17.2.6 BigDecimal.java --- java/math/BigDecimal.java 21 Feb 2006 21:14:59 - 1.17.2.6 +++ java/math/BigDecimal.java 22 Feb 2006 21:51:56 - @@ -170,6 +170,209 @@ } } + /** + * Constructs a BigDecimal from the char subarray and rounding + * according to the MathContext. + * @param in the char array + * @param offset the start of the subarray + * @param len the length of the subarray + * @param mc the MathContext for rounding + * @throws NumberFormatException if the char subarray is not a valid + * BigDecimal representation + * @throws ArithmeticException if the result is inexact but the rounding + * mode is RoundingMode.UNNECESSARY + * @since 1.5 + */ + public BigDecimal(char[] in, int offset, int len, MathContext mc) + { +this(in, offset, len); +// If mc has precision other than zero then we must round. +if (mc.getPrecision() != 0) + { +BigDecimal temp = this.round(mc); +this.intVal = temp.intVal; +this.scale = temp.scale; +this.precision = temp.precision; + } + } + + /** + * Constructs a BigDecimal from the char array and rounding according + * to the MathContext. + * @param in the char array + * @param mc the MathContext + * @throws NumberFormatException if codein/code is not a valid BigDecimal + * representation + * @throws ArithmeticException if the result is inexact but the rounding mode + * is RoundingMode.UNNECESSARY + * @since 1.5 + */ + public BigDecimal(char[] in, MathContext mc) + { +this(in, 0, in.length); +// If mc has precision other than zero then we must round. +if (mc.getPrecision() != 0) + { +BigDecimal temp = this.round(mc); +this.intVal = temp.intVal; +this.scale = temp.scale; +this.precision = temp.precision; + } + } + + /** + * Constructs a BigDecimal from the given char array, accepting the same + * sequence of characters as the BigDecimal(String) constructor. + * @param in the char array + * @throws NumberFormatException if codein/code is not a valid BigDecimal + * representation + * @since 1.5 + */ + public BigDecimal(char[] in) + { +this(in, 0, in.length); + } + + /** + * Constructs a BigDecimal from a char subarray, accepting the same sequence + * of characters as the BigDecimal(String) constructor. + * @param in the char array + * @param offset the start of the subarray + * @param len the length of the subarray + * @throws NumberFormatException if codein/code is not a valid + * BigDecimal representation. + * @since 1.5 + */ + public BigDecimal(char[] in, int offset, int len) + { +// start is the index into the char array where the significand starts +int start = offset; +// end is one greater than the index of the last character used +int end = offset + len; +// point is the index into the char array where the exponent starts +// (or, if there is no exponent, this is equal to end) +int point = offset; +// dot is the index into the char array where the decimal point is +// found, or -1 if there is no decimal point +int dot = -1; + +// The following examples show what these variables mean. Note that +// point and dot don't yet have the correct values, they will be +// properly assigned in a loop later on in this method. +// +// Example 1 +// +// + 1 0 2 . 4 6 9 +// __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ +// +// offset = 2, len = 8, start = 3, dot = 6, point = end = 10 +// +// Example 2 +// +// + 2 3 4 . 6 1 3 E - 1 +// __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ +// +// offset = 2, len = 11, start = 3, dot = 6, point = 10, end = 13 +// +// Example 3 +// +// - 1 2 3 4 5 e 7 +// __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ +// +// offset = 2, len = 8, start = 3, dot = -1, point = 8, end = 10
Re: [cp-patches] [generics] RFC: new Enum java.math.RoundingMode
This is committed as: 2006-02-21 Anthony Balkissoon [EMAIL PROTECTED] * java/math/MathContext.java: New class. * java/math/RoundingMode: New Enum. In response to Andrew and Tom: Andrew: Yes, the only thing restricting this to the generics branch is the Enum. But reading Sun's arguments in favour of Enums (http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html) , they make some reasonable points. So maybe the pity isn't that they use Enums here but that we're still not able to handle them on the trunk. I'm not sure how far away that is though - from what I understand it's because not all the compilers we use support the new language features? Tom: Yeah, the header template isn't there, and also the Eclipse builder options don't seem to be working properly. Everytime I made any small change it would do an entire rebuild, running autogen, configure, ClasspathHeaders, BuildNative, etc. Andrew Overholt gave it a quick look for me but we didn't see the problem so we just worked around it on my local machine. That's all for now, I should have some more java.math stuff ready soon. --Tony On Tue, 2006-02-21 at 08:32 +, Andrew John Hughes wrote: On Mon, 2006-02-20 at 17:33 -0500, Anthony Balkissoon wrote: On Mon, 2006-02-20 at 15:09 -0500, Anthony Balkissoon wrote: This is RFC because it's my first commit to the generics branch and I just want to make sure there aren't any special procedures I forgot. 2006-02-20 Anthony Balkissoon [EMAIL PROTECTED] * java/math/RoundingMode: New Enum. --Tony This is replaced by: 2006-02-20 Anthony Balkissoon [EMAIL PROTECTED] * java/math/MathContext.java: New class. * java/math/RoundingMode: New Enum. Also, I forgot to put the GNU Classpath header in RoundingMode, but this patch includes it. Comments are still appreciated. I'll commit this tomorrow if no one objects. --Tony Looks fine to me -- the header would have been my only comment. Of course, I'm assuming it applies cleanly and compiles... ;) It's a pity this new math stuff uses an enum for RoundingMode, because AFAICS that's the only thing that restricts this to the generics branch. Index: java/math/MathContext.java === RCS file: java/math/MathContext.java diff -N java/math/MathContext.java --- /dev/null 1 Jan 1970 00:00:00 - +++ java/math/MathContext.java 21 Feb 2006 15:32:37 - @@ -0,0 +1,198 @@ +/* MathContext.java -- + Copyright (C) 1999, 2000, 2002, 2004, 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 java.math; + +import java.io.Serializable; + +/** + * Immutable objects describing settings such as rounding mode and digit + * precision for numerical operations such as those in the BigDecimal class. + * @author Anthony Balkissoon abalkiss at redhat dot com + * + */ +public final class MathContext implements Serializable +{ + /** A MathContext for unlimited precision arithmetic * */ + public static final MathContext UNLIMITED = +new MathContext(0, RoundingMode.HALF_UP); + + /** + * A MathContext for the IEEE 754R Decimal32 format - 7 digit preicision and + * HALF_EVEN rounding. + */ + public static final MathContext DECIMAL32 = +new
[cp-patches] [generics] new BigDecimal methods.
Here are some of the missing BigDecimal methods. More are coming but I'm committing these now so the JAPI results will be more readable. 2006-02-21 Anthony Balkissoon [EMAIL PROTECTED] * java/math/BigDecimal.java: (mathContext): New field. (precision): Likewise. (BigDecimal(int)): New constructor. (BigDecimal(long)): Likewise. (BigDecimal(BigInteger)): Added API docs. (BigDecimal(BigInteger, int)): Removed incorrect NumberFormatException and added API docs. (plus): New method. (round): Likewise. (precision): Likewise. (valueOf): Likewise. (numDigitsInLong): New implementation method. --Tony Index: java/math/BigDecimal.java === RCS file: /cvsroot/classpath/classpath/java/math/BigDecimal.java,v retrieving revision 1.17.2.5 diff -u -r1.17.2.5 BigDecimal.java --- java/math/BigDecimal.java 2 Nov 2005 00:43:34 - 1.17.2.5 +++ java/math/BigDecimal.java 21 Feb 2006 21:07:26 - @@ -41,6 +41,8 @@ { private BigInteger intVal; private int scale; + private MathContext mathContext; + private int precision = 0; private static final long serialVersionUID = 6108874887143696463L; /** @@ -73,15 +75,47 @@ public static final int ROUND_HALF_EVEN = 6; public static final int ROUND_UNNECESSARY = 7; + /** + * Constructs a new BigDecimal whose unscaled value is val and whose + * scale is zero. + * @param val the value of the new BigDecimal + * @since 1.5 + */ + public BigDecimal (int val) + { +this.intVal = BigInteger.valueOf(val); +this.scale = 0; + } + + /** + * Constructs a new BigDecimal whose unscaled value is val and whose + * scale is zero. + * @param val the value of the new BigDecimal + */ + public BigDecimal (long val) + { +this.intVal = BigInteger.valueOf(val); +this.scale = 0; + } + + /** + * Constructs a BigDecimal whose unscaled value is num and whose + * scale is zero. + * @param num the value of the new BigDecimal + */ public BigDecimal (BigInteger num) { this (num, 0); } - public BigDecimal (BigInteger num, int scale) throws NumberFormatException + /** + * Constructs a BigDecimal whose unscaled value is num and whose + * scale is scale. + * @param num + * @param scale + */ + public BigDecimal (BigInteger num, int scale) { -if (scale 0) - throw new NumberFormatException (scale of + scale + is 0); this.intVal = num; this.scale = scale; } @@ -455,7 +489,108 @@ { return new BigDecimal (intVal.negate (), scale); } + + /** + * Returns this BigDecimal. This is included for symmetry with the + * method negate(). + * @return this + * @since 1.5 + */ + public BigDecimal plus() + { +return this; + } + + /** + * Returns a BigDecimal which is this BigDecimal rounded according to the + * MathContext rounding settings. + * @param mc the MathContext that tells us how to round + * @return the rounded BigDecimal + */ + public BigDecimal round(MathContext mc) + { +int mcPrecision = mc.getPrecision(); +int numToChop = precision - mcPrecision; +// If mc specifies not to chop any digits or if we've already chopped +// enough digits (say by using a MathContext in the constructor for this +// BigDecimal) then just return this. +if (mcPrecision == 0 || numToChop = 0) + return this; + +// Make a new BigDecimal which is the correct power of 10 to chop off +// the required number of digits and then call divide. +BigDecimal div = + new BigDecimal(BigInteger.valueOf((long)Math.pow(10, numToChop))); +BigDecimal rounded = divide(div, scale, mc.getRoundingMode().ordinal()); +rounded.scale -= numToChop; +return rounded; + } + + /** + * Returns the precision of this BigDecimal (the number of digits in the + * unscaled value). The precision of a zero value is 1. + * @return the number of digits in the unscaled value, or 1 if the value + * is zero. + */ + public int precision() + { +if (precision == 0) + precision = numDigitsInLong(intVal.longValue()); +return precision; + } + /** + * This method determines the number of digits in the long value l. + * @param l the long value + * @return the number of digits in l + */ + private static int numDigitsInLong(long l) + { +// We divide up the range in a binary fashion, this first if +// takes care of numbers with 1 to 9 digits. +if (l 10L) +{ + // This if is for numbers with 1 to 5 digits. + if (l 10L) +{ + if (l 100L) +return (l 10L) ? 1 : 2; + if (l 1L) +return (l 1000L) ? 3 : 4; + return 5; +} + // Here we handle numbers with 6 to 9 digits. + if (l 1000L) +return (l 100L) ? 6 : 7
[cp-patches] [generics] RFC: new Enum java.math.RoundingMode
This is RFC because it's my first commit to the generics branch and I just want to make sure there aren't any special procedures I forgot. 2006-02-20 Anthony Balkissoon [EMAIL PROTECTED] * java/math/RoundingMode: New Enum. --Tony ? include/gnu_java_net_PlainDatagramSocketImpl.h ? include/gnu_java_net_PlainSocketImpl.h Index: java/math/RoundingMode.java === RCS file: java/math/RoundingMode.java diff -N java/math/RoundingMode.java --- /dev/null 1 Jan 1970 00:00:00 - +++ java/math/RoundingMode.java 20 Feb 2006 20:07:39 - @@ -0,0 +1,40 @@ +package java.math; + +public enum RoundingMode +{ + UP, DOWN, CEILING, FLOOR, HALF_UP, HALF_DOWN, HALF_EVEN, UNNECESSARY; + + /** + * Returns the RoundingMode object corresponding to the legacy rounding modes + * in BigDecimal. + * @param rm the legacy rounding mode + * @return the corresponding RoundingMode + */ + public static RoundingMode valueOf(int rm) + { +switch (rm) + { + case BigDecimal.ROUND_CEILING: +return CEILING; + case BigDecimal.ROUND_FLOOR: +return FLOOR; + case BigDecimal.ROUND_DOWN: +return DOWN; + case BigDecimal.ROUND_UP: +return UP; + case BigDecimal.ROUND_HALF_UP: +return HALF_UP; + case BigDecimal.ROUND_HALF_DOWN: +return HALF_DOWN; + case BigDecimal.ROUND_HALF_EVEN: +return HALF_EVEN; + case BigDecimal.ROUND_UNNECESSARY: +return UNNECESSARY; + default: +throw new + IllegalArgumentException(invalid argument: + rm + + . Argument should be one of the + + rounding modes defined in BigDecimal.); + } + } +}
Re: [cp-patches] [generics] RFC: new Enum java.math.RoundingMode
On Mon, 2006-02-20 at 15:09 -0500, Anthony Balkissoon wrote: This is RFC because it's my first commit to the generics branch and I just want to make sure there aren't any special procedures I forgot. 2006-02-20 Anthony Balkissoon [EMAIL PROTECTED] * java/math/RoundingMode: New Enum. --Tony This is replaced by: 2006-02-20 Anthony Balkissoon [EMAIL PROTECTED] * java/math/MathContext.java: New class. * java/math/RoundingMode: New Enum. Also, I forgot to put the GNU Classpath header in RoundingMode, but this patch includes it. Comments are still appreciated. I'll commit this tomorrow if no one objects. --Tony Index: java/math/MathContext.java === RCS file: java/math/MathContext.java diff -N java/math/MathContext.java --- /dev/null 1 Jan 1970 00:00:00 - +++ java/math/MathContext.java 20 Feb 2006 22:30:02 - @@ -0,0 +1,195 @@ +/* MathContext.java -- + Copyright (C) 1999, 2000, 2002, 2004, 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 java.math; + +import java.io.Serializable; + +/** + * Immutable objects describing settings such as rounding mode and digit + * precision for numerical operations such as those in the BigDecimal class. + * @author Anthony Balkissoon abalkiss at redhat dot com + * + */ +public final class MathContext implements Serializable +{ + /** A MathContext for unlimited precision arithmetic * */ + public static final MathContext UNLIMITED = +new MathContext(0, RoundingMode.HALF_UP); + + /** + * A MathContext for the IEEE 754R Decimal32 format - 7 digit preicision and + * HALF_EVEN rounding. + */ + public static final MathContext DECIMAL32 = +new MathContext(7, RoundingMode.HALF_EVEN); + + /** + * A MathContext for the IEEE 754R Decimal64 format - 16 digit preicision and + * HALF_EVEN rounding. + */ + public static final MathContext DECIMAL64 = +new MathContext(16, RoundingMode.HALF_EVEN); + + /** + * A MathContext for the IEEE 754R Decimal128 format - 34 digit preicision and + * HALF_EVEN rounding. + */ + public static final MathContext DECIMAL128 = +new MathContext(34, RoundingMode.HALF_EVEN); + + /** + * This is the serialVersionUID reported here: + * java.sun.com/j2se/1.5.0/docs/api/serialized-form.html#java.math.MathContext + */ + private static final long serialVersionUID = 5579720004786848255L; + + private int precision; + + private RoundingMode roundMode; + + /** + * Constructs a new MathContext with the specified precision and with HALF_UP + * rounding. + * @param setPrecision the precision for the new MathContext + * + * @throws IllegalArgumentException if precision is 0. + */ + public MathContext(int setPrecision) + { +this(setPrecision, RoundingMode.HALF_UP); + } + + /** + * Constructs a new MathContext with the specified precision and rounding + * mode. + * @param setPrecision the precision + * @param setRoundingMode the rounding mode + * + * @throws IllegalArgumentException if precision is 0. + */ + public MathContext(int setPrecision, RoundingMode setRoundingMode) + { +if (setPrecision 0) + throw new IllegalArgumentException(Precision cannot be less than zero.); +precision
Re: [cp-patches] FYI: ElementBuffer.clone
On Fri, 2006-02-10 at 15:10 +, Roman Kennke wrote: I added the missing ElementBuffer.clone() method. 2006-02-10 Roman Kennke [EMAIL PROTECTED] * javax/swing/text/DefaultStyledDocument.java (ElementBuffer.clone): New method. I don't understand ... I implemented this method on November 8, 2005 and committed the ChangeLog and sent an email to this list ... did I forget to commit the actual change or something? Oh I see now...it was in the wrong place, not in the inner ElementBuffer class. Wups. Roman, comparing the one I wrote to the one you wrote, I think your second argument to replace is wrong ... no Elements are being removed here since the just-created BranchElement has no children. I think it should be branchClone.replace(0, 0, cloneChildren). If you agree, can you fix this? And could you remove the one I wrote at the same time? --Tony
Re: [cp-patches] RFC: new TextActions
On Tue, 2006-02-07 at 16:15 +0100, Robert Schuster wrote: Hi, I am starting to grok that swing stuff. :) I added TextAction implementations for selecting the current line (backward and forward), the whole text from the current position (backward forward) and corrected the behavior of single character deletions when the text has a selection. Or textfield and textareas now do what you would expect from them when pressing shift-home, shift-end, shift-ctrl-home, shift-ctrl-end and del/backspace when your text has a selection. 2006-02-07 Robert Schuster [EMAIL PROTECTED] * javax/swing/text/DefaultEditorToolkit.java: Changed behavior of actions delete-next and delete-previous, added new TextAction implementations for selection-begin, selection-begin-line, selection-end and selection-end-line. Please comment. Hi Robert, this looks great! Cheers, Tony
[cp-patches] FYI: More Character Unicode methods
Implemented more of the missing Unicode-related methods in java.lang.Character, and a missing constructor in java.lang.String. Also fixed an off by one problem in Character and threw an Exception in toChars that we weren't throwing. Note that the String constructor still has issues - I believe the code there is correct and the internal representation seems to be correct, but when printing the String to an output stream it doesn't print correctly. I haven't investigated this very much, but I suspect it's a problem with the printing (looping through the characters one 'char' at a time rather than one 'character' at a time - since characters can be two chars long if they are supplementary characters). I have tests for this stuff but they are not yet in Mauve form. I guess I'll convert them now. More to follow. 2006-01-27 Anthony Balkissoon [EMAIL PROTECTED] * java/lang/Character.java: (offsetByCodePoints(CharSequence, int, int)): New API method. (offsetByCodePoints(char[], int, int, int, int)): Likewise. (toChars): Throw the Exception that the docs say we throw. (codePointAt): Fixed an off-by-one error in the bounds of the if statement. * java/lang/String.java: (String(int[], int, int)): New API constructor. --Tony Index: java/lang/Character.java === RCS file: /cvsroot/classpath/classpath/java/lang/Character.java,v retrieving revision 1.42 diff -u -r1.42 Character.java --- java/lang/Character.java 25 Jan 2006 22:00:44 - 1.42 +++ java/lang/Character.java 27 Jan 2006 19:13:57 - @@ -1741,6 +1741,136 @@ } /** + * Returns the index into the given CharSequence that is offset + * codecodePointOffset/code code points from codeindex/code. + * @param seq the CharSequence + * @param index the start position in the CharSequence + * @param codePointOffset the number of code points offset from the start + * position + * @return the index into the CharSequence that is codePointOffset code + * points offset from index + * + * @throws NullPointerException if seq is null + * @throws IndexOutOfBoundsException if index is negative or greater than the + * length of the sequence. + * @throws IndexOutOfBoundsException if codePointOffset is positive and the + * subsequence from index to the end of seq has fewer than codePointOffset + * code points + * @throws IndexOutOfBoundsException if codePointOffset is negative and the + * subsequence from the start of seq to index has fewer than + * (-codePointOffset) code points + * @since 1.5 + */ + public static int offsetByCodePoints(CharSequence seq, + int index, + int codePointOffset) + { +int len = seq.length(); +if (index 0 || index len) + throw new IndexOutOfBoundsException(); + +int numToGo = codePointOffset; +int offset = index; +int adjust = 1; +if (numToGo = 0) + { +for (; numToGo 0; offset++) + { +numToGo--; +if (Character.isHighSurrogate(seq.charAt(offset)) + (offset + 1) len + Character.isLowSurrogate(seq.charAt(offset + 1))) + offset++; + } +return offset; + } +else + { +numToGo *= -1; +for (; numToGo 0;) + { +numToGo--; +offset--; +if (Character.isLowSurrogate(seq.charAt(offset)) + (offset - 1) = 0 + Character.isHighSurrogate(seq.charAt(offset - 1))) + offset--; + } +return offset; + } + } + + /** + * Returns the index into the given char subarray that is offset + * codecodePointOffset/code code points from codeindex/code. + * @param a the char array + * @param start the start index of the subarray + * @param count the length of the subarray + * @param index the index to be offset + * @param codePointOffset the number of code points offset from codeindex + * /code + * @return the index into the char array + * + * @throws NullPointerException if a is null + * @throws IndexOutOfBoundsException if start or count is negative or if + * start + count is greater than the length of the array + * @throws IndexOutOfBoundsException if index is less than start or larger + * than start + count + * @throws IndexOutOfBoundsException if codePointOffset is positive and the + * subarray from index to start + count - 1 has fewer than codePointOffset + * code points. + * @throws IndexOutOfBoundsException if codePointOffset is negative and the + * subarray from start to index - 1 has fewer than (-codePointOffset) code + * points + * @since 1.5 + + */ + public static int offsetByCodePoints(char[] a, + int start
Re: [cp-patches] FYI: FormView
On Wed, 2006-01-25 at 15:10 +, Roman Kennke wrote: I did a partial implementation of javax.swing.text.html.FormView and added FIXMEs for the things to do. nice work! --Tony ___ Classpath-patches mailing list Classpath-patches@gnu.org http://developer.classpath.org/mailman/listinfo/classpath-patches
Re: [cp-patches] FYI: Implementing multiple editors for JTable (with example)
On Thu, 2006-01-19 at 13:36 +0100, Meskauskas Audrius wrote: This patch add the multi-editor support for JTable. The table now supports the two editors: text and boolean. The boolean values are rendered and edited using JCheckBox. I add the more complicated table example to the Swing demo to show the table with header, multiple data types (text and boolean at the moment) and placed int the scroll window. This is awesome stuff! Good work, man. --Tony ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] FYI: DefaultStyledDocument DocumentEvent handling and more
I eagerly await the day when DefaultStyledDocument won't haunt my every waking minute. This patch addresses an outstanding and known issue with DefaultStyledDocument and ElementBuffer which is that we weren't updating the DocumentEvent associated with changes at the proper time. We also weren't making structural changes at the proper time, and this leads to problems within the text classes. The main part of this patch is to allow change Edit objects to use Vectors instead of arrays to store added and removed children, and then to properly use this throughout the ElementBuffer class. Rather than always creating a new Edit, we see if one exists already for the paragraph in question, and if so, we simply augment it. We then apply all the structural changes stored in the Edit objects all at once and at the same time as updating the DocumentEvent. This patch also deals with a more subtle internal problem by treating the first ContentTag inserted separately from the other tags. Finally, a small fix that I found for StyleContext, an ArrayIndexOutOfBoundsException was being thrown because the bounds of a for loop were off by one. 2006-01-17 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/text/DefaultStyledDocument.java: (pad): New debugging method. (printElements): Likewise. (printPendingEdits): Likewise. (printElement): Likewise. (Edit): Improved docs, moved this class to be an inner class of ElementBuffer since it only applies within that scope. Changed added and removed to be Vectors instead of arrays because we need to be able to add to them after construction. (ElementBuffer): Updated docs with link to article that helped in this classes implementation. (ElementBuffer.Edit.getRemovedElements): New method. (ElementBuffer.Edit.getAddedElements): Likewise. (ElementBuffer.Edit.addRemovedElement): Likewise. (ElementBuffer.Edit.addRemovedElements): Likewise. (ElementBuffer.Edit.addAddedElement): Likewise. (ElementBuffer.Edit.addAddedElements): Likewise. (ElementBuffer.Editinit): Improved docs, call addRemovedElements and addAddedElements. (ElementBuffer.getEditForParagraphAndIndex): New method. (ElementBuffer.removeUpdate): Changed type of paragraph to BranchElement. Corrected style of adding the edit to use the new Edit facilities. (ElementBuffer.changeUpdate): Changed style of adding the edit to use the new Edit facilities. (ElementBuffer.split): Likewise. (ElementBuffer.insertParagraph): Likewise. (ElementBuffer.insertContentTag): Likewise. (ElementBuffer.insert): Push all BranchElements until the deepest one, not just the root and the first one. Apply the structural changes to the tree at the same time as updating the DocumentEvent. (ElementBuffer.insertUpdate): Fixed docs. Removed the special case handling of EndTags as the first ElementSpec. Instead have to handle ContentTags as a special case if they are the first ElementSpec and if not have to fracture the tree. (ElementBuffer.createFracture): New method. May not be complete yet. Added FIXME indicating what may remain to be done. (ElementBuffer.insertFirstContentTag): New method. (ElementBuffer.insertFracture): Added FIXME explaining what remains to be done. Changed the adding of edits to use the new Edit facilities. Removed the adding of edits for Elements that weren't in the tree prior to the insertion. (insertUpdate): Removed incorrect condition for setting a StartTag's direction to JoinNextDirection. * javax/swing/text/StyleContent.java: (SmallAttributeSet.toString): Fixed an off-by-one error in the loop that was causing an ArrayOutOfBoundsException. --Tony ? include/gnu_java_net_PlainDatagramSocketImpl.h ? include/gnu_java_net_PlainSocketImpl.h Index: javax/swing/text/DefaultStyledDocument.java === RCS file: /cvsroot/classpath/classpath/javax/swing/text/DefaultStyledDocument.java,v retrieving revision 1.38 diff -u -r1.38 DefaultStyledDocument.java --- javax/swing/text/DefaultStyledDocument.java 13 Jan 2006 20:04:38 - 1.38 +++ javax/swing/text/DefaultStyledDocument.java 17 Jan 2006 16:21:05 - @@ -67,6 +67,44 @@ public class DefaultStyledDocument extends AbstractDocument implements StyledDocument { + // Prints some spaces. + // This is just debugging code that will be used temporarily. + static void pad(int pad) + { +for (int i = 0; i pad; i++) + System.out.print( ); + } + + // Displays the Element hierarchy starting with codestart/code. + // This is just debugging code that will be used temporarily. + static void printElements (Element start, int pad
Re: [cp-patches] FYI: Old style event fixes, part 2
On Fri, 2006-01-13 at 21:29 +, Roman Kennke wrote: This is the second part for the old (1.0) style AWT event handling. The problem that is fixed here is that events that are targetted at menu components (like ActionEvents) must be forwarded along the parent chain and finally must end up in the frame that holds the menu bar (I have an application here that expects exactly this). Unfortunatly, the MenuBar knows nothing about its parent frame (MenuBars are not part of the normal component hierarchy, also they are not derived from Component). MenuBar.getParent() returns null. So I had to add a reference to the parent frame to MenuBar and forward the event this way. I haven't looked at this stuff, but this resembles very much what happens in Swing's KeyboardManager class. I don't know if the AWT handles it the same way or not, but you might want to look at how it's handled in Swing. Cheers, --Tony ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] FYI: fixlet for TransferHandler fixes Mauve regression
This patch fixes a Mauve regression that Mark pointed out: gnu.testlet.javax.swing.JTextField.CopyPaste I also checked in a Mauve test for it: gnu/testlet/javax/swing/TransferHandler/TransferActionConstructor 2006-01-12 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/TransferHandler.java: (TransferActioninit): Call super constructor. Fixes Mauve regression gnu/testlet/javax/swing/JTextField/CopyPaste. --Tony ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] FYI: More DefaultStyledDocument ElementBuffer fixes
This patch fixes more issues with the ElementBuffer. 2006-01-11 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/text/DefaultStyledDocument.java: (ElementBuffer.insertUpdate): Properly recreate Elements if the first tag is an end tag. Avoid NPE by pushing the proper Element on to the elementStack when there is a start tag with JoinNextDirection. --Tony Index: javax/swing/text/DefaultStyledDocument.java === RCS file: /cvsroot/classpath/classpath/javax/swing/text/DefaultStyledDocument.java,v retrieving revision 1.29 diff -u -r1.29 DefaultStyledDocument.java --- javax/swing/text/DefaultStyledDocument.java 11 Jan 2006 19:25:57 - 1.29 +++ javax/swing/text/DefaultStyledDocument.java 11 Jan 2006 20:04:00 - @@ -785,18 +785,31 @@ if (data[0].getType() == ElementSpec.EndTagType) { // fracture deepest child here - Element curr = getDefaultRootElement(); + 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 newEl1 = createLeafElement(curr.getParentElement(), + Element parent = curr.getParentElement(); + Element newEl1 = createLeafElement(parent, curr.getAttributes(), curr.getStartOffset(), offset); - ((BranchElement) curr.getParentElement()). + 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 }); } @@ -812,9 +825,8 @@ insertFracture(data[i]); break; case ElementSpec.JoinNextDirection: - Element parent = paragraph.getParentElement(); - int index = parent.getElementIndex(offset); - elementStack.push(parent.getElement(index + 1)); + int index = paragraph.getElementIndex(offset); + elementStack.push(paragraph.getElement(index)); break; case ElementSpec.OriginateDirection: Element current = (Element) elementStack.peek(); ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] FYI: Another DefaultStyledDocument ElementBuffer fix
These changes to DefaultStyledDocument make all the local tests I have here pass. I will commit these tests to Mauve now. The number one outstanding problem with DefaultStyledDocument and ElementBuffer is the way DocumentEvents are handled and marked up. Lillian is working on that right now, hopefully we can have it sorted out before too long. 2006-01-11 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/text/DefaultStyledDocument.java: (ElementBuffer.insertContentTag): Don't adjust the structure here. This will have been taken care of in insertFracture. Added a comment explaining that we need to add edits to the DocumentEvent and that this may be the place to do it. --Tony Index: javax/swing/text/DefaultStyledDocument.java === RCS file: /cvsroot/classpath/classpath/javax/swing/text/DefaultStyledDocument.java,v retrieving revision 1.30 diff -u -r1.30 DefaultStyledDocument.java --- javax/swing/text/DefaultStyledDocument.java 11 Jan 2006 20:07:24 - 1.30 +++ javax/swing/text/DefaultStyledDocument.java 11 Jan 2006 20:34:36 - @@ -798,14 +798,19 @@ curr.getAttributes(), curr.getStartOffset(), offset); Element grandParent = parent.getParentElement(); - BranchElement nextBranch = (BranchElement) grandParent.getElement(grandParent.getElementIndex(parent.getEndOffset())); + 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()); + Element newEl2 = +createLeafElement(parent2, + firstLeaf.getAttributes(), + offset, firstLeaf.getEndOffset()); parent2.replace(0, 1, new Element[] { newEl2 }); @@ -941,6 +946,9 @@ */ private void insertFracture(ElementSpec tag) { + System.out.println (BEFORE FRACTURE:); + printElements(getDefaultRootElement(), 0); + // 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(); @@ -1007,6 +1015,9 @@ parent.replace(parentIndex + 1, 0, new Element[] { newBranch }); // FIXME: Add the edits to the DocumentEvent via the addEdit method. + + System.out.println (AFTER FRACTURE:); + printElements(getDefaultRootElement(), 0); } /** @@ -1029,28 +1040,10 @@ } else if (dir == ElementSpec.JoinNextDirection) { - BranchElement paragraph = (BranchElement) elementStack.peek(); - int currentIndex = paragraph.getElementIndex(offset); - Element current = paragraph.getElement(currentIndex); - Element next = paragraph.getElement(currentIndex + 1); - - if (next == null) -return; - - Element newEl1 = createLeafElement(paragraph, - current.getAttributes(), - current.getStartOffset(), - offset); - Element newEl2 = createLeafElement(paragraph, - current.getAttributes(), - offset, - next.getEndOffset()); - - Element[] add = new Element[] { newEl1, newEl2 }; - Element[] remove = new Element[] { current, next }; - paragraph.replace(currentIndex, 2, add); - // Add this action to the document event. - addEdit(paragraph, currentIndex, remove, add); + // Doing nothing here gives us the proper structure. + // However, edits must be added to the document event. + // It is possible these should happen here, or also possible that + // they should happen in insertFracture. } else if (dir == ElementSpec.OriginateDirection) { ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] FYI: patch for DefaultStyledDocument
Now that Lillian and I have good documentation for the ElementBuffer class (http://java.sun.com/products/jfc/tsc/articles/text/element_buffer/index.html) we can finally nail this class down and get it right. I coded some examples suggested in the document linked above and made the following change. The examples I coded will be turned into Mauve tests and committed. 2006-01-09 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/text/DefaultStyledDocument.java: (insertUpdate): Removed call to checkForInsertAfterNewline and instead inlined this method because it needs to change the value of the finalStartTag and finalStartDirection variables. (checkForInsertAfterNewline): Removed this method. (handleInsertAfterNewline): Added case for making the start tag's direction JoinNextDirection. --Tony ? include/gnu_java_net_PlainDatagramSocketImpl.h ? include/gnu_java_net_PlainSocketImpl.h Index: javax/swing/text/DefaultStyledDocument.java === RCS file: /cvsroot/classpath/classpath/javax/swing/text/DefaultStyledDocument.java,v retrieving revision 1.26 diff -u -r1.26 DefaultStyledDocument.java --- javax/swing/text/DefaultStyledDocument.java 5 Jan 2006 20:15:34 - 1.26 +++ javax/swing/text/DefaultStyledDocument.java 9 Jan 2006 18:53:51 - @@ -1596,9 +1596,36 @@ int segmentEnd = txt.offset + txt.count; // Check to see if we're inserting immediately after a newline. -checkForInsertAfterNewline(offset, endOffset, prevParagraph, paragraph, - paragraphAttributes, prevCharWasNewline, - finalStartTag, finalStartDirection, specs); +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 = txt.offset; i segmentEnd; ++i) { @@ -1663,49 +1690,6 @@ } /** - * A helper method that checks to see if insertUpdate was called when text - * was inserted immediately after a newline, and calls - * handleInsertAfterNewline if that is the case. - */ - void checkForInsertAfterNewline(int offset, int endOffset, - Element prevParagraph, Element paragraph, - AttributeSet paragraphAttributes, - boolean prevCharWasNewline, - ElementSpec finalStartTag, - short finalStartDirection, Vector specs) - { -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; -} - } - } - - /** * 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. @@ -1720,7 +1704,10 @@ specs.add(new ElementSpec(a, ElementSpec.StartTagType)); if (prevParagraph.getEndOffset() != endOffset) return ElementSpec.JoinFractureDirection; - +// If there is an Element after
[cp-patches] FYI: PlainDocument patch fixes recent regressions
PlainDocument.insertUpdate needs to explicitly handle the special case of an insertion happening right after a newline. Apparently this worked by accident before, and a recent patch that Lillian and I made to GapContent exposed the weakness. This is fixed and committed now. 2006-01-09 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/text/PlainDocument.java: (insertUpdate): Handle special case of an insertion immediately following a newline character. --Tony ? include/gnu_java_net_PlainDatagramSocketImpl.h ? include/gnu_java_net_PlainSocketImpl.h Index: javax/swing/text/PlainDocument.java === RCS file: /cvsroot/classpath/classpath/javax/swing/text/PlainDocument.java,v retrieving revision 1.18 diff -u -r1.18 PlainDocument.java --- javax/swing/text/PlainDocument.java 16 Nov 2005 18:31:42 - 1.18 +++ javax/swing/text/PlainDocument.java 9 Jan 2006 21:53:51 - @@ -113,6 +113,46 @@ 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]; ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
Re: [cp-patches] FYI: Patches for several javax.swing.text files
On Thu, 2006-01-05 at 21:36 +0100, Mark Wielaard wrote: Hi Tony, +Document doc = textComponent.getDocument(); +if (doc != null) + this.dot = Math.min(dot, doc.getLength()); +this.dot = Math.max(dot, 0); There seems to be some confusion here between dot the parameter and this.dot. if doc != null you probably want to set the parameter dot to Math.min(dot,etc) since you will override this.dot immediately after that assignment. Thanks Mark, this is fixed as follows: 2006-01-05 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/text/DefaultCaret.java: (setDot): Fixed paramater to Math.max to be this.dot and not the parameter dot. RCS file: /cvsroot/classpath/classpath/javax/swing/text/DefaultCaret.java,v retrieving revision 1.27 diff -u -r1.27 DefaultCaret.java --- javax/swing/text/DefaultCaret.java 5 Jan 2006 20:15:34 - 1.27 +++ javax/swing/text/DefaultCaret.java 5 Jan 2006 23:53:08 - @@ -833,7 +833,7 @@ Document doc = textComponent.getDocument(); if (doc != null) this.dot = Math.min(dot, doc.getLength()); -this.dot = Math.max(dot, 0); +this.dot = Math.max(this.dot, 0); this.mark = dot; handleHighlight(); adjustVisibility(this); ? include/gnu_java_net_PlainDatagramSocketImpl.h ? include/gnu_java_net_PlainSocketImpl.h Index: javax/swing/text/DefaultCaret.java === RCS file: /cvsroot/classpath/classpath/javax/swing/text/DefaultCaret.java,v retrieving revision 1.27 diff -u -r1.27 DefaultCaret.java --- javax/swing/text/DefaultCaret.java 5 Jan 2006 20:15:34 - 1.27 +++ javax/swing/text/DefaultCaret.java 5 Jan 2006 23:50:04 - @@ -833,7 +833,7 @@ Document doc = textComponent.getDocument(); if (doc != null) this.dot = Math.min(dot, doc.getLength()); -this.dot = Math.max(dot, 0); +this.dot = Math.max(this.dot, 0); this.mark = dot; handleHighlight(); adjustVisibility(this); ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
Re: [cp-patches] RFC: JMenuItem null accelerators
On Wed, 2006-01-04 at 00:08 +0100, Mark Wielaard wrote: Hi, At various points we try to register a null KeyStroke with an InputMap. This gives some problems later on when InputMaps are copied because null entries aren't always expected. Does the following patch make sense? looks OK to me. Tony 2006-01-03 Mark Wielaard [EMAIL PROTECTED] * javax/swing/JMenuItem.java (configurePropertiesFromAction): Only register keyboard action when accelerator is not null. * javax/swing/plaf/basic/BasicMenuItemUI.java (propertyChange): Only re-register accelerator if not null. (installKeyboardActions): Only put accelerator in map when not null. Cheers, Mark ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] Patch: More fixes for DefaultStyledDocument
Here come some more changes for DefaultStyledDocument. These fix an NPE and improve performance. 2005-12-22 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/text/DefaultStyledDocument.java: (ElementBuffer.insertContentTag): Get the attributes from the tag. Return early if direction is JoinNextDirection but there is no next Element. (createDefaultRoot): Don't call createBranchElement here just instantiate a new BranchElement. (insertUpdate): Removed unneeded fields newElement, newElement2. When building the buffer ElementSpecs, no need to check each time if we should join to the previous or next Element, just check the first and last ElementSpecs after the buffer has been completely built. --Tony Index: javax/swing/text/DefaultStyledDocument.java === RCS file: /cvsroot/classpath/classpath/javax/swing/text/DefaultStyledDocument.java,v retrieving revision 1.23 diff -u -r1.23 DefaultStyledDocument.java --- javax/swing/text/DefaultStyledDocument.java 21 Dec 2005 20:27:31 - 1.23 +++ javax/swing/text/DefaultStyledDocument.java 22 Dec 2005 20:00:54 - @@ -817,7 +817,7 @@ prepareContentInsertion(); int len = tag.getLength(); int dir = tag.getDirection(); - AttributeSet tagAtts = createLeafElement(null, null, 0, 0).getAttributes(); + AttributeSet tagAtts = tag.getAttributes(); if (dir == ElementSpec.JoinPreviousDirection) { // The mauve tests to this class show that a JoinPrevious insertion @@ -832,19 +832,21 @@ Element current = paragraph.getElement(currentIndex); Element next = paragraph.getElement(currentIndex + 1); + if (next == null) +return; + Element newEl1 = createLeafElement(paragraph, current.getAttributes(), - current.getStartOffset(), + current.getStartOffset(), offset); Element newEl2 = createLeafElement(paragraph, - current.getAttributes(), + current.getAttributes(), offset, next.getEndOffset()); - Element[] add = new Element[] {newEl1, newEl2}; - Element[] remove = new Element[] {current, next}; + Element[] add = new Element[] { newEl1, newEl2 }; + Element[] remove = new Element[] { current, next }; paragraph.replace(currentIndex, 2, add); - // Add this action to the document event. addEdit(paragraph, currentIndex, remove, add); } @@ -1148,8 +1150,7 @@ // Use createBranchElement() and createLeafElement instead. SectionElement section = new SectionElement(); -BranchElement paragraph = - (BranchElement) createBranchElement(section, null); +BranchElement paragraph = new BranchElement(section, null); paragraph.setResolveParent(getStyle(StyleContext.DEFAULT_STYLE)); tmp = new Element[1]; tmp[0] = paragraph; @@ -1483,7 +1484,6 @@ int offset = ev.getOffset(); int length = ev.getLength(); int endOffset = offset + length; -Element newElement, newElement2; AttributeSet paragraphAttributes = getParagraphElement(endOffset).getAttributes(); Segment txt = new Segment(); @@ -1503,7 +1503,7 @@ Element prev = getCharacterElement(offset); Element next = getCharacterElement(endOffset); - + int segmentEnd = txt.offset + txt.count; for (int i = txt.offset; i segmentEnd; ++i) { @@ -1512,21 +1512,6 @@ { 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 == segmentEnd - 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 ElementSpecs for the newline. @@ -1542,22 +1527,20 @@ } // Create last element if last character hasn't been a newline. -if (len 0) - { -ElementSpec spec = new ElementSpec(attr, ElementSpec.ContentType
[cp-patches] Patch: StyleContext.SmallAttributeSet fix and remove hack from DefaultStyledDocument
I sent a message to the list yesterday (message is attached) detailing a hack that I put into DefaultStyledDocument. Roman helped me track down the real problem and this patch fixes the problem as well as removes the hack from DefaultStyledDocument. This is accompanied by gnu/testlet/javax/swing/text/AttributeSet/isEqual.java 2005-12-21 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/text/DefaultStyledDocument.java: (insertUpdate): If the AttributeSet argument is null use an empty AttributeSet for comparisons. No need to create a new LeafElement to compare AttributeSets (ie - remove the hack added yesterday). * javax/swing/text/StyleContext.java: (SmallAttributeSet.isEqual): Don't return false for null arguments, this should throw an NPE instead. Also, for performance, check that sizes are equal and one set contains the other, rather than checking that each set contains the other. --Tony Index: javax/swing/text/DefaultStyledDocument.java === RCS file: /cvsroot/classpath/classpath/javax/swing/text/DefaultStyledDocument.java,v retrieving revision 1.22 diff -u -r1.22 DefaultStyledDocument.java --- javax/swing/text/DefaultStyledDocument.java 20 Dec 2005 18:35:22 - 1.22 +++ javax/swing/text/DefaultStyledDocument.java 21 Dec 2005 20:21:53 - @@ -834,0 +834,0 @@ Element newEl1 = createLeafElement(paragraph, current.getAttributes(), - current.getStartOffset(), + current.getStartOffset(), offset); Element newEl2 = createLeafElement(paragraph, current.getAttributes(), @@ -844,7 +844,7 @@ Element[] add = new Element[] {newEl1, newEl2}; Element[] remove = new Element[] {current, next}; paragraph.replace(currentIndex, 2, add); - + // Add this action to the document event. addEdit(paragraph, currentIndex, remove, add); } @@ -1477,6 +1477,9 @@ 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; @@ -1508,28 +1511,18 @@ if (txt.array[i] == '\n') { ElementSpec spec = new ElementSpec(attr, ElementSpec.ContentType, - len); -// FIXME: This is a hack. Without this, our check to see if -// prev.getAttributes was the same as the attribute set for the new -// ElementSpec was never true, because prev has an attribute key -// LeafElement(content) that contains its start and end offset as -// the value. Similarly for next. -newElement = createLeafElement(null, attr, prev.getStartOffset(), - prev.getEndOffset()); -newElement2 = createLeafElement(null, attr, next.getStartOffset(), - next.getEndOffset()); - + len); // If we are at the last index, then check if we could probably be // joined with the next element. if (i == segmentEnd - 1) { -if (next.getAttributes().isEqual(newElement2.getAttributes())) +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(newElement.getAttributes())) +if (prev.getAttributes().isEqual(attr)) spec.setDirection(ElementSpec.JoinPreviousDirection); } @@ -1551,25 +1544,14 @@ // Create last element if last character hasn't been a newline. if (len 0) { -ElementSpec spec = new ElementSpec(attr, ElementSpec.ContentType, len); - -// FIXME: This is a hack. Without this, our check to see if -// prev.getAttributes was the same as the attribute set for the new -// ElementSpec was never true, because prev has an attribute key -// LeafElement(content) that contains its start and end offset as -// the value. Similarly for next. -newElement = createLeafElement(null, attr, prev.getStartOffset
[cp-patches] Patch: DefaultEditorKit.read
2005-12-21 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/text/DefaultEditorKit.java: (read): Changed the call to insertString to leave out the trailing new line. Index: javax/swing/text/DefaultEditorKit.java === RCS file: /cvsroot/classpath/classpath/javax/swing/text/DefaultEditorKit.java,v retrieving revision 1.26 diff -u -r1.26 DefaultEditorKit.java --- javax/swing/text/DefaultEditorKit.java 20 Dec 2005 22:42:04 - 1.26 +++ javax/swing/text/DefaultEditorKit.java 21 Dec 2005 21:57:22 - @@ -948,7 +948,7 @@ content.append(\n); } -document.insertString(offset, content.toString(), +document.insertString(offset, content.substring(0, content.length() - 1), SimpleAttributeSet.EMPTY); } ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] Re: Patch: DefaultEditorKit.read
Sorry, I meant to hit enter, but I hit CTRL-enter and sent that last patch without any text description. I'll include the patch and ChangeLog entry here, so at least one of the emails is complete. This patch accompanies changes to gnu.testlet.javax.swing.text.DefaultStyledDocument.ElementBuffer.ElementStructure3 2005-12-21 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/text/DefaultEditorKit.java: (read): Changed the call to insertString to leave out the trailing new line. --Tony Index: javax/swing/text/DefaultEditorKit.java === RCS file: /cvsroot/classpath/classpath/javax/swing/text/DefaultEditorKit.java,v retrieving revision 1.26 diff -u -r1.26 DefaultEditorKit.java --- javax/swing/text/DefaultEditorKit.java 20 Dec 2005 22:42:04 - 1.26 +++ javax/swing/text/DefaultEditorKit.java 21 Dec 2005 21:57:22 - @@ -948,7 +948,7 @@ content.append(\n); } -document.insertString(offset, content.toString(), +document.insertString(offset, content.substring(0, content.length() - 1), SimpleAttributeSet.EMPTY); } ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
Re: [cp-patches] Patch: several fixes for DefaultStyledDocument
On Mon, 2005-12-19 at 17:54 -0500, Anthony Balkissoon wrote: This is the first part of the work I'm doing on DefaultStyledDocument. This fixes a couple issues associated with PR 24744 but the bug is not completely fixed yet, so the testcase for that PR still crashes. I will continue to work on this but these changes are ready to go in and may help get some text/html test apps up and running so I'm committing this now. This patch caused some Mauve regressions because it's causing an unexpected exception, I'm working on this and will also be checking in the Mauve tests I wrote while creating this patch. --Tony ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
Re: [cp-patches] Patch: several fixes for DefaultStyledDocument
On Tue, 2005-12-20 at 11:01 -0500, Anthony Balkissoon wrote: On Mon, 2005-12-19 at 17:54 -0500, Anthony Balkissoon wrote: This is the first part of the work I'm doing on DefaultStyledDocument. This fixes a couple issues associated with PR 24744 but the bug is not completely fixed yet, so the testcase for that PR still crashes. I will continue to work on this but these changes are ready to go in and may help get some text/html test apps up and running so I'm committing this now. This patch caused some Mauve regressions because it's causing an unexpected exception, I'm working on this and will also be checking in the Mauve tests I wrote while creating this patch. --Tony Okay, I've fixed the regressions and made progress with the attached patch. Yesterday I put code in ElementBuffer.insertContentTag to join Elements if they had the same attribute sets. This was incorrect and led to the Mauve regressions. The problem was that the wrong information was being passed to insertContentTag. DefaultStyledDocument.insertUpdate basically makes a list of ElementSpecs that it wants the ElementBuffer to turn into Elements. There was a problem in this method that was causing the wrong ElementSpecs to be sent to the ElementBuffer (and eventually to insertContentTag). This is fixed, but the solution is somewhat of a hack. The reason for the hack is as follows. To create a LeafElement (a structural object) we call AbstractDocument.createLeafElement which takes as one of its parameters an AttributeSet that you want the LeafElement to have. However, in the process of creating the LeafElement we actually add an attribute to the set that describes the LeafElement's start and end offset positions. So for instance, the following code would print false (the parent, start_offset, end_offset arguments are not important to this discussion): SimpleAttributeSet set = new SimpleAttributeSet(); set.addAttribute(A, B); Element e = createLeafElement(parent, set, start_offset, end_offset); System.out.println (e.isEqual(set)); And this is the basis of our problem .. before we were comparing the AttributeSet that we were going to use to create an Element with the attribute set from an Element that already existed and so we'd always get that they were not equal. So the hack basically calls createLeafElement to create an Element from which we get an AttributeSet, and we use _that_ set in our comparisons. The element returned from createLeafElement is then thrown away, we don't actually add it to the Document structure. Since I consider this a bit of a hack, comments are appreciated (Roman?) in case another solution is preferred. 2005-12-20 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/text/DefaultStyledDocument.java: (ElementBuffer.insertContentTag): If the direction is OriginateDirection split all the time, don't check the attribute sets. Removed the special case for the first insertion. These cases should fall under the direction JoinPreviousDirection. Changed the comments to reflect this. (insertUpdate): Added a hack to get the right result when comparing the attributes of the new ElementSpec to the attributes of either the previous or next Element. --Tony Index: javax/swing/text/DefaultStyledDocument.java === RCS file: /cvsroot/classpath/classpath/javax/swing/text/DefaultStyledDocument.java,v retrieving revision 1.21 diff -u -r1.21 DefaultStyledDocument.java --- javax/swing/text/DefaultStyledDocument.java 19 Dec 2005 22:52:32 - 1.21 +++ javax/swing/text/DefaultStyledDocument.java 20 Dec 2005 18:24:13 - @@ -866,89 +866,36 @@ removed = new Element[0]; index++; } - else if (current.getStartOffset() == offset -current.getEndOffset() - 1 == endOffset) -{ - // This is if the new insertion covers the entire range of - // codecurrent/code. This will generally happen for the - // first insertion into a new paragraph. - added = new Element[1]; - added[0] = createLeafElement(paragraph, tagAtts, - offset, endOffset + 1); -} else if (current.getStartOffset() == offset) -{ +{ // This is if the new insertion happens immediately before - // the codecurrent/code Element. In this case, if there is - // a split, there are 2 resulting Elements. - - AttributeSet splitAtts = splitRes[1].getAttributes(); - if (attributeSetsAreSame(tagAtts, splitAtts)) -{ - // If the attributes of the adjacent Elements are the same - // then we don't split them, we join them
[cp-patches] Patch for AbstractDocument fixes PR 25506
Small fixlet fixes a long standing and annoying problem with text components. 2005-12-20 Anthony Balkissoon [EMAIL PROTECTED] Fixes bug #25506 * javax/swing/text/AbstractDocument.java: (insertString): Fire insert update whether the DocumentEvent was changed or not. --Tony Index: javax/swing/text/AbstractDocument.java === RCS file: /cvsroot/classpath/classpath/javax/swing/text/AbstractDocument.java,v retrieving revision 1.41 diff -u -r1.41 AbstractDocument.java --- javax/swing/text/AbstractDocument.java 15 Dec 2005 21:17:46 - 1.41 +++ javax/swing/text/AbstractDocument.java 20 Dec 2005 21:25:57 - @@ -544,8 +544,7 @@ insertUpdate(event, attributes); writeUnlock(); -if (event.modified) - fireInsertUpdate(event); +fireInsertUpdate(event); if (undo != null) fireUndoableEditUpdate(new UndoableEditEvent(this, undo)); } ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
Re: [cp-patches] FYI: SwingUtilities.processKeyBindings() implemented
On Sat, 2005-12-17 at 00:30 +, Roman Kennke wrote: Hi, thanks to the work done by Anthony Balkissoon (KeyboardManager) I finally could make some sense out of the method SwingUtilities.processKeyBindings() which previously caused headaches to me :-) What I think what this method actually should do (and this is how I implemented it) is, that it processes key bindings for a java.awt.Component (that is not derived from JComponent) that are in the WHEN_IN_FOCUSED_WINDOW scope. This is necessary because otherwise such events would get lost without notifying components with such bindings. However, I am not sure how this method should be triggered. From within Component.processKeyEvent() maybe, but calling into Swing code from AWT seems so ugly... My interpretation was that it was up to the user to call this method if they subclassed JComponent and didn't call super.processKeyEvent from the subclass' processKeyEvent method. Or, if they wrote Swing Components that were not derived from JComponent .. I still thought it was up to them to call it. Things like JFrame, which aren't derived from JComponent, shouldn't call this method internally. Thanks for implementing this, I believe that was actually in my PR list. --Tony ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
Re: [cp-patches] FYI: DefaultStyledDocument fixlet
On Mon, 2005-12-19 at 13:59 +, Roman Kennke wrote: Hi there, this patch fixes DefaultStyledDocument.setParagraphAttributes(), so that it doesn't hang in an infinite loop like in the testcase of bug# Hi Roman, I worked on a patch on Friday that fixed this issue and also added ElementEdits to the DocumentEvent. I was going to commit it but my internet connection went down. Also, the writeLock() and writeUnlock() should be in a try/finally block. The patch includes several changes to DefaultStyledDocument that I made as I read through the O'Reilly book beefing up my knowledge about this class before I try to fix PR 24744. I'll just paste the body of this method (setParagraphAttributes) here, and let me know if you're okay with this change, and I'll send the full patch up when it's ready. public void setParagraphAttributes(int offset, int length, AttributeSet attributes, boolean replace) { 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 { writeUnlock(); } } --Tony ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] Patch: several fixes for DefaultStyledDocument
This is the first part of the work I'm doing on DefaultStyledDocument. This fixes a couple issues associated with PR 24744 but the bug is not completely fixed yet, so the testcase for that PR still crashes. I will continue to work on this but these changes are ready to go in and may help get some text/html test apps up and running so I'm committing this now. 2005-12-19 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/text/DefaultStyledDocument.java: (endOffset): New field. (ElementBuffer.insert): If length is 0 return early. Set the endOffset variable here. (ElementBuffer.insertContentTag): Added special case for when insertion covers entire range of the current Element. Replaced (offset + length) with endOffset everywhere. Added checks to see if the insertion has the same attributes as the surrounding Element(s), in which case we don't split them, we join them. (SectionElement.getName): Return the field SectionElementName instead of hardcoding a return value. (getLogicalStyle): As the specs require, if the attributes from the resolve parent aren't of type Style, return null. (setCharacterAttributes): Exit early if length is 0. Obtain a write lock for the body of this method. Changed the way we iterate through the paragraphs to be more efficient and more intuitive. Added AttributeUndoableEdits to the DocumentEvent and fired the UndoableEditUpdate. (setLogicalStyle): Return early if the Element is null. Obtain a write lock for the body of this method. Fire the appropriate DocumentEvent. (setParagraphAttributes): Changed the way we iterated through the paragraphs because it was incorrect and unintuitive. Obtained a write lock within a try/finally block. Added AttributeUndoableEdits to the DocumentEvent and fired the event. (insertUpdate): Changed the way we iterate because we cannot assume the Segment holds the characters starting from index 0. Give the startTag the same attributes as the paragraph. Removed the useless offset += len line because len is 0. (printElements): New temporary debugging method. (attributeSetsAreSame): New method. --Tony Index: javax/swing/text/DefaultStyledDocument.java === RCS file: /cvsroot/classpath/classpath/javax/swing/text/DefaultStyledDocument.java,v retrieving revision 1.20 diff -u -r1.20 DefaultStyledDocument.java --- javax/swing/text/DefaultStyledDocument.java 19 Dec 2005 10:21:39 - 1.20 +++ javax/swing/text/DefaultStyledDocument.java 19 Dec 2005 22:36:04 - @@ -48,6 +48,7 @@ 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; @@ -428,6 +429,9 @@ /** 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 @@ -675,8 +679,11 @@ 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(); @@ -799,7 +806,7 @@ } return ret; } - + /** * Inserts a content element into the document structure. * @@ -810,6 +817,7 @@ prepareContentInsertion(); int len = tag.getLength(); int dir = tag.getDirection(); + AttributeSet tagAtts = createLeafElement(null, null, 0, 0).getAttributes(); if (dir == ElementSpec.JoinPreviousDirection) { // The mauve tests to this class show that a JoinPrevious insertion @@ -845,45 +853,103 @@ BranchElement paragraph = (BranchElement) elementStack.peek(); int index = paragraph.getElementIndex(offset); Element current = paragraph.getElement(index); - + Element[] added; - Element[] removed; + Element[] removed = new Element[] {current}; Element[] splitRes = split(current, offset, length); - // Special case for when offset == startOffset or offset == endOffset. if (splitRes[0] == null) { added = new Element[2]; - added[0] = createLeafElement(paragraph, tag.getAttributes(), - offset, offset + length); + added[0
Re: [cp-patches] RFC: HTMLDocument.HTMLReader partial implementation
No objections were raised, and I got a couple of go-aheads, so this is committed as follows (same as before plus 1 more stubbed method that Lillian needed). 2005-12-12 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/text/html/HTMLDocument.java: (tokenThreshold): New field. (parser): New field. (getParser): New API method. (setParser): New API method. (getTokenThreshold): New API method. (setTokenThreshold): New API method. (getReader(int, int, int, HTML.Tag)): New API method, not implemented. (HTMLReader): New API class, partially implemented. (HTMLReader.BlockAction): New API class, not implemented. (HTMLReader.CharacterAction): Likewise. (HTMLReader.FormAction): Likewise. (HTMLReader.HiddenAction): Likewise. (HTMLReader.IsindexAction): Likewise. (HTMLReader.ParagraphAction): Likewise. (HTMLReader.PreAction): Likewise. (HTMLReader.SpecialAction): Likewise. (HTMLReader.TagAction): New API class, implemented. * javax/swing/text/html/HTMLEditorKit.java: (createDefaultDocument): Set the parser for the new HTMLDocument. --Tony On Mon, 2005-12-12 at 17:38 -0500, Anthony Balkissoon wrote: This is a partial implementation of HTMLDocument.HTMLReader. I am still working on this, so it will be more fully implemented soon. I submit this as RFC because it has several methods that have nothing more than FIXME: Implement as well as some debugging statements. These are there so that Lillian and myself can work on the entire HTML package. Since some of the classes she's working on require HTMLDocument.HTMLReader I want these methods to be available so her classes can build even if they are not yet implemented, with the understanding that I will implement them shortly. The debugging (System.out.println) statements are there so that as we run test apps we can see how the different classes are linked together. Since we are the only two people that I know of working on this javax.swing.text.html package I don't think this should be a problem but I'm still asking if anyone has objections to me checking in this patch with stubs and println's. Note that all of the stubs have FIXME notes and that the println's can easily be taken out before the next release if we haven't finished implementing the methods yet. Objections? 2005-12-12 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/text/html/HTMLDocument.java: (tokenThreshold): New field. (parser): New field. (getParser): New API method. (setParser): New API method. (getTokenThreshold): New API method. (setTokenThreshold): New API method. (HTMLReader): New API class, partially implemented. (HTMLReader.BlockAction): New API class, not implemented. (HTMLReader.CharacterAction): Likewise. (HTMLReader.FormAction): Likewise. (HTMLReader.HiddenAction): Likewise. (HTMLReader.IsindexAction): Likewise. (HTMLReader.ParagraphAction): Likewise. (HTMLReader.PreAction): Likewise. (HTMLReader.SpecialAction): Likewise. (HTMLReader.TagAction): New API class, implemented. * javax/swing/text/html/HTMLEditorKit.java: (createDefaultDocument): Set the parser for the new HTMLDocument. --Tony ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches Index: javax/swing/text/html/HTMLDocument.java === RCS file: /cvsroot/classpath/classpath/javax/swing/text/html/HTMLDocument.java,v retrieving revision 1.7 diff -u -r1.7 HTMLDocument.java --- javax/swing/text/html/HTMLDocument.java 9 Dec 2005 17:52:54 - 1.7 +++ javax/swing/text/html/HTMLDocument.java 13 Dec 2005 16:10:41 - @@ -39,12 +39,18 @@ package javax.swing.text.html; import java.net.URL; +import java.util.HashMap; +import java.util.Stack; +import java.util.Vector; 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.MutableAttributeSet; +import javax.swing.text.SimpleAttributeSet; import javax.swing.text.html.HTML.Tag; /** @@ -60,6 +66,49 @@ public static final String AdditionalComments = AdditionalComments; URL baseURL = null; boolean preservesUnknownTags = true; + int tokenThreshold = Integer.MAX_VALUE; + HTMLEditorKit.Parser parser; + + /** + * 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
[cp-patches] RFC: HTMLDocument.HTMLReader partial implementation
This is a partial implementation of HTMLDocument.HTMLReader. I am still working on this, so it will be more fully implemented soon. I submit this as RFC because it has several methods that have nothing more than FIXME: Implement as well as some debugging statements. These are there so that Lillian and myself can work on the entire HTML package. Since some of the classes she's working on require HTMLDocument.HTMLReader I want these methods to be available so her classes can build even if they are not yet implemented, with the understanding that I will implement them shortly. The debugging (System.out.println) statements are there so that as we run test apps we can see how the different classes are linked together. Since we are the only two people that I know of working on this javax.swing.text.html package I don't think this should be a problem but I'm still asking if anyone has objections to me checking in this patch with stubs and println's. Note that all of the stubs have FIXME notes and that the println's can easily be taken out before the next release if we haven't finished implementing the methods yet. Objections? 2005-12-12 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/text/html/HTMLDocument.java: (tokenThreshold): New field. (parser): New field. (getParser): New API method. (setParser): New API method. (getTokenThreshold): New API method. (setTokenThreshold): New API method. (HTMLReader): New API class, partially implemented. (HTMLReader.BlockAction): New API class, not implemented. (HTMLReader.CharacterAction): Likewise. (HTMLReader.FormAction): Likewise. (HTMLReader.HiddenAction): Likewise. (HTMLReader.IsindexAction): Likewise. (HTMLReader.ParagraphAction): Likewise. (HTMLReader.PreAction): Likewise. (HTMLReader.SpecialAction): Likewise. (HTMLReader.TagAction): New API class, implemented. * javax/swing/text/html/HTMLEditorKit.java: (createDefaultDocument): Set the parser for the new HTMLDocument. --Tony Index: javax/swing/text/html/HTMLDocument.java === RCS file: /cvsroot/classpath/classpath/javax/swing/text/html/HTMLDocument.java,v retrieving revision 1.7 diff -u -r1.7 HTMLDocument.java --- javax/swing/text/html/HTMLDocument.java 9 Dec 2005 17:52:54 - 1.7 +++ javax/swing/text/html/HTMLDocument.java 12 Dec 2005 22:25:59 - @@ -39,12 +39,18 @@ package javax.swing.text.html; import java.net.URL; +import java.util.HashMap; +import java.util.Stack; +import java.util.Vector; 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.MutableAttributeSet; +import javax.swing.text.SimpleAttributeSet; import javax.swing.text.html.HTML.Tag; /** @@ -60,6 +66,49 @@ public static final String AdditionalComments = AdditionalComments; URL baseURL = null; boolean preservesUnknownTags = true; + int tokenThreshold = Integer.MAX_VALUE; + HTMLEditorKit.Parser parser; + + /** + * 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. @@ -267,6 +316,769 @@ } /** + * 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; + +protected Vector parseBuffer; + +/** 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; + +public class
[cp-patches] FYI: Patch for JEditorPane
This patch accompanies the new tests in gnu.testlet.javax.swing.JEditorPane.ContentType This patch makes JEditorPane handle different content types properly, using the appropriate EditorKit for different types. This will allow Lillian and myself to write test apps for html using JEditorPane because now it will use HTMLEditorKit to display the content. 2005-12-08 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/JEditorPane.java: (registerMap): New field. (editorMap): New field. (JEditorPane()): Call init instead of setEditorKit. (JEditorPane(String, String)): Likewise. (init): New method. (createEditorKitForContentType): Implemented and documented. (getEditorKitClassNameForContentType): Likewise. (getEditorKitForContentType): Likewise. (registerEditorKitForContentType): Likewise. (replaceSelection): Call super (this is temporary until the real implementation happens. There is already a TODO noting that this needs to be implemented. (setEditorKitForContentType): Implemented and documented. --Tony Index: javax/swing/JEditorPane.java === RCS file: /cvsroot/classpath/classpath/javax/swing/JEditorPane.java,v retrieving revision 1.27 diff -u -r1.27 JEditorPane.java --- javax/swing/JEditorPane.java 22 Nov 2005 21:58:15 - 1.27 +++ javax/swing/JEditorPane.java 8 Dec 2005 19:49:41 - @@ -45,6 +45,7 @@ import java.io.Reader; import java.net.MalformedURLException; import java.net.URL; +import java.util.HashMap; import javax.accessibility.AccessibleContext; import javax.accessibility.AccessibleHyperlink; @@ -88,6 +89,7 @@ * * @author original author unknown * @author Roman Kennke ([EMAIL PROTECTED]) + * @author Anthony Balkissoon abalkiss at redhat dot com */ public class JEditorPane extends JTextComponent { @@ -507,10 +509,16 @@ 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() { -setEditorKit(createDefaultEditorKit()); +init(createDefaultEditorKit()); } public JEditorPane(String url) throws IOException @@ -520,7 +528,7 @@ public JEditorPane(String type, String text) { -setEditorKit(createEditorKitForContentType(type)); +init(createEditorKitForContentType(type)); setText(text); } @@ -529,15 +537,61 @@ this(); setPage(url); } + + /** + * Called by the constructors to set the EditorKit and set up the + * default bindings for content types and EditorKits. + * + * @param kit the initial EditorKit + */ + void init(EditorKit kit) + { +setEditorKit(kit); +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; } /** @@ -586,14 +640,44 @@ 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
Re: [cp-patches] FYI: Patch for JEditorPane
I wrote the functionality, but forgot to actually USE it.. so this new patch actually makes JEditorPane by default use HTMLEditorKit when needed. This one is accompanied by gnu.testlet.javax.swing.JEditorPane.ConstructorsAndTypes which demonstrates the correct behaviour but which we do not pass yet because of an AssertionError being thrown in the text classes. This may be happening because methods that should be overridden in the html packages are not completed yet. 2005-12-08 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/JEditorPane.java: (init): Changed to no-argument instead of taking in an EditorKit and passing it to setEditorKit. Callers will have to call setEditorKit themselves. (JEditorPane()): Changed call to init to have no arguments, call setEditorKit after init. (JEditorPane(String, String)): Likewise. (JEditorPane(URL)): Don't call default constructor, call init and then setEditorKit using the appropriate EditorKit for text/html. --Tony On Thu, 2005-12-08 at 15:02 -0500, Anthony Balkissoon wrote: This patch accompanies the new tests in gnu.testlet.javax.swing.JEditorPane.ContentType This patch makes JEditorPane handle different content types properly, using the appropriate EditorKit for different types. This will allow Lillian and myself to write test apps for html using JEditorPane because now it will use HTMLEditorKit to display the content. 2005-12-08 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/JEditorPane.java: (registerMap): New field. (editorMap): New field. (JEditorPane()): Call init instead of setEditorKit. (JEditorPane(String, String)): Likewise. (init): New method. (createEditorKitForContentType): Implemented and documented. (getEditorKitClassNameForContentType): Likewise. (getEditorKitForContentType): Likewise. (registerEditorKitForContentType): Likewise. (replaceSelection): Call super (this is temporary until the real implementation happens. There is already a TODO noting that this needs to be implemented. (setEditorKitForContentType): Implemented and documented. --Tony ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches Index: javax/swing/JEditorPane.java === RCS file: /cvsroot/classpath/classpath/javax/swing/JEditorPane.java,v retrieving revision 1.28 diff -u -r1.28 JEditorPane.java --- javax/swing/JEditorPane.java 8 Dec 2005 20:00:42 - 1.28 +++ javax/swing/JEditorPane.java 8 Dec 2005 20:12:54 - @@ -518,7 +518,8 @@ public JEditorPane() { -init(createDefaultEditorKit()); +init(); +setEditorKit(createDefaultEditorKit()); } public JEditorPane(String url) throws IOException @@ -528,25 +529,24 @@ public JEditorPane(String type, String text) { -init(createEditorKitForContentType(type)); +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 the EditorKit and set up the - * default bindings for content types and EditorKits. - * - * @param kit the initial EditorKit + * Called by the constructors to set up the default bindings for content + * types and EditorKits. */ - void init(EditorKit kit) + void init() { -setEditorKit(kit); editorMap = new HashMap(); registerMap = new HashMap(); registerEditorKitForContentType(application/rtf, ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] Patch: BoxLayout fix
2005-12-06 Anthony Balkissoon [EMAIL PROTECTED] Fixes bug #25233 * javax/swing/BoxLayout.java: (maximumLayoutSize): Don't add the Insets to the Dimension calculated in checkTotalRequirements(). ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] Patch: BoxLayout fix
This patch fixes PR 25233. 2005-12-06 Anthony Balkissoon [EMAIL PROTECTED] Fixes bug #25233 * javax/swing/BoxLayout.java: (maximumLayoutSize): Don't add the Insets to the Dimension calculated in checkTotalRequirements(). --Tony Index: javax/swing/BoxLayout.java === RCS file: /cvsroot/classpath/classpath/javax/swing/BoxLayout.java,v retrieving revision 1.25 diff -u -r1.25 BoxLayout.java --- javax/swing/BoxLayout.java 2 Nov 2005 11:47:57 - 1.25 +++ javax/swing/BoxLayout.java 6 Dec 2005 19:34:56 - @@ -334,9 +334,8 @@ throw new AWTError(BoxLayout can't be shared); checkTotalRequirements(); -Insets i = container.getInsets(); -return new Dimension(xTotal.maximum + i.left + i.right, - yTotal.maximum + i.top + i.bottom); +return new Dimension(xTotal.maximum, + yTotal.maximum); } } ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
Re: [cp-patches] Patch: BoxLayout fix
I reverted this patch because it caused a Mauve regression. I'll have to write more tests and figure out what was wrong. regression: gnu.testlet.javax.swing.BoxLayout.maximumLayoutSize On Tue, 2005-12-06 at 14:52 -0500, Anthony Balkissoon wrote: This patch fixes PR 25233. 2005-12-06 Anthony Balkissoon [EMAIL PROTECTED] Fixes bug #25233 * javax/swing/BoxLayout.java: (maximumLayoutSize): Don't add the Insets to the Dimension calculated in checkTotalRequirements(). --Tony ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches --Tony ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
Re: [cp-patches] Patch: BoxLayout fix
On Tue, 2005-12-06 at 15:58 -0500, Anthony Balkissoon wrote: I reverted this patch because it caused a Mauve regression. I'll have to write more tests and figure out what was wrong. regression: gnu.testlet.javax.swing.BoxLayout.maximumLayoutSize Okay, here's the new patch. It doesn't cause the regression and also makes us pass the new test: gnu.testlet.javax.swing.BoxLayout.maximumLayoutSize2 Patch simply involves checking for overflow. 2005-12-06 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/BoxLayout.java: (maximumLayoutSize): Add Insets to Dimension and then check for overflow. --Tony Index: javax/swing/BoxLayout.java === RCS file: /cvsroot/classpath/classpath/javax/swing/BoxLayout.java,v retrieving revision 1.26 diff -u -r1.26 BoxLayout.java --- javax/swing/BoxLayout.java 6 Dec 2005 19:50:23 - 1.26 +++ javax/swing/BoxLayout.java 6 Dec 2005 21:25:01 - @@ -334,8 +334,16 @@ throw new AWTError(BoxLayout can't be shared); checkTotalRequirements(); -return new Dimension(xTotal.maximum, - yTotal.maximum); +Insets i = container.getInsets(); +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); } } ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] Patch: More JFormattedTextField implementations and fixes
This is the last big part of JFormattedTextField I was working on. It implements all the parts that were throwing InternalError (not implemented) and fixes a lot of bugs with how we were generating formatters and formatter factories. It also implements missing parts of JFormattedTextField.AbstractFormatter. I added 3 more tests to gnu.testlet.javax.swing.JFormattedTextField.JFormattedTextFieldTests that this patch makes us pass. 2005-12-02 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/JFormattedTextField.java: Added docs all over. (AbstractFormatter.clone): Implemented. (AbstractFormatter.getActions): Implemented. (AbstractFormatter.getDocumentFilter): Implemented. (AbstractFormatter.getNavigationFilter): Implemented. (AbstractFormatter.install): Install the DocumentFilter and NavigationFilter. Properly catch ParseException. Added FIXME to add custom Actions to the JFormattedTextField. (AbstractFormatter.uninstall): Remove the DocumentFilter and NavigationFilter. Added FIXME to remove the custom Actions. (JFormattedTextField(AbstractFormatter)): Call the single argument constructor that takes in an AbstractFormatterFactory. This avoids a call to setValue that shouldn't occur. (JFormattedTextField(AbstractFormatterFactory): Call setFormatterFactory instead of calling the 2-argument constructor which would also make an unwanted call to setValue. (JFormattedTextField(AbstractFormatterFactory, Object)): Switch the order of the calls to setValue and setFormatterFactory. This ensures that the passed in factory is actually the one used, not one generated by setValue. (commitEdit): Implemented. (setFormatter): Removed incorrect early escape if the parameter is the same as the current formatter. (setFormatterFactory): If formatterFactory is null set the formatter to null as well. (setValue): Don't set the text here, this is done when we call setFormatter and it calls AbstractFormatter.install. Create a formatter factory if one doesn't exist already. Call setFormatter to get an appropriate formatter from the factory. (createFormatter): Changed this to createFormatterFactory because we should return a factory, not just a formatter. (createFormatterFactory): New method adapted from createFormatter. --Tony Index: javax/swing/JFormattedTextField.java === RCS file: /cvsroot/classpath/classpath/javax/swing/JFormattedTextField.java,v retrieving revision 1.18 diff -u -r1.18 JFormattedTextField.java --- javax/swing/JFormattedTextField.java 30 Nov 2005 23:02:37 - 1.18 +++ javax/swing/JFormattedTextField.java 2 Dec 2005 16:11:22 - @@ -46,6 +46,7 @@ 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; @@ -67,6 +68,7 @@ * formatting of the value of the JFormattedTextField. * * @author Michael Koch + * @author Anthony Balkissoon abalkiss at redhat dot com * * @since 1.4 */ @@ -90,70 +92,184 @@ //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 [EMAIL PROTECTED] 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 codenull/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 codenull/code. Should be subclassed by formatters + * that want to restrict Document mutations. + */ protected DocumentFilter getDocumentFilter () { - throw new InternalError
[cp-patches] FYI: InternationalFormatter fixlet
Small fixlet for InternationalFormatter. 2005-12-02 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/text/InternationalFormatter.java: (valueToString): If argument is null return empty String. --Tony Index: javax/swing/text/InternationalFormatter.java === RCS file: /cvsroot/classpath/classpath/javax/swing/text/InternationalFormatter.java,v retrieving revision 1.6 diff -u -r1.6 InternationalFormatter.java --- javax/swing/text/InternationalFormatter.java 24 Nov 2005 17:58:52 - 1.6 +++ javax/swing/text/InternationalFormatter.java 2 Dec 2005 20:10:42 - @@ -228,6 +228,8 @@ public String valueToString(Object value) throws ParseException { +if (value == null) + return ; if (format != null) return format.format(value); else ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
Re: [cp-patches] Patch: fixlet for Component focus event handling
I wrote a better testcase and attached it to this bug report: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25165 . It shows the problem was fixed incorrectly. So I reopened the bug, and now this new patch fixes it properly and removes the old fix. I'll close the bug now. The problem with the old fix was that processFocusEvent (and, in fact, processEvent) can be overridden from Component. Doing so in a test case showed that on the JDK these methods weren't called with FocusEvents whose receiving Component and opposite Component were the same. That means it had to be tackled before it got to this stage. That is what is done now. 2005-11-30 Anthony Balkissoon [EMAIL PROTECTED] Fixes bug #25165 * java/awt/Component.java: (processFocusEvent): Don't check if focus opposite is the same as the receiving Component, this is now done in dispatchEventImpl. (dispatchEventImpl): Don't dispatch FocusEvents whose opposite Components are the same. On Wed, 2005-11-30 at 13:15 -0500, Anthony Balkissoon wrote: This patch fixes PR 25165. If an attempt is made to give focus to a Component that already has it, no FOCUS_LOST and FOCUS_GAINED events should be processed. 2005-11-30 Anthony Balkissoon [EMAIL PROTECTED] * java/awt/Component.java: (processFocusEvent): Don't dispatch events if the focus opposite is the same as the receiving Component. --Tony ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches Index: java/awt/Component.java === RCS file: /cvsroot/classpath/classpath/java/awt/Component.java,v retrieving revision 1.90 diff -u -r1.90 Component.java --- java/awt/Component.java 30 Nov 2005 18:03:07 - 1.90 +++ java/awt/Component.java 30 Nov 2005 19:16:04 - @@ -3019,11 +3019,6 @@ if (focusListener == null) return; -// Don't dispatch FOCUS_GAINED or FOCUS_LOST events if the opposite -// Component is the same as the receiving Component. -if (e.getOppositeComponent() == this) - return; - switch (e.id) { case FocusEvent.FOCUS_GAINED: @@ -4796,7 +4791,12 @@ void dispatchEventImpl(AWTEvent e) { Event oldEvent = translateEvent (e); - +// This boolean tells us not to process focus events when the focus +// opposite component is the same as the focus component. +boolean ignoreFocus = + (e instanceof FocusEvent + ((FocusEvent)e).getComponent() == ((FocusEvent)e).getOppositeComponent()); + if (oldEvent != null) postEvent (oldEvent); @@ -4827,7 +4827,8 @@ break; } } -if (e.id != PaintEvent.PAINT e.id != PaintEvent.UPDATE) +if (e.id != PaintEvent.PAINT e.id != PaintEvent.UPDATE + !ignoreFocus) processEvent(e); } ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] Patch: JFormattedTextField improvements
I implemented missing parts and improved other parts of JFormattedTextField. The changes are accompanied by the following Mauve test: gnu.testlet.javax.swing.JFormattedTextField.JFormattedTextFieldTests More to come, as JFormattedTextField is still quite buggy. 2005-11-30 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/JFormattedTextField.java: (AbstractFormatter.install): Try to set the text of the formatted text field using this formatter. (FormatterFactoryWrapper): Removed this unneeded class, this is handled by DefaultFormatterFactory now. (formatter): New field. (JFormattedTextField(Format)): Implemented. (JFormattedTextField(AbstractFormatter)): Instantiate a DefaultFormatterFactory instead of a FormatterFactoryWrapper. (JFormattedTextField(AbstractFormatterFactory, Object)): Call setValue and setFormatterFactory instead of setting variables directly because more needs to be done than just setting the value of the variables. (JFormattedTextField(Object value)): Call setValue instead of setting the variable directly. (getAppropriateFormatterFactory): New implementation method. (getFormatter): Don't use the formatter factory here, just return the cached formatter. (processFocusEvent): Set the formatter to the appropriate one as determined by the formatter factory. (setFormatter): Don't get the old formatter from the factory, just use the cached formatter. Uninstall the old formatter. Install the new formatter. Cache the new formatter. Don't create a new formatter factory. (setFormatterFactory): Set the formatter according to the new formatter factory. (setValue): Moved the setting of the value variable to above the call to createFormatter so that an appropriate formatter is created. Cache the formatter that is created. (createFormatter): If argument is a Number, use a NumberFormatter. * javax/swing/text/DefaultFormatter.java: (valueToString): If argument is null return empty String. --Tony Index: javax/swing/JFormattedTextField.java === RCS file: /cvsroot/classpath/classpath/javax/swing/JFormattedTextField.java,v retrieving revision 1.17 diff -u -r1.17 JFormattedTextField.java --- javax/swing/JFormattedTextField.java 5 Sep 2005 14:05:28 - 1.17 +++ javax/swing/JFormattedTextField.java 30 Nov 2005 22:43:13 - @@ -40,15 +40,20 @@ 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.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 @@ -114,9 +119,21 @@ public void install(JFormattedTextField textField) { if (this.textField != null) - uninstall(); +uninstall(); this.textField = textField; + + if (textField != null) +{ + try + { +textField.setText(valueToString(textField.getValue())); + } + catch (ParseException pe) + { +// FIXME: Not sure what to do here. + } +} } public void uninstall () @@ -155,21 +172,6 @@ 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; -} - } - public static final int COMMIT = 0; public static final int COMMIT_OR_REVERT = 1; public static final int REVERT = 2; @@ -178,6 +180,7 @@ private Object value; private int focusLostBehavior = COMMIT_OR_REVERT; private AbstractFormatterFactory formatterFactory; + private AbstractFormatter formatter; // Package-private to avoid an accessor method. boolean editValid = true; @@ -188,12 +191,13 @@ public JFormattedTextField (Format format) { -throw new InternalError (not implemented); +this (); +setFormatterFactory(getAppropriateFormatterFactory(format)); } public JFormattedTextField (AbstractFormatter formatter) { -this(new FormatterFactoryWrapper(formatter), null); +this(new DefaultFormatterFactory
Re: [cp-patches] FYI: javax.swing.text cleanup
On Wed, 2005-10-19 at 14:58 +, Roman Kennke wrote: Some cleanup for javax.swing.text. 2005-10-19 Roman Kennke [EMAIL PROTECTED] * javax/swing/text/AbstractDocument.java * javax/swing/text/AttributeSet.java * javax/swing/text/ComponentView.java * javax/swing/text/DefaultCaret.java * javax/swing/text/DefaultEditorKit.java * javax/swing/text/DefaultHighlighter.java * javax/swing/text/EditorKit.java * javax/swing/text/FieldView.java * javax/swing/text/FlowView.java * javax/swing/text/GlyphView.java * javax/swing/text/JTextComponent.java * javax/swing/text/LayoutQueue.java * javax/swing/text/PlainView.java * javax/swing/text/Segment.java * javax/swing/text/StyledDocument.java * javax/swing/text/html/HTMLEditorKit.java * javax/swing/text/html/HTMLFrameHyperlinkEvent.java * javax/swing/text/html/parser/DocumentParser.java Reformatted slightly. Filled emtpy blocks with comments. Fixed some slight API doc errors. Removed some unneeded imports. /Roman The changes to PlainView were more than just reformatting and docs, and were regressions that were then fixed on November 24 (message attached). Please keep the functional changes separate from reformatting patches. --Tony ---BeginMessage--- This patch fixes the PasswordView, so that the caret gets positioned correctly. The model-view mapping was previously done by the superclass, which provides a mapping based on the real content. However, the PasswordView needs to base this mapping on the echo character. Also I did some small cleanups in PlainView. 2005-11-24 Roman Kennke [EMAIL PROTECTED] * javax/swing/text/PasswordView.java (modelToView): Overridden to correctly map between model and view respecting the echo character. (viewToModel): Added FIXME to show that this method also needs to be adjusted like the above method. * javax/swing/text/PlainView.java (paint): Don't set the font here. This is already done in the text component's JComponent.getComponentGraphics() method. (damageLineRange): Only repaint the damaged rectangle. /Roman Index: javax/swing/text/PasswordView.java === RCS file: /cvsroot/classpath/classpath/javax/swing/text/PasswordView.java,v retrieving revision 1.7 diff -u -r1.7 PasswordView.java --- javax/swing/text/PasswordView.java 17 Aug 2005 19:59:35 - 1.7 +++ javax/swing/text/PasswordView.java 24 Nov 2005 20:36:15 - @@ -41,6 +41,7 @@ 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 @@ /** * 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 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 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); } } Index: javax/swing/text/PlainView.java === RCS file: /cvsroot/classpath/classpath/javax/swing/text/PlainView.java,v retrieving revision 1.33 diff -u -r1.33 PlainView.java ---
[cp-patches] FYI: NumberFormatter implemented
Implemented the class javax.swing.text.NumberFormatter. It will likely need further work but all the tests I can easily run work okay. Once I implement DefaultFormatterFactory it should be easier to run real-world tests and make sure this has the proper behaviour. Also made a change in the superclass, InternationalFormatter, and committed the corresponding test: gnu.testlet.javax.swing.text.InternationalFormatter.InternationalFormatterTest 2005-11-24 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/text/InternationalFormatter: (InternationalFormatterinit): Override superclass defaults for commitsOnValidEdit and overwriteMode. * javax/swing/text/NumberFormatter.java: New class. --Tony Index: javax/swing/text/InternationalFormatter.java === RCS file: /cvsroot/classpath/classpath/javax/swing/text/InternationalFormatter.java,v retrieving revision 1.5 diff -u -r1.5 InternationalFormatter.java --- javax/swing/text/InternationalFormatter.java 13 Sep 2005 23:44:50 - 1.5 +++ javax/swing/text/InternationalFormatter.java 24 Nov 2005 17:56:25 - @@ -78,6 +78,8 @@ minimum = null; maximum = null; format = null; +setCommitsOnValidEdit(false); +setOverwriteMode(false); } /** Index: javax/swing/text/NumberFormatter.java === RCS file: javax/swing/text/NumberFormatter.java diff -N javax/swing/text/NumberFormatter.java --- /dev/null 1 Jan 1970 00:00:00 - +++ javax/swing/text/NumberFormatter.java 24 Nov 2005 17:56:25 - @@ -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; + +/** + * codeNumberFormatter/code is an [EMAIL PROTECTED] InternationalFormatter} + * that implements value to string and string to value conversion via + * an instance of [EMAIL PROTECTED] 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); + } +} ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
Re: [cp-patches] FYI: New class MaskFormatter.java
Checked in a small fix that the Mauve tests pointed out (I'll reply to this with the specific tests once I've checked those in). 2005-11-22 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/text/MaskFormatter.java: (convertValue): If character is a literal don't throw a ParseException unless literals aren't allowd in values and this method is being called from valueToString rather than stringToValue. The convert flag is used to distinguish these two cases. --Tony On Tue, 2005-11-22 at 14:15 -0500, Anthony Balkissoon wrote: Implemented this missing class from javax.swing.text. I have a bunch of related tests that I need to commit to Mauve-form and I'll commit those. 2005-11-22 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/text/MaskFormatter.java: New class. --Tony ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches Index: javax/swing/text/MaskFormatter.java === RCS file: /cvsroot/classpath/classpath/javax/swing/text/MaskFormatter.java,v retrieving revision 1.1 diff -u -r1.1 MaskFormatter.java --- javax/swing/text/MaskFormatter.java 22 Nov 2005 19:11:51 - 1.1 +++ javax/swing/text/MaskFormatter.java 22 Nov 2005 19:38:18 - @@ -454,7 +454,7 @@ throw new ParseException (Invalid character: +resultChar, i); break; default: -if (!getValueContainsLiteralCharacters()) +if (!getValueContainsLiteralCharacters() convert) throw new ParseException (Invalid character: +resultChar, i); else if (resultChar != mask.charAt(j)) throw new ParseException (Invalid character: +resultChar, i); ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
Re: [cp-patches] FYI: New class MaskFormatter.java
On Tue, 2005-11-22 at 14:42 -0500, Anthony Balkissoon wrote: Checked in a small fix that the Mauve tests pointed out (I'll reply to this with the specific tests once I've checked those in). the tests are in gnu/testlet/javax/swing/text/MaskFormatter/MaskFormatterTest.java --Tony ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
Re: [cp-patches] FYI: New class MaskFormatter.java
I updated the Mauve tests and had to check in this small change. 2005-11-22 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/text/MaskFormatter.java: (convertValue): Don't check the valid/invalid character sets if we're matching a literal. --Tony Index: javax/swing/text/MaskFormatter.java === RCS file: /cvsroot/classpath/classpath/javax/swing/text/MaskFormatter.java,v retrieving revision 1.2 diff -u -r1.2 MaskFormatter.java --- javax/swing/text/MaskFormatter.java 22 Nov 2005 19:42:04 - 1.2 +++ javax/swing/text/MaskFormatter.java 22 Nov 2005 20:07:17 - @@ -399,6 +399,7 @@ 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 @@ -406,11 +407,8 @@ for (int i = 0, j = 0; i value.length(); i++, j++) { +literal = false; resultChar = result.charAt(i); -// If necessary, check if the character is valid. -if (checkCharSets !isCharValid(resultChar)) - throw new ParseException(invalid character: +resultChar, i); - // This switch block on the mask character checks that the character // within codevalue/code at that point is valid according to the // mask and also converts to upper/lowercase as needed. @@ -450,15 +448,21 @@ // 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(); } ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] FYI: patch for DefaultEditorKit fixes PR 24925
This patch fixes bug 24925 by not inserting text into a text component that is either disabled or uneditable. Also, when a key is typed, instead of calling insertString, we should be calling replaceSelection. Fixed. 2005-11-21 Anthony Balkissoon [EMAIL PROTECTED] Fixes bug #24925 * javax/swing/text/DefaultEditorKit.java: (DefaultKeyTypedAction.actionPeformed): Call replaceSelection here instead of insertString and only do so if the text component is both enabled and editable. --Tony Index: javax/swing/text/DefaultEditorKit.java === RCS file: /cvsroot/classpath/classpath/javax/swing/text/DefaultEditorKit.java,v retrieving revision 1.23 diff -u -r1.23 DefaultEditorKit.java --- javax/swing/text/DefaultEditorKit.java 19 Oct 2005 14:57:30 - 1.23 +++ javax/swing/text/DefaultEditorKit.java 21 Nov 2005 16:05:34 - @@ -216,19 +216,9 @@ 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()); +} } /** ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] FYI: fixlet for BasicEditorPaneUI
This accompanies the Mauve test gnu.testlet.javax.swing.JEditorPane.ViewType. JEditorPane uses a WrappedPlainView, not a PlainView. 2005-11-17 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/plaf/basic/BasicEditorPaneUI.java: (create): Create new WrappedPlainView instance instead of PlainView. --Tony Index: javax/swing/plaf/basic/BasicEditorPaneUI.java === RCS file: /cvsroot/classpath/classpath/javax/swing/plaf/basic/BasicEditorPaneUI.java,v retrieving revision 1.5 diff -u -r1.5 BasicEditorPaneUI.java --- javax/swing/plaf/basic/BasicEditorPaneUI.java 29 Jul 2005 14:13:09 - 1.5 +++ javax/swing/plaf/basic/BasicEditorPaneUI.java 17 Nov 2005 19:00:48 - @@ -44,8 +44,8 @@ import javax.swing.text.EditorKit; import javax.swing.text.Element; import javax.swing.text.JTextComponent; -import javax.swing.text.PlainView; import javax.swing.text.View; +import javax.swing.text.WrappedPlainView; /** * The UI class for [EMAIL PROTECTED] JEditorPane}s. @@ -81,7 +81,7 @@ // place this doesn't make much sense. public View create(Element elem) { -return new PlainView(elem); +return new WrappedPlainView(elem); } /** ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] FYI: fixlet for BoxView
BoxView was using CompositeView's modelToView method, but it really should override it and make sure the children are allocated first, otherwise you'll get BadLocationError. This matches what the docs say to do and it eliminates a bunch of AssertionErrors. 2005-11-17 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/text/BoxView.java: (modelToView): New API method. --Tony Index: javax/swing/text/BoxView.java === RCS file: /cvsroot/classpath/classpath/javax/swing/text/BoxView.java,v retrieving revision 1.11 diff -u -r1.11 BoxView.java --- javax/swing/text/BoxView.java 17 Nov 2005 20:45:13 - 1.11 +++ javax/swing/text/BoxView.java 17 Nov 2005 20:55:10 - @@ -740,4 +740,22 @@ yLayoutValid = false; super.preferenceChanged(child, width, height); } + + /** + * Maps the document model position codepos/code to a Shape + * in the view coordinate space. This method overrides CompositeView's + * method to make sure the children are allocated properly before + * calling the super's behaviour. + */ + public Shape modelToView(int pos, Shape a, Position.Bias bias) + throws BadLocationException + { +// Make sure everything is allocated properly and then call super +if (!isAllocationValid()) + { +Rectangle bounds = a.getBounds(); +setSize(bounds.width, bounds.height); + } +return super.modelToView(pos, a, bias); + } } ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] FYI: Patch to PlainDocument fixes Mauve regressions
Very sorry, but my PlainDocument patch yesterday caused some regressions in text components that use PlainDocument. Yesterday's patch had the performance improvement of not having to look through the entire document to index all of the lines every time text is inserted. Instead, we only look at the range where the text was inserted to look for new lines to index. However, if we find any newlines, the very first new Element we add doesn't start at the point of insertion, it starts at the beginning of the line where text was inserted. This is fixed now. 2005-11-16 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/text/PlainDocument.java: (insertUpdate): The very first new element added doesn't start at the start of the event, it starts at the start offset of the Element that contains the start of the event. --Tony Index: javax/swing/text/PlainDocument.java === RCS file: /cvsroot/classpath/classpath/javax/swing/text/PlainDocument.java,v retrieving revision 1.16 diff -u -r1.16 PlainDocument.java --- javax/swing/text/PlainDocument.java 15 Nov 2005 19:45:46 - 1.16 +++ javax/swing/text/PlainDocument.java 16 Nov 2005 16:30:03 - @@ -111,6 +111,7 @@ int offset = event.getOffset(); int end = offset + event.getLength(); int elementIndex = rootElement.getElementIndex(offset); +Element firstElement = rootElement.getElement(elementIndex); // added and removed are Element arrays used to add an ElementEdit // to the DocumentEvent if there were entire lines added or removed. @@ -123,8 +124,8 @@ // Determine how many NEW lines were added by finding the newline // characters within the newly inserted text -int j = offset; -int i = str.indexOf('\n', j); +int j = firstElement.getStartOffset(); +int i = str.indexOf('\n', offset); while (i != -1 i = end) { // For each new line, create a new element @@ -145,7 +146,7 @@ added = new Element[elts.size()]; for (int k = 0; k elts.size(); ++k) added[k] = (Element) elts.get(k); -removed[0] = rootElement.getElement(elementIndex); +removed[0] = firstElement; // Now create and add the ElementEdit ElementEdit e = new ElementEdit(rootElement, elementIndex, removed, ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] FYI: fixlet in PlainDocument fixes PR 24890
Simple != null check fixes PR 24890. 2005-11-16 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/text/PlainDocument.java: (insertString): Null check fixes PR 24890. --Tony Index: javax/swing/text/PlainDocument.java === RCS file: /cvsroot/classpath/classpath/javax/swing/text/PlainDocument.java,v retrieving revision 1.17 diff -u -r1.17 PlainDocument.java --- javax/swing/text/PlainDocument.java 16 Nov 2005 16:35:40 - 1.17 +++ javax/swing/text/PlainDocument.java 16 Nov 2005 18:28:44 - @@ -235,7 +235,7 @@ throws BadLocationException { String string = str; -if (Boolean.TRUE.equals(getProperty(filterNewlines))) +if (str != null Boolean.TRUE.equals(getProperty(filterNewlines))) string = str.replaceAll(\n, ); super.insertString(offs, string, atts); } ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] FYI: added myself to AUTHORS
I didn't do it when it was cool a few weeks ago, but now I have finally added myself to the AUTHORS list, and fixed the @author tags in two places. 2005-11-16 Anthony Balkissoon [EMAIL PROTECTED] * AUTHORS: Added myself. * javax/swing/KeyboardManager.java: Changed @author tag to match the other ones I have. * javax/swing/text/WrappedPlainView.java: Likewise. --Tony Index: AUTHORS === RCS file: /cvsroot/classpath/classpath/AUTHORS,v retrieving revision 1.28 diff -u -r1.28 AUTHORS --- AUTHORS 2 Nov 2005 21:52:18 - 1.28 +++ AUTHORS 16 Nov 2005 18:56:06 - @@ -5,6 +5,7 @@ alphabetic order. Lillian Angel ([EMAIL PROTECTED]) +Anthony Balkissoon ([EMAIL PROTECTED]) Stuart Ballard ([EMAIL PROTECTED]) Mark Benvenuto ([EMAIL PROTECTED]) Geoff Berry ([EMAIL PROTECTED]) Index: javax/swing/KeyboardManager.java === RCS file: /cvsroot/classpath/classpath/javax/swing/KeyboardManager.java,v retrieving revision 1.4 diff -u -r1.4 KeyboardManager.java --- javax/swing/KeyboardManager.java 14 Nov 2005 21:15:52 - 1.4 +++ javax/swing/KeyboardManager.java 16 Nov 2005 18:56:06 - @@ -53,7 +53,7 @@ * Components register keyboard actions with the condition * JComponent.WHEN_IN_FOCUSED_WINDOW. * - * @author Anthony Balkissoon [EMAIL PROTECTED] + * @author Anthony Balkissoon abalkiss at redhat dot com * */ class KeyboardManager Index: javax/swing/text/WrappedPlainView.java === RCS file: /cvsroot/classpath/classpath/javax/swing/text/WrappedPlainView.java,v retrieving revision 1.7 diff -u -r1.7 WrappedPlainView.java --- javax/swing/text/WrappedPlainView.java 3 Nov 2005 21:04:48 - 1.7 +++ javax/swing/text/WrappedPlainView.java 16 Nov 2005 18:56:06 - @@ -50,7 +50,7 @@ import javax.swing.text.Position.Bias; /** - * @author abalkiss + * @author Anthony Balkissoon abalkiss at redhat dot com * */ public class WrappedPlainView extends BoxView implements TabExpander ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] Patch: JSplitPane patch fixes PR 24904
This patch for JSplitPane fixes PR 24904 (sorry, forgot to put that in the ChangeLog) and makes a bunch of new Mauve tests pass (they are pasted at the bottom of this email). Only the no-argument constructor is a demo constructor (this seems like a ridiculous idea in the first place, who would want this?) so it creates a JButton as the left component and a JButton as the right component. The other constructors should allow null to be passed as arguments for the components, and setLeftComponent and setRightComponent should allow null as well. The changes to BasicSplitPaneUI are just != null checks now that the components can be null. 2005-11-16 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/JSplitPane.java: (JSplitPaneinit): This is a demo constructor, should create two new JButtons, one with label left button and the other with label right button. (setLeftComponent): Do not create JButtons here. A null argument is taken to mean remove the current component. (setRightComponent): Likewise. * javax/swing/plaf/basic/BasicSplitPaneUI: (setDividerLocation): Check that right component is not null before trying to get its preferred size. (startDragging): Avoid NPE by checking that left and right components are not null. --Tony ** FIXED MAUVE TESTS ** gnu.testlet.javax.swing.JSplitPane.Constructor FAIL: gnu.testlet.javax.swing.JSplitPane.Constructor: constructor with only orientation (number 1) FAIL: gnu.testlet.javax.swing.JSplitPane.Constructor: constructor with only orientation (number 2) FAIL: gnu.testlet.javax.swing.JSplitPane.Constructor: constructor with only orientation (number 3) FAIL: gnu.testlet.javax.swing.JSplitPane.Constructor: constructor with only orientation (number 4) FAIL: gnu.testlet.javax.swing.JSplitPane.Constructor: constructor with orientation and layout (number 1) FAIL: gnu.testlet.javax.swing.JSplitPane.Constructor: constructor with orientation and layout (number 2) FAIL: gnu.testlet.javax.swing.JSplitPane.Constructor: constructor with orientation and layout (number 3) FAIL: gnu.testlet.javax.swing.JSplitPane.Constructor: constructor with orientation and layout (number 4) FAIL: gnu.testlet.javax.swing.JSplitPane.Constructor: constructor with orientation and layout (number 5) FAIL: gnu.testlet.javax.swing.JSplitPane.Constructor: constructor with orientation and layout (number 6) FAIL: gnu.testlet.javax.swing.JSplitPane.Constructor: constructor with orientation and layout (number 7) FAIL: gnu.testlet.javax.swing.JSplitPane.Constructor: constructor with orientation and layout (number 8) FAIL: gnu.testlet.javax.swing.JSplitPane.Constructor: constructor with orientation and 2 components (number 1) FAIL: gnu.testlet.javax.swing.JSplitPane.Constructor: constructor with orientation and 2 components (number 2) FAIL: gnu.testlet.javax.swing.JSplitPane.Constructor: constructor with orientation and 2 components (number 3) FAIL: gnu.testlet.javax.swing.JSplitPane.Constructor: constructor with orientation and 2 components (number 4) FAIL: gnu.testlet.javax.swing.JSplitPane.Constructor: most general constructor (number 1) FAIL: gnu.testlet.javax.swing.JSplitPane.Constructor: most general constructor (number 2) FAIL: gnu.testlet.javax.swing.JSplitPane.Constructor: most general constructor (number 3) FAIL: gnu.testlet.javax.swing.JSplitPane.Constructor: most general constructor (number 4) FAIL: gnu.testlet.javax.swing.JSplitPane.Constructor: most general constructor (number 5) FAIL: gnu.testlet.javax.swing.JSplitPane.Constructor: most general constructor (number 6) FAIL: gnu.testlet.javax.swing.JSplitPane.Constructor: most general constructor (number 7) FAIL: gnu.testlet.javax.swing.JSplitPane.Constructor: most general constructor (number 8) gnu.testlet.javax.swing.JSplitPane.setComponent FAIL: gnu.testlet.javax.swing.JSplitPane.setComponent: set left (number 1) FAIL: gnu.testlet.javax.swing.JSplitPane.setComponent: set left (number 3) FAIL: gnu.testlet.javax.swing.JSplitPane.setComponent: set right (number 1) FAIL: gnu.testlet.javax.swing.JSplitPane.setComponent: set right (number 3) Index: javax/swing/JSplitPane.java === RCS file: /cvsroot/classpath/classpath/javax/swing/JSplitPane.java,v retrieving revision 1.8 diff -u -r1.8 JSplitPane.java --- javax/swing/JSplitPane.java 19 Oct 2005 15:45:04 - 1.8 +++ javax/swing/JSplitPane.java 16 Nov 2005 21:34:57 - @@ -286,7 +286,8 @@ */ public JSplitPane() { -this(HORIZONTAL_SPLIT, false, null, null); +this(HORIZONTAL_SPLIT, false, new JButton(left button), + new JButton(right button)); } /** @@ -696,11 +697,11 @@ * @param comp The left component. */ public void setLeftComponent(Component comp) - { + { if (comp != null) add(comp, LEFT); else - add(new JButton(left button), LEFT); + remove
[cp-patches] FYI: Reformatted JSplitPane and BasicSplitPaneUI
Reformatted these files to match our standards. 2005-11-16 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/JSplitPane.java: Reformatted file. * javax/swing/plaf/basic/BasicSplitPaneUI.java: Reformatted file. --Tony Index: javax/swing/JSplitPane.java === RCS file: /cvsroot/classpath/classpath/javax/swing/JSplitPane.java,v retrieving revision 1.9 diff -u -r1.9 JSplitPane.java --- javax/swing/JSplitPane.java 16 Nov 2005 21:48:24 - 1.9 +++ javax/swing/JSplitPane.java 16 Nov 2005 22:18:29 - @@ -170,13 +170,15 @@ public static final int HORIZONTAL_SPLIT = 1; /** The property fired when the last divider location property changes. */ - public static final String LAST_DIVIDER_LOCATION_PROPERTY = lastDividerLocation; + public static final String LAST_DIVIDER_LOCATION_PROPERTY = +lastDividerLocation; /** The constraints string used to add components to the left. */ public static final String LEFT = left; /** The property fired when the one touch expandable property changes. */ - public static final String ONE_TOUCH_EXPANDABLE_PROPERTY = oneTouchExpandable; + public static final String ONE_TOUCH_EXPANDABLE_PROPERTY = +oneTouchExpandable; /** The property fired when the orientation property changes. */ public static final String ORIENTATION_PROPERTY = orientation; @@ -199,7 +201,8 @@ /** Whether the JSplitPane uses one touch expandable buttons. */ protected boolean oneTouchExpandable = false; - // This is the master dividerSize variable and sets the BasicSplitPaneDivider one accordingly + // This is the master dividerSize variable and sets the + // BasicSplitPaneDivider one accordingly /** The size of the divider. */ protected int dividerSize = 10; @@ -301,7 +304,8 @@ * @param constraints The constraints string to use. * @param index Where to place to component in the list of components. * - * @throws IllegalArgumentException When the constraints is not a known identifier. + * @throws IllegalArgumentException When the constraints is not a known + * identifier. */ protected void addImpl(Component comp, Object constraints, int index) { @@ -311,34 +315,35 @@ int place; if (constraints == null) { - if (leftComponent == null) - constraints = LEFT; - else if (rightComponent == null) - constraints = RIGHT; +if (leftComponent == null) + constraints = LEFT; +else if (rightComponent == null) + constraints = RIGHT; } if (constraints instanceof String) { - String placement = (String) constraints; +String placement = (String) constraints; - if (placement.equals(BOTTOM) || placement.equals(RIGHT)) - { - if (rightComponent != null) - remove(rightComponent); - rightComponent = comp; - } - else if (placement.equals(LEFT) || placement.equals(TOP)) - { - if (leftComponent != null) - remove(leftComponent); - leftComponent = comp; - } - else if (placement.equals(DIVIDER)) - constraints = null; - else - throw new IllegalArgumentException(Constraints is not a known identifier.); +if (placement.equals(BOTTOM) || placement.equals(RIGHT)) + { +if (rightComponent != null) + remove(rightComponent); +rightComponent = comp; + } +else if (placement.equals(LEFT) || placement.equals(TOP)) + { +if (leftComponent != null) + remove(leftComponent); +leftComponent = comp; + } +else if (placement.equals(DIVIDER)) + constraints = null; +else + throw new +IllegalArgumentException(Constraints is not a known identifier.); - super.addImpl(comp, constraints, index); +super.addImpl(comp, constraints, index); } invalidate(); layout(); @@ -615,10 +620,10 @@ { if (newContinuousLayout != continuousLayout) { - boolean oldValue = continuousLayout; - continuousLayout = newContinuousLayout; - firePropertyChange(CONTINUOUS_LAYOUT_PROPERTY, oldValue, - continuousLayout); +boolean oldValue = continuousLayout; +continuousLayout = newContinuousLayout; +firePropertyChange(CONTINUOUS_LAYOUT_PROPERTY, oldValue, + continuousLayout); } } @@ -635,7 +640,8 @@ public void setDividerLocation(double proportionalLocation) { if (proportionalLocation 1 || proportionalLocation 0) - throw new IllegalArgumentException(proportion has to be between 0 and 1.); + throw new IllegalArgumentException +(proportion has to be between 0 and 1.); int max = (orientation == HORIZONTAL_SPLIT) ? getWidth() : getHeight(); setDividerLocation((int) (proportionalLocation * max)); @@ -650,9 +656,9 @@ { if (ui != null location != getDividerLocation()) { - int
[cp-patches] Patch: PlainDocument improvements and added functionality
This patch implements ElementChange interface behaviour for PlainDocument. When entire lines are inserted or removed the DocumentEvent must have an ElementChange attached to it describing the new lines or the removed lines. Roman correctly noticed that this behaviour should not be in AbstractDocument so he removed the code from insertString. This patch further removes it from AbstractDocument.remove() and puts it where it belongs, in the insertUpdate() and removeUpdate() methods of the Document implementation. I removed the package private method reindex and moved most of this code directly into insertUpdate. However, instead of reindexing the entire Document we only look for new lines in the newly inserted text. This is necessary to get the correct ElementEdit and also represents a performance improvement. Before this, entering each character caused us to reindex the entire document (this is basically searching through and finding all the new lines in the whole document). Now after a character insertion we only have to check that character to see if it's a newline. This should be an important difference in a large document. Note however that I've only implemented this for PlainView, there are other text View classes that need similar improvements. 2005-11-14 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/text/AbstractDocument.java: (remove): Do not set up an ElementEdit here, this is done in the Document implementation's removeUpdate method. * javax/swing/text/PlainDocument.java: (insertUpdate): Do not call reindex, instead, reindex the lines here directly but only starting from the offset of the newly inserted text. Also, if entire lines have been added or removed, set up an ElementEdit and add it to the DocumentEvent. Chain BadLocationException to an AssertionError and throw it in the unexpected case. (removeUpdate): If entire lines have been added or removed, set up an ElementEdit and add it to the DocumentEvent. Chain BadLocationException to an AssertionError and throw it in the unexpected case. (reindex): Removed unnecessary method. Index: javax/swing/text/AbstractDocument.java === RCS file: /cvsroot/classpath/classpath/javax/swing/text/AbstractDocument.java,v retrieving revision 1.37 diff -u -r1.37 AbstractDocument.java --- javax/swing/text/AbstractDocument.java 30 Oct 2005 18:02:53 - 1.37 +++ javax/swing/text/AbstractDocument.java 15 Nov 2005 19:40:20 - @@ -672,20 +672,8 @@ new DefaultDocumentEvent(offset, length, DocumentEvent.EventType.REMOVE); -// Here we set up the parameters for an ElementChange, if one -// needs to be added to the DocumentEvent later -Element root = getDefaultRootElement(); -int start = root.getElementIndex(offset); -int end = root.getElementIndex(offset + length); - -Element[] removed = new Element[end - start + 1]; -for (int i = start; i = end; i++) - removed[i - start] = root.getElement(i); - removeUpdate(event); -Element[] added = new Element[1]; -added[0] = root.getElement(start); boolean shouldFire = content.getString(offset, length).length() != 0; writeLock(); @@ -693,17 +681,6 @@ writeUnlock(); postRemoveUpdate(event); - -GapContent.UndoRemove changes = null; -if (content instanceof GapContent) - changes = (GapContent.UndoRemove) temp; - -if (changes != null !(start == end)) - { -// We need to add an ElementChange to our DocumentEvent -ElementEdit edit = new ElementEdit (root, start, removed, added); -event.addEdit(edit); - } if (shouldFire) fireRemoveUpdate(event); Index: javax/swing/text/PlainDocument.java === RCS file: /cvsroot/classpath/classpath/javax/swing/text/PlainDocument.java,v retrieving revision 1.15 diff -u -r1.15 PlainDocument.java --- javax/swing/text/PlainDocument.java 27 Oct 2005 14:53:42 - 1.15 +++ javax/swing/text/PlainDocument.java 15 Nov 2005 19:40:21 - @@ -105,10 +105,64 @@ return root; } - protected void insertUpdate(DefaultDocumentEvent event, AttributeSet attributes) + protected void insertUpdate(DefaultDocumentEvent event, + AttributeSet attributes) { -reindex(); +int offset = event.getOffset(); +int end = offset + event.getLength(); +int elementIndex = rootElement.getElementIndex(offset); + +// 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]; +Element[] added; +try + { +String str = content.getString(0, content.length()); +ArrayList elts = new ArrayList
[cp-patches] FYI: a small addition for WHEN_IN_FOCUSED_WINDOW bindings
This patch removes the bindings for a JComponent when it has been removed from its parent container. 2005-11-15 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/JComponent.java: (removeNotify): Unregister WHEN_IN_FOCUSED_WINDOW bindings from the KeyboardManager. --Tony Index: javax/swing/JComponent.java === RCS file: /cvsroot/classpath/classpath/javax/swing/JComponent.java,v retrieving revision 1.84 diff -u -r1.84 JComponent.java --- javax/swing/JComponent.java 14 Nov 2005 20:58:47 - 1.84 +++ javax/swing/JComponent.java 15 Nov 2005 21:47:44 - @@ -2921,8 +2921,7 @@ { super.removeNotify(); -// FIXME: remove the WHEN_IN_FOCUSED_WINDOW bindings from the -// KeyboardManager +KeyboardManager.getManager().clearBindingsForComp(this); // Notify ancestor listeners. fireAncestorEvent(this, AncestorEvent.ANCESTOR_REMOVED); ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] Patch: large patch implements menu accelerators
This rather large patch makes menu accelerators work in our implementation. Attached is a demo (MenuBars.java) - while focused in the JButton pressing CTRL + {1,2,3,4,Z,X,C,V} causes different menu items from either the top or bottom menu to be clicked. The patches to ActionMap and InputMap now make the following Mauve tests pass: gnu/testlet/javax/swing/InputMap/newMapKeysNull gnu/testlet/javax/swing/ActionMap/newMapKeysNull and they also fix PR 24854. For JMenuBar, I removed the FIXME comment in addNotify and did what it said - register the JMenuBar with the KeyboardManager. This is because the KeyboardManager needs to have a fast way to access all the JMenuBars in a top-level container to give them a chance to consume any key event that happens in that container (JMenuBars are the LAST things that get a chance at the event). Also, JMenuBar.processKeyBinding now overrides the method in JComponent (this agrees with the API docs) to give all its MenuElement descendants a chance to process the binding. JMenuItem.setAccelerator had to fire a property change event that is handled in BasicMenuItemUI so that when you change the accelerator key for a menuitem, its key bindings get changed accordingly (the old one gets thrown out and the new one gets mapped propertly). In KeyboardManager I put the new functionality it for registering JMenuBars and also avoided some NPEs with standard != null checks. Also, processKeyStroke now gives the JMenuBars a chance to consume the event. Note that KeyboardManager currently only has the ability to REGISTER bindings and JMenuBars, and not UNREGISTER them. This is an obvious flaw that I'll get to fixing at some point. Finally, in BasicMenuItemUI I implemented a PropertyChangeListener to change the bindings for the accelerator keystroke, and implemented the installKeyboardActions and uninstallKeyboardActions methods. Also made sure that installUI calls installKeyboardActions and that installListeners and uninstallListeners now reference the new PropertyChangeListener. 2005-11-14 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/ActionMap.java: (keys): Return null if the map is empty. (allKeys): Likewise. * javax/swing/InputMap.java: (keys): Return null if the map is empty. (allKeys): Likewise. * javax/swing/JMenuBar: (addNotify): Register the menu with the KeyboardManager. (processKeyBinding): New API method. (processKeyBindingHelper): New implementation method. * javax/swing/JMenuItem.java: (setAccelerator): Fire a PropertyChangeEvent after changing the accelerator. * javax/swing/KeyboardManager.java: (menuBarLookup): New field, Hashtable mapping between top-level containers and a Vector of the JMenuBars contained in them. (getHashtableForTopLevel): Changed this public method to package private. (registerEntireMap): Avoid NPE by returning early if the parameter is null or contains no mappings. (processKeyStroke): If the mapped component doesn't consume the event, let all JMenuBars in the top-level container have a chance at it. (getVectorForTopLevel): New implementation method. (registerJMenuBar): Likewise. * javax/swing/plaf/basic/BasicMenuItemUI.java: (propertyChangeListener): New field. (PropertyChangeHandler): New class to handle PropertyChangeEvents on the JMenuItem. (ClickAction): New class to implement accelerator key handling. (BasicMenuItemUIinit): Instantiate the propertyChangeListener field. (installKeyboardActions): Implemented. (installListeners): Install the propertyChangeListener. (installUI): Call installKeyboardAcions after installing the listeners. (uninstallKeyboardActions): Implemented. (uninstallListeners): Remove the propertyChangeListener. --Tony Index: javax/swing/ActionMap.java === RCS file: /cvsroot/classpath/classpath/javax/swing/ActionMap.java,v retrieving revision 1.12 diff -u -r1.12 ActionMap.java --- javax/swing/ActionMap.java 19 Oct 2005 15:45:03 - 1.12 +++ javax/swing/ActionMap.java 14 Nov 2005 20:10:43 - @@ -171,7 +171,9 @@ */ public Object[] keys() { -return actionMap.keySet().toArray(); +if (size() != 0) + return actionMap.keySet().toArray(); +return null; } /** @@ -188,7 +190,9 @@ set.addAll(Arrays.asList(parent.allKeys())); set.addAll(actionMap.keySet()); -return set.toArray(); +if (set.size() != 0) + return set.toArray(); +return null; } /** Index: javax/swing/InputMap.java === RCS file: /cvsroot/classpath/classpath/javax/swing/InputMap.java,v retrieving revision 1.12 diff -u -r1.12 InputMap.java --- javax/swing/InputMap.java 27 Jul
[cp-patches] Patch: fixlet for JComponent
Lillian pointed out that JComponent was giving some NPEs. This is probably because last week I removed some unnecessary code from addNotify but forgot to remove the corresponding code from removeNotify. This is fixed now. While I was there I also added a FIXME note to remind myself to remove the WHEN_IN_FOCUSED_WINDOW bindings for this component, but first I have to write that capability into the KeyboardManager. This will take some thought as I have to improve the performance of KeyboardManager when it comes to removing/updating bindings. I also added a FIXME in JMenuBar's removeNotify to unregister the JMenuBar. Again, I have to write the capability into the KeyboardManager first. This one is pretty easy. 2005-11-14 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/JComponent.java: (removeNotify): Removed unncessary InputMap and ActionMap inheritance code. Added FIXME to remove the WHEN_IN_FOCUSED_WINDOW bindings from the KeyboardManager. * javax/swing/JMenuBar.java: (removeNotify): Added FIXME to unregister this JMenuBar from the KeyboardManager. --Tony Index: javax/swing/JComponent.java === RCS file: /cvsroot/classpath/classpath/javax/swing/JComponent.java,v retrieving revision 1.83 diff -u -r1.83 JComponent.java --- javax/swing/JComponent.java 10 Nov 2005 20:03:55 - 1.83 +++ javax/swing/JComponent.java 14 Nov 2005 20:53:25 - @@ -2921,37 +2921,14 @@ { super.removeNotify(); -// let parents inherit the keybord mapping -InputMap input = getInputMap(); -ActionMap actions = getActionMap(); - -Container parent = getParent(); -while ((parent != null) (parent instanceof JComponent)) - { -JComponent jParent = (JComponent) parent; -InputMap parentInput = jParent.getInputMap(); -ActionMap parentAction = jParent.getActionMap(); - -KeyStroke[] ikeys = input.allKeys(); -for (int i = 0; i ikeys.length; i++) - { -parentInput.remove(ikeys[i]); - } - -Object[] akeys = actions.allKeys(); -for (int i = 0; i akeys.length; i++) - { -parentAction.remove(akeys[i]); - } - -parent = jParent.getParent(); - } - +// FIXME: remove the WHEN_IN_FOCUSED_WINDOW bindings from the +// KeyboardManager + // Notify ancestor listeners. fireAncestorEvent(this, AncestorEvent.ANCESTOR_REMOVED); // fire property change event for 'ancestor' -firePropertyChange(ancestor, parent, null); +firePropertyChange(ancestor, getParent(), null); } /** Index: javax/swing/JMenuBar.java === RCS file: /cvsroot/classpath/classpath/javax/swing/JMenuBar.java,v retrieving revision 1.19 diff -u -r1.19 JMenuBar.java --- javax/swing/JMenuBar.java 14 Nov 2005 20:23:56 - 1.19 +++ javax/swing/JMenuBar.java 14 Nov 2005 20:53:25 - @@ -551,7 +551,7 @@ */ public void removeNotify() { -// Must unregister this menu bar with the current keyboard manager. +// FIXME: Must unregister this menu bar with the current keyboard manager. super.removeNotify(); } ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] FYI: Implemented unregistering of JMenuBars
This patch fixes the FIXME note in JMenuBar.removeNotify (yes, the one I put there about 10 minutes ago). The JMenuBar is now unregistered from the KeyboardManager. 2005-11-14 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/JMenuBar.java: (removeNotify): Unregister this JMenuBar from the KeyboardManager. * javax/swing/KeyboardManager.java: (unregisterJMenuBar): New implementation method. --Tony Index: javax/swing/JMenuBar.java === RCS file: /cvsroot/classpath/classpath/javax/swing/JMenuBar.java,v retrieving revision 1.20 diff -u -r1.20 JMenuBar.java --- javax/swing/JMenuBar.java 14 Nov 2005 20:58:47 - 1.20 +++ javax/swing/JMenuBar.java 14 Nov 2005 21:14:01 - @@ -551,7 +551,7 @@ */ public void removeNotify() { -// FIXME: Must unregister this menu bar with the current keyboard manager. +KeyboardManager.getManager().unregisterJMenuBar(this); super.removeNotify(); } Index: javax/swing/KeyboardManager.java === RCS file: /cvsroot/classpath/classpath/javax/swing/KeyboardManager.java,v retrieving revision 1.3 diff -u -r1.3 KeyboardManager.java --- javax/swing/KeyboardManager.java 14 Nov 2005 20:23:56 - 1.3 +++ javax/swing/KeyboardManager.java 14 Nov 2005 21:14:01 - @@ -263,4 +263,18 @@ if (!menuBars.contains(menuBar)) menuBars.add(menuBar); } + + /** + * Unregisters a JMenuBar from its top-level container. This is + * called before the JMenuBar is actually removed from the container + * so findTopLevel will still find us the correct top-level container. + * @param menuBar the JMenuBar to unregister. + */ + public void unregisterJMenuBar (JMenuBar menuBar) + { +Container topLevel = findTopLevel(menuBar); +Vector menuBars = getVectorForTopLevel(topLevel); +if (menuBars.contains(menuBar)) + menuBars.remove(menuBar); + } } ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] FYI: Improved (and corrected) Swing key handling
The method JComponent.processKeyEvent is Swing's entry point for handling key events. Events like typing text in a text area even pass through here to check first if the key event changes the focus (like alt-tab), then if there is a low-level key listener that wants the event, then if there is a registered key binding that deals with the event, and then finally defaulting to inserting the text. So I decided to tidy the code up and cut away the excess. In the process, I noticed that there were actually correctness problems in the code as well, specifically dealing with JInternalFrames, and so I reported this bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24781 . This patch fixes that bug and improves performance for certain cases. 2005-11-10 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/JComponent.java: (processKeyEvent): Reworked this method to improve performance. Return early if the event has already been handled. Don't stop climbing when we hit a JInternalFrame, only stop at Applets or Windows (this fixes PR 24781). Don't check WHEN_IN_FOCUSED_WINDOW bindings if there is no top-level container present. If there is a top-level container, pass it to KeyboardManager.processKeyStroke rather than the JComponent that actually received the event, to save time in finding the top-level container within KeyboardManager. * javax/swing/KeyboardManager.java: (findTopLevel): Changed parameter from JComponent to Component to allow generality and to allow passing in of already-determined top-level containers to save time. (processKeyStroke): Likewise. --Tony Index: javax/swing/JComponent.java === RCS file: /cvsroot/classpath/classpath/javax/swing/JComponent.java,v retrieving revision 1.82 diff -u -r1.82 JComponent.java --- javax/swing/JComponent.java 10 Nov 2005 12:36:44 - 1.82 +++ javax/swing/JComponent.java 10 Nov 2005 19:50:06 - @@ -988,7 +988,8 @@ { VetoableChangeListener[] listeners = getVetoableChangeListeners(); -PropertyChangeEvent evt = new PropertyChangeEvent(this, propertyName, oldValue, newValue); +PropertyChangeEvent evt = + new PropertyChangeEvent(this, propertyName, oldValue, newValue); for (int i = 0; i listeners.length; i++) listeners[i].vetoableChange(evt); @@ -2209,36 +2210,52 @@ boolean pressed = e.getID() == KeyEvent.KEY_PRESSED; if (processKeyBinding(keyStroke, e, WHEN_FOCUSED, pressed)) - // This is step 1 from above comment. - e.consume(); + { +// This is step 1 from above comment. +e.consume(); +return; + } else if (processKeyBinding (keyStroke, e, WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, pressed)) - // This is step 2 from above comment. - e.consume(); -else { -// This is step 3 from above comment. -Container current = this; -while ((current = current.getParent()) instanceof JComponent) +// This is step 2 from above comment. +e.consume(); +return; + } + +// This is step 3 from above comment. +Container current = getParent(); +while (current != null) + { +// If current is a JComponent, see if it handles the event in its +// WHEN_ANCESTOR_OF_FOCUSED_COMPONENT maps. +if ((current instanceof JComponent) +((JComponent)current).processKeyBinding +(keyStroke, e,WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, pressed)) { -if (((JComponent)current).processKeyBinding -(keyStroke, e,WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, - pressed)) - { -e.consume(); -break; - } -if (current instanceof Window || current instanceof Applet -|| current instanceof JInternalFrame) - break; - } -if (e.isConsumed()) - return; - -// This is step 4 from above comment. -if (KeyboardManager.getManager().processKeyStroke(this, keyStroke, e)) - e.consume(); +e.consume(); +return; + } + +// Stop when we've tried a top-level container and it didn't handle it +if (current instanceof Window || current instanceof Applet) + break; + +// Move up the hierarchy +current = current.getParent(); } + +// Current being null means the JComponent does not currently have a +// top-level ancestor, in which case we don't need to check +// WHEN_IN_FOCUSED_WINDOW bindings. +if (current == null || e.isConsumed()) + return; + +// This is step 4 from above comment. KeyboardManager maintains mappings +// related to WHEN_IN_FOCUSED_WINDOW
[cp-patches] Patch: ComponentInputMaps implemented
This patch fixes all the FIXME notes in ComponentInputMap and tidies a few places in JComponent relating to ComponentInputMap. The main method however, JComponent.udpateComponentInputMap is not fully implemented because I first have to write a KeyboardManager class, which I'll do now. 2005-11-09 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/ComponentInputMap.java: (put): Notify the component. (clear): Likewise. (remove): Likewise. (setParent): Notify the parent. Improved the exception messages. * javax/swing/JComponent.java: (inputMap_whenInFocusedWindow): Changed type from InputMap to ComponentInputMap. (setInputMap): If we're setting the WHEN_IN_FOCUSED_WINDOW map and the parameter is not a ComponentInputMap or is not associated with the same Component, throw an IllegalArgumentException. (getInputMap): Create a new ComponentInputMap instead of a new InputMap when the WHEN_IN_FOCUSED_WINDOW map doesn't yet exist. (udpateComponentInputMap): New method. This is the method that ComponentInputMap calls when it is updated. Not yet completely implemented. --Tony Index: javax/swing/ComponentInputMap.java === RCS file: /cvsroot/classpath/classpath/javax/swing/ComponentInputMap.java,v retrieving revision 1.8 diff -u -r1.8 ComponentInputMap.java --- javax/swing/ComponentInputMap.java 26 Jul 2005 15:30:54 - 1.8 +++ javax/swing/ComponentInputMap.java 9 Nov 2005 19:07:40 - @@ -78,7 +78,8 @@ public void put(KeyStroke keystroke, Object value) { super.put(keystroke, value); -// FIXME: Notify component. +if (component != null) + component.updateComponentInputMap(this); } /** @@ -87,7 +88,8 @@ public void clear() { super.clear(); -// FIXME: Notify component. +if (component != null) + component.updateComponentInputMap(this); } /** @@ -98,7 +100,8 @@ public void remove(KeyStroke keystroke) { super.remove(keystroke); -// FIXME: Notify component. +if (component != null) + component.updateComponentInputMap(this); } /** @@ -111,14 +114,19 @@ */ public void setParent(InputMap parentMap) { -if (! (parentMap instanceof ComponentInputMap)) - throw new IllegalArgumentException(); - -if (((ComponentInputMap) parentMap).getComponent() != component) - throw new IllegalArgumentException(); +if (parentMap != null !(parentMap instanceof ComponentInputMap)) + throw new IllegalArgumentException(ComponentInputMaps can only have + + ComponentInputMaps for parents); + +if (parentMap != null +((ComponentInputMap) parentMap).getComponent() != component) + throw new +IllegalArgumentException(ComponentInputMaps' parents must + + be associated with the same JComponents); super.setParent(parentMap); -// FIXME: Notify component. +if (component != null) + component.updateComponentInputMap(this); } /** Index: javax/swing/JComponent.java === RCS file: /cvsroot/classpath/classpath/javax/swing/JComponent.java,v retrieving revision 1.78 diff -u -r1.78 JComponent.java --- javax/swing/JComponent.java 9 Nov 2005 14:44:00 - 1.78 +++ javax/swing/JComponent.java 9 Nov 2005 19:07:41 - @@ -546,7 +546,7 @@ private InputMap inputMap_whenFocused; private InputMap inputMap_whenAncestorOfFocused; - private InputMap inputMap_whenInFocusedWindow; + private ComponentInputMap inputMap_whenInFocusedWindow; private ActionMap actionMap; /** @since 1.3 */ private boolean verifyInputWhenFocusTarget; @@ -2022,7 +2022,11 @@ break; case WHEN_IN_FOCUSED_WINDOW: -inputMap_whenInFocusedWindow = map; +if (map != null !(map instanceof ComponentInputMap)) +throw new + IllegalArgumentException(WHEN_IN_FOCUSED_WINDOW + + InputMap must be a ComponentInputMap); +inputMap_whenInFocusedWindow = (ComponentInputMap)map; break; case UNDEFINED_CONDITION: @@ -2048,7 +2052,7 @@ case WHEN_IN_FOCUSED_WINDOW: if (inputMap_whenInFocusedWindow == null) - inputMap_whenInFocusedWindow = new InputMap(); + inputMap_whenInFocusedWindow = new ComponentInputMap(this); return inputMap_whenInFocusedWindow; case UNDEFINED_CONDITION: @@ -3297,5 +3301,27 @@ found = p; } return found; + } + + /** + * This is the method that gets called when the WHEN_IN_FOCUSED_WINDOW map + * is changed. + * @param c the JComponent associated with the WHEN_IN_FOCUSED_WINDOW map + */ + void updateComponentInputMap(ComponentInputMap changed
[cp-patches] Patch (Suggestions Needed): JComponent key bindings
This patch implements the package-private class javax.swing.KeyboardManager and makes some adjustments in JComponent to allow keybindings registered with the condition WHEN_IN_FOCUSED_WINDOW to work. This mechanism is not 100% correct yet. Attached is a test case that works. Click on the JButton to give it focus. Then pressing 'a' prints I'm Focused to the screen. Clicking on the JCheckBox gives it focus (so the JButton is not focused) and then pressing 'a' prints I'm In Focused Window to the screen == this is new functionality, the JButton can register key bindings that work even when it is not focused or an ancestor of the focused component, it's just in the focused window. However, if, in the testcase, the keybinding is registered before the JButton is added to the JFrame (its top-level ancestor), our implementation fails. This is because when the key action is bound the JButton had no top-level ancestor, and when the JButton was added to the JFrame it doesn't re-hash its bindings. So, I have to find a way to re-hash WHEN_IN_FOCUSED_WINDOW bindings when components are added to containers. Unfortunately, adding occurs in Containers in AWT and much of the needed code is in package-private methods or classes in Swing. For instance, to re-hash bindings I need to use the KeyboardManager class, or at least the method JComponent.updateComponentInputMap. Anyone have any suggestions? 2005-11-09 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/JComponent.java: (processKeyEvent): Use local variables for boolean pressed and for the KeyStroke. Implemented the code for WHEN_IN_FOCUSED_WINDOW bindings. (updateComponentInputMap): Implemented and fixed typo in docs. * javax/swing/KeyboardManager.java: New class. Index: javax/swing/JComponent.java === RCS file: /cvsroot/classpath/classpath/javax/swing/JComponent.java,v retrieving revision 1.79 diff -u -r1.79 JComponent.java --- javax/swing/JComponent.java 9 Nov 2005 19:15:03 - 1.79 +++ javax/swing/JComponent.java 9 Nov 2005 21:54:20 - @@ -2167,13 +2167,14 @@ // 4. The WHEN_IN_FOCUSED_WINDOW maps of all the enabled components in //the focused window are searched. -if (processKeyBinding(KeyStroke.getKeyStrokeForEvent(e), - e, WHEN_FOCUSED, e.getID() == KeyEvent.KEY_PRESSED)) +KeyStroke keyStroke = KeyStroke.getKeyStrokeForEvent(e); +boolean pressed = e.getID() == KeyEvent.KEY_PRESSED; + +if (processKeyBinding(keyStroke, e, WHEN_FOCUSED, pressed)) // This is step 1 from above comment. e.consume(); -else if (processKeyBinding(KeyStroke.getKeyStrokeForEvent(e), - e, WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, - e.getID() == KeyEvent.KEY_PRESSED)) +else if (processKeyBinding + (keyStroke, e, WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, pressed)) // This is step 2 from above comment. e.consume(); else @@ -2183,9 +2184,8 @@ while ((current = current.getParent()) instanceof JComponent) { if (((JComponent)current).processKeyBinding -(KeyStroke.getKeyStrokeForEvent(e), e, - WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, - e.getID() == KeyEvent.KEY_PRESSED)) +(keyStroke, e,WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, + pressed)) { e.consume(); break; @@ -2196,10 +2196,10 @@ } if (e.isConsumed()) return; - + // This is step 4 from above comment. -// FIXME: Implement. Note, should use ComponentInputMaps rather -// than walking the entire containment hierarchy. +if (KeyboardManager.getManager().processKeyStroke(this, keyStroke, e)) + e.consume(); } } @@ -3306,7 +3306,7 @@ /** * This is the method that gets called when the WHEN_IN_FOCUSED_WINDOW map * is changed. - * @param c the JComponent associated with the WHEN_IN_FOCUSED_WINDOW map + * @param changed the JComponent associated with the WHEN_IN_FOCUSED_WINDOW map */ void updateComponentInputMap(ComponentInputMap changed) { @@ -3322,6 +3322,12 @@ return; // Now we have to update the keyboard manager's hashtable -// FIXME: not yet implemented +KeyboardManager km = KeyboardManager.getManager(); + +// This is a poor strategy, should be improved. We currently +// delete all the old bindings for the component and then register +// the current bindings. +km.clearBindingsForComp(changed.getComponent()); +km.registerEntireMap((ComponentInputMap) getInputMap(WHEN_IN_FOCUSED_WINDOW)); } } Index: javax/swing/KeyboardManager.java === RCS file: javax
Re: [cp-patches] FYI: Component invalidate() fix
On Tue, 2005-11-08 at 11:53 +, Roman Kennke wrote: Hi again, Yesterday I checked in a change to java.awt.Component. Today I wrote a testcase for that (bad me, I should really do that before starting to code) that shows that this fix was wrong. I revert that. Hi all, can we please mention which test cases (if they are Mauve tests) we're referring to in our messages to classpath-patches? Thanks! Tony ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
Re: [cp-patches] Patch: 2 API methods implemented in java.lang.String
On Mon, 2005-11-07 at 13:52 -0800, David Daney wrote: Try StringBuilder instead of StringBuffer. Done. This is faster than StringBuffer but doesn't provide thread-safety, which we didn't need in this case anyway. 2005-11-08 Anthony Balkissoon [EMAIL PROTECTED] * java/lang/String.java: (replace): Use a StringBuilder instead of a StringBuffer because this is faster and we don't need thread-safety. --Tony Index: java/lang/String.java === RCS file: /cvsroot/classpath/classpath/java/lang/String.java,v retrieving revision 1.75 diff -u -r1.75 String.java --- java/lang/String.java 7 Nov 2005 20:50:56 - 1.75 +++ java/lang/String.java 8 Nov 2005 16:03:11 - @@ -1901,7 +1901,7 @@ int replaceLength = replacement.length(); int startPos = this.indexOf(targetString); -StringBuffer result = new StringBuffer(this); +StringBuilder result = new StringBuilder(this); while (startPos != -1) { // Replace the target with the replacement ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] FYI: Implemented method in DefaultStyledDocument
I implemented the method ElementBuffer.clone in DefaultStyledDocument, one of the remaining missing methods in javax.swing.text. 2005-11-08 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/text/DefaultStyledDocument.java: (ElementBuffer.clone): New API method. --Tony Index: javax/swing/text/DefaultStyledDocument.java === RCS file: /cvsroot/classpath/classpath/javax/swing/text/DefaultStyledDocument.java,v retrieving revision 1.16 diff -u -r1.16 DefaultStyledDocument.java --- javax/swing/text/DefaultStyledDocument.java 4 Nov 2005 22:50:03 - 1.16 +++ javax/swing/text/DefaultStyledDocument.java 8 Nov 2005 16:40:02 - @@ -772,6 +772,34 @@ } offset += len; } + +/** + * Creates a copy of the element codeclonee/code that has the parent + * codeparent/code. + * @param parent the parent of the newly created Element + * @param clonee the Element to clone + * @return the cloned Element + */ +public Element clone (Element parent, Element clonee) +{ + // If the Element we want to clone is a leaf, then simply copy it + if (clonee.isLeaf()) +return createLeafElement(parent, clonee.getAttributes(), + clonee.getStartOffset(), clonee.getEndOffset()); + + // Otherwise create a new BranchElement with the desired parent and + // the clonee's attributes + BranchElement result = (BranchElement) createBranchElement(parent, clonee.getAttributes()); + + // And clone all the of clonee's children + Element[] children = new Element[clonee.getElementCount()]; + for (int i = 0; i children.length; i++) +children[i] = clone(result, clonee.getElement(i)); + + // Make the cloned children the children of the BranchElement + result.replace(0, 0, children); + return result; +} } /** ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] Patch: SwingUtilities.replaceUIActionMap fixed
As I reported in bug 24742: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24742 SwingUtilities.replaceUIActionMap wasn't working properly. This patch fixes it and also fixes BasicListUI, BasicTableUI, and BasicTreeUI to use ActionMapUIResource for their ActionMaps as they should. 2005-11-08 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/SwingUtilities.java: (replaceUIActionMap): Stop climbing hierarchy once we've found an ActionMapUIResource, don't keep looking until parent is null. No need to check if child is null. (replaceUIInputMap): Use a local variable for the parent rather than 3 calls to get parent. No need to check if child is null. * javax/swing/plaf/basic/BasicListUI.java: * javax/swing/plaf/basic/BasicTableUI.java: * javax/swing/plaf/basic/BasicTreeUI.java: (installKeyboardActions): UI ActionMap should be of type ActionMapUIResource, not just ActionMap. --Tony Index: javax/swing/SwingUtilities.java === RCS file: /cvsroot/classpath/classpath/javax/swing/SwingUtilities.java,v retrieving revision 1.38 diff -u -r1.38 SwingUtilities.java --- javax/swing/SwingUtilities.java 19 Oct 2005 15:45:05 - 1.38 +++ javax/swing/SwingUtilities.java 8 Nov 2005 20:30:20 - @@ -1138,14 +1138,12 @@ else { ActionMap parent = child.getParent(); -while(parent != null) +while (parent != null !(parent instanceof ActionMapUIResource)) { child = parent; parent = child.getParent(); } - -if (child != null) - child.setParent(uiActionMap); +child.setParent(uiActionMap); } } @@ -1181,11 +1179,13 @@ component.setInputMap(condition, uiInputMap); else { -while(child.getParent() != null - !(child.getParent() instanceof InputMapUIResource)) - child = child.getParent(); -if (child != null) - child.setParent(uiInputMap); +InputMap parent = child.getParent(); +while (parent != null !(parent instanceof InputMapUIResource)) + { +child = parent; +parent = parent.getParent(); + } +child.setParent(uiInputMap); } } Index: javax/swing/plaf/basic/BasicListUI.java === RCS file: /cvsroot/classpath/classpath/javax/swing/plaf/basic/BasicListUI.java,v retrieving revision 1.36 diff -u -r1.36 BasicListUI.java --- javax/swing/plaf/basic/BasicListUI.java 20 Oct 2005 18:58:47 - 1.36 +++ javax/swing/plaf/basic/BasicListUI.java 8 Nov 2005 20:30:20 - @@ -51,7 +51,6 @@ import java.awt.event.ComponentListener; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; -import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; @@ -76,6 +75,7 @@ import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.event.MouseInputListener; +import javax.swing.plaf.ActionMapUIResource; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.InputMapUIResource; import javax.swing.plaf.ListUI; @@ -940,7 +940,7 @@ InputMap focusInputMap = (InputMap)defaults.get(List.focusInputMap); InputMapUIResource parentInputMap = new InputMapUIResource(); // FIXME: The JDK uses a LazyActionMap for parentActionMap -ActionMap parentActionMap = new ActionMap(); +ActionMap parentActionMap = new ActionMapUIResource(); action = new ListAction(); Object keys[] = focusInputMap.allKeys(); // Register key bindings in the UI InputMap-ActionMap pair Index: javax/swing/plaf/basic/BasicTableUI.java === RCS file: /cvsroot/classpath/classpath/javax/swing/plaf/basic/BasicTableUI.java,v retrieving revision 1.35 diff -u -r1.35 BasicTableUI.java --- javax/swing/plaf/basic/BasicTableUI.java 28 Oct 2005 14:46:10 - 1.35 +++ javax/swing/plaf/basic/BasicTableUI.java 8 Nov 2005 20:30:20 - @@ -71,6 +71,7 @@ import javax.swing.border.Border; import javax.swing.event.ChangeEvent; import javax.swing.event.MouseInputListener; +import javax.swing.plaf.ActionMapUIResource; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.InputMapUIResource; import javax.swing.plaf.TableUI; @@ -401,7 +402,7 @@ InputMap ancestorMap = (InputMap)defaults.get(Table.ancestorInputMap); InputMapUIResource parentInputMap = new InputMapUIResource(); // FIXME: The JDK uses a LazyActionMap for parentActionMap -ActionMap parentActionMap = new ActionMap(); +ActionMap parentActionMap = new ActionMapUIResource(); action = new TableAction(); Object keys[] = ancestorMap.allKeys(); // Register key bindings in the UI
Re: [cp-patches] Patch: implemented InvocationEvent.getThrowable
Thanks for the advice Mark, I fixed this up and committed it. 2005-11-08 Anthony Balkissoon [EMAIL PROTECTED] * java/awt/event/InvocationEvent.java: (exception): Removed unnecessary field. (dispatch): Removed reference to field exception. (getException): If throwable is an Exception, return a casted version, otherwise return null. (getThrowable): Improved docs. --Tony On Tue, 2005-11-08 at 19:22 +0100, Mark Wielaard wrote: Hi Tony, On Mon, 2005-11-07 at 13:29 -0500, Anthony Balkissoon wrote: JAPI pointed out that InvocationEvent.getThrowable was missing. I wrote it, which involved a slight tweak of dispatch() as well. [...] + /** + * Returns a throwable caught while executing the Runnable's run() method. + * Null if none was thrown or if this InvocationEvent doesn't catch + * throwables. + * @return the caught Throwable + */ + public Throwable getThrowable() + { +return throwable; + } Please add @since 1.5 to such new methods. Now we have both a throwable and a exception private field. Unless we need them for serialization it is probably better to collapse them into one and let getException() do an instanceof Exception. Cheers, Mark ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches Index: java/awt/event/InvocationEvent.java === RCS file: /cvsroot/classpath/classpath/java/awt/event/InvocationEvent.java,v retrieving revision 1.10 diff -u -r1.10 InvocationEvent.java --- java/awt/event/InvocationEvent.java 7 Nov 2005 18:28:03 - 1.10 +++ java/awt/event/InvocationEvent.java 8 Nov 2005 20:49:01 - @@ -98,16 +98,9 @@ protected boolean catchExceptions; /** - * This is the caught exception thrown in the coderun()/code method. It - * is null if exceptions are ignored, the run method hasn't completed, or - * there were no exceptions. - * - * @serial the caught exception, if any - */ - private Exception exception; - - /** * This is the caught Throwable thrown in the coderun()/code method. + * It is null if throwables are ignored, the run method hasn't completed, + * or there were no throwables thrown. */ private Throwable throwable; @@ -191,8 +184,6 @@ catch (Throwable t) { throwable = t; - if (t instanceof Exception) -exception = (Exception)t; } else runnable.run(); @@ -214,7 +205,9 @@ */ public Exception getException() { -return exception; +if (throwable == null || !(throwable instanceof Exception)) + return null; +return (Exception) throwable; } /** @@ -222,6 +215,7 @@ * Null if none was thrown or if this InvocationEvent doesn't catch * throwables. * @return the caught Throwable + * @since 1.5 */ public Throwable getThrowable() { ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
Re: [cp-patches] FYI: New TextField demo
On Fri, 2005-11-04 at 12:24 +, Roman Kennke wrote: Hi, I added a cool new JTextField demo that shows the JTextField in various states. The best thing is, most stuff is actually working now :-) A special highlight is the custom caret in the text field at the bottom left. Running this demo I noticed two things: 1) After unchecking editable, the JTextFields are still editable - you can still enter text. 2) Clicking somewhere in the text doesn't move the cursor to that point - this is a regression. --Tony ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] Patch: Boolean.compareTo(Boolean) implemented
JAPI pointed out that this method (@since 1.5) wasn't implemented so I wrote it. JAPI also said that Boolean.compareTo(Object) is missing, but I don't believe that's actually in the JDK library. It's not in the specs and a testcase I wrote using it doesn't compile. JAPI problem? 2005-11-07 Anthony Balkissoon [EMAIL PROTECTED] * java/lang/Boolean.java: (compareTo(Boolean)): New API method. --Tony Index: java/lang/Boolean.java === RCS file: /cvsroot/classpath/classpath/java/lang/Boolean.java,v retrieving revision 1.23 diff -u -r1.23 Boolean.java --- java/lang/Boolean.java 17 Sep 2005 21:58:41 - 1.23 +++ java/lang/Boolean.java 7 Nov 2005 16:59:47 - @@ -233,4 +233,24 @@ { return true.equalsIgnoreCase(b) ? true : false; } + + /** + * Compares this Boolean to another. + * @param b the Boolean to compare this Boolean to + * @return 0 if both Booleans represent the same value, a positive number + * if this Boolean represents true and b represents false, or a negative + * number otherwise. + * @since 1.5 + */ + public int compareTo (Boolean b) + { +if (b == null) + throw new NullPointerException(argument passed to compareTo(Boolean) cannot be null); + +if (this.value == b.value) + return 0; +if (this.value == true) + return 1; +return -1; + } } ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] Patch: 2 API methods implemented in java.lang.String
I implemented the methods String.contains(CharSequence) and String.replace(CharSequence, CharSequence) that JAPI pointed out as missing. This was 2 commits because of a typo in the ChangeLog. 2005-11-07 Anthony Balkissoon [EMAIL PROTECTED] * java/lang/String.java: (contains): New API method. (replace): New API method. --Tony Index: java/lang/String.java === RCS file: /cvsroot/classpath/classpath/java/lang/String.java,v retrieving revision 1.73 diff -u -r1.73 String.java --- java/lang/String.java 2 Nov 2005 10:23:01 - 1.73 +++ java/lang/String.java 7 Nov 2005 18:01:16 - @@ -1873,4 +1873,36 @@ return value; } + + /** + * Returns true iff this String contains the sequence of Characters + * described in s. + * @param s the CharSequence + * @return true iff this String contains s + */ + public boolean contains (CharSequence s) + { +return this.indexOf(s.toString()) != -1; + } + + /** + * Returns a string that is this string with all instances of the sequence + * represented by codetarget/code replaced by the sequence in + * codereplacement/code. + * @param target the sequence to be replaced + * @param replacement the sequence used as the replacement + * @return the string constructed as above + */ + public String replace (CharSequence target, CharSequence replacement) + { +String result = this; +int pos = result.indexOf(target.toString()); +while (pos != -1) + { +result = result.substring(0, pos) + replacement.toString() + + result.substring(pos + target.length(), result.length()); +pos = result.indexOf(target.toString()); + } +return result; + } } ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] Patch: implemented InvocationEvent.getThrowable
JAPI pointed out that InvocationEvent.getThrowable was missing. I wrote it, which involved a slight tweak of dispatch() as well. 2005-11-07 Anthony Balkissoon [EMAIL PROTECTED] * java/awt/event/InvocationEvent.java: (throwable): New field. (getThrowable): New API method. (dispatch()): Catch Throwable, not Exception. Save the Throwable. If it is an Exception, save the Exception. --Tony Index: java/awt/event/InvocationEvent.java === RCS file: /cvsroot/classpath/classpath/java/awt/event/InvocationEvent.java,v retrieving revision 1.9 diff -u -r1.9 InvocationEvent.java --- java/awt/event/InvocationEvent.java 2 Jul 2005 20:32:28 - 1.9 +++ java/awt/event/InvocationEvent.java 7 Nov 2005 18:23:55 - @@ -107,6 +107,11 @@ private Exception exception; /** + * This is the caught Throwable thrown in the coderun()/code method. + */ + private Throwable throwable; + + /** * The timestamp when this event was created. * * @see #getWhen() @@ -183,9 +188,11 @@ { runnable.run(); } - catch (Exception e) + catch (Throwable t) { - exception = e; + throwable = t; + if (t instanceof Exception) +exception = (Exception)t; } else runnable.run(); @@ -210,6 +217,17 @@ return exception; } + /** + * Returns a throwable caught while executing the Runnable's run() method. + * Null if none was thrown or if this InvocationEvent doesn't catch + * throwables. + * @return the caught Throwable + */ + public Throwable getThrowable() + { +return throwable; + } + /** * Gets the timestamp of when this event was created. * ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] Patch: java.util.Arrays API methods implemented
Implemented the toString methods from java.util.Arrays that JAPI pointed out were missing. 2005-11-07 Anthony Balkissoon [EMAIL PROTECTED] * java/util/Arrays.java: (toString(long[])): New API method. (toString(int[])): Likewise. (toString(short[])): Likewise. (toString(char[])): Likewise. (toString(byte[])): Likewise. (toString(boolean[])): Likewise. (toString(float[])): Likewise. (toString(double[])): Likewise. (toString(Object[])): Likewise. --Tony Index: java/util/Arrays.java === RCS file: /cvsroot/classpath/classpath/java/util/Arrays.java,v retrieving revision 1.25 diff -u -r1.25 Arrays.java --- java/util/Arrays.java 2 Jul 2005 20:32:41 - 1.25 +++ java/util/Arrays.java 7 Nov 2005 19:06:14 - @@ -2353,6 +2353,186 @@ } /** + * Returns a String representation of the argument array. Returns null + * if codea/code is null. + * @param a the array to represent + * @return a String representing this array + * @since 1.5 + */ + public static String toString (long[] a) + { +if (a == null) + return null; +if (a.length == 0) + return []; +String result = [; +for (int i = 0; i a.length - 1; i++) + result += String.valueOf(a[i]) + , ; +result += String.valueOf(a[a.length - 1]) + ]; +return result; + } + + /** + * Returns a String representation of the argument array. Returns null + * if codea/code is null. + * @param a the array to represent + * @return a String representing this array + * @since 1.5 + */ + public static String toString (int[] a) + { +if (a == null) + return null; +if (a.length == 0) + return []; +String result = [; +for (int i = 0; i a.length - 1; i++) + result += String.valueOf(a[i]) + , ; +result += String.valueOf(a[a.length - 1]) + ]; +return result; + } + + /** + * Returns a String representation of the argument array. Returns null + * if codea/code is null. + * @param a the array to represent + * @return a String representing this array + * @since 1.5 + */ + public static String toString (short[] a) + { +if (a == null) + return null; +if (a.length == 0) + return []; +String result = [; +for (int i = 0; i a.length - 1; i++) + result += String.valueOf(a[i]) + , ; +result += String.valueOf(a[a.length - 1]) + ]; +return result; + } + + /** + * Returns a String representation of the argument array. Returns null + * if codea/code is null. + * @param a the array to represent + * @return a String representing this array + * @since 1.5 + */ + public static String toString (char[] a) + { +if (a == null) + return null; +if (a.length == 0) + return []; +String result = [; +for (int i = 0; i a.length - 1; i++) + result += String.valueOf(a[i]) + , ; +result += String.valueOf(a[a.length - 1]) + ]; +return result; + } + + /** + * Returns a String representation of the argument array. Returns null + * if codea/code is null. + * @param a the array to represent + * @return a String representing this array + * @since 1.5 + */ + public static String toString (byte[] a) + { +if (a == null) + return null; +if (a.length == 0) + return []; +String result = [; +for (int i = 0; i a.length - 1; i++) + result += String.valueOf(a[i]) + , ; +result += String.valueOf(a[a.length - 1]) + ]; +return result; + } + + /** + * Returns a String representation of the argument array. Returns null + * if codea/code is null. + * @param a the array to represent + * @return a String representing this array + * @since 1.5 + */ + public static String toString (boolean[] a) + { +if (a == null) + return null; +if (a.length == 0) + return []; +String result = [; +for (int i = 0; i a.length - 1; i++) + result += String.valueOf(a[i]) + , ; +result += String.valueOf(a[a.length - 1]) + ]; +return result; + } + + /** + * Returns a String representation of the argument array. Returns null + * if codea/code is null. + * @param a the array to represent + * @return a String representing this array + * @since 1.5 + */ + public static String toString (float[] a) + { +if (a == null) + return null; +if (a.length == 0) + return []; +String result = [; +for (int i = 0; i a.length - 1; i++) + result += String.valueOf(a[i]) + , ; +result += String.valueOf(a[a.length - 1]) + ]; +return result; + } + + /** + * Returns a String representation of the argument array. Returns null + * if codea/code is null. + * @param a the array to represent + * @return a String representing this array + * @since 1.5 + */ + public static String toString (double[] a) + { +if (a == null
Re: [cp-patches] Patch: 2 API methods implemented in java.lang.String
On Mon, 2005-11-07 at 12:39 -0700, Tom Tromey wrote: Tony == Anthony Balkissoon [EMAIL PROTECTED] writes: Tony + public String replace (CharSequence target, CharSequence replacement) Tony + { Tony +String result = this; Tony +int pos = result.indexOf(target.toString()); Tony +while (pos != -1) Tony + { Tony +result = result.substring(0, pos) + replacement.toString() Tony + + result.substring(pos + target.length(), result.length()); Tony +pos = result.indexOf(target.toString()); Tony + } Tony +return result; Tony + } Tony } This is inefficient. For one thing, target is converted to a String twice. For another, it creates a lot of garbage if there is more than one match. It is also incorrect, consider what happens if the replacement string contains the target string. Thanks Tom. I fixed this now, it uses a StringBuffer for better performance and also only checks for occurrences of the target string that occur after the replacement insertion. Also doesn't re-initialize the start part of the String each time which was just wasteful. 2005-11-07 Anthony Balkissoon [EMAIL PROTECTED] * java/lang/String.java: (replace): Use a StringBuffer instead of String. Only search for new occurrences of the target that occur AFTER the text just inserted, so if the replacement string contains the target string we won't go into an infinite loop. Use local variables instead of repeated calls to length() and toString(). Index: java/lang/String.java === RCS file: /cvsroot/classpath/classpath/java/lang/String.java,v retrieving revision 1.74 diff -u -r1.74 String.java --- java/lang/String.java 7 Nov 2005 18:04:32 - 1.74 +++ java/lang/String.java 7 Nov 2005 20:40:28 - @@ -1895,14 +1895,21 @@ */ public String replace (CharSequence target, CharSequence replacement) { -String result = this; -int pos = result.indexOf(target.toString()); -while (pos != -1) +String targetString = target.toString(); +String replaceString = replacement.toString(); +int targetLength = target.length(); +int replaceLength = replacement.length(); + +int startPos = this.indexOf(targetString); +StringBuffer result = new StringBuffer(this); +while (startPos != -1) { -result = result.substring(0, pos) + replacement.toString() - + result.substring(pos + target.length(), result.length()); -pos = result.indexOf(target.toString()); +// Replace the target with the replacement +result.replace(startPos, startPos + targetLength, replaceString); + +// Search for a new occurrence of the target +startPos = result.indexOf(targetString, startPos + replaceLength); } -return result; +return result.toString(); } } ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] FYI: StyleConstants addition
Added these two fields that JAPI pointed out. 2005-11-04 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/text/StyleConstants.java: (Family): New API field. (Size): New API field. --Tony Index: javax/swing/text/StyleConstants.java === RCS file: /cvsroot/classpath/classpath/javax/swing/text/StyleConstants.java,v retrieving revision 1.7 diff -u -r1.7 StyleConstants.java --- javax/swing/text/StyleConstants.java 13 Sep 2005 23:44:50 - 1.7 +++ javax/swing/text/StyleConstants.java 4 Nov 2005 20:13:10 - @@ -54,11 +54,13 @@ public static final Object BidiLevel = CharacterConstants.BidiLevel; public static final Object Bold = CharacterConstants.Bold; public static final Object ComponentAttribute = CharacterConstants.ComponentAttribute; - public static final Object FontFamily = CharacterConstants.Family; + public static final Object Family = CharacterConstants.Family; + public static final Object FontFamily = CharacterConstants.Family; public static final Object FontSize = CharacterConstants.Size; public static final Object Foreground = CharacterConstants.Foreground; public static final Object IconAttribute = CharacterConstants.IconAttribute; public static final Object Italic = CharacterConstants.Italic; + public static final Object Size = CharacterConstants.Size; public static final Object StrikeThrough = CharacterConstants.StrikeThrough; public static final Object Subscript = CharacterConstants.Subscript; public static final Object Superscript = CharacterConstants.Superscript; ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] FYI: reformatted DefaultStyledDocument
Reformatted this file. 2005-11-04 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/text/DefaultStyledDocument.java: Reformatted. --Tony Index: javax/swing/text/DefaultStyledDocument.java === RCS file: /cvsroot/classpath/classpath/javax/swing/text/DefaultStyledDocument.java,v retrieving revision 1.15 diff -u -r1.15 DefaultStyledDocument.java --- javax/swing/text/DefaultStyledDocument.java 3 Nov 2005 15:40:32 - 1.15 +++ javax/swing/text/DefaultStyledDocument.java 4 Nov 2005 22:46:56 - @@ -509,37 +509,37 @@ void split(Element el, int offset) { if (el instanceof AbstractElement) - { - AbstractElement ael = (AbstractElement) el; - int startOffset = ael.getStartOffset(); - int endOffset = ael.getEndOffset(); - int len = endOffset - startOffset; - if (startOffset != offset endOffset != offset) - { - Element paragraph = ael.getParentElement(); - if (paragraph instanceof BranchElement) - { - 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)); - } +{ + AbstractElement ael = (AbstractElement) el; + int startOffset = ael.getStartOffset(); + int endOffset = ael.getEndOffset(); + int len = endOffset - startOffset; + if (startOffset != offset endOffset != offset) +{ + Element paragraph = ael.getParentElement(); + if (paragraph instanceof BranchElement) +{ + 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)); +} else throw new AssertionError(paragraph elements are expected to + be instances of + javax.swing.text.AbstractDocument.BranchElement); - } - } +} +} else - throw new AssertionError(content elements are expected to be - + instances of +throw new AssertionError(content elements are expected to be + + instances of + javax.swing.text.AbstractDocument.AbstractElement); } @@ -946,10 +946,10 @@ { Element element = getDefaultRootElement(); -while (! element.isLeaf()) +while (!element.isLeaf()) { - int index = element.getElementIndex(position); - element = element.getElement(index); +int index = element.getElementIndex(position); +element = element.getElement(index); } return element; @@ -1097,34 +1097,34 @@ int paragraphCount = root.getElementCount(); for (int pindex = 0; pindex paragraphCount; pindex++) { - 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++) - { - 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 +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
[cp-patches] FYI: updates to WrappedPlainView and JTextComponent
This patch fixes a bug in JTextComponent.select, the end of the selection is constrained to be = the start of the selection, not 0. This is fixed. I implemented WrappedPlainView.drawLine to properly call drawUnselectedText and drawSelectedText rather than just drawing the whole line using drawUnselectedText. However, this exposed some problems: - the method javax.swing.Utilities.drawTabbedText is not returning the proper value. This is causing selected and unselected text to overlap. - the JTextComponent is returning a value for getSelectedTextColor() that is the same as its selected background color (black) and so the text can't be seen. I temporarily fixed this by setting the selected text to be white, but I'll fix this as soon as I fix the underlying problem. After lunch I'll look into the first problem, but if I can't solve it right away I'll file a bug. 2005-11-03 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/text/JTextComponent.java: (select): The end index cannot be smaller than the start index, changed Math.max(end, 0) to Math.max(end, start). * javax/swing/text/WrappedPlainView.java: (selectionStart): New package private field. (selectionEnd): Likewise. (drawLine): Implemented to call drawUnselectedText and drawSelectedText on the appropriate parts of the line. Before it just drew the whole line with drawUnselectedText. (paint): Store the start and end of the selection. (WrappedLine.paint): Set the selected color to Color.WHITE. --Tony Index: javax/swing/text/JTextComponent.java === RCS file: /cvsroot/classpath/classpath/javax/swing/text/JTextComponent.java,v retrieving revision 1.44 diff -u -r1.44 JTextComponent.java --- javax/swing/text/JTextComponent.java 3 Nov 2005 11:19:29 - 1.44 +++ javax/swing/text/JTextComponent.java 3 Nov 2005 19:32:16 - @@ -1347,7 +1347,7 @@ start = Math.max(start, 0); start = Math.min(start, length); -end = Math.max(end, 0); +end = Math.max(end, start); end = Math.min(end, length); setCaretPosition(start); Index: javax/swing/text/WrappedPlainView.java === RCS file: /cvsroot/classpath/classpath/javax/swing/text/WrappedPlainView.java,v retrieving revision 1.5 diff -u -r1.5 WrappedPlainView.java --- javax/swing/text/WrappedPlainView.java 3 Nov 2005 14:09:22 - 1.5 +++ javax/swing/text/WrappedPlainView.java 3 Nov 2005 19:32:17 - @@ -73,6 +73,12 @@ /** A ViewFactory that creates WrappedLines **/ ViewFactory viewFactory = new WrappedLineCreator(); + /** The start of the selected text **/ + int selectionStart; + + /** The end of the selected text **/ + int selectionEnd; + /** * The instance returned by [EMAIL PROTECTED] #getLineBuffer()}. */ @@ -144,7 +150,44 @@ { try { - drawUnselectedText(g, x, y, p0, p1); + // We have to draw both selected and unselected text. There are + // several cases: + // - entire range is unselected + // - entire range is selected + // - start of range is selected, end of range is unselected + // - start of range is unselected, end of range is selected + // - middle of range is selected, start and end of range is unselected + + // entire range unselected: + if ((selectionStart == selectionEnd) || + (p0 selectionEnd || p1 selectionStart)) +drawUnselectedText(g, x, y, p0, p1); + + // entire range selected + else if (p0 = selectionStart p1 = selectionEnd) +drawSelectedText(g, x, y, p0, p1); + + // start of range selected, end of range unselected + else if (p0 = selectionStart) +{ + x = drawSelectedText(g, x, y, p0, selectionEnd); + drawUnselectedText(g, x, y, selectionEnd, p1); +} + + // start of range unselected, end of range selected + else if (selectionStart p0 selectionEnd p1) +{ + x = drawUnselectedText(g, x, y, p0, selectionStart); + drawSelectedText(g, x, y, selectionStart, p1); +} + + // middle of range selected + else if (selectionStart p0) +{ + x = drawUnselectedText(g, x, y, p0, selectionStart); + x = drawSelectedText(g, x, y, selectionStart, selectionEnd); + drawUnselectedText(g, x, y, selectionEnd, p1); +} } catch (BadLocationException ble) { @@ -185,7 +228,7 @@ */ protected int drawUnselectedText(Graphics g, int x, int y, int p0, int p1) throws BadLocationException - { + { JTextComponent textComponent = (JTextComponent) getContainer(); if (textComponent.isEnabled()) g.setColor(unselectedColor); @@ -320,6 +363,9 @@ */ public void paint(Graphics g, Shape a) { +JTextComponent comp
[cp-patches] FYI: more WrappedPlainView improvements
This patch implements insertUpdate and removeUpdate for WrappedPlainView.WrappedLine and also fixes some small issues in WrappedPlainView. ChangeLog entry explains them. 2005-11-03 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/text/WrappedPlainView.java: Fixed some 80 chars lines. (drawSelectedText): Fixed startOffset for call to Utilities.drawTabbedText to make sure tabs are properly expanded. (drawUnselectedText): Likewise. (getMinimumSpan): New API method. (getMaximumSpan): New API method. (setSize): Call preferenceChanged if the width has changed. (WrappedLine.determineNumLines): Move numLines=0 to the top in case the early return happens, numLines will still be correct. (WrappedLine.updateDamage): New implementation method called by insertUpdate and removeUpdate to repaint the appropriate part of the JTextArea. (WrappedLine.insertUpdate): New method. (WrappedLine.removeUpdate): New method. --Tony Index: javax/swing/text/WrappedPlainView.java === RCS file: /cvsroot/classpath/classpath/javax/swing/text/WrappedPlainView.java,v retrieving revision 1.6 diff -u -r1.6 WrappedPlainView.java --- javax/swing/text/WrappedPlainView.java 3 Nov 2005 19:40:37 - 1.6 +++ javax/swing/text/WrappedPlainView.java 3 Nov 2005 20:58:38 - @@ -213,7 +213,7 @@ g.setColor(selectedColor); Segment segment = getLineBuffer(); getDocument().getText(p0, p1 - p0, segment); -return Utilities.drawTabbedText(segment, x, y, g, this, 0); +return Utilities.drawTabbedText(segment, x, y, g, this, p0); } /** @@ -237,7 +237,7 @@ Segment segment = getLineBuffer(); getDocument().getText(p0, p1 - p0, segment); -return Utilities.drawTabbedText(segment, x, y, g, this, segment.offset); +return Utilities.drawTabbedText(segment, x, y, g, this, p0); } /** @@ -311,6 +311,26 @@ } /** + * Determines the minimum span along the given axis. Implemented to + * cache the font metrics and then call the super classes method. + */ + public float getMinimumSpan (int axis) + { +updateMetrics(); +return super.getMinimumSpan(axis); + } + + /** + * Determines the maximum span along the given axis. Implemented to + * cache the font metrics and then call the super classes method. + */ + public float getMaximumSpan (int axis) + { +updateMetrics(); +return super.getMaximumSpan(axis); + } + + /** * Called when something was inserted. Overridden so that * the view factory creates WrappedLine views. */ @@ -377,6 +397,8 @@ public void setSize (float width, float height) { updateMetrics(); +if (width != getWidth()) + preferenceChanged(null, true, true); super.setSize(width, height); } @@ -435,11 +457,11 @@ */ int determineNumLines() { + numLines = 0; int end = getEndOffset(); if (end == 0) return 0; - - numLines = 0; + int breakPoint; for (int i = getStartOffset(); i end;) { @@ -485,7 +507,8 @@ * in model space * @throws BadLocationException if the given model position is invalid */ -public Shape modelToView(int pos, Shape a, Bias b) throws BadLocationException +public Shape modelToView(int pos, Shape a, Bias b) +throws BadLocationException { Segment s = getLineBuffer(); int lineHeight = metrics.getHeight(); @@ -518,7 +541,9 @@ { // Shouldn't happen } - rect.x += Utilities.getTabbedTextWidth(s, metrics, rect.x, WrappedPlainView.this, currLineStart); + rect.x += Utilities.getTabbedTextWidth(s, metrics, rect.x, + WrappedPlainView.this, + currLineStart); return rect; } // Increment rect.y so we're checking the next logical line @@ -614,8 +639,8 @@ * document position codepos/code in the given direction * coded/code * - * @throws BadLocationException if codepos/code is not a valid offset in - * the document model + * @throws BadLocationException if codepos/code is not a valid offset + * in the document model */ public int getNextVisualPositionFrom(JTextComponent c, int pos, Position.Bias b, int d, @@ -624,6 +649,52 @@ { // TODO: Implement this properly. throw new AssertionError(Not implemented yet.); +} + +/** + * This method is called from insertUpdate and removeUpdate. + * If the number of lines in the document has changed, just repaint + * the whole thing (note, could improve performance
Re: [cp-patches] FYI: NEWS, AUTHORS
On Wed, 2005-11-02 at 10:10 +, David Gilbert wrote: * AUTHORS: added my name to bring honour and glory to myself and all my descendants. Awesome, can all my descendants be glorified as well? --Tony ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] FYI: JTable fixlet fixes mauve regressions
This patch fixes mauve regressions in JTable that Mark mentioned on the classpath mailing list. The JTable model has to be set before the call to initializeLocalVars is made. This is fixed. 2005-11-01 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/JTable.java: (JTable(TableModel, TableColumnModel, ListSelectionModel)): Set the model before calling initializeLocalVars. --Tony Index: javax/swing/JTable.java === RCS file: /cvsroot/classpath/classpath/javax/swing/JTable.java,v retrieving revision 1.56 diff -u -r1.56 JTable.java --- javax/swing/JTable.java 31 Oct 2005 10:13:38 - 1.56 +++ javax/swing/JTable.java 1 Nov 2005 16:38:01 - @@ -1081,12 +1081,12 @@ { setColumnModel(createDefaultColumnModel()); autoCreate = true; - } -initializeLocalVars(); + } updateUI(); setSelectionModel(sm == null ? createDefaultSelectionModel() : sm); setModel(dm == null ? createDefaultDataModel() : dm); setAutoCreateColumnsFromModel(autoCreate); +initializeLocalVars(); } protected void initializeLocalVars() ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] FYI: JFileChooser patch fixes mauve regressions
This patch fixes the following mauve regressions that Mark pointed out: +FAIL: gnu.testlet.javax.swing.JFileChooser.getApproveButtonText (number 1) +FAIL: gnu.testlet.javax.swing.JFileChooser.getDialogTitle: uncaught exception: java.lang.StackOverflowError +FAIL: gnu.testlet.javax.swing.JFileChooser.getFileView (number 1) +FAIL: gnu.testlet.javax.swing.JFileChooser.getFileView (number 3) +FAIL: gnu.testlet.javax.swing.JFileChooser.setApproveButtonText (number 1) +FAIL: gnu.testlet.javax.swing.JFileChooser.setApproveButtonText (number 6) +FAIL: gnu.testlet.javax.swing.JFileChooser.setDialogTitle: uncaught exception: java.lang.StackOverflowError +FAIL: gnu.testlet.javax.swing.JFileChooser.setFileView (number 1) +FAIL: gnu.testlet.javax.swing.JFileChooser.setFileView (number 6) 2005-11-01 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/JFileChooser.java: (getDialogTitle): Allow return of null. (getApproveButtonText): Likewise. (getFileView): Likewise. (getName): First try using the JFileChooser's FileView, if null, then pass call to UI. (getDescription): Likewise. (getTypeDescription): Likewise. (getIcon): Likewise. --Tony ? JFileChooser.txt Index: javax/swing/JFileChooser.java === RCS file: /cvsroot/classpath/classpath/javax/swing/JFileChooser.java,v retrieving revision 1.21 diff -u -r1.21 JFileChooser.java --- javax/swing/JFileChooser.java 19 Oct 2005 15:45:03 - 1.21 +++ javax/swing/JFileChooser.java 1 Nov 2005 17:57:52 - @@ -828,10 +828,7 @@ */ public String getDialogTitle() { -if (dialogTitle == null) - return getUI().getDialogTitle(this); -else - return dialogTitle; +return dialogTitle; } /** @@ -942,10 +939,7 @@ */ public String getApproveButtonText() { -if (approveButtonText == null) - return getUI().getApproveButtonText(this); -else - return approveButtonText; +return approveButtonText; } /** @@ -1264,10 +1258,7 @@ */ public FileView getFileView() { -if (fv == null) - return getUI().getFileView(this); -else - return fv; +return fv; } /** @@ -1280,7 +1271,12 @@ */ public String getName(File f) { -return getFileView().getName(f); +String name = null; +if (fv != null) + name = fv.getName(f); +if (name == null) + name = getUI().getFileView(this).getName(f); +return name; } /** @@ -1293,7 +1289,12 @@ */ public String getDescription(File f) { -return getFileView().getDescription(f); +String result = null; +if (fv != null) + result = fv.getDescription(f); +if (result == null) + result = getUI().getFileView(this).getDescription(f); +return result; } /** @@ -1306,7 +1307,12 @@ */ public String getTypeDescription(File f) { -return getFileView().getTypeDescription(f); +String result = null; +if (fv != null) + result = getFileView().getTypeDescription(f); +if (result == null) + result = getUI().getFileView(this).getTypeDescription(f); +return result; } /** @@ -1318,7 +1324,12 @@ */ public Icon getIcon(File f) { -return getFileView().getIcon(f); +Icon result = null; +if (fv != null) + result = fv.getIcon(f); +if (result == null) + result = getUI().getFileView(this).getIcon(f); +return result; } /** ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] FYI: JTable fixlet corrects NPE
Some apps were getting NPE with JTable because variables were not set before the call to updateUI which could be overridden. This is fixed now, although there are some intricacies which may be fixed after the release, I put a TODO in the code for now. 2005-11-01 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/JTable.java: (JTable(TableModel, TableColumnModel, ListSelectionModel)): Call updateUI after initializeLocalVars. Manually set the lead selection indices. --Tony ? JFileChooser.txt Index: javax/swing/JTable.java === RCS file: /cvsroot/classpath/classpath/javax/swing/JTable.java,v retrieving revision 1.57 diff -u -r1.57 JTable.java --- javax/swing/JTable.java 1 Nov 2005 16:41:25 - 1.57 +++ javax/swing/JTable.java 1 Nov 2005 20:14:28 - @@ -1081,12 +1081,23 @@ { setColumnModel(createDefaultColumnModel()); autoCreate = true; - } -updateUI(); + } setSelectionModel(sm == null ? createDefaultSelectionModel() : sm); setModel(dm == null ? createDefaultDataModel() : dm); setAutoCreateColumnsFromModel(autoCreate); initializeLocalVars(); +// The following four lines properly set the lead selection indices. +// After this, the UI will handle the lead selection indices. +// FIXME: this should probably not be necessary, if the UI is installed +// before the TableModel is set then the UI will handle things on its +// own, but certain variables need to be set before the UI can be installed +// so we must get the correct order for all the method calls in this +// constructor. +selectionModel.setAnchorSelectionIndex(0); +selectionModel.setLeadSelectionIndex(0); +columnModel.getSelectionModel().setAnchorSelectionIndex(0); +columnModel.getSelectionModel().setLeadSelectionIndex(0); +updateUI(); } protected void initializeLocalVars() ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] FYI: WrappedPlainView additions make line-wrapping work!
I added a lot to WrappedPlainView (and fixed a bug in Utilities that I mentioned in a previous email) to make line-wrapping in JTextAreas actually work! Of course, when testing, I hardcoded into JTextArea that it's View should be of type WrappedPlainView so I could see the line wrapping working. This is incorrect and I didn't commit that. WrappedPlainView should be set as a JTextArea's View when setLineWrap(true) is called. Once this is working (soon), you'll be able to see the line-wrapping working. I also haven't done a whole lot of testing, just a one-time insertion of text and it wrapped properly, so I'll have to test (and fix) this much more. 2005-10-31 Anthony Balkissoon [EMAIL PROTECTED] * javax/swing/text/WrappedPlainView.java: (viewFactory): New field. (drawLine): New API method. (calculateBreakPosition): Update the metrics before calling Utilities methods. Fixed error in offset argument passed to the Utilities methods. (updateMetrics): New implementation method. (getPreferredSpan): New API method. (insertUpdate): Likewise. (removeUpdate): Likewise. (changedUpdate): Likewise. (WrappedLineCreator): New class. (paint): New API method. (setSize): New API method. (WrappedLine.paint): Implemented. (WrappedLine.getPreferredSpan): Don't update the metrics, this is now done in WrappedPlainView.paint. (WrappedLine.modelToView): Likewise. (WrappedLine.viewToModel): Likewise. --Tony Index: javax/swing/text/WrappedPlainView.java === RCS file: /cvsroot/classpath/classpath/javax/swing/text/WrappedPlainView.java,v retrieving revision 1.1 diff -u -r1.1 WrappedPlainView.java --- javax/swing/text/WrappedPlainView.java 25 Oct 2005 20:11:12 - 1.1 +++ javax/swing/text/WrappedPlainView.java 31 Oct 2005 20:38:02 - @@ -45,6 +45,8 @@ import java.awt.Rectangle; import java.awt.Shape; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentEvent.ElementChange; import javax.swing.text.Position.Bias; /** @@ -68,6 +70,9 @@ /** Whether or not to wrap on word boundaries **/ boolean wordWrap; + /** A ViewFactory that creates WrappedLines **/ + ViewFactory viewFactory = new WrappedLineCreator(); + /** * The instance returned by [EMAIL PROTECTED] #getLineBuffer()}. */ @@ -125,6 +130,27 @@ return 8; return ((Integer)tabSize).intValue(); } + + /** + * Draws a line of text, suppressing white space at the end and expanding + * tabs. Calls drawSelectedText and drawUnselectedText. + * @param p0 starting document position to use + * @param p1 ending document position to use + * @param g graphics context + * @param x starting x position + * @param y starting y position + */ + protected void drawLine(int p0, int p1, Graphics g, int x, int y) + { +try +{ + drawUnselectedText(g, x, y, p0, p1); +} +catch (BadLocationException ble) +{ + // shouldn't happen +} + } /** * Renders the range of text as selected text. Just paints the text @@ -202,6 +228,7 @@ { Container c = getContainer(); Rectangle alloc = c.getBounds(); +updateMetrics(); try { getDocument().getText(p0, p1 - p0, getLineBuffer()); @@ -214,11 +241,90 @@ if (wordWrap) return p0 + Utilities.getBreakLocation(lineBuffer, metrics, alloc.x, - alloc.x + alloc.width, this, p0); + alloc.x + alloc.width, this, 0); else + { return p0 + Utilities.getTabbedTextOffset(lineBuffer, metrics, alloc.x, - alloc.x + alloc.width, this, p0); + alloc.x + alloc.width, this, 0); + } + } + + void updateMetrics() + { +Container component = getContainer(); +metrics = component.getFontMetrics(component.getFont()); + } + + /** + * Determines the preferred span along the given axis. Implemented to + * cache the font metrics and then call the super classes method. + */ + public float getPreferredSpan (int axis) + { +updateMetrics(); +return super.getPreferredSpan(axis); + } + + /** + * Called when something was inserted. Overridden so that + * the view factory creates WrappedLine views. + */ + public void insertUpdate (DocumentEvent e, Shape a, ViewFactory f) + { +super.insertUpdate(e, a, viewFactory); + } + + /** + * Called when something is removed. Overridden so that + * the view factory creates WrappedLine views. + */ + public void removeUpdate (DocumentEvent e, Shape a, ViewFactory f) + { +super.removeUpdate(e, a, viewFactory); + } + + /** + * Called when the portion of the Document that this View
[cp-patches] FYI: fix for Component.requestFocus
This patch makes us pass gnu/testlet/java/awt/Component/requestFocus.java. requestFocus was throwing a NPE unexpectedly. When looking for our top-level ancestor, we should start with ourselves if we are Containers, and if not, then start with getParent(). Before we were just starting with getParent(). Also, if we find no top-level ancestor, we should just return (this is a standard != null check before continuing). 2005-10-28 Anthony Balkissoon [EMAIL PROTECTED] * java/awt/Component.java: (requestFocus): If this component is a Container, start here, not at its parent when looking for the top-level ancestor. If no top-level ancestor is found (parent == null), return. --Tony Index: java/awt/Component.java === RCS file: /cvsroot/classpath/classpath/java/awt/Component.java,v retrieving revision 1.81 diff -u -r1.81 Component.java --- java/awt/Component.java 19 Oct 2005 16:09:09 - 1.81 +++ java/awt/Component.java 28 Oct 2005 16:05:51 - @@ -3808,13 +3808,16 @@ { synchronized (getTreeLock ()) { -// Find this Component's top-level ancestor. -Container parent = getParent (); - +// Find this Component's top-level ancestor. +Container parent = (this instanceof Container) ? (Container) this + : getParent(); while (parent != null !(parent instanceof Window)) parent = parent.getParent (); +if (parent == null) + return; + Window toplevel = (Window) parent; if (toplevel.isFocusableWindow ()) { ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches