Hi, the following patch implements the above mentioned method in View and its EastWest and NorthSouth cousins in CompositeView. *However* I could not provide an implementation I am feeling 100% sure about. It works for our JTextField and JTextArea with and without line wrap but I am sure that it will lead to problems some day: If someone knows the JDK's code and writes a subclass of CompositeView that depends on their implementation it will break on our's.
Therefore I decided to document my intentions and assumptions when implementing
the two CompositeView methods and provided a PR[0][1] for each one. I hope that
this will help to get the implementation right when a free application shows up
that depends on the proper behavior.
The getNextVisualPositionFrom methods are very important for a proper cursor
navigation implementation which I described in PR 27220. This patch is the first
part to fix it.
The ChangeLog:
2006-04-28 Robert Schuster <[EMAIL PROTECTED]>
* javax/swing/text/View.java:
(getNextVisualPositionFrom): Rewritten.
* javax/swing/text/CompositeView.java:
(getNextEastWestVisualPositionFrom): Partly implemented.
(getNextNorthSouthVisualPositionFrom): Partly implemented.
cya
Robert
[0] - http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27345
[1] - http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27346
Index: javax/swing/text/View.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/View.java,v
retrieving revision 1.30
diff -u -r1.30 View.java
--- javax/swing/text/View.java 1 Mar 2006 20:39:49 -0000 1.30
+++ javax/swing/text/View.java 28 Apr 2006 10:25:08 -0000
@@ -1,5 +1,5 @@
/* View.java --
- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -733,23 +733,35 @@
throws BadLocationException
{
int ret = pos;
+ Rectangle r;
+
switch (d)
{
- case WEST:
- ret = pos - 1;
- break;
case EAST:
- ret = pos + 1;
+ // TODO: take component orientation into account?
+ // Note: If pos is below zero the implementation will return
+ // pos + 1 regardless of whether that value is a correct offset
+ // in the document model. However this is what the RI does.
+ ret = Math.min(pos + 1, getEndOffset());
+ break;
+ case WEST:
+ // TODO: take component orientation into account?
+ ret = Math.max(pos - 1, getStartOffset());
break;
case NORTH:
- // TODO: Implement this
+ // Try to find a suitable offset by examining the area above.
+ r = modelToView(pos, a, b).getBounds();
+ ret = viewToModel(r.x, r.y - 1, a, biasRet);
break;
case SOUTH:
- // TODO: Implement this
+ // Try to find a suitable offset by examining the area below.
+ r = modelToView(pos, a, b).getBounds();
+ ret = viewToModel(r.x + r.width, r.y + r.height, a, biasRet);
break;
default:
throw new IllegalArgumentException("Illegal value for d");
}
+
return ret;
}
}
Index: javax/swing/text/CompositeView.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/CompositeView.java,v
retrieving revision 1.17
diff -u -r1.17 CompositeView.java
--- javax/swing/text/CompositeView.java 1 Apr 2006 15:22:07 -0000 1.17
+++ javax/swing/text/CompositeView.java 28 Apr 2006 10:25:08 -0000
@@ -633,8 +633,51 @@
Position.Bias[] biasRet)
throws BadLocationException
{
- // FIXME: Implement this correctly.
- return pos;
+ // TODO: It is unknown to me how this method has to be implemented and
+ // there is no specification telling me how to do it properly. Therefore
+ // the implementation was done for cases that are known.
+ //
+ // If this method ever happens to act silly for your particular case then
+ // it is likely that it is a cause of not knowing about your case when it
+ // was implemented first. You are free to fix the behavior.
+ //
+ // Here are the assumptions that lead to the implementation:
+ // If direction is NORTH chose the View preceding the one that contains the
+ // offset 'pos' (imagine the views are stacked on top of each other where
+ // the top is 0 and the bottom is getViewCount()-1.
+ // Consecutively when the direction is SOUTH the View following the one
+ // the offset 'pos' lies in is questioned.
+ //
+ // This limitation is described as PR 27345.
+ int index = getViewIndex(pos, b);
+ View v = null;
+
+ if (index == -1)
+ return pos;
+
+ switch (direction)
+ {
+ case NORTH:
+ // If we cannot calculate a proper offset return the one that was
+ // provided.
+ if (index <= 0)
+ return pos;
+
+ v = getView(index - 1);
+ break;
+ case SOUTH:
+ // If we cannot calculate a proper offset return the one that was
+ // provided.
+ if (index >= getViewCount() - 1)
+ return pos;
+
+ v = getView(index + 1);
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+
+ return v.getNextVisualPositionFrom(pos, b, a, direction, biasRet);
}
/**
@@ -667,8 +710,55 @@
Position.Bias[] biasRet)
throws BadLocationException
{
- // FIXME: Implement this correctly.
- return pos;
+ // TODO: It is unknown to me how this method has to be implemented and
+ // there is no specification telling me how to do it properly. Therefore
+ // the implementation was done for cases that are known.
+ //
+ // If this method ever happens to act silly for your particular case then
+ // it is likely that it is a cause of not knowing about your case when it
+ // was implemented first. You are free to fix the behavior.
+ //
+ // Here are the assumptions that lead to the implementation:
+ // If direction is EAST increase the offset by one and ask the View to
+ // which that index belong to calculate the 'next visual position'.
+ // If the direction is WEST do the same with offset 'pos' being decreased
+ // by one.
+ // This behavior will fail in a right-to-left or bidi environment!
+ //
+ // This limitation is described as PR 27346.
+ int index;
+
+ View v = null;
+
+ switch (direction)
+ {
+ case EAST:
+ index = getViewIndex(pos + 1, b);
+ // If we cannot calculate a proper offset return the one that was
+ // provided.
+ if (index == -1)
+ return pos;
+
+ v = getView(index);
+ break;
+ case WEST:
+ index = getViewIndex(pos - 1, b);
+ // If we cannot calculate a proper offset return the one that was
+ // provided.
+ if (index == -1)
+ return pos;
+
+ v = getView(index);
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+
+ return v.getNextVisualPositionFrom(pos,
+ b,
+ a,
+ direction,
+ biasRet);
}
/**
signature.asc
Description: OpenPGP digital signature
