/** * Provides a way to determine the next visually represented model location at which one might * place a caret. Some views may not be visible, they might not be in the same order found in the * model, or they just might not allow access to some of the locations in the model. * * <p>NOTE: You should only call this method if the passed-in <code>javax.swing.text.View</code> * is an instance of {@link TokenOrientedView} and <code>javax.swing.text.TabExpander</code>; * otherwise, a <code>ClassCastException</code> could be thrown. * * @param pos the position to convert >= 0 * @param a the allocated region in which to render * @param direction the direction from the current position that can be thought of as the arrow * keys typically found on a keyboard. This will be one of the following values: * <ul> * <li>SwingConstants.WEST * <li>SwingConstants.EAST * <li>SwingConstants.NORTH * <li>SwingConstants.SOUTH * </ul> * * @return the location within the model that best represents the next location visual position * @exception BadLocationException * @exception IllegalArgumentException if <code>direction</code> doesn't have one of the legal * values above */ public static int getNextVisualPositionFrom( int pos, Position.Bias b, Shape a, int direction, Position.Bias[] biasRet, View view) throws BadLocationException { biasRet[0] = Position.Bias.Forward; // Do we want the "next position" above, below, to the left or right? switch (direction) { case NORTH: case SOUTH: if (pos == -1) { pos = (direction == NORTH) ? Math.max(0, view.getEndOffset() - 1) : view.getStartOffset(); break; } RSyntaxTextArea target = (RSyntaxTextArea) view.getContainer(); Caret c = (target != null) ? target.getCaret() : null; // YECK! Ideally, the x location from the magic caret // position would be passed in. Point mcp; if (c != null) mcp = c.getMagicCaretPosition(); else mcp = null; int x; if (mcp == null) { Rectangle loc = target.modelToView(pos); x = (loc == null) ? 0 : loc.x; } else { x = mcp.x; } if (direction == NORTH) pos = getPositionAbove(target, pos, x, (TabExpander) view); else pos = getPositionBelow(target, pos, x, (TabExpander) view); break; case WEST: if (pos == -1) pos = Math.max(0, view.getEndOffset() - 1); else pos = Math.max(0, pos - 1); break; case EAST: if (pos == -1) pos = view.getStartOffset(); else pos = Math.min(pos + 1, view.getDocument().getLength()); break; default: throw new IllegalArgumentException("Bad direction: " + direction); } return pos; }