Source Code Cross Referenced for ExtFormatter.java in  » Swing-Library » abeille-forms-designer » org » netbeans » editor » ext » 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.ext 
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.ext;
015:
016:        import java.io.CharArrayWriter;
017:        import java.io.IOException;
018:        import java.io.Writer;
019:        import java.util.ArrayList;
020:        import java.util.HashMap;
021:        import java.util.Iterator;
022:        import java.util.List;
023:        import java.util.Map;
024:
025:        import javax.swing.text.BadLocationException;
026:        import javax.swing.text.Document;
027:        import javax.swing.text.JTextComponent;
028:
029:        import org.netbeans.editor.Acceptor;
030:        import org.netbeans.editor.AcceptorFactory;
031:        import org.netbeans.editor.BaseDocument;
032:        import org.netbeans.editor.Formatter;
033:        import org.netbeans.editor.GuardedException;
034:        import org.netbeans.editor.Settings;
035:        import org.netbeans.editor.SettingsChangeEvent;
036:        import org.netbeans.editor.SettingsUtil;
037:        import org.netbeans.editor.Syntax;
038:        import org.netbeans.editor.Utilities;
039:
040:        /**
041:         * Unlike the formatter class, the ExtFormatter concentrates on providing a
042:         * support for the real formatting process. Each formatter (there's only one per
043:         * each kit) can contain one or more formatting layers. The <tt>FormatLayer</tt>
044:         * operates over the chain of the tokens provided by the <tt>FormatWriter</tt>.
045:         * The formatting consist of changing the chain of the tokens until it gets the
046:         * desired look. Each formatting requires a separate instance of
047:         * <tt>FormatWriter</tt> but the same set of format-layers is used for all the
048:         * format-writers. Although the base implementation is synchronized so that only
049:         * one format-writer at time is processed by each format-writer, in general it's
050:         * not necessary. The basic implementation processes all the format-layers
051:         * sequentialy in the order they were added to the formatter but this can be
052:         * redefined. The <tt>getSettingValue</tt> enables to get the up-to-date value
053:         * for the particular setting.
054:         * 
055:         * @author Miloslav Metelka
056:         * @version 1.00
057:         */
058:
059:        public class ExtFormatter extends Formatter implements  FormatLayer {
060:
061:            /** List holding the format layers */
062:            private List formatLayerList = new ArrayList();
063:
064:            /** Use this instead of testing by containsKey() */
065:            private static final Object NULL_VALUE = new Object();
066:
067:            /** Map that contains the requested [setting-name, setting-value] pairs */
068:            private HashMap settingsMap = new HashMap();
069:
070:            /**
071:             * Contains the names of the keys that were turned into custom settings and
072:             * are no longer read from the Settings.
073:             */
074:            private HashMap customSettingsNamesMap = new HashMap();
075:
076:            private Acceptor indentHotCharsAcceptor;
077:            private boolean reindentWithTextBefore;
078:
079:            public ExtFormatter(Class kitClass) {
080:                super (kitClass);
081:
082:                initFormatLayers();
083:            }
084:
085:            /** Add the desired format-layers to the formatter */
086:            protected void initFormatLayers() {
087:            }
088:
089:            /**
090:             * Return the name of this formatter. By default it's the name of the
091:             * kit-class for which it's created without the package name.
092:             */
093:            public String getName() {
094:                return getKitClass().getName().substring(
095:                        getKitClass().getName().lastIndexOf('.') + 1);
096:            }
097:
098:            public void settingsChange(SettingsChangeEvent evt) {
099:                super .settingsChange(evt);
100:                String settingName = (evt != null) ? evt.getSettingName()
101:                        : null;
102:
103:                Class kitClass = getKitClass();
104:                Iterator eit = settingsMap.entrySet().iterator();
105:                while (eit.hasNext()) {
106:                    Map.Entry e = (Map.Entry) eit.next();
107:                    if (settingName == null || e.getKey().equals(e.getKey())) {
108:                        if (!customSettingsNamesMap.containsKey(e.getKey())) { // not
109:                            // custom
110:                            e.setValue(Settings.getValue(kitClass, (String) e
111:                                    .getKey()));
112:                        }
113:                    }
114:                }
115:
116:                indentHotCharsAcceptor = SettingsUtil.getAcceptor(kitClass,
117:                        ExtSettingsNames.INDENT_HOT_CHARS_ACCEPTOR,
118:                        AcceptorFactory.FALSE);
119:
120:                reindentWithTextBefore = SettingsUtil.getBoolean(kitClass,
121:                        ExtSettingsNames.REINDENT_WITH_TEXT_BEFORE, false);
122:            }
123:
124:            /**
125:             * Get the value of the given setting.
126:             * 
127:             * @param settingName
128:             *            name of the setting to get.
129:             */
130:            public Object getSettingValue(String settingName) {
131:                synchronized (Settings.class) {
132:                    Object value = settingsMap.get(settingName);
133:                    if (value == null
134:                            && !customSettingsNamesMap.containsKey(settingName)) {
135:                        value = Settings.getValue(getKitClass(), settingName);
136:                        if (value == null) {
137:                            value = NULL_VALUE;
138:                        }
139:                        settingsMap.put(settingName, value);
140:                    }
141:                    return (value != NULL_VALUE) ? value : null;
142:                }
143:            }
144:
145:            /**
146:             * This method allows to set a custom value to a setting thus overriding the
147:             * value retrieved from the <tt>Settings</tt>. Once done the value is no
148:             * longer synchronized with the changes in <tt>Settings</tt> for the
149:             * particular setting. There's a map holding the names of all the custom
150:             * settings.
151:             */
152:            public void setSettingValue(String settingName, Object settingValue) {
153:                synchronized (Settings.class) {
154:                    customSettingsNamesMap.put(settingName, settingName);
155:                    settingsMap.put(settingName, settingValue);
156:                }
157:            }
158:
159:            /**
160:             * Add the new format layer to the layer hierarchy.
161:             */
162:            public synchronized void addFormatLayer(FormatLayer layer) {
163:                formatLayerList.add(layer);
164:            }
165:
166:            /**
167:             * Replace the format-layer with the layerName with the the given layer. If
168:             * there's no such layer with the same name, the layer is not replaced and
169:             * false is returned.
170:             */
171:            public synchronized boolean replaceFormatLayer(String layerName,
172:                    FormatLayer layer) {
173:                int cnt = formatLayerList.size();
174:                for (int i = 0; i < cnt; i++) {
175:                    if (layerName.equals(((FormatLayer) formatLayerList.get(i))
176:                            .getName())) {
177:                        formatLayerList.set(i, layer);
178:                        return true;
179:                    }
180:                }
181:                return false;
182:            }
183:
184:            /**
185:             * Remove the first layer which has the same name as the given one.
186:             */
187:            public synchronized void removeFormatLayer(String layerName) {
188:                Iterator it = formatLayerIterator();
189:                while (it.hasNext()) {
190:                    if (layerName.equals(((FormatLayer) it.next()).getName())) {
191:                        it.remove();
192:                        return;
193:                    }
194:                }
195:            }
196:
197:            /**
198:             * Get the iterator over the format layers.
199:             */
200:            public Iterator formatLayerIterator() {
201:                return formatLayerList.iterator();
202:            }
203:
204:            /**
205:             * Whether do no formatting at all. If this method returns true, the
206:             * FormatWriter will simply write its input into the underlying writer.
207:             */
208:            public boolean isSimple() {
209:                return false;
210:            }
211:
212:            /** Called by format-writer to do the format */
213:            public synchronized void format(FormatWriter fw) {
214:                boolean done = false;
215:                int safetyCounter = 0;
216:                do {
217:                    // Mark the chain as unmodified at the begining
218:                    fw.setChainModified(false);
219:                    fw.setRestartFormat(false);
220:
221:                    Iterator it = formatLayerIterator();
222:                    while (it.hasNext()) {
223:                        ((FormatLayer) it.next()).format(fw);
224:                        if (fw.isRestartFormat()) {
225:                            break;
226:                        }
227:                    }
228:
229:                    if (!it.hasNext() && !fw.isRestartFormat()) {
230:                        done = true;
231:                    }
232:
233:                    if (safetyCounter > 1000) { // prevent infinite loop
234:                        new Exception("Indentation infinite loop detected")
235:                                .printStackTrace(); // NOI18N
236:                        break;
237:                    }
238:                } while (!done);
239:            }
240:
241:            /**
242:             * Reformat a block of code.
243:             * 
244:             * @param doc
245:             *            document to work with
246:             * @param startOffset
247:             *            position at which the formatting starts
248:             * @param endOffset
249:             *            position at which the formatting ends
250:             * @param indentOnly
251:             *            whether just the indentation should be changed or regular
252:             *            formatting should be performed.
253:             * @return formatting writer. The text was already reformatted but the
254:             *         writer can contain useful information.
255:             */
256:            public Writer reformat(BaseDocument doc, int startOffset,
257:                    int endOffset, boolean indentOnly)
258:                    throws BadLocationException, IOException {
259:                CharArrayWriter cw = new CharArrayWriter();
260:                Writer w = createWriter(doc, startOffset, cw);
261:                FormatWriter fw = (w instanceof  FormatWriter) ? (FormatWriter) w
262:                        : null;
263:
264:                boolean fix5620 = true; // whether apply fix for #5620 or not
265:
266:                if (fw != null) {
267:                    fw.setIndentOnly(indentOnly);
268:                    if (fix5620) {
269:                        fw.setReformatting(true); // #5620
270:                    }
271:                }
272:
273:                w.write(doc.getChars(startOffset, endOffset - startOffset));
274:                w.close();
275:
276:                if (!fix5620 || fw == null) { // #5620 - for (fw != null) the doc was
277:                    // already modified
278:                    String out = new String(cw.toCharArray());
279:                    doc.remove(startOffset, endOffset - startOffset);
280:                    doc.insertString(startOffset, out, null);
281:                }
282:
283:                return w;
284:            }
285:
286:            /** Fix of #5620 - same method exists in Formatter (predecessor */
287:            public int reformat(BaseDocument doc, int startOffset, int endOffset)
288:                    throws BadLocationException {
289:                try {
290:                    javax.swing.text.Position pos = doc
291:                            .createPosition(endOffset);
292:                    reformat(doc, startOffset, endOffset, false);
293:                    return pos.getOffset() - startOffset;
294:                } catch (IOException e) {
295:                    e.printStackTrace();
296:                    return 0;
297:                }
298:            }
299:
300:            /**
301:             * Get the block to be reformatted after keystroke was pressed.
302:             * 
303:             * @param target
304:             *            component to which the text was typed. Caaret position can be
305:             *            checked etc.
306:             * @param typedText
307:             *            text (usually just one character) that the user has typed.
308:             * @return block of the code to be reformatted or null if nothing should
309:             *         reformatted. It can return block containing just one character.
310:             *         The caller usually expands even one character to the whole line
311:             *         because less than the whole line usually doesn't provide enough
312:             *         possibilities for formatting.
313:             * @see ExtKit.ExtDefaultKeyTypedAction.checkIndentHotChars()
314:             */
315:            public int[] getReformatBlock(JTextComponent target,
316:                    String typedText) {
317:                if (indentHotCharsAcceptor == null) { // init if necessary
318:                    settingsChange(null);
319:                }
320:
321:                if (indentHotCharsAcceptor.accept(typedText.charAt(0))) {
322:                    /*
323:                     * This is bugfix 10771. See the issue for problem description. The
324:                     * behaviour before fix was that whenever the lbrace is entered, the
325:                     * line is indented. This make no sense if a text exist on the line
326:                     * before the lbrace. In this case we simply will not indent the
327:                     * line. This is handled by the hasTextBefore check
328:                     */
329:                    if (!reindentWithTextBefore) {
330:                        if (hasTextBefore(target, typedText)) {
331:                            return null;
332:                        }
333:                    }
334:                    int dotPos = target.getCaret().getDot();
335:                    return new int[] { Math.max(dotPos - 1, 0), dotPos };
336:
337:                } else {
338:                    return null;
339:                }
340:            }
341:
342:            protected boolean hasTextBefore(JTextComponent target,
343:                    String typedText) {
344:                BaseDocument doc = Utilities.getDocument(target);
345:                int dotPos = target.getCaret().getDot();
346:                try {
347:                    int fnw = Utilities.getRowFirstNonWhite(doc, dotPos);
348:                    return dotPos != fnw + typedText.length();
349:                } catch (BadLocationException e) {
350:                    return false;
351:                }
352:            }
353:
354:            /**
355:             * Create the indentation writer.
356:             */
357:            public Writer createWriter(Document doc, int offset, Writer writer) {
358:                return new FormatWriter(this , doc, offset, writer, false);
359:            }
360:
361:            /**
362:             * Indents the current line. Should not affect any other lines.
363:             * 
364:             * @param doc
365:             *            the document to work on
366:             * @param offset
367:             *            the offset of a character on the line
368:             * @return new offset of the original character
369:             */
370:            public int indentLine(Document doc, int offset) {
371:                if (doc instanceof  BaseDocument) {
372:                    try {
373:                        BaseDocument bdoc = (BaseDocument) doc;
374:                        int lineStart = Utilities.getRowStart(bdoc, offset);
375:                        int nextLineStart = Utilities.getRowStart(bdoc, offset,
376:                                1);
377:                        if (nextLineStart < 0) { // end of doc
378:                            nextLineStart = bdoc.getLength();
379:                        }
380:                        reformat(bdoc, lineStart, nextLineStart, false);
381:                        return Utilities.getRowEnd(bdoc, lineStart);
382:                    } catch (GuardedException e) {
383:                        java.awt.Toolkit.getDefaultToolkit().beep();
384:
385:                    } catch (BadLocationException e) {
386:                        if (Boolean.getBoolean("netbeans.debug.exceptions")) { // NOI18N
387:                            e.printStackTrace();
388:                        }
389:
390:                    } catch (IOException e) {
391:                        if (Boolean.getBoolean("netbeans.debug.exceptions")) { // NOI18N
392:                            e.printStackTrace();
393:                        }
394:
395:                    }
396:
397:                    return offset;
398:
399:                }
400:
401:                return super .indentLine(doc, offset);
402:            }
403:
404:            /**
405:             * Inserts new line at given position and indents the new line with spaces.
406:             * 
407:             * @param doc
408:             *            the document to work on
409:             * @param offset
410:             *            the offset of a character on the line
411:             * @return new offset to place cursor to
412:             */
413:            public int indentNewLine(Document doc, int offset) {
414:                if (doc instanceof  BaseDocument) {
415:                    BaseDocument bdoc = (BaseDocument) doc;
416:                    boolean newLineInserted = false;
417:
418:                    bdoc.atomicLock();
419:                    try {
420:                        bdoc.insertString(offset, "\n", null); // NOI18N
421:                        offset++;
422:                        newLineInserted = true;
423:
424:                        int eolOffset = Utilities.getRowEnd(bdoc, offset);
425:
426:                        // Try to change the indent of the new line
427:                        // It may fail when inserting '\n' before the guarded block
428:                        Writer w = reformat(bdoc, offset, eolOffset, true);
429:
430:                        // Find the caret position
431:                        eolOffset = Utilities.getRowFirstNonWhite(bdoc, offset);
432:                        if (eolOffset < 0) { // white line
433:                            eolOffset = Utilities.getRowEnd(bdoc, offset);
434:                        }
435:
436:                        offset = eolOffset;
437:
438:                        // Resulting offset (caret position) can be shifted
439:                        if (w instanceof  FormatWriter) {
440:                            offset += ((FormatWriter) w).getIndentShift();
441:                        }
442:
443:                    } catch (GuardedException e) {
444:                        // Possibly couldn't insert additional indentation
445:                        // at the begining of the guarded block
446:                        // but the initial '\n' could be fine
447:                        if (!newLineInserted) {
448:                            java.awt.Toolkit.getDefaultToolkit().beep();
449:                        }
450:
451:                    } catch (BadLocationException e) {
452:                        if (Boolean.getBoolean("netbeans.debug.exceptions")) { // NOI18N
453:                            e.printStackTrace();
454:                        }
455:
456:                    } catch (IOException e) {
457:                        if (Boolean.getBoolean("netbeans.debug.exceptions")) { // NOI18N
458:                            e.printStackTrace();
459:                        }
460:
461:                    } finally {
462:                        bdoc.atomicUnlock();
463:                    }
464:
465:                } else { // not BaseDocument
466:                    try {
467:                        doc.insertString(offset, "\n", null); // NOI18N
468:                        offset++;
469:                    } catch (BadLocationException ex) {
470:                    }
471:                }
472:
473:                return offset;
474:            }
475:
476:            /**
477:             * Whether the formatter accepts the given syntax that will be used for
478:             * parsing the text passed to the FormatWriter.
479:             * 
480:             * @param syntax
481:             *            syntax to be tested.
482:             * @return true whether this formatter is able to process the tokens created
483:             *         by the syntax or false otherwise.
484:             */
485:            protected boolean acceptSyntax(Syntax syntax) {
486:                return true;
487:            }
488:
489:            /** Simple formatter */
490:            public static class Simple extends ExtFormatter {
491:
492:                public Simple(Class kitClass) {
493:                    super (kitClass);
494:                }
495:
496:                public boolean isSimple() {
497:                    return true;
498:                }
499:
500:            }
501:
502:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.