Source Code Cross Referenced for Formatter.java in  » Swing-Library » abeille-forms-designer » org » netbeans » editor » 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 » Swing Library » abeille forms designer » org.netbeans.editor 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *                 Sun Public License Notice
003:         * 
004:         * The contents of this file are subject to the Sun Public License
005:         * Version 1.0 (the "License"). You may not use this file except in
006:         * compliance with the License. A copy of the License is available at
007:         * http://www.sun.com/
008:         * 
009:         * The Original Code is NetBeans. The Initial Developer of the Original
010:         * Code is Sun Microsystems, Inc. Portions Copyright 1997-2000 Sun
011:         * Microsystems, Inc. All Rights Reserved.
012:         */
013:
014:        package org.netbeans.editor;
015:
016:        import java.io.CharArrayWriter;
017:        import java.io.IOException;
018:        import java.io.Writer;
019:        import java.util.HashMap;
020:        import java.util.Map;
021:
022:        import javax.swing.text.BadLocationException;
023:        import javax.swing.text.Document;
024:
025:        /**
026:         * Various services related to indentation and text formatting are located here.
027:         * Each kit can have different formatter so the first action should be getting
028:         * the right formatter for the given kit by calling
029:         * Formatter.getFormatter(kitClass).
030:         * 
031:         * @author Miloslav Metelka
032:         * @version 1.00
033:         */
034:
035:        public class Formatter implements  SettingsChangeListener {
036:
037:            private static Map kitClass2Formatter = new HashMap();
038:
039:            /** Get the formatter for the given kit-class */
040:            public static synchronized Formatter getFormatter(Class kitClass) {
041:                Formatter f = (Formatter) kitClass2Formatter.get(kitClass);
042:                if (f == null) {
043:                    f = BaseKit.getKit(kitClass).createFormatter();
044:                    kitClass2Formatter.put(kitClass, f);
045:                }
046:                return f;
047:            }
048:
049:            /**
050:             * Set the formatter for the given kit-class.
051:             * 
052:             * @param kitClass
053:             *            class of the kit for which the formatter is being assigned.
054:             * @param formatter
055:             *            new formatter for the given kit
056:             */
057:            public static synchronized void setFormatter(Class kitClass,
058:                    Formatter formatter) {
059:                kitClass2Formatter.put(kitClass, formatter);
060:            }
061:
062:            /** Maximum tab size for which the indent strings will be cached. */
063:            private static final int ISC_MAX_TAB_SIZE = 16;
064:
065:            /** Cache the indentation strings up to this size */
066:            private static final int ISC_MAX_INDENT_SIZE = 32;
067:
068:            /** Cache holding the indentation strings for various tab-sizes. */
069:            private static final String[][] indentStringCache = new String[ISC_MAX_TAB_SIZE][];
070:
071:            private final Class kitClass;
072:
073:            /** Whether values were already inited from the cache */
074:            private boolean inited;
075:
076:            private int tabSize;
077:
078:            private boolean customTabSize;
079:
080:            private Integer shiftWidth;
081:
082:            private boolean customShiftWidth;
083:
084:            private boolean expandTabs;
085:
086:            private boolean customExpandTabs;
087:
088:            private int spacesPerTab;
089:
090:            private boolean customSpacesPerTab;
091:
092:            /**
093:             * Construct new formatter.
094:             * 
095:             * @param kitClass
096:             *            the class of the kit for which this formatter is being
097:             *            constructed.
098:             */
099:            public Formatter(Class kitClass) {
100:                this .kitClass = kitClass;
101:                Settings.addSettingsChangeListener(this );
102:            }
103:
104:            /** Get the kit-class for which this formatter is constructed. */
105:            public Class getKitClass() {
106:                return kitClass;
107:            }
108:
109:            public void settingsChange(SettingsChangeEvent evt) {
110:                String settingName = (evt != null) ? evt.getSettingName()
111:                        : null;
112:                if (!inited || settingName == null
113:                        || SettingsNames.TAB_SIZE.equals(settingName)) {
114:                    if (!customTabSize) {
115:                        tabSize = SettingsUtil.getInteger(kitClass,
116:                                SettingsNames.TAB_SIZE,
117:                                SettingsDefaults.defaultTabSize);
118:                    }
119:                }
120:
121:                // Shift-width often depends on the rest of parameters
122:                if (!customShiftWidth) {
123:                    Object shw = Settings.getValue(kitClass,
124:                            SettingsNames.INDENT_SHIFT_WIDTH);
125:                    if (shw instanceof  Integer) {
126:                        shiftWidth = (Integer) shw;
127:                    }
128:                }
129:
130:                if (!inited || settingName == null
131:                        || SettingsNames.EXPAND_TABS.equals(settingName)) {
132:                    if (!customExpandTabs) {
133:                        expandTabs = SettingsUtil.getBoolean(kitClass,
134:                                SettingsNames.EXPAND_TABS,
135:                                SettingsDefaults.defaultExpandTabs);
136:                    }
137:                }
138:                if (!inited || settingName == null
139:                        || SettingsNames.SPACES_PER_TAB.equals(settingName)) {
140:                    if (!customSpacesPerTab) {
141:                        spacesPerTab = SettingsUtil.getInteger(kitClass,
142:                                SettingsNames.SPACES_PER_TAB,
143:                                SettingsDefaults.defaultSpacesPerTab);
144:                    }
145:                }
146:
147:                inited = true;
148:            }
149:
150:            /**
151:             * Get the number of spaces the TAB character ('\t') visually represents for
152:             * non-BaseDocument documents. It shouldn't be used for BaseDocument based
153:             * documents. The reason for that is that the returned value reflects the
154:             * value of the setting for the kit class over which this formatter was
155:             * constructed. However it's possible that the kit class of the document
156:             * being formatted is different than the kit of the formatter. For example
157:             * java document could be formatted by html formatter. Therefore
158:             * <code>BaseDocument.getTabSize()</code> must be used for BaseDocuments
159:             * to reflect the document's own tabsize.
160:             * 
161:             * @see BaseDocument.getTabSize()
162:             */
163:            public int getTabSize() {
164:                if (!customTabSize && !inited) {
165:                    settingsChange(null);
166:                }
167:
168:                return tabSize;
169:            }
170:
171:            /**
172:             * Set the number of spaces the TAB character ('\t') visually represents for
173:             * non-BaseDocument documents. It doesn't affect BaseDocument based
174:             * documents.
175:             * 
176:             * @see getTabSize()
177:             * @see BaseDocument.setTabSize()
178:             */
179:            public void setTabSize(int tabSize) {
180:                customTabSize = true;
181:                this .tabSize = tabSize;
182:            }
183:
184:            /**
185:             * Get the width of one indentation level for non-BaseDocument documents.
186:             * The algorithm first checks whether there's a value for the
187:             * INDENT_SHIFT_WIDTH setting. If so it uses it, otherwise it uses
188:             * <code>getSpacesPerTab()</code>
189:             * 
190:             * @see setShiftWidth()
191:             * @see getSpacesPerTab()
192:             */
193:            public int getShiftWidth() {
194:                if (!customShiftWidth && !inited) {
195:                    settingsChange(null);
196:                }
197:
198:                return (shiftWidth != null) ? shiftWidth.intValue()
199:                        : getSpacesPerTab();
200:            }
201:
202:            /**
203:             * Set the width of one indentation level for non-BaseDocument documents. It
204:             * doesn't affect BaseDocument based documents.
205:             * 
206:             * @see getShiftWidth()
207:             */
208:            public void setShiftWidth(int shiftWidth) {
209:                customShiftWidth = true;
210:                if (this .shiftWidth == null
211:                        || this .shiftWidth.intValue() != shiftWidth) {
212:                    this .shiftWidth = new Integer(shiftWidth);
213:                }
214:            }
215:
216:            /** Should the typed tabs be expanded to the spaces? */
217:            public boolean expandTabs() {
218:                if (!customExpandTabs && !inited) {
219:                    settingsChange(null);
220:                }
221:
222:                return expandTabs;
223:            }
224:
225:            public void setExpandTabs(boolean expandTabs) {
226:                customExpandTabs = true;
227:                this .expandTabs = expandTabs;
228:            }
229:
230:            /**
231:             * Get the number of spaces that should be inserted into the document
232:             * instead of one typed tab.
233:             */
234:            public int getSpacesPerTab() {
235:                if (!customSpacesPerTab && !inited) {
236:                    settingsChange(null);
237:                }
238:
239:                return spacesPerTab;
240:            }
241:
242:            public void setSpacesPerTab(int spacesPerTab) {
243:                customSpacesPerTab = true;
244:                this .spacesPerTab = spacesPerTab;
245:            }
246:
247:            static String getIndentString(int indent, boolean expandTabs,
248:                    int tabSize) {
249:                if (indent <= 0) {
250:                    return "";
251:                }
252:
253:                if (expandTabs) { // store in 0th slot
254:                    tabSize = 0;
255:                }
256:
257:                synchronized (Settings.class) {
258:                    boolean large = (tabSize >= indentStringCache.length)
259:                            || (indent > ISC_MAX_INDENT_SIZE); // indexed
260:                    // by
261:                    // (indent
262:                    // - 1)
263:                    String indentString = null;
264:                    String[] tabCache = null;
265:                    if (!large) {
266:                        tabCache = indentStringCache[tabSize]; // cache for this tab
267:                        if (tabCache == null) {
268:                            tabCache = new String[ISC_MAX_INDENT_SIZE];
269:                            indentStringCache[tabSize] = tabCache;
270:                        }
271:                        indentString = tabCache[indent - 1];
272:                    }
273:
274:                    if (indentString == null) {
275:                        indentString = Analyzer.getIndentString(indent,
276:                                expandTabs, tabSize);
277:
278:                        if (!large) {
279:                            tabCache[indent - 1] = indentString;
280:                        }
281:                    }
282:
283:                    return indentString;
284:                }
285:            }
286:
287:            public String getIndentString(BaseDocument doc, int indent) {
288:                return getIndentString(indent, expandTabs(), doc.getTabSize());
289:            }
290:
291:            /**
292:             * Get the string that is appropriate for the requested indentation. The
293:             * returned string respects the <tt>expandTabs()</tt> and the
294:             * <tt>getTabSize()</tt> and will contain either spaces only or fully or
295:             * partially tabs as necessary.
296:             */
297:            public String getIndentString(int indent) {
298:                return getIndentString(indent, expandTabs(), getTabSize());
299:            }
300:
301:            /**
302:             * Modify the line to move the text starting at dotPos one tab column to the
303:             * right. Whitespace preceeding dotPos may be replaced by a TAB character if
304:             * tabs expanding is on.
305:             * 
306:             * @param doc
307:             *            document to operate on
308:             * @param dotPos
309:             *            insertion point
310:             */
311:            public void insertTabString(BaseDocument doc, int dotPos)
312:                    throws BadLocationException {
313:                doc.atomicLock();
314:                try {
315:                    // Determine first white char before dotPos
316:                    int rsPos = Utilities.getRowStart(doc, dotPos);
317:                    int startPos = Utilities.getFirstNonWhiteBwd(doc, dotPos,
318:                            rsPos);
319:                    startPos = (startPos >= 0) ? (startPos + 1) : rsPos;
320:
321:                    int startCol = Utilities.getVisualColumn(doc, startPos);
322:                    int endCol = Utilities.getNextTabColumn(doc, dotPos);
323:                    String tabStr = Analyzer.getWhitespaceString(startCol,
324:                            endCol, expandTabs(), doc.getTabSize());
325:
326:                    // Search for the first non-common char
327:                    char[] removeChars = doc.getChars(startPos, dotPos
328:                            - startPos);
329:                    int ind = 0;
330:                    while (ind < removeChars.length
331:                            && removeChars[ind] == tabStr.charAt(ind)) {
332:                        ind++;
333:                    }
334:
335:                    startPos += ind;
336:                    doc.remove(startPos, dotPos - startPos);
337:                    doc.insertString(startPos, tabStr.substring(ind), null);
338:
339:                } finally {
340:                    doc.atomicUnlock();
341:                }
342:            }
343:
344:            /**
345:             * Change the indent of the given row. Document is atomically locked during
346:             * this operation.
347:             */
348:            public void changeRowIndent(BaseDocument doc, int pos, int newIndent)
349:                    throws BadLocationException {
350:                doc.atomicLock();
351:                try {
352:                    if (newIndent < 0) {
353:                        newIndent = 0;
354:                    }
355:                    int firstNW = Utilities.getRowFirstNonWhite(doc, pos);
356:                    if (firstNW == -1) { // valid first non-blank
357:                        firstNW = Utilities.getRowEnd(doc, pos);
358:                    }
359:                    int bolPos = Utilities.getRowStart(doc, pos);
360:                    doc.remove(bolPos, firstNW - bolPos); // !!! indent by spaces/tabs
361:
362:                    doc.insertString(bolPos, getIndentString(doc, newIndent),
363:                            null);
364:                } finally {
365:                    doc.atomicUnlock();
366:                }
367:            }
368:
369:            /**
370:             * Increase/decrease indentation of the block of the code. Document is
371:             * atomically locked during the operation.
372:             * 
373:             * @param doc
374:             *            document to operate on
375:             * @param startPos
376:             *            starting line position
377:             * @param endPos
378:             *            ending line position
379:             * @param shiftCnt
380:             *            positive/negative count of shiftwidths by which indentation
381:             *            should be shifted right/left
382:             */
383:            public void changeBlockIndent(BaseDocument doc, int startPos,
384:                    int endPos, int shiftCnt) throws BadLocationException {
385:                doc.atomicLock();
386:                try {
387:
388:                    int indentDelta = shiftCnt * doc.getShiftWidth();
389:                    if (endPos > 0
390:                            && Utilities.getRowStart(doc, endPos) == endPos) {
391:                        endPos--;
392:                    }
393:
394:                    int pos = Utilities.getRowStart(doc, startPos);
395:                    for (int lineCnt = Utilities.getRowCount(doc, startPos,
396:                            endPos); lineCnt > 0; lineCnt--) {
397:                        int indent = Utilities.getRowIndent(doc, pos);
398:                        if (Utilities.isRowWhite(doc, pos)) {
399:                            indent = -indentDelta; // zero indentation for white line
400:                        }
401:                        changeRowIndent(doc, pos, Math.max(
402:                                indent + indentDelta, 0));
403:                        pos = Utilities.getRowStart(doc, pos, +1);
404:                    }
405:
406:                } finally {
407:                    doc.atomicUnlock();
408:                }
409:            }
410:
411:            /** Shift line either left or right */
412:            public void shiftLine(BaseDocument doc, int dotPos, boolean right)
413:                    throws BadLocationException {
414:                int ind = doc.getShiftWidth();
415:                if (!right) {
416:                    ind = -ind;
417:                }
418:
419:                if (Utilities.isRowWhite(doc, dotPos)) {
420:                    ind += Utilities.getVisualColumn(doc, dotPos);
421:                } else {
422:                    ind += Utilities.getRowIndent(doc, dotPos);
423:                }
424:                ind = Math.max(ind, 0);
425:                changeRowIndent(doc, dotPos, ind);
426:            }
427:
428:            /**
429:             * Reformat a block of code.
430:             * 
431:             * @param doc
432:             *            document to work with
433:             * @param startOffset
434:             *            offset at which the formatting starts
435:             * @param endOffset
436:             *            offset at which the formatting ends
437:             * @return length of the reformatted code
438:             */
439:            public int reformat(BaseDocument doc, int startOffset, int endOffset)
440:                    throws BadLocationException {
441:                try {
442:                    CharArrayWriter cw = new CharArrayWriter();
443:                    Writer w = createWriter(doc, startOffset, cw);
444:                    w.write(doc.getChars(startOffset, endOffset - startOffset));
445:                    w.close();
446:                    String out = new String(cw.toCharArray());
447:                    doc.remove(startOffset, endOffset - startOffset);
448:                    doc.insertString(startOffset, out, null);
449:                    return out.length();
450:                } catch (IOException e) {
451:                    if (System.getProperty("netbeans.debug.exceptions") != null) { // NOI18N
452:                        e.printStackTrace();
453:                    }
454:                    return 0;
455:                }
456:            }
457:
458:            /**
459:             * Indents the current line. Should not affect any other lines.
460:             * 
461:             * @param doc
462:             *            the document to work on
463:             * @param offset
464:             *            the offset of a character on the line
465:             * @return new offset of the original character
466:             */
467:            public int indentLine(Document doc, int offset) {
468:                return offset;
469:            }
470:
471:            /**
472:             * Inserts new line at given position and indents the new line with spaces.
473:             * 
474:             * @param doc
475:             *            the document to work on
476:             * @param offset
477:             *            the offset of a character on the line
478:             * @return new offset to place cursor to
479:             */
480:            public int indentNewLine(Document doc, int offset) {
481:                try {
482:                    doc.insertString(offset, "\n", null); // NOI18N
483:                    offset++;
484:
485:                } catch (GuardedException e) {
486:                    java.awt.Toolkit.getDefaultToolkit().beep();
487:
488:                } catch (BadLocationException e) {
489:                    if (Boolean.getBoolean("netbeans.debug.exceptions")) { // NOI18N
490:                        e.printStackTrace();
491:                    }
492:                }
493:
494:                return offset;
495:            }
496:
497:            /**
498:             * Creates a writer that formats text that is inserted into it. The writer
499:             * should not modify the document but use the provided writer to write to.
500:             * Usually the underlaying writer will modify the document itself and
501:             * optionally it can remember the current position in document. That is why
502:             * the newly created writer should do no buffering.
503:             * <P>
504:             * The provided document and pos are only informational, should not be
505:             * modified but only used to find correct indentation strategy.
506:             * 
507:             * @param doc
508:             *            document
509:             * @param offset
510:             *            position to begin inserts at
511:             * @param writer
512:             *            writer to write to
513:             * @return new writer that will format written text and pass it into the
514:             *         writer
515:             */
516:            public Writer createWriter(Document doc, int offset, Writer writer) {
517:                return writer;
518:            }
519:
520:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.