下面列出了怎么用java.text.AttributedCharacterIterator的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* finds attributes with regards to char index in this
* AttributedCharacterIterator, and puts them in a vector
*
* @param iterator
* @return a vector, each entry in this vector are of type FieldContainer ,
* which stores start and end indexes and an attribute this range
* has
*/
private static List<FieldContainer> findFields(AttributedCharacterIterator iterator) {
List<FieldContainer> result = new ArrayList<FieldContainer>();
while (iterator.getIndex() != iterator.getEndIndex()) {
int start = iterator.getRunStart();
int end = iterator.getRunLimit();
Iterator it = iterator.getAttributes().keySet().iterator();
while (it.hasNext()) {
AttributedCharacterIterator.Attribute attribute = (AttributedCharacterIterator.Attribute) it
.next();
Object value = iterator.getAttribute(attribute);
result.add(new FieldContainer(start, end, attribute, value));
// System.out.println(start + " " + end + ": " + attribute + ",
// " + value );
// System.out.println("v.add(new FieldContainer(" + start +"," +
// end +"," + attribute+ "," + value+ "));");
}
iterator.setIndex(end);
}
return result;
}
protected HSSFRichTextString getRichTextString(JRStyledText styledText, short forecolor, JRFont defaultFont, Locale locale)
{
String text = styledText.getText();
HSSFRichTextString richTextStr = new HSSFRichTextString(text);
int runLimit = 0;
AttributedCharacterIterator iterator = styledText.getAttributedString().getIterator();
while(runLimit < styledText.length() && (runLimit = iterator.getRunLimit()) <= styledText.length())
{
Map<Attribute,Object> attributes = iterator.getAttributes();
JRFont runFont = attributes.isEmpty()? defaultFont : new JRBaseFont(attributes);
short runForecolor = attributes.get(TextAttribute.FOREGROUND) != null ?
getWorkbookColor((Color)attributes.get(TextAttribute.FOREGROUND)).getIndex() :
forecolor;
HSSFFont font = getLoadedFont(runFont, runForecolor, attributes, locale);
richTextStr.applyFont(iterator.getIndex(), runLimit, font);
iterator.setIndex(runLimit);
}
return richTextStr;
}
/**
* Gets kerning offset for two characters of the font
*
* @param font Font
* @param char1 First character
* @param char2 Second character
* @return offset
*/
public static int getFontCharsKerning(Font font, char char1, char char2) {
char[] chars = new char[]{char1, char2};
Map<AttributedCharacterIterator.Attribute, Object> withKerningAttrs = new HashMap<>();
withKerningAttrs.put(TextAttribute.FONT, font);
withKerningAttrs.put(TextAttribute.KERNING, TextAttribute.KERNING_ON);
Font withKerningFont = Font.getFont(withKerningAttrs);
GlyphVector withKerningVector = withKerningFont.layoutGlyphVector(getFontRenderContext(withKerningFont), chars, 0, chars.length, Font.LAYOUT_LEFT_TO_RIGHT);
int withKerningX = withKerningVector.getGlyphLogicalBounds(1).getBounds().x;
Map<AttributedCharacterIterator.Attribute, Object> noKerningAttrs = new HashMap<>();
noKerningAttrs.put(TextAttribute.FONT, font);
noKerningAttrs.put(TextAttribute.KERNING, 0);
Font noKerningFont = Font.getFont(noKerningAttrs);
GlyphVector noKerningVector = noKerningFont.layoutGlyphVector(getFontRenderContext(noKerningFont), chars, 0, chars.length, Font.LAYOUT_LEFT_TO_RIGHT);
int noKerningX = noKerningVector.getGlyphLogicalBounds(1).getBounds().x;
return withKerningX - noKerningX;
}
private List<StyleAttributeInterval> getOutlineIntervals(int from, int to) {
StyleAttribute outlineAttr = StyleAttribute.OUTLINE;
List<StyleAttributeInterval> outlines = new java.util.ArrayList<StyleAttributeInterval>();
int[] intervals = getAttributeIntervals(from, to, outlineAttr);
AttributedCharacterIterator aci = iterator;
int savedIndex = aci.getIndex();
for (int i = 0, n = intervals.length / 2; i < n; ++i) {
int s = start + intervals[i*2 + 0];
int e = start + intervals[i*2 + 1];
aci.setIndex(s);
Object v = aci.getAttribute(outlineAttr);
if (v != null)
outlines.add(new StyleAttributeInterval(outlineAttr, v, s, e));
}
aci.setIndex(savedIndex);
if (outlines.isEmpty() && (outline != null) && !outline.equals(defaults.getOutline()))
outlines.add(new StyleAttributeInterval(outlineAttr, outline, start + from, start + to));
return outlines;
}
/**
* 12.1.6 PartitionDateTimePattern ( dateTimeFormat, x )
*
* @param dateTimeFormat
* the date format object
* @param date
* the date object
* @return the formatted date-time object
*/
private static List<Map.Entry<String, String>> PartitionDateTimePattern(DateTimeFormatObject dateTimeFormat,
Date date) {
ArrayList<Map.Entry<String, String>> parts = new ArrayList<>();
DateFormat dateFormat = dateTimeFormat.getDateFormat();
AttributedCharacterIterator iterator = dateFormat.formatToCharacterIterator(date);
StringBuilder sb = new StringBuilder();
for (char ch = iterator.first(); ch != CharacterIterator.DONE; ch = iterator.next()) {
sb.append(ch);
if (iterator.getIndex() + 1 == iterator.getRunLimit()) {
Iterator<Attribute> keyIterator = iterator.getAttributes().keySet().iterator();
String key;
if (keyIterator.hasNext()) {
key = fieldToString((DateFormat.Field) keyIterator.next());
} else {
key = "literal";
}
String value = sb.toString();
sb.setLength(0);
parts.add(new AbstractMap.SimpleImmutableEntry<>(key, value));
}
}
return parts;
}
/**
* Create a TextLine from the text. chars is just the text in the iterator.
*/
public static TextLine standardCreateTextLine(FontRenderContext frc,
AttributedCharacterIterator text,
char[] chars,
float[] baselineOffsets) {
StyledParagraph styledParagraph = new StyledParagraph(text, chars);
Bidi bidi = new Bidi(text);
if (bidi.isLeftToRight()) {
bidi = null;
}
int layoutFlags = 0; // no extra info yet, bidi determines run and line direction
TextLabelFactory factory = new TextLabelFactory(frc, chars, bidi, layoutFlags);
boolean isDirectionLTR = true;
if (bidi != null) {
isDirectionLTR = bidi.baseIsLeftToRight();
}
return createLineFromText(chars, styledParagraph, factory, isDirectionLTR, baselineOffsets);
}
static Font getFontAtCurrentPos(AttributedCharacterIterator aci) {
Object value = aci.getAttribute(TextAttribute.FONT);
if (value != null) {
return (Font) value;
}
if (aci.getAttribute(TextAttribute.FAMILY) != null) {
return Font.getFont(aci.getAttributes());
}
int ch = CodePointIterator.create(aci).next();
if (ch != CodePointIterator.DONE) {
FontResolver resolver = FontResolver.getInstance();
return resolver.getFont(resolver.getFontIndex(ch), aci.getAttributes());
}
return null;
}
/**
* Returns the value of the named attribute for the current character.
* Returns null if the attribute is not defined.
* @param attribute the key of the attribute whose value is requested.
*/
public Object getAttribute(AttributedCharacterIterator.Attribute attribute) {
int pos = toModelPosition(getIndex());
int childIndex = v.getViewIndex(pos, Position.Bias.Forward);
if (attribute == TextAttribute.FONT) {
return getFont(childIndex);
} else if( attribute == TextAttribute.RUN_DIRECTION ) {
return
v.getDocument().getProperty(TextAttribute.RUN_DIRECTION);
} else if (attribute == TextAttribute.NUMERIC_SHAPING) {
return shaper;
}
return null;
}
public AttributedCharacterIterator cancelLatestCommittedText(Attribute[] attributes) {
InputMethodRequests req = getClientInputMethodRequests();
if(req != null) {
return req.cancelLatestCommittedText(attributes);
}
// we don't have access to the client component's text.
return null;
}
public boolean isEmbedding() {
boolean rv = true;
AttributedCharacterIterator aci = getIterator();
int savedIndex = aci.getIndex();
int b = aci.getBeginIndex();
int e = aci.getEndIndex();
if ((e - b) != 1)
rv = false;
else if (aci.setIndex(b) != Characters.UC_OBJECT)
rv = false;
aci.setIndex(savedIndex);
return rv;
}
@Override
public void drawString(AttributedCharacterIterator iterator, int x, int y) {
int index = iterator.getIndex();
g1.drawString(iterator, x, y);
iterator.setIndex(index);
g2.drawString(iterator, x, y);
}
private static final void checkIteratorSubranges(AttributedCharacterIterator iterator, int[] expectedLimits) throws Exception {
int previous = 0;
char c = iterator.first();
for (int i = 0; i < expectedLimits.length; i++) {
if (iterator.getRunStart() != previous || iterator.getRunLimit() != expectedLimits[i]) {
throwException(iterator, "run boundaries are not as expected: " + iterator.getRunStart() + ", " + iterator.getRunLimit());
}
previous = expectedLimits[i];
c = iterator.setIndex(previous);
}
if (c != CharacterIterator.DONE) {
throwException(iterator, "iterator's run sequence doesn't end with DONE");
}
}
public AttributedCharacterIterator getCommittedText(int beginIndex,
int endIndex,
Attribute[] attributes) {
InputMethodRequests req = getClientInputMethodRequests();
if(req != null) {
return req.getCommittedText(beginIndex, endIndex, attributes);
}
// we don't have access to the client component's text.
return EMPTY_TEXT;
}
/**
* Returns the value of the named attribute for the current character.
* Returns null if the attribute is not defined.
* @param attribute the key of the attribute whose value is requested.
*/
public Object getAttribute(AttributedCharacterIterator.Attribute attribute) {
int pos = toModelPosition(getIndex());
int childIndex = v.getViewIndex(pos, Position.Bias.Forward);
if (attribute == TextAttribute.FONT) {
return getFont(childIndex);
} else if( attribute == TextAttribute.RUN_DIRECTION ) {
return
v.getDocument().getProperty(TextAttribute.RUN_DIRECTION);
} else if (attribute == TextAttribute.NUMERIC_SHAPING) {
return shaper;
}
return null;
}
/**
* Overrides <code>Graphics.drawString</code>.
*/
public void drawString(AttributedCharacterIterator iterator, int x, int y) {
DebugGraphicsInfo info = info();
if (debugLog()) {
info().log(toShortString() +
" Drawing text: \"" + iterator +
"\" at: " + new Point(x, y));
}
if (isDrawingBuffer()) {
if (debugBuffered()) {
Graphics debugGraphics = debugGraphics();
debugGraphics.drawString(iterator, x, y);
debugGraphics.dispose();
}
} else if (debugFlash()) {
Color oldColor = getColor();
int i, count = (info.flashCount * 2) - 1;
for (i = 0; i < count; i++) {
graphics.setColor((i % 2) == 0 ? info.flashColor
: oldColor);
graphics.drawString(iterator, x, y);
Toolkit.getDefaultToolkit().sync();
sleep(info.flashTime);
}
graphics.setColor(oldColor);
}
graphics.drawString(iterator, x, y);
}
/**
* Create a text box with an image background.
*
* @param text the text inside the box
* @param textColor base color of the text
* @param width maximum width of the text in the box in pixels
* @param leftMargin margin from the left side of the background image to
* the drawn text
* @param rightMargin margin from the right side of the background image to
* the drawn text
* @param topMargin margin from the top of the background image to the drawn
* text
* @param bottomMargin margin from the bottom of the background image to the
* drawn text
* @param background painter for the background
*
* @return text box sprite
*/
public Sprite createFancyTextBox(final String text, final Color textColor,
final int width, final int leftMargin, final int rightMargin,
final int topMargin, final int bottomMargin,
final BackgroundPainter background) {
List<AttributedCharacterIterator> lines = createFormattedLines(text, textColor, width);
int imageWidth = getMaxPixelWidth(lines) + leftMargin + rightMargin;
final int imageHeight = LINE_HEIGHT * lines.size() + topMargin + bottomMargin;
final GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
final BufferedImage image = gc.createCompatibleImage(imageWidth, imageHeight, TransparencyMode.TRANSPARENCY);
final Graphics2D g2d = image.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// Background image
g2d.setComposite(AlphaComposite.Src);
background.paint(g2d, imageWidth, imageHeight);
g2d.setComposite(AlphaComposite.SrcOver);
// Text
drawTextLines(g2d, lines, textColor, leftMargin, topMargin);
g2d.dispose();
return new ImageSprite(image);
}
/**
* Returns the value of the named attribute for the current character.
* Returns null if the attribute is not defined.
* @param attribute the key of the attribute whose value is requested.
*/
public Object getAttribute(AttributedCharacterIterator.Attribute attribute) {
int pos = toModelPosition(getIndex());
int childIndex = v.getViewIndex(pos, Position.Bias.Forward);
if (attribute == TextAttribute.FONT) {
return getFont(childIndex);
} else if( attribute == TextAttribute.RUN_DIRECTION ) {
return
v.getDocument().getProperty(TextAttribute.RUN_DIRECTION);
} else if (attribute == TextAttribute.NUMERIC_SHAPING) {
return shaper;
}
return null;
}
public AttributedCharacterIterator getCommittedText(int beginIndex,
int endIndex,
Attribute[] attributes) {
InputMethodRequests req = getClientInputMethodRequests();
if(req != null) {
return req.getCommittedText(beginIndex, endIndex, attributes);
}
// we don't have access to the client component's text.
return EMPTY_TEXT;
}
/**
* Return a StyledParagraph reflecting the insertion of a single character
* into the text. This method will attempt to reuse the given paragraph,
* but may create a new paragraph.
* @param aci an iterator over the text. The text should be the same as the
* text used to create (or most recently update) oldParagraph, with
* the exception of deleting a single character at deletePos.
* @param chars the characters in aci
* @param deletePos the index where a character was removed
* @param oldParagraph a StyledParagraph for the text in aci before the
* insertion
*/
public static StyledParagraph deleteChar(AttributedCharacterIterator aci,
char[] chars,
int deletePos,
StyledParagraph oldParagraph) {
// We will reuse oldParagraph unless there was a length-1 run
// at deletePos. We could do more work and check the individual
// Font and Decoration runs, but we don't right now...
deletePos -= aci.getBeginIndex();
if (oldParagraph.decorations == null && oldParagraph.fonts == null) {
oldParagraph.length -= 1;
return oldParagraph;
}
if (oldParagraph.getRunLimit(deletePos) == deletePos+1) {
if (deletePos == 0 || oldParagraph.getRunLimit(deletePos-1) == deletePos) {
return new StyledParagraph(aci, chars);
}
}
oldParagraph.length -= 1;
if (oldParagraph.decorations != null) {
deleteFrom(deletePos,
oldParagraph.decorationStarts,
oldParagraph.decorations.size());
}
if (oldParagraph.fonts != null) {
deleteFrom(deletePos,
oldParagraph.fontStarts,
oldParagraph.fonts.size());
}
return oldParagraph;
}
/**
* When this returns, the ACI's current position will be at the start of the
* first run which does NOT contain a GraphicAttribute. If no such run exists
* the ACI's position will be at the end, and this method will return false.
*/
static boolean advanceToFirstFont(AttributedCharacterIterator aci) {
for (char ch = aci.first();
ch != CharacterIterator.DONE;
ch = aci.setIndex(aci.getRunLimit()))
{
if (aci.getAttribute(TextAttribute.CHAR_REPLACEMENT) == null) {
return true;
}
}
return false;
}
/**
* Constructs a <code>TextLayout</code> from an iterator over styled text.
* <p>
* The iterator must specify a single paragraph of text because an
* entire paragraph is required for the bidirectional
* algorithm.
* @param text the styled text to display
* @param frc contains information about a graphics device which is needed
* to measure the text correctly.
* Text measurements can vary slightly depending on the
* device resolution, and attributes such as antialiasing. This
* parameter does not specify a translation between the
* <code>TextLayout</code> and user space.
*/
public TextLayout(AttributedCharacterIterator text, FontRenderContext frc) {
if (text == null) {
throw new IllegalArgumentException("Null iterator passed to TextLayout constructor.");
}
int start = text.getBeginIndex();
int limit = text.getEndIndex();
if (start == limit) {
throw new IllegalArgumentException("Zero length iterator passed to TextLayout constructor.");
}
int len = limit - start;
text.first();
char[] chars = new char[len];
int n = 0;
for (char c = text.first();
c != CharacterIterator.DONE;
c = text.next())
{
chars[n++] = c;
}
text.first();
if (text.getRunLimit() == limit) {
Map<? extends Attribute, ?> attributes = text.getAttributes();
Font font = singleFont(chars, 0, len, attributes);
if (font != null) {
fastInit(chars, font, attributes, frc);
return;
}
}
standardInit(text, chars, frc);
}
public AttributedCharacterIterator getCommittedText(int beginIndex,
int endIndex,
Attribute[] attributes) {
InputMethodRequests req = getClientInputMethodRequests();
if(req != null) {
return req.getCommittedText(beginIndex, endIndex, attributes);
}
// we don't have access to the client component's text.
return EMPTY_TEXT;
}
public void drawString(AttributedCharacterIterator iterator,
float x, float y) {
if (iterator == null) {
throw new NullPointerException("AttributedCharacterIterator is null");
}
if (iterator.getBeginIndex() == iterator.getEndIndex()) {
return; /* nothing to draw */
}
TextLayout tl = new TextLayout(iterator, getFontRenderContext());
tl.draw(this, x, y);
}
public AttributedCharacterIterator getCommittedText(int beginIndex,
int endIndex,
Attribute[] attributes) {
InputMethodRequests req = getClientInputMethodRequests();
if(req != null) {
return req.getCommittedText(beginIndex, endIndex, attributes);
}
// we don't have access to the client component's text.
return EMPTY_TEXT;
}
@Override
public void paint(Graphics g, JComponent c) {
if (c.isOpaque()) {
ImageLibrary.drawTiledImage("image.background.FreeColToolTip",
g, c, null);
}
g.setColor(Color.BLACK); // FIXME: find out why this is necessary
Graphics2D graphics = (Graphics2D)g;
float x = margin;
float y = margin;
for (String line : lineBreak.split(((JToolTip) c).getTipText())) {
if (line.isEmpty()) {
y += LEADING;
continue;
}
AttributedCharacterIterator styledText =
new AttributedString(line).getIterator();
LineBreakMeasurer measurer = new LineBreakMeasurer(styledText, frc);
while (measurer.getPosition() < styledText.getEndIndex()) {
TextLayout layout = measurer.nextLayout(maximumWidth);
y += (layout.getAscent());
float dx = layout.isLeftToRight() ?
0 : (maximumWidth - layout.getAdvance());
layout.draw(graphics, x + dx, y);
y += layout.getDescent() + layout.getLeading();
}
}
}
@Override
protected JComponent getComponent() {
JTextComponent text = getTextComponent();
if (text == null) {
return null;
}
if (Config.getDefault().isAsEditor()) {
return getEditorComponent(text);
}
Document document = myEditor.getDocument();
if (document == null) {
return null;
}
int start;
int end;
if (Config.getDefault().isSelection()) {
start = text.getSelectionStart();
end = text.getSelectionEnd();
}
else {
start = 0;
end = document.getLength();
}
AttributedCharacterIterator[] iterators = getIterators(document, start, end);
//out();
//out("iterators: " + iterators);
//out();
if (iterators != null) {
return new ComponentDocument(iterators);
}
try {
return new ComponentDocument(text.getText(start, end - start));
}
catch (BadLocationException e) {
return null;
}
}
@Override
public void drawString(AttributedCharacterIterator iterator,
int x, int y)
{
if (logger.check( POILogger.WARN ))
logger.log(POILogger.WARN,"drawString not supported");
}
@Override
public AttributedCharacterIterator create() {
int index = ((Number) map.get(KEY_INDEX)).intValue();
AttributedStringSerializationWrapper w = (AttributedStringSerializationWrapper) map
.get(KEY_ATTRIBUTED_STRING);
AttributedString as = w.create();
AttributedCharacterIterator iter = as.getIterator();
iter.setIndex(index);
return iter;
}
private static final void dumpIterator(AttributedCharacterIterator iterator) {
Set attributeKeys = iterator.getAllAttributeKeys();
System.out.print("All attributes: ");
Iterator keyIterator = attributeKeys.iterator();
while (keyIterator.hasNext()) {
Attribute key = (Attribute) keyIterator.next();
System.out.print(key);
}
for(char c = iterator.first(); c != CharacterIterator.DONE; c = iterator.next()) {
if (iterator.getIndex() == iterator.getBeginIndex() ||
iterator.getIndex() == iterator.getRunStart()) {
System.out.println();
Map attributes = iterator.getAttributes();
Set entries = attributes.entrySet();
Iterator attributeIterator = entries.iterator();
while (attributeIterator.hasNext()) {
Map.Entry entry = (Map.Entry) attributeIterator.next();
System.out.print("<" + entry.getKey() + ": "
+ entry.getValue() + ">");
}
}
System.out.print(" ");
System.out.print(c);
}
System.out.println();
System.out.println("done");
System.out.println();
}
@SuppressWarnings("serial")
private static AttributedCharacterIterator.Attribute
getTextAttribute(String name)
{
if (clazz == null) {
// fake attribute
return new AttributedCharacterIterator.Attribute(name) { };
} else {
return (AttributedCharacterIterator.Attribute)getStaticField(clazz, name);
}
}