Source Code Cross Referenced for TextUtils.java in  » Apache-Harmony-Java-SE » org-package » org » apache » harmony » awt » text » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Apache Harmony Java SE » org package » org.apache.harmony.awt.text 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         *  Licensed to the Apache Software Foundation (ASF) under one or more
0003:         *  contributor license agreements.  See the NOTICE file distributed with
0004:         *  this work for additional information regarding copyright ownership.
0005:         *  The ASF licenses this file to You under the Apache License, Version 2.0
0006:         *  (the "License"); you may not use this file except in compliance with
0007:         *  the License.  You may obtain a copy of the License at
0008:         *
0009:         *     http://www.apache.org/licenses/LICENSE-2.0
0010:         *
0011:         *  Unless required by applicable law or agreed to in writing, software
0012:         *  distributed under the License is distributed on an "AS IS" BASIS,
0013:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         *  See the License for the specific language governing permissions and
0015:         *  limitations under the License.
0016:         */
0017:        /**
0018:         * @author Evgeniya G. Maenkova, Alexey A. Ivanov
0019:         * @version $Revision$
0020:         */package org.apache.harmony.awt.text;
0021:
0022:        import java.awt.Color;
0023:        import java.awt.Component;
0024:        import java.awt.ComponentOrientation;
0025:        import java.awt.Dimension;
0026:        import java.awt.FontMetrics;
0027:        import java.awt.Graphics;
0028:        import java.awt.Insets;
0029:        import java.awt.Point;
0030:        import java.awt.Rectangle;
0031:        import java.awt.Shape;
0032:        import java.awt.Toolkit;
0033:        import java.awt.datatransfer.Clipboard;
0034:        import java.awt.datatransfer.DataFlavor;
0035:        import java.awt.datatransfer.StringSelection;
0036:        import java.awt.datatransfer.Transferable;
0037:        import java.awt.datatransfer.UnsupportedFlavorException;
0038:        import java.awt.event.InputMethodEvent;
0039:        import java.awt.event.InputMethodListener;
0040:        import java.awt.font.TextAttribute;
0041:        import java.io.IOException;
0042:        import java.text.AttributedCharacterIterator;
0043:        import java.text.AttributedString;
0044:        import java.text.BreakIterator;
0045:        import java.text.CharacterIterator;
0046:        import java.text.DateFormat;
0047:        import java.text.Format.Field;
0048:        import java.util.Calendar;
0049:        import java.util.Date;
0050:
0051:        import javax.swing.BoundedRangeModel;
0052:        import javax.swing.JComponent;
0053:        import javax.swing.JEditorPane;
0054:        import javax.swing.JFormattedTextField;
0055:        import javax.swing.SwingConstants;
0056:        import javax.swing.text.AbstractDocument;
0057:        import javax.swing.text.AttributeSet;
0058:        import javax.swing.text.BadLocationException;
0059:        import javax.swing.text.DateFormatter;
0060:        import javax.swing.text.Document;
0061:        import javax.swing.text.Element;
0062:        import javax.swing.text.MutableAttributeSet;
0063:        import javax.swing.text.PlainDocument;
0064:        import javax.swing.text.Position;
0065:        import javax.swing.text.Segment;
0066:        import javax.swing.text.StyleConstants;
0067:        import javax.swing.text.StyledDocument;
0068:        import javax.swing.text.TabExpander;
0069:        import javax.swing.text.View;
0070:        import javax.swing.text.Position.Bias;
0071:
0072:        import org.apache.harmony.awt.ComponentInternals;
0073:        import org.apache.harmony.awt.internal.nls.Messages;
0074:
0075:        public class TextUtils {
0076:            public TextUtils() {
0077:            }
0078:
0079:            static final Position.Bias backward = Position.Bias.Backward;
0080:
0081:            static final Position.Bias forward = Position.Bias.Forward;
0082:
0083:            /**
0084:             * Sets new value to dot or mark of the given component caret
0085:             * depending on <code>isMovingCaret</code> value
0086:             */
0087:            public static final void changeCaretPosition(final TextKit textKit,
0088:                    final int newPos, final boolean isMovingCaret) {
0089:
0090:                TextCaret caret = textKit.getCaret();
0091:
0092:                Point pt = caret.getMagicCaretPosition();
0093:                if (isMovingCaret) {
0094:                    caret.moveDot(newPos, Position.Bias.Forward);
0095:                } else {
0096:                    caret.setDot(newPos, Position.Bias.Forward);
0097:                }
0098:                caret.setMagicCaretPosition(pt);
0099:            }
0100:
0101:            //  TODO remove this method as duplicate
0102:
0103:            /**
0104:             * Sets new value to dot or mark of the given component caret
0105:             * depending on <code>isMovingCaret</code> value
0106:             */
0107:            public static final void changeCaretPosition(final TextKit textKit,
0108:                    final int newPos, final boolean isMovingCaret,
0109:                    final Position.Bias newBias) {
0110:
0111:                TextCaret caret = textKit.getCaret();
0112:                Point pt = caret.getMagicCaretPosition();
0113:                if (isMovingCaret) {
0114:                    caret.moveDot(newPos, newBias);
0115:                } else {
0116:                    caret.setDot(newPos, newBias);
0117:                }
0118:                //TODO in original TextAction this is after not here
0119:                //(after getCaretMagicPosition).
0120:                //Probably there is mistake
0121:                caret.setMagicCaretPosition(pt);
0122:            }
0123:
0124:            public static final int getNextWord(final Document doc,
0125:                    final int pos) throws BadLocationException {
0126:
0127:                BreakIterator bi = BreakIterator.getWordInstance();
0128:                int length = doc.getLength();
0129:                if (pos < 0 || pos >= length) {
0130:                    // awt.2F=No more words
0131:                    throwException(Messages.getString("awt.2F"), pos); //$NON-NLS-1$
0132:                }
0133:                String content = null;
0134:
0135:                content = doc.getText(0, doc.getLength());
0136:                bi.setText(content);
0137:
0138:                int iteratorNextWord = bi.following(pos);
0139:                while (iteratorNextWord < length
0140:                        && Character.isWhitespace(content
0141:                                .charAt(iteratorNextWord))) {
0142:                    iteratorNextWord = bi.following(iteratorNextWord);
0143:                }
0144:                if (iteratorNextWord == length) {
0145:                    // awt.2F=No more words
0146:                    throwException(Messages.getString("awt.2F"), pos); //$NON-NLS-1$
0147:                }
0148:                return iteratorNextWord;
0149:            }
0150:
0151:            public static final int getPreviousWord(final Document doc,
0152:                    final int pos) throws BadLocationException {
0153:
0154:                BreakIterator bi = BreakIterator.getWordInstance();
0155:                int length = doc.getLength();
0156:                if (pos < 0 || pos > length) {
0157:                    // awt.2F=No more words
0158:                    throwException(Messages.getString("awt.2F"), pos); //$NON-NLS-1$
0159:                }
0160:                String content = null;
0161:
0162:                content = doc.getText(0, doc.getLength());
0163:                bi.setText(content);
0164:
0165:                int iteratorPrevWord = bi.preceding(pos);
0166:                while (iteratorPrevWord > 0
0167:                        && ((content.charAt(iteratorPrevWord) == ' ' || content
0168:                                .charAt(iteratorPrevWord) == '\n') || content
0169:                                .charAt(iteratorPrevWord) == '\t')) {
0170:                    iteratorPrevWord = bi.preceding(iteratorPrevWord);
0171:                }
0172:                return iteratorPrevWord == -1 ? 0 : iteratorPrevWord;
0173:            }
0174:
0175:            public static final boolean isBidirectional(final Document document) {
0176:                if (!(document instanceof  AbstractDocument)) {
0177:                    return false;
0178:                }
0179:                Element bidiRoot = ((AbstractDocument) document)
0180:                        .getBidiRootElement();
0181:                return (bidiRoot != null && bidiRoot.getElementCount() >= 2);
0182:            }
0183:
0184:            static final boolean isLTR(final Element element) {
0185:                return isLTR(StyleConstants.getBidiLevel(element
0186:                        .getAttributes()));
0187:            }
0188:
0189:            public static final boolean isLTR(final int level) {
0190:                return (level & 1) == 0;
0191:            }
0192:
0193:            static final boolean isRTL(final int level) {
0194:                return (level & 1) == 1;
0195:            }
0196:
0197:            public static final int getTabbedTextWidth(final Segment s,
0198:                    final FontMetrics fm, final int x, final TabExpander t,
0199:                    final int pos) {
0200:                return getTabbedTextEnd(s, fm, x, t, pos, false, null, 0) - x;
0201:            }
0202:
0203:            public static final int getTabbedTextOffset(final Segment s,
0204:                    final FontMetrics fm, final int start, final int end,
0205:                    final TabExpander t, final int pos) {
0206:                return getTabbedTextOffset(s, fm, start, end, t, pos, true);
0207:            }
0208:
0209:            /**
0210:             * If round equals false it needs that symbol is placed completely. If
0211:             * round equals true it needs that more than half of the symbol is placed.
0212:             */
0213:            public static final int getTabbedTextOffset(final Segment s,
0214:                    final FontMetrics fm, final int start, final int end,
0215:                    final TabExpander t, final int pos, final boolean round) {
0216:                String str = ""; //$NON-NLS-1$
0217:                int segmentOffset = pos - s.getBeginIndex();
0218:                boolean isTab = false;
0219:                boolean isNullTabExpander = (t == null);
0220:                int currentEnd = start < 0 ? 0 : start;
0221:                int x1 = start < 0 ? start : 0;
0222:                int currentIndex = 0;
0223:                int prevEnd = currentEnd;
0224:                int tabEnd = currentEnd;
0225:                for (char c = s.first(); c != CharacterIterator.DONE; c = s
0226:                        .next()) {
0227:                    isTab = (c == '\t');
0228:                    if (isTab && !isNullTabExpander) {
0229:                        tabEnd = (int) t.nextTabStop(currentEnd, s.getIndex()
0230:                                + segmentOffset);
0231:                        str = ""; //$NON-NLS-1$
0232:                    } else {
0233:                        str += (isTab) ? ' ' : c;
0234:                        isTab = false;
0235:                    }
0236:                    int tmpEnd = tabEnd + x1;
0237:                    currentEnd = isTab ? tmpEnd : tmpEnd + fm.stringWidth(str);
0238:                    int delta = (round) ? (currentEnd - prevEnd) / 2 : 0;
0239:                    if (currentEnd > end + delta) {
0240:                        break;
0241:                    }
0242:                    currentIndex++;
0243:                    prevEnd = currentEnd;
0244:                }
0245:                return currentIndex;
0246:            }
0247:
0248:            public static final int drawTabbedText(final Segment s,
0249:                    final int x, final int y, final Graphics g,
0250:                    final TabExpander t, final int pos) {
0251:                return getTabbedTextEnd(s, g.getFontMetrics(), x, t, pos, true,
0252:                        g, y);
0253:            }
0254:
0255:            public static final int drawComposedText(final TextKit textKit,
0256:                    final AttributedString text, final Graphics g, final int x,
0257:                    final int y) {
0258:                text.addAttribute(TextAttribute.FONT, textKit.getComponent()
0259:                        .getFont());
0260:                final AttributedCharacterIterator iterator = text.getIterator();
0261:
0262:                g.drawString(iterator, x, y);
0263:
0264:                final int width = g.getFontMetrics().getStringBounds(iterator,
0265:                        iterator.getBeginIndex(), iterator.getEndIndex(), g)
0266:                        .getBounds().width;
0267:                return width + x;
0268:            }
0269:
0270:            public static final int getBreakLocation(final Segment s,
0271:                    final FontMetrics fm, final int start, final int end,
0272:                    final TabExpander t, final int pos) {
0273:                int offset = s.offset;
0274:                int index = TextUtils.getTabbedTextOffset(s, fm, start, end, t,
0275:                        pos, false);
0276:                int fullIndex = offset + index;
0277:
0278:                BreakIterator bi = BreakIterator.getWordInstance();
0279:                bi.setText(s);
0280:                if (bi.last() <= fullIndex) {
0281:                    return bi.last() - offset;
0282:                }
0283:                if (bi.isBoundary(fullIndex)) {
0284:                    return Character.isWhitespace(s.array[fullIndex]) ? index + 1
0285:                            : index;
0286:                }
0287:                int prev = bi.preceding(fullIndex);
0288:                if (prev == bi.first()) {
0289:                    return index;
0290:                }
0291:                return prev - offset;
0292:            }
0293:
0294:            public static final int getRowStart(final TextKit tk, final int pos)
0295:                    throws BadLocationException {
0296:                Dimension d = tk.getVisibleRect().getSize();
0297:                if (d != null && (d.height == 0 || d.width == 0)) {
0298:                    return -1;
0299:                }
0300:                int length = tk.getDocument().getLength();
0301:                if (pos < 0 || pos > length) {
0302:                    // awt.2A=Position not represented by view
0303:                    throwException(Messages.getString("awt.2A"), pos); //$NON-NLS-1$
0304:                }
0305:                int y = tk.modelToView(pos).y;
0306:                Rectangle tmp = null;
0307:                for (int i = pos - 1; i >= 0; i--) {
0308:                    tmp = tk.modelToView(i);
0309:                    if (tmp.y < y) {
0310:                        return i + 1;
0311:                    }
0312:                }
0313:                return 0;
0314:            }
0315:
0316:            public static final int getWordEnd(final TextKit tk, final int pos)
0317:                    throws BadLocationException {
0318:
0319:                Document doc = tk.getDocument();
0320:                BreakIterator bi = BreakIterator.getWordInstance();
0321:                int length = doc.getLength();
0322:                if (pos < 0 || pos > length) {
0323:                    // awt.2B=No word at {0}
0324:                    throwException(Messages.getString("awt.2B", pos), pos); //$NON-NLS-1$
0325:                }
0326:                String content = doc.getText(0, doc.getLength());
0327:                bi.setText(content);
0328:                return (pos < bi.last()) ? bi.following(pos) : pos;
0329:            }
0330:
0331:            public static final int getWordStart(final TextKit tk, final int pos)
0332:                    throws BadLocationException {
0333:                Document doc = tk.getDocument();
0334:                BreakIterator bi = BreakIterator.getWordInstance();
0335:                int length = doc.getLength();
0336:                if (pos < 0 || pos > length) {
0337:                    // awt.2B=No word at {0}
0338:                    throwException(Messages.getString("awt.2B", pos), pos); //$NON-NLS-1$
0339:                }
0340:                String content = null;
0341:
0342:                content = doc.getText(0, doc.getLength());
0343:                bi.setText(content);
0344:                int iteratorWordStart = pos;
0345:                if (pos < length - 1) {
0346:                    iteratorWordStart = bi.preceding(pos + 1);
0347:                } else {
0348:                    bi.last();
0349:                    iteratorWordStart = bi.previous();
0350:                }
0351:                return iteratorWordStart;
0352:            }
0353:
0354:            /**
0355:             * Finds row above, calculates modelToView for all the positions from this view
0356:             * and selects the closest one.
0357:             */
0358:            public static final int getPositionAbove(final TextKit textKit,
0359:                    final int p, final int x) throws BadLocationException {
0360:                int p0 = getRowStart(textKit, p);
0361:                if (p0 <= 0) {
0362:                    return -1;
0363:                }
0364:                int end = p0 - 1;
0365:                int offset = end;
0366:                int dy = 0;
0367:                Rectangle rect = textKit.modelToView(end);
0368:                int lastY = rect.y;
0369:                int dx = Math.abs(rect.x - x);
0370:                int index = end;
0371:                do {
0372:                    if (index != end) {
0373:                        rect = textKit.modelToView(index);
0374:                    }
0375:                    dy = rect.y - lastY;
0376:                    int locDiff = Math.abs(rect.x - x);
0377:                    if (locDiff <= dx && dy == 0) {
0378:                        dx = locDiff;
0379:                        offset = index;
0380:                    }
0381:                    index--;
0382:                    lastY = rect.y;
0383:                } while (dx >= 1 && dy == 0 && index >= 0);
0384:                return offset;
0385:            }
0386:
0387:            /**
0388:             * Finds row below, calculates modelToView for all the positions from this view
0389:             * and selects the closest one.
0390:             */
0391:            public static final int getPositionBelow(final TextKit textKit,
0392:                    final int p, final int x) throws BadLocationException {
0393:                int p0 = getRowEnd(textKit, p);
0394:                if (p0 == -1) {
0395:                    return -1;
0396:                }
0397:                int length = textKit.getDocument().getLength();
0398:                if (p0 == length) {
0399:                    return p;
0400:                }
0401:                int start = p0 + 1;
0402:                int offset = p0 + 1;
0403:                int dy = 0;
0404:                Rectangle rect = textKit.modelToView(start);
0405:                int lastY = rect.y;
0406:                int dx = Math.abs(rect.x - x);
0407:                int index = start;
0408:                do {
0409:                    rect = textKit.modelToView(index);
0410:                    dy = rect.y - lastY;
0411:                    int locDiff = Math.abs(rect.x - x);
0412:                    if (locDiff < dx && dy == 0) {
0413:                        dx = locDiff;
0414:                        offset = index;
0415:                    }
0416:                    index++;
0417:                    lastY = rect.y;
0418:                } while (index <= length && dy == 0 && dx >= 1);
0419:
0420:                return offset;
0421:            }
0422:
0423:            public static final TextKit getTextKit(final Component c) {
0424:                return ComponentInternals.getComponentInternals().getTextKit(c);
0425:            }
0426:
0427:            public static final TextFieldKit getTextFieldKit(final Component c) {
0428:                return ComponentInternals.getComponentInternals()
0429:                        .getTextFieldKit(c);
0430:            }
0431:
0432:            public static final int getRowEnd(final TextKit tk, final int pos)
0433:                    throws BadLocationException {
0434:                Dimension d = tk.getVisibleRect().getSize();
0435:                if (d != null && (d.height == 0 || d.width == 0)) {
0436:                    return -1;
0437:                }
0438:                int length = tk.getDocument().getLength();
0439:                if (pos < 0 || pos > length) {
0440:                    // awt.2A=Position not represented by view
0441:                    throwException(Messages.getString("awt.2A"), pos); //$NON-NLS-1$
0442:                }
0443:
0444:                int y = tk.modelToView(pos).y;
0445:                Rectangle r = null;
0446:                for (int i = pos + 1; i <= length; i++) {
0447:                    r = tk.modelToView(i);
0448:                    if (r.y > y) {
0449:                        return i - 1;
0450:                    }
0451:                }
0452:                return length;
0453:            }
0454:
0455:            //TODO Probably here is a bug:
0456:            //Why NORTH?
0457:            //Where bias?
0458:            public static final void setCurrentPositionAsMagic(
0459:                    final TextKit textKit) {
0460:                TextCaret caret = textKit.getCaret();
0461:                int newPos = caret.getDot();
0462:                try {
0463:                    Point pt = textKit.modelToView(newPos, caret.getDotBias())
0464:                            .getLocation();
0465:                    caret.setMagicCaretPosition(newPos, SwingConstants.NORTH,
0466:                            pt);
0467:                } catch (BadLocationException e) {
0468:                }
0469:            }
0470:
0471:            /**
0472:             * If the component document is an instance of AbstractDocument then its
0473:             * {@link AbstractDocument#getParagraphElement(int)} method is called.
0474:             * Otherwise {@link Document#getDefaultRootElement()} is used to search
0475:             * paragraph element.
0476:             */
0477:            public static final Element getParagraphElement(final Document doc,
0478:                    final int p) {
0479:                if (doc instanceof  AbstractDocument) {
0480:                    AbstractDocument abstrDoc = (AbstractDocument) doc;
0481:                    abstrDoc.readLock();
0482:                    Element elem = null;
0483:                    int length = 0;
0484:                    boolean incorrectPosition = false;
0485:                    try {
0486:                        length = doc.getLength();
0487:                        incorrectPosition = (p < 0 || p > length)
0488:                                && (doc instanceof  PlainDocument);
0489:                        if (!incorrectPosition) {
0490:                            elem = abstrDoc.getParagraphElement(p);
0491:                        }
0492:                    } finally {
0493:                        abstrDoc.readUnlock();
0494:                    }
0495:                    return elem;
0496:                }
0497:
0498:                Element root = doc.getDefaultRootElement();
0499:                int index = root.getElementIndex(p);
0500:                return index == -1 ? null : root.getElement(index);
0501:            }
0502:
0503:            /*
0504:             * Returns end x-coordinate of tabbed text. Uses by drawTabbedText and
0505:             * getTabbedTextWidth.
0506:             */
0507:            private static int getTabbedTextEnd(final Segment s,
0508:                    final FontMetrics fm, final int x, final TabExpander t,
0509:                    final int pos, final boolean needDraw, final Graphics g,
0510:                    final int y) {
0511:                int x1 = x < 0 ? x : 0;
0512:                int res = x < 0 ? 0 : x;
0513:                String buffer = s.toString();
0514:                int tabIndex = buffer.indexOf("\t"); //$NON-NLS-1$
0515:                int currentIndex = pos - s.getBeginIndex() + s.offset;
0516:                if (t == null) {
0517:                    String buf = buffer.replaceAll("\t", " "); //$NON-NLS-1$ //$NON-NLS-2$
0518:                    drawString(buf, needDraw, g, x, y);
0519:                    return fm.stringWidth(buf) + x;
0520:                }
0521:                String substr = null;
0522:                int lastTabIndex = -1;
0523:                while (tabIndex >= 0) {
0524:                    substr = buffer.substring(lastTabIndex + 1, tabIndex);
0525:                    drawString(substr, needDraw, g, res + x1, y);
0526:                    res = (int) t.nextTabStop(res + fm.stringWidth(substr),
0527:                            tabIndex + currentIndex);
0528:                    lastTabIndex = tabIndex;
0529:                    tabIndex = buffer.indexOf("\t", tabIndex + 1); //$NON-NLS-1$
0530:                }
0531:                int tmp = res + x1;
0532:                substr = buffer.substring(lastTabIndex + 1, buffer.length());
0533:                drawString(substr, needDraw, g, tmp, y);
0534:                return (tabIndex >= 0) ? tmp : tmp + fm.stringWidth(substr);
0535:            }
0536:
0537:            private static void drawString(final String text,
0538:                    final boolean needDraw, final Graphics g, final int x,
0539:                    final int y) {
0540:                if (needDraw) {
0541:                    g.drawString(text, x, y);
0542:                }
0543:            }
0544:
0545:            public static final void readLock(final Document document) {
0546:                if (document instanceof  AbstractDocument) {
0547:                    ((AbstractDocument) document).readLock();
0548:                }
0549:            }
0550:
0551:            public static final void readUnlock(final Document document) {
0552:                if (document instanceof  AbstractDocument) {
0553:                    ((AbstractDocument) document).readUnlock();
0554:                }
0555:            }
0556:
0557:            private static void throwException(final String s, final int i)
0558:                    throws BadLocationException {
0559:                throw new BadLocationException(s, i);
0560:            }
0561:
0562:            //---NextVisualPosition---------------------------------------------
0563:            //  for a stub (getNexVisualPositionFrom)
0564:            public static final int getNextVisualPositionFrom(
0565:                    final TextKit textKit, final View v, final int pos,
0566:                    final Position.Bias bias, final Shape shape,
0567:                    final int direction, final Position.Bias[] biasRet)
0568:                    throws BadLocationException {
0569:                int length = v.getDocument().getLength();
0570:                if (pos < 0 || pos > length) {
0571:                    // awt.2C=Invalid position: {0}
0572:                    throwException(Messages.getString("awt.2C", pos), pos); //$NON-NLS-1$
0573:                }
0574:                biasRet[0] = Position.Bias.Forward;
0575:                if (direction == SwingConstants.WEST
0576:                        || direction == SwingConstants.EAST) {
0577:                    return getNextVisualPosition(v, pos, bias, direction,
0578:                            biasRet);
0579:                }
0580:                Point pt = textKit.getCaret().getMagicCaretPosition();
0581:                if (direction == SwingConstants.NORTH) {
0582:                    return TextUtils.getPositionAbove(textKit, pos,
0583:                            pt != null ? pt.x : v.modelToView(pos, shape, bias)
0584:                                    .getBounds().x);
0585:                } else if (direction == SwingConstants.SOUTH) {
0586:                    return TextUtils.getPositionBelow(textKit, pos,
0587:                            pt != null ? pt.x : v.modelToView(pos, shape, bias)
0588:                                    .getBounds().x);
0589:                }
0590:
0591:                // awt.2D=Invalid direction
0592:                throw new IllegalArgumentException(Messages.getString("awt.2D")); //$NON-NLS-1$
0593:            }
0594:
0595:            private static Element getElementByPosition(
0596:                    final Element rootElement, final int pos) {
0597:                int index = rootElement.getElementIndex(pos);
0598:                return rootElement.getElement(index);
0599:            }
0600:
0601:            private static int getNextVisualPosition(final View v,
0602:                    final int pos, final Position.Bias b0, final int direction,
0603:                    final Position.Bias[] biasRet) {
0604:                boolean toWest = (direction == SwingConstants.WEST);
0605:                Document document = v.getDocument();
0606:                int length = document.getLength();
0607:                if (!isBidirectional(document)) {
0608:                    return getTrivialVisualPosition(toWest, pos, b0, length,
0609:                            biasRet, true);
0610:                }
0611:                Element bidiRoot = ((AbstractDocument) document)
0612:                        .getBidiRootElement();
0613:                Element elem = getElementByPosition(bidiRoot, pos);
0614:                boolean isLTR = isLTR(elem);
0615:                int start = elem.getStartOffset();
0616:                int end = elem.getEndOffset() - 1;
0617:
0618:                int posInNeighboringElement = toWest ? Math.max(start - 1, 0)
0619:                        : Math.min(end + 1, length);
0620:                Element neighboringElement = getElementByPosition(bidiRoot,
0621:                        posInNeighboringElement);
0622:
0623:                Element paragraph = getElementByPosition(document
0624:                        .getDefaultRootElement(), pos);
0625:                int startParagraph = paragraph.getStartOffset();
0626:                int endParagraph = paragraph.getEndOffset() - 1;
0627:
0628:                boolean nextIsLTR = isLTR(getElementByPosition(bidiRoot, Math
0629:                        .min(endParagraph + 1, length)));
0630:
0631:                int result = checkBoundaryCondition(pos, b0, biasRet,
0632:                        neighboringElement, isLTR, toWest, start, length,
0633:                        startParagraph, endParagraph, nextIsLTR);
0634:
0635:                return result >= 0 ? result : getBidiVisualPosition(start, end,
0636:                        neighboringElement, pos, b0, biasRet, length, toWest,
0637:                        isLTR);
0638:            }
0639:
0640:            private static int checkBoundaryCondition(final int pos,
0641:                    final Position.Bias b0, final Position.Bias[] biasRet,
0642:                    final Element neighboringElement, final boolean isLTR,
0643:                    final boolean toWest, final int start, final int length,
0644:                    final int startParagraph, final int endParagraph,
0645:                    final boolean nextIsLTR) {
0646:
0647:                if (toWest && isLTR) {
0648:                    if (pos == startParagraph) {
0649:                        return Math.max(0, pos - 1);
0650:                    } else if (neighboringElement.getStartOffset() == startParagraph
0651:                            && pos == start && b0 == backward) {
0652:                        return Math.max(0, startParagraph - 1);
0653:                    }
0654:                } else if (!toWest) {
0655:                    if (b0 == forward && pos == length) {
0656:                        biasRet[0] = b0;
0657:                        return pos;
0658:                    }
0659:                    if (b0 == forward && pos == endParagraph) {
0660:                        if (nextIsLTR) {
0661:                            return pos + 1;
0662:                        }
0663:                        biasRet[0] = backward;
0664:                        return neighboringElement.getEndOffset();
0665:                    }
0666:                }
0667:                return -1;
0668:            }
0669:
0670:            static final int getBidiVisualPosition(final int start,
0671:                    final int end, final Element neighbouringElement,
0672:                    final int pos, final Position.Bias b0,
0673:                    final Position.Bias[] biasRet, final int length,
0674:                    final boolean toWest, final boolean isLTR) {
0675:                boolean direction = toWest ^ isLTR;
0676:                if (pos == end && direction && b0 == forward) {
0677:                    biasRet[0] = backward;
0678:                    return pos + 1;
0679:                } else if (pos == start + 1 && pos <= end && !direction) {
0680:                    return pos - 1;
0681:                } else if (pos == start) {
0682:                    if (direction) {
0683:                        return (b0 == forward) ? pos + 1 : pos - 1;
0684:                    }
0685:                    biasRet[0] = b0;
0686:                    return neighbouringElement.getStartOffset();
0687:                } else {
0688:                    return getTrivialVisualPosition(toWest, pos, b0, length,
0689:                            biasRet, isLTR);
0690:                }
0691:            }
0692:
0693:            private static int getTrivialVisualPosition(final boolean toWest,
0694:                    final int pos, final Position.Bias bias,
0695:                    final int docLength, final Position.Bias[] biasRet,
0696:                    final boolean isLTR) {
0697:                boolean condition = (toWest && isLTR) || (!toWest && !isLTR);
0698:                return condition ? Math.max(pos - 1, 0) : Math.min(pos + 1,
0699:                        docLength);
0700:            }
0701:
0702:            //-------TextField Methods
0703:            public static final Shape getFieldViewAllocation(final View v,
0704:                    final TextFieldKit tfk, final Shape shape,
0705:                    final ComponentOrientation orientation) {
0706:                if (tfk == null || shape == null) {
0707:                    return null;
0708:                }
0709:
0710:                Rectangle bounds = shape.getBounds();
0711:                int prefWidth = (int) v.getPreferredSpan(View.X_AXIS);
0712:                int height = (int) v.getPreferredSpan(View.Y_AXIS);
0713:                int diff = bounds.width - prefWidth;
0714:                int alignment = tfk.getHorizontalAlignment();
0715:                boolean toLeft = isToLeft(orientation, alignment);
0716:                int offset = 0;
0717:                if (alignment == SwingConstants.CENTER) {
0718:                    offset = diff / 2;
0719:                } else {
0720:                    offset = toLeft ? 0 : diff;
0721:                }
0722:                int extent = bounds.width - 1;
0723:                int max = Math.max(extent, prefWidth);
0724:                BoundedRangeModel brm = tfk.getHorizontalVisibility();
0725:                int value = Math.min(brm.getValue(), max - extent);
0726:                brm.setRangeProperties(value, extent, brm.getMinimum(), max,
0727:                        false);
0728:
0729:                int x = (diff < 0 ? -value + tfk.getInsets().left : bounds.x
0730:                        + offset);
0731:                int y = (bounds.height - height) / 2 + bounds.y;
0732:                if (!toLeft) {
0733:                    x--;
0734:                }
0735:                return new Rectangle(x, y, prefWidth + 1, height);
0736:            }
0737:
0738:            private static boolean isToLeft(
0739:                    final ComponentOrientation orientation, final int alignment) {
0740:                boolean isRTL = !orientation.isLeftToRight();
0741:                return isRTL && alignment == SwingConstants.TRAILING || !isRTL
0742:                        && alignment == SwingConstants.LEADING
0743:                        || alignment == SwingConstants.LEFT;
0744:            }
0745:
0746:            //-------Highlight painting
0747:
0748:            public static Shape paintLayer(final Graphics g, final int p0,
0749:                    final int p1, final Shape shape, final Color color,
0750:                    final View view, final boolean fill) {
0751:                if (shape == null) {
0752:                    return null;
0753:                }
0754:                Shape result = null;
0755:                try {
0756:                    result = view.modelToView(Math.min(p0, p1),
0757:                            Position.Bias.Forward, Math.max(p0, p1),
0758:                            Position.Bias.Backward, shape);
0759:                    Rectangle bounds = result.getBounds();
0760:                    g.setColor(color);
0761:                    if (fill) {
0762:                        g.fillRect(bounds.x, bounds.y, bounds.width,
0763:                                bounds.height);
0764:                    } else {
0765:                        g.drawRect(bounds.x, bounds.y, bounds.width - 1,
0766:                                bounds.height - 1);
0767:                    }
0768:                } catch (final BadLocationException e) {
0769:                }
0770:                return result;
0771:            }
0772:
0773:            //------IM support
0774:            public static ComposedTextParams getComposedTextParams(
0775:                    final TextKit tk) {
0776:                Document doc = tk.getDocument();
0777:                Object currentProperty = tk.getDocument().getProperty(
0778:                        PropertyNames.COMPOSED_TEXT_PROPERTY);
0779:                if (!(currentProperty instanceof  ComposedTextParams)) {
0780:                    ComposedTextParams result = new ComposedTextParams(doc);
0781:                    int caretPosition = tk.getCaret().getDot();
0782:                    result.setComposedTextStart(caretPosition);
0783:                    result.setLastCommittedTextStart(caretPosition);
0784:                    return result;
0785:                }
0786:                return (ComposedTextParams) currentProperty;
0787:            }
0788:
0789:            public static void processIMEvent(
0790:                    final InputMethodListener listener, final InputMethodEvent e) {
0791:                if (e.getID() == InputMethodEvent.CARET_POSITION_CHANGED) {
0792:                    listener.caretPositionChanged(e);
0793:                }
0794:                if (e.getID() == InputMethodEvent.INPUT_METHOD_TEXT_CHANGED) {
0795:                    listener.inputMethodTextChanged(e);
0796:                }
0797:            }
0798:
0799:            //----highlighter
0800:            public static final Rectangle getBoundsByOffsets(final TextKit tk,
0801:                    final int p0, final int p1) {
0802:                Rectangle r0 = null;
0803:                Rectangle r1 = null;
0804:                Rectangle rect = new Rectangle();
0805:                if (tk == null) {
0806:                    return null;
0807:                }
0808:                try {
0809:                    r0 = tk.modelToView(p0, Position.Bias.Forward);
0810:                    r1 = tk.modelToView(p1, Position.Bias.Forward);
0811:                } catch (final BadLocationException e) {
0812:                }
0813:                if (r0 == null || r1 == null) {
0814:                    return null;
0815:                }
0816:                if (r0.y == r1.y) {
0817:                    rect.x = Math.min(r0.x, r1.x);
0818:                    rect.y = r0.y;
0819:                    rect.width = Math.max(r0.x, r1.x) - rect.x + 1;
0820:                    rect.height = Math.max(r0.height, r1.height);
0821:                    return rect;
0822:                }
0823:                Rectangle visibleRect = tk.getVisibleRect();
0824:                rect.x = visibleRect.x;
0825:                rect.y = Math.min(r0.y, r1.y);
0826:                rect.width = visibleRect.width;
0827:                rect.height = Math.max(r0.y, r1.y) - rect.y
0828:                        + Math.max(r0.height, r1.height);
0829:                return rect;
0830:            }
0831:
0832:            public static final void setNativeCaretPosition(
0833:                    final Rectangle rect, final Component comp) {
0834:                ComponentInternals.getComponentInternals().setCaretPos(comp,
0835:                        rect.x, rect.y);
0836:            }
0837:
0838:            //-----clipboard operations (Perhaps, that's temporary solution.
0839:            public static final void copy(final TextKit textKit) {
0840:                exportToClipboard(textKit, getSystemClipboard(),
0841:                        ActionNames.COPY);
0842:            }
0843:
0844:            public static final void cut(final TextKit textKit) {
0845:                exportToClipboard(textKit, getSystemClipboard(),
0846:                        ActionNames.MOVE);
0847:            }
0848:
0849:            public static final void paste(final TextKit textKit) {
0850:                TextUtils.importData(textKit, getSystemClipboard().getContents(
0851:                        null));
0852:            }
0853:
0854:            public static final void exportToClipboard(final TextKit textKit,
0855:                    final Clipboard clipboard, final int action) {
0856:                if (textKit == null) {
0857:                    return;
0858:                }
0859:                int realAction = (action & (getSourceActions(textKit)));
0860:                Transferable transferable = TextUtils
0861:                        .createTransferable(textKit);
0862:                if (realAction > 0 && transferable != null) {
0863:                    clipboard.setContents(transferable, null);
0864:                }
0865:                exportDone(textKit, transferable, realAction);
0866:            }
0867:
0868:            public static final Transferable createTransferable(
0869:                    final TextKit textKit) {
0870:                String text = textKit.getSelectedText();
0871:                return text != null ? new StringSelection(text) : null;
0872:            }
0873:
0874:            public static final void exportDone(final TextKit textKit,
0875:                    final Transferable transferable, final int action) {
0876:                if (textKit != null && (action & ActionNames.MOVE) > 0) {
0877:                    textKit.replaceSelectedText(""); //$NON-NLS-1$
0878:                }
0879:            }
0880:
0881:            public static final boolean importData(final TextKit textKit,
0882:                    final Transferable t) {
0883:
0884:                if (t == null) {
0885:                    return false;
0886:                }
0887:                DataFlavor[] flavors = t.getTransferDataFlavors();
0888:                DataFlavor flavor = null;
0889:                for (DataFlavor element : flavors) {
0890:                    flavor = element;
0891:                    if (String.class.isAssignableFrom(flavor
0892:                            .getRepresentationClass())) {
0893:                        break;
0894:                    }
0895:                    flavor = null;
0896:                }
0897:                if (flavor != null) {
0898:                    try {
0899:                        String text = (String) t.getTransferData(flavor);
0900:                        textKit.replaceSelectedText(text);
0901:                        return true;
0902:                    } catch (UnsupportedFlavorException e) {
0903:                        return false;
0904:                    } catch (IOException e) {
0905:                        return false;
0906:                    }
0907:                }
0908:                return false;
0909:            }
0910:
0911:            public static final Clipboard getSystemClipboard() {
0912:                return Toolkit.getDefaultToolkit().getSystemClipboard();
0913:            }
0914:
0915:            public static int getSourceActions(final TextKit textKit) {
0916:                if (textKit != null
0917:                        && !"javax.swing.JPasswordField".equals(textKit.getClass())) { //$NON-NLS-1$
0918:                    return (textKit.isEditable()) ? ActionNames.COPY_OR_MOVE
0919:                            : ActionNames.COPY;
0920:
0921:                }
0922:                return ActionNames.NONE;
0923:            }
0924:
0925:            public static Rectangle scrollRectToVisible(Rectangle viewRect,
0926:                    Rectangle r) {
0927:                Rectangle retVal = (Rectangle) viewRect.clone();
0928:                retVal.x = -retVal.x;
0929:                retVal.y = -retVal.y;
0930:
0931:                int dx;
0932:                int dy;
0933:
0934:                if (r.x > 0) {
0935:                    if (r.x + r.width > viewRect.width) {
0936:                        int dx2 = r.x + r.width - viewRect.width;
0937:                        dx = Math.min(r.x, dx2);
0938:                    } else {
0939:                        dx = 0;
0940:                    }
0941:                } else if (r.x < 0) {
0942:                    if (r.x + r.width < viewRect.width) {
0943:                        int dx2 = r.x + r.width - viewRect.width;
0944:                        dx = Math.max(r.x, dx2);
0945:                    } else {
0946:                        dx = 0;
0947:                    }
0948:                } else {
0949:                    dx = 0;
0950:                }
0951:
0952:                if (r.y > 0) {
0953:                    if (r.y + r.height > viewRect.height) {
0954:                        int dy2 = r.y + r.height - viewRect.height;
0955:                        dy = Math.min(r.y, dy2);
0956:                    } else {
0957:                        dy = 0;
0958:                    }
0959:                } else if (r.y < 0) {
0960:                    if (r.y + r.height < viewRect.height) {
0961:                        int dy2 = r.y + r.height - viewRect.height;
0962:                        dy = Math.max(r.y, dy2);
0963:                    } else {
0964:                        dy = 0;
0965:                    }
0966:                } else {
0967:                    dy = 0;
0968:                }
0969:
0970:                if (dx != 0 || dy != 0) {
0971:                    int x = retVal.x + dx;
0972:                    int y = retVal.y + dy;
0973:
0974:                    retVal.x = x;
0975:                    retVal.y = y;
0976:                }
0977:
0978:                return retVal;
0979:            }
0980:
0981:            public static Rectangle getEditorRect(final JComponent component) {
0982:                if (component == null) {
0983:                    return null;
0984:                }
0985:                Insets insets = component.getInsets();
0986:                int left = 0;
0987:                int top = 0;
0988:                if (insets != null) {
0989:                    left = insets.left;
0990:                    top = insets.top;
0991:                }
0992:                Dimension r = component.getSize();
0993:                return r.width == 0 || r.height == 0 ? null : new Rectangle(
0994:                        left, top, r.width - getHrzInsets(insets), r.height
0995:                                - getVrtInsets(insets));
0996:            }
0997:
0998:            public static int getHrzInsets(final Insets insets) {
0999:                return (insets != null) ? insets.left + insets.right : 0;
1000:            }
1001:
1002:            public static int getVrtInsets(final Insets insets) {
1003:                return (insets != null) ? insets.top + insets.bottom : 0;
1004:            }
1005:
1006:            public static void setCharacterAttributes(final AttributeSet attr,
1007:                    final boolean replace, final JEditorPane editorPane,
1008:                    final StyledDocument doc,
1009:                    final MutableAttributeSet inputAttrs) {
1010:
1011:                final int selectionStart = editorPane.getSelectionStart();
1012:                final int selectionEnd = editorPane.getSelectionEnd();
1013:                doc.setCharacterAttributes(selectionStart, selectionEnd
1014:                        - selectionStart, attr, replace);
1015:                if (selectionStart == selectionEnd) {
1016:                    if (replace) {
1017:                        inputAttrs.removeAttributes(inputAttrs
1018:                                .getAttributeNames());
1019:                    }
1020:                    inputAttrs.addAttributes(attr);
1021:                }
1022:            }
1023:
1024:            public static void setParagraphAttributes(final AttributeSet attr,
1025:                    final boolean replace, final JEditorPane editorPane,
1026:                    final StyledDocument doc) {
1027:                final int selectStart = editorPane.getSelectionStart();
1028:                int intervalLength = Math.max(editorPane.getSelectionEnd()
1029:                        - selectStart, 1);
1030:                doc.setParagraphAttributes(selectStart, intervalLength, attr,
1031:                        replace);
1032:            }
1033:
1034:            public static int getCalendarField(
1035:                    final JFormattedTextField textField) {
1036:                DateFormatter formatter = (DateFormatter) textField
1037:                        .getFormatter();
1038:                Field[] fields = formatter.getFields(textField
1039:                        .getCaretPosition());
1040:
1041:                for (int i = textField.getCaretPosition(); fields.length == 0
1042:                        || i < 0; i--) {
1043:                    fields = formatter.getFields(i);
1044:                }
1045:                if (fields.length == 0) {
1046:                    int length = textField.getText().length();
1047:                    for (int i = textField.getCaretPosition(); fields.length == 0
1048:                            || i > length; i++) {
1049:                        fields = formatter.getFields(i);
1050:                    }
1051:                }
1052:                return ((DateFormat.Field) fields[0]).getCalendarField();
1053:            }
1054:
1055:            public static void selectCalendarField(
1056:                    final JFormattedTextField textField, final int calendarField) {
1057:                boolean selecting = false;
1058:                int length = textField.getText().length();
1059:                for (int i = 0; i <= length; i++) {
1060:                    if (!selecting) {
1061:                        textField.setCaretPosition(i);
1062:                    } else {
1063:                        textField.moveCaretPosition(i);
1064:                    }
1065:                    if (getCalendarField(textField) == calendarField) {
1066:                        selecting = true;
1067:                    } else {
1068:                        if (selecting) {
1069:                            textField.moveCaretPosition(i - 1);
1070:                            return;
1071:                        }
1072:                    }
1073:                }
1074:            }
1075:
1076:            public static Object getNextValue(final Date value,
1077:                    final int calendarField, final Comparable<Date> end) {
1078:                Calendar calendar = Calendar.getInstance();
1079:                calendar.setTime(value);
1080:                calendar.add(calendarField, 1);
1081:                Date result = calendar.getTime();
1082:                return (end == null) ? result
1083:                        : (end.compareTo(result) < 0) ? null : result;
1084:            }
1085:
1086:            public static Object getPreviousValue(final Date value,
1087:                    final int calendarField, final Comparable<Date> start) {
1088:                Calendar calendar = Calendar.getInstance();
1089:                calendar.setTime(value);
1090:                calendar.add(calendarField, -1);
1091:                Date result = calendar.getTime();
1092:                return (start == null) ? result
1093:                        : (start.compareTo(result) > 0) ? null : result;
1094:            }
1095:
1096:            /**
1097:             * Transforms position at the document model coordinate space to the
1098:             * coordinate space of the corresponding icon or component view.
1099:             */
1100:            public static Shape modelToIconOrComponentView(final View view,
1101:                    final int pos, final Shape shape, final Bias bias)
1102:                    throws BadLocationException {
1103:
1104:                TextUtils.isPositionValid(view, pos);
1105:
1106:                final Rectangle bounds = shape.getBounds();
1107:                final int x = (pos == view.getStartOffset() ? bounds.x
1108:                        : bounds.x + bounds.width);
1109:
1110:                return new Rectangle(x, bounds.y, 0, bounds.height);
1111:            }
1112:
1113:            /**
1114:             * Throws BadLocationException if the position does not represent a
1115:             * valid location in the associated document element.
1116:             */
1117:            public static void isPositionValid(final View view, final int pos)
1118:                    throws BadLocationException {
1119:
1120:                if (pos < view.getStartOffset() || pos > view.getEndOffset()) {
1121:                    // awt.2E={0} not in range {1},{2}
1122:                    throw new BadLocationException(Messages.getString("awt.2E", //$NON-NLS-1$
1123:                            new Object[] { pos, view.getStartOffset(),
1124:                                    view.getEndOffset() }), pos);
1125:                }
1126:            }
1127:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.