8132119: Provide public API for text related methods in SwingUtilities2
Reviewed-by: prr, serb
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/TextUI.java Mon Jul 04 17:10:29 2016 +0530
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/TextUI.java Tue Jul 05 09:26:34 2016 +0300
@@ -24,11 +24,10 @@
*/
package javax.swing.plaf;
-import javax.swing.Action;
-import javax.swing.BoundedRangeModel;
import java.awt.Point;
import java.awt.Rectangle;
-import java.awt.Insets;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
import javax.swing.text.*;
/**
@@ -64,6 +63,27 @@
public abstract Rectangle modelToView(JTextComponent t, int pos, Position.Bias bias) throws BadLocationException;
/**
+ * Converts the given location in the model to a place in
+ * the view coordinate system.
+ *
+ * @implSpec This implementation calls
+ * {@link #modelToView(JTextComponent, int, Position.Bias) modelToView(t, pos, bias)}.
+ *
+ * @param t the text component for which this UI is installed
+ * @param pos the local location in the model to translate {@code >= 0}
+ * @param bias the bias for the position
+ * @return the coordinates as a {@code Rectangle2D}
+ * @exception BadLocationException if the given position does not
+ * represent a valid location in the associated document
+ *
+ * @since 9
+ */
+ public Rectangle2D modelToView2D(JTextComponent t, int pos, Position.Bias bias)
+ throws BadLocationException {
+ return modelToView(t, pos, bias);
+ }
+
+ /**
* Converts the given place in the view coordinate system
* to the nearest representative location in the model.
*
@@ -95,6 +115,33 @@
Position.Bias[] biasReturn);
/**
+ * Provides a mapping from the view coordinate space to the logical
+ * coordinate space of the model.
+ *
+ * @implSpec This implementation calls
+ * {@link #viewToModel(JTextComponent, Point, Position.Bias[])
+ * viewToModel(t, new Point((int) pt.getX(), (int) pt.getY()),
+ * biasReturn)}.
+ *
+ * @param t the text component for which this UI is installed
+ * @param pt the location in the view to translate.
+ * @param biasReturn
+ * filled in by this method to indicate whether
+ * the point given is closer to the previous or the next
+ * character in the model
+ *
+ * @return the location within the model that best represents the
+ * given point in the view {@code >= 0}
+ *
+ * @since 9
+ */
+ public int viewToModel2D(JTextComponent t, Point2D pt,
+ Position.Bias[] biasReturn) {
+ return viewToModel(t, new Point((int) pt.getX(), (int) pt.getY()),
+ biasReturn);
+ }
+
+ /**
* Provides a way to determine the next visually represented model
* location that 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
@@ -179,4 +226,22 @@
public String getToolTipText(JTextComponent t, Point pt) {
return null;
}
+ /**
+ * Returns the string to be used as the tooltip at the passed in location.
+ *
+ * @implSpec This implementation calls
+ * {@link #getToolTipText(JTextComponent, Point)
+ * getToolTipText(t, new Point((int) pt.getX(), (int) pt.getY())))}.
+ *
+ * @param t the text component for which this UI is installed
+ * @param pt a {@code Point} specifying location for which to get a tooltip
+ * @return a {@code String} containing the tooltip
+ *
+ * @see javax.swing.text.JTextComponent#getToolTipText
+ *
+ * @since 9
+ */
+ public String getToolTipText2D(JTextComponent t, Point2D pt) {
+ return getToolTipText(t, new Point((int) pt.getX(), (int) pt.getY()));
+ }
}
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicGraphicsUtils.java Mon Jul 04 17:10:29 2016 +0530
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicGraphicsUtils.java Tue Jul 05 09:26:34 2016 +0300
@@ -31,10 +31,10 @@
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
+import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.Toolkit;
-import java.awt.event.KeyEvent;
import java.awt.event.InputEvent;
import sun.swing.SwingUtilities2;
@@ -386,4 +386,102 @@
return (event.getModifiers() &
Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) != 0;
}
+
+ /**
+ * Draws the given string at the specified location using text properties
+ * and anti-aliasing hints from the provided component.
+ * Nothing is drawn for the null string.
+ *
+ * @param c the component that will display the string, may be null
+ * @param g the graphics context, must not be null
+ * @param string the string to display, may be null
+ * @param x the x coordinate to draw the text at
+ * @param y the y coordinate to draw the text at
+ * @throws NullPointerException if the specified {@code g} is {@code null}
+ *
+ * @since 9
+ */
+ public static void drawString(JComponent c, Graphics2D g, String string,
+ float x, float y) {
+ SwingUtilities2.drawString(c, g, string, (int) x, (int) y);
+ }
+
+ /**
+ * Draws the given string at the specified location underlining
+ * the specified character. The provided component is used to query text
+ * properties and anti-aliasing hints.
+ * <p>
+ * The {@code underlinedIndex} parameter points to a char value
+ * (Unicode code unit) in the given string.
+ * If the char value specified at the underlined index is in
+ * the high-surrogate range and the char value at the following index is in
+ * the low-surrogate range then the supplementary character corresponding
+ * to this surrogate pair is underlined.
+ * <p>
+ * No character is underlined if the index is negative or greater
+ * than the string length {@code (index < 0 || index >= string.length())}
+ * or if the char value specified at the given index
+ * is in the low-surrogate range.
+ *
+ * @param c the component that will display the string, may be null
+ * @param g the graphics context, must not be null
+ * @param string the string to display, may be null
+ * @param underlinedIndex index of a a char value (Unicode code unit)
+ * in the string to underline
+ * @param x the x coordinate to draw the text at
+ * @param y the y coordinate to draw the text at
+ * @throws NullPointerException if the specified {@code g} is {@code null}
+ *
+ * @see #getStringWidth
+ *
+ * @since 9
+ */
+ public static void drawStringUnderlineCharAt(JComponent c, Graphics2D g,
+ String string, int underlinedIndex, float x, float y) {
+ SwingUtilities2.drawStringUnderlineCharAt(c, g, string, underlinedIndex,
+ (int) x, (int) y);
+ }
+
+ /**
+ * Clips the passed in string to the space provided.
+ * The provided component is used to query text properties and anti-aliasing hints.
+ * The unchanged string is returned if the space provided is greater than
+ * the string width.
+ *
+ * @param c the component, may be null
+ * @param fm the FontMetrics used to measure the string width, must be
+ * obtained from the correct font and graphics. Must not be null.
+ * @param string the string to clip, may be null
+ * @param availTextWidth the amount of space that the string can be drawn in
+ * @return the clipped string that fits in the provided space, an empty
+ * string if the given string argument is {@code null} or empty
+ * @throws NullPointerException if the specified {@code fm} is {@code null}
+ *
+ * @see #getStringWidth
+ *
+ * @since 9
+ */
+ public static String getClippedString(JComponent c, FontMetrics fm,
+ String string, int availTextWidth) {
+ return SwingUtilities2.clipStringIfNecessary(c, fm, string, availTextWidth);
+ }
+
+ /**
+ * Returns the width of the passed in string using text properties
+ * and anti-aliasing hints from the provided component.
+ * If the passed string is {@code null}, returns zero.
+ *
+ * @param c the component, may be null
+ * @param fm the FontMetrics used to measure the advance string width, must
+ * be obtained from the correct font and graphics. Must not be null.
+ * @param string the string to get the advance width of, may be null
+ * @return the advance width of the specified string, zero is returned for
+ * {@code null} string
+ * @throws NullPointerException if the specified {@code fm} is {@code null}
+ *
+ * @since 9
+ */
+ public static float getStringWidth(JComponent c, FontMetrics fm, String string) {
+ return SwingUtilities2.stringWidth(c, fm, string);
+ }
}
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/PasswordView.java Mon Jul 04 17:10:29 2016 +0530
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/PasswordView.java Tue Jul 05 09:26:34 2016 +0300
@@ -139,6 +139,26 @@
}
/**
+ * Renders the echo character, or whatever graphic should be used
+ * to display the password characters. The color in the Graphics
+ * object is set to the appropriate foreground color for selected
+ * or unselected text.
+ *
+ * @implSpec This implementation calls
+ * {@link #drawEchoCharacter(Graphics, int, int, char)
+ * drawEchoCharacter((Graphics) g, (int) x, (int) y, c)}.
+ *
+ * @param g the graphics context
+ * @param x the starting X coordinate {@code >= 0}
+ * @param y the starting Y coordinate {@code >= 0}
+ * @param c the echo character
+ * @return the updated X position {@code >= 0}
+ */
+ protected float drawEchoCharacter(Graphics2D g, float x, float y, char c) {
+ return drawEchoCharacter((Graphics) g, (int) x, (int) y, c);
+ }
+
+ /**
* Provides a mapping from the document model coordinate space
* to the coordinate space of the view mapped to it.
*
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/PlainView.java Mon Jul 04 17:10:29 2016 +0530
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/PlainView.java Tue Jul 05 09:26:34 2016 +0300
@@ -60,6 +60,17 @@
}
/**
+ * Returns the tab size set for the document, defaulting to 8.
+ *
+ * @implSpec This implementation calls {@link #getTabSize() getTabSize()}.
+ *
+ * @return the tab size
+ */
+ protected float getFractionalTabSize() {
+ return getTabSize();
+ }
+
+ /**
* Renders a line of text, suppressing whitespace at the end
* and expanding any tabs. This is implemented to make calls
* to the methods <code>drawUnselectedText</code> and
@@ -93,6 +104,28 @@
}
}
+ /**
+ * Renders a line of text, suppressing whitespace at the end
+ * and expanding any tabs. This is implemented to make calls
+ * to the methods {@code drawUnselectedText} and
+ * {@code drawSelectedText} so that the way selected and
+ * unselected text are rendered can be customized.
+ *
+ * @implSpec This implementation calls
+ * {@link #drawLine(int, Graphics, int, int)
+ * drawLine(lineIndex, (Graphics)g, (int) x, (int) y)}.
+ *
+ * @param lineIndex the line to draw {@code >= 0}
+ * @param g the {@code Graphics} context
+ * @param x the starting X position {@code >= 0}
+ * @param y the starting Y position {@code >= 0}
+ * @see #drawUnselectedText
+ * @see #drawSelectedText
+ */
+ protected void drawLine(int lineIndex, Graphics2D g, float x, float y) {
+ drawLine(lineIndex, (Graphics)g, (int) x, (int) y);
+ }
+
private int drawElement(int lineIndex, Element elem, Graphics g, int x, int y) throws BadLocationException {
int p0 = elem.getStartOffset();
int p1 = elem.getEndOffset();
@@ -157,6 +190,27 @@
}
/**
+ * Renders the given range in the model as normal unselected
+ * text. Uses the foreground or disabled color to render the text.
+ *
+ * @implSpec This implementation calls
+ * {@link #drawUnselectedText(Graphics, int, int, int, int)
+ * drawUnselectedText((Graphics)g, (int) x, (int) y, p0, p1)}.
+ *
+ * @param g the graphics context
+ * @param x the starting X coordinate {@code >= 0}
+ * @param y the starting Y coordinate {@code >= 0}
+ * @param p0 the beginning position in the model {@code >= 0}
+ * @param p1 the ending position in the model {@code >= 0}
+ * @return the X location of the end of the range {@code >= 0}
+ * @exception BadLocationException if the range is invalid
+ */
+ protected float drawUnselectedText(Graphics2D g, float x, float y,
+ int p0, int p1) throws BadLocationException {
+ return drawUnselectedText((Graphics)g, (int) x, (int) y, p0, p1);
+ }
+
+ /**
* Renders the given range in the model as selected text. This
* is implemented to render the text in the color specified in
* the hosting component. It assumes the highlighter will render
@@ -182,6 +236,30 @@
}
/**
+ * Renders the given range in the model as selected text. This
+ * is implemented to render the text in the color specified in
+ * the hosting component. It assumes the highlighter will render
+ * the selected background.
+ *
+ * @implSpec This implementation calls
+ * {@link #drawSelectedText(Graphics, int, int, int, int)
+ * drawSelectedText((Graphics)g, (int) x, (int) y, p0, p1)}.
+ *
+ * @param g the graphics context
+ * @param x the starting X coordinate {@code >= 0}
+ * @param y the starting Y coordinate {@code >= 0}
+ * @param p0 the beginning position in the model {@code >= 0}
+ * @param p1 the ending position in the model {@code >= 0}
+ * @return the location of the end of the range
+ * @exception BadLocationException if the range is invalid
+ */
+
+ protected float drawSelectedText(Graphics2D g, float x,
+ float y, int p0, int p1) throws BadLocationException {
+ return drawSelectedText((Graphics)g, (int) x, (int) y, p0, p1);
+ }
+
+ /**
* Gives access to a buffer that can be used to fetch
* text from the associated document.
*
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/Utilities.java Mon Jul 04 17:10:29 2016 +0530
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/Utilities.java Tue Jul 05 09:26:34 2016 +0300
@@ -86,6 +86,27 @@
/**
* Draws the given text, expanding any tabs that are contained
+ * using the given tab expansion technique.
+ *
+ * @param s the source of the text
+ * @param x the X origin {@code >= 0}
+ * @param y the Y origin {@code >= 0}
+ * @param g the graphics context
+ * @param e how to expand the tabs. If this value is null,
+ * tabs will be expanded as a space character.
+ * @param startOffset starting offset of the text in the document {@code >= 0}
+ * @return the X location at the end of the rendered text
+ */
+ public static final float drawTabbedText(Segment s, float x, float y,
+ Graphics2D g,
+ TabExpander e,
+ int startOffset)
+ {
+ return drawTabbedText(s, (int) x, (int) y, (Graphics) g, e, startOffset);
+ }
+
+ /**
+ * Draws the given text, expanding any tabs that are contained
* using the given tab expansion technique. This particular
* implementation renders in a 1.1 style coordinate system
* where ints are used and 72dpi is assumed.
@@ -208,6 +229,23 @@
return getTabbedTextWidth(null, s, metrics, x, e, startOffset, null);
}
+ /**
+ * Determines the width of the given segment of text taking tabs
+ * into consideration.
+ *
+ * @param s the source of the text
+ * @param metrics the font metrics to use for the calculation
+ * @param x the X origin {@code >= 0}
+ * @param e how to expand the tabs. If this value is null,
+ * tabs will be expanded as a space character.
+ * @param startOffset starting offset of the text in the document {@code >= 0}
+ * @return the width of the text
+ */
+ public static final float getTabbedTextWidth(Segment s, FontMetrics metrics,
+ float x, TabExpander e,
+ int startOffset) {
+ return getTabbedTextWidth(s, metrics, (int) x, e, startOffset);
+ }
// In addition to the previous method it can extend spaces for
// justification.
@@ -336,6 +374,34 @@
return getTabbedTextOffset(null, s, metrics, x0, x, e, startOffset, round, null);
}
+ /**
+ * Determines the relative offset into the given text that
+ * best represents the given span in the view coordinate
+ * system.
+ *
+ * @param s the source of the text
+ * @param metrics the font metrics to use for the calculation
+ * @param x0 the starting view location representing the start
+ * of the given text {@code >= 0}.
+ * @param x the target view location to translate to an
+ * offset into the text {@code >= 0}.
+ * @param e how to expand the tabs. If this value is null,
+ * tabs will be expanded as a space character.
+ * @param startOffset starting offset of the text in the document {@code >= 0}
+ * @param round whether or not to round
+ * @return the offset into the text {@code >= 0}
+ */
+ public static final int getTabbedTextOffset(Segment s,
+ FontMetrics metrics,
+ float x0, float x,
+ TabExpander e,
+ int startOffset,
+ boolean round)
+ {
+ return getTabbedTextOffset(null, s, metrics, (int) x0, (int) x, e,
+ startOffset, round, null);
+ }
+
// In addition to the previous method it can extend spaces for
// justification.
//
@@ -499,6 +565,26 @@
}
/**
+ * Determine where to break the given text to fit
+ * within the given span. This tries to find a word boundary.
+ * @param s the source of the text
+ * @param metrics the font metrics to use for the calculation
+ * @param x0 the starting view location representing the start
+ * of the given text.
+ * @param x the target view location to translate to an
+ * offset into the text.
+ * @param e how to expand the tabs. If this value is null,
+ * tabs will be expanded as a space character.
+ * @param startOffset starting offset in the document of the text
+ * @return the offset into the given text
+ */
+ public static final int getBreakLocation(Segment s, FontMetrics metrics,
+ float x0, float x, TabExpander e,
+ int startOffset) {
+ return getBreakLocation(s, metrics, (int) x0, (int) x, e, startOffset);
+ }
+
+ /**
* Determines the starting row model position of the row that contains
* the specified model position. The component given must have a
* size to compute the result. If the component doesn't have a size
@@ -598,6 +684,24 @@
/**
* Determines the position in the model that is closest to the given
+ * view location in the row above. The component given must have a
+ * size to compute the result. If the component doesn't have a size
+ * a value of -1 will be returned.
+ *
+ * @param c the editor
+ * @param offs the offset in the document {@code >= 0}
+ * @param x the X coordinate {@code >= 0}
+ * @return the position {@code >= 0} if the request can be computed, otherwise
+ * a value of -1 will be returned.
+ * @exception BadLocationException if the offset is out of range
+ */
+ public static final int getPositionAbove(JTextComponent c, int offs, float x)
+ throws BadLocationException {
+ return getPositionAbove(c, offs, (int) x);
+ }
+
+ /**
+ * Determines the position in the model that is closest to the given
* view location in the row below. The component given must have a
* size to compute the result. If the component doesn't have a size
* a value of -1 will be returned.
@@ -635,6 +739,24 @@
}
/**
+ * Determines the position in the model that is closest to the given
+ * view location in the row below. The component given must have a
+ * size to compute the result. If the component doesn't have a size
+ * a value of -1 will be returned.
+ *
+ * @param c the editor
+ * @param offs the offset in the document {@code >= 0}
+ * @param x the X coordinate {@code >= 0}
+ * @return the position {@code >= 0} if the request can be computed, otherwise
+ * a value of -1 will be returned.
+ * @exception BadLocationException if the offset is out of range
+ */
+ public static final int getPositionBelow(JTextComponent c, int offs, float x)
+ throws BadLocationException {
+ return getPositionBelow(c, offs, (int) x);
+ }
+
+ /**
* Determines the start of a word for the given model location.
* Uses BreakIterator.getWordInstance() to actually get the words.
*
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/WrappedPlainView.java Mon Jul 04 17:10:29 2016 +0530
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/WrappedPlainView.java Tue Jul 05 09:26:34 2016 +0300
@@ -87,6 +87,17 @@
}
/**
+ * Returns the tab size set for the document, defaulting to 8.
+ *
+ * @implSpec This implementation calls {@link #getTabSize() getTabSize()}.
+ *
+ * @return the tab size
+ */
+ protected float getFractionalTabSize() {
+ return getTabSize();
+ }
+
+ /**
* Renders a line of text, suppressing whitespace at the end
* and expanding any tabs. This is implemented to make calls
* to the methods <code>drawUnselectedText</code> and
@@ -125,6 +136,29 @@
}
}
+ /**
+ * Renders a line of text, suppressing whitespace at the end
+ * and expanding any tabs. This is implemented to make calls
+ * to the methods <code>drawUnselectedText</code> and
+ * <code>drawSelectedText</code> so that the way selected and
+ * unselected text are rendered can be customized.
+ *
+ * @implSpec This implementation calls
+ * {@link #drawLine(int, int, Graphics, int, int)
+ * drawLine(p0, p1, (Graphics) g, (int) x, (int) y)}.
+ *
+ * @param p0 the starting document location to use >= 0
+ * @param p1 the ending document location to use >= p1
+ * @param g the graphics context
+ * @param x the starting X position >= 0
+ * @param y the starting Y position >= 0
+ * @see #drawUnselectedText
+ * @see #drawSelectedText
+ */
+ protected void drawLine(int p0, int p1, Graphics2D g, float x, float y) {
+ drawLine(p0, p1, (Graphics) g, (int) x, (int) y);
+ }
+
private int drawText(Element elem, int p0, int p1, Graphics g, int x, int y) throws BadLocationException {
p1 = Math.min(getDocument().getLength(), p1);
AttributeSet attr = elem.getAttributes();
@@ -184,6 +218,26 @@
}
/**
+ * Renders the given range in the model as normal unselected
+ * text.
+ *
+ * @implSpec This implementation calls
+ * {@link #drawUnselectedText(Graphics, int, int, int, int)
+ * drawUnselectedText((Graphics)g, (int) x, (int) y, p0, p1)}.
+ *
+ * @param g the graphics context
+ * @param x the starting X coordinate >= 0
+ * @param y the starting Y coordinate >= 0
+ * @param p0 the beginning position in the model >= 0
+ * @param p1 the ending position in the model >= p0
+ * @return the X location of the end of the range >= 0
+ * @exception BadLocationException if the range is invalid
+ */
+ protected float drawUnselectedText(Graphics2D g, float x, float y,
+ int p0, int p1) throws BadLocationException {
+ return drawUnselectedText((Graphics) g, (int) x, (int) y, p0, p1);
+ }
+ /**
* Renders the given range in the model as selected text. This
* is implemented to render the text in the color specified in
* the hosting component. It assumes the highlighter will render
@@ -209,6 +263,28 @@
}
/**
+ * Renders the given range in the model as selected text. This
+ * is implemented to render the text in the color specified in
+ * the hosting component. It assumes the highlighter will render
+ * the selected background.
+ *
+ * @implSpec This implementation calls
+ * {@link #drawSelectedText(Graphics, int, int, int, int)
+ * drawSelectedText((Graphics)g, (int) x, (int) y, p0, p1)}.
+ *
+ * @param g the graphics context
+ * @param x the starting X coordinate >= 0
+ * @param y the starting Y coordinate >= 0
+ * @param p0 the beginning position in the model >= 0
+ * @param p1 the ending position in the model >= p0
+ * @return the location of the end of the range.
+ * @exception BadLocationException if the range is invalid
+ */
+ protected float drawSelectedText(Graphics2D g, float x, float y,
+ int p0, int p1) throws BadLocationException {
+ return drawSelectedText((Graphics) g, (int) x, (int) y, p0, p1);
+ }
+ /**
* Gives access to a buffer that can be used to fetch
* text from the associated document.
*