Source Code Cross Referenced for SyntaxHighlighterPanel.java in  » Database-Client » DBBrowser » org » dbbrowser » ui » widget » 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 » Database Client » DBBrowser » org.dbbrowser.ui.widget 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        package org.dbbrowser.ui.widget;
0002:
0003:        /*
0004:         * A simple text editor that demonstrates the integration of the 
0005:         * com.Ostermiller.Syntax Syntax Highlighting package with a text editor.
0006:         * Copyright (C) 2001 Stephen Ostermiller 
0007:         * http://ostermiller.org/contact.pl?regarding=Syntax+Highlighting
0008:         *
0009:         * This program is free software; you can redistribute it and/or modify
0010:         * it under the terms of the GNU General Public License as published by
0011:         * the Free Software Foundation; either version 2 of the License, or
0012:         * (at your option) any later version.
0013:         *
0014:         * This program is distributed in the hope that it will be useful,
0015:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0016:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0017:         * GNU General Public License for more details.
0018:         *
0019:         * See COPYING.TXT for details.
0020:         */
0021:        import java.awt.*;
0022:        import java.awt.event.*;
0023:        import javax.swing.*;
0024:        import javax.swing.text.*;
0025:        import java.io.*;
0026:        import java.util.*;
0027:        import com.Ostermiller.Syntax.Lexer.*;
0028:
0029:        /**
0030:         * A <a href="http://ostermiller.org/syntax/editor.html">demonstration text editor</a>
0031:         * that uses syntax highlighting.
0032:         */
0033:        public class SyntaxHighlighterPanel extends JPanel {
0034:            /**
0035:             * The place where the text is drawn.
0036:             */
0037:            protected JTextPane textPane;
0038:            /**
0039:             * the styled document that is the model for
0040:             * the textPane
0041:             */
0042:            protected HighLightedDocument document;
0043:            /**
0044:             * A reader wrapped around the document
0045:             * so that the document can be fed into
0046:             * the lexer.
0047:             */
0048:            protected DocumentReader documentReader;
0049:            /**
0050:             * The lexer that tells us what colors different
0051:             * words should be.
0052:             */
0053:            protected Lexer syntaxLexer;
0054:            /**
0055:             * A thread that handles the actual coloring.
0056:             */
0057:            protected Colorer colorer;
0058:            /**
0059:             * A lock for modifying the document, or for
0060:             * actions that depend on the document not being
0061:             * modified.
0062:             */
0063:            private Object doclock = new Object();
0064:
0065:            /**
0066:             * Create a new Demo
0067:             */
0068:            public SyntaxHighlighterPanel() {
0069:                // initial set up that sets the title
0070:                //super("Programmer's Editor Demonstration");
0071:
0072:                // Create the document model.
0073:                document = new HighLightedDocument();
0074:
0075:                // Create the text pane and configure it.
0076:                textPane = new JTextPane(document);
0077:
0078:                textPane.setCaretPosition(0);
0079:                textPane.setMargin(new Insets(5, 5, 5, 5));
0080:                JScrollPane scrollPane = new JScrollPane(textPane);
0081:
0082:                // specify the initial size and location for the window.
0083:                scrollPane.setPreferredSize(new Dimension(620, 460));
0084:                setLocation(50, 50);
0085:
0086:                // Add the components to the frame.
0087:                //        JPanel contentPane = new JPanel(new BorderLayout());
0088:                //        contentPane.add(scrollPane, BorderLayout.CENTER);
0089:                //        setContentPane(contentPane);
0090:                this .setLayout(new BorderLayout());
0091:                this .add(scrollPane, BorderLayout.CENTER);
0092:
0093:                // Set up the menu bar.
0094:                JMenu styleMenu = createStyleMenu();
0095:                JMenuBar mb = new JMenuBar();
0096:                mb.add(styleMenu);
0097:                //setJMenuBar(mb);
0098:
0099:                // Make the window so that it can close the application
0100:                //        addWindowListener(new WindowAdapter() {
0101:                //            public void windowClosing(WindowEvent e) {
0102:                //                System.exit(0);
0103:                //            }
0104:                //            public void windowActivated(WindowEvent e) {
0105:                //                // focus magic
0106:                //                textPane.requestFocus();
0107:                //            }
0108:                //        });
0109:
0110:                // Start the thread that does the coloring
0111:                colorer = new Colorer();
0112:                colorer.start();
0113:
0114:                // Set up the hash table that contains the styles.
0115:                initStyles();
0116:
0117:                // create the new document.
0118:                documentReader = new DocumentReader(document);
0119:
0120:                // Put the initial text into the text pane and
0121:                // set it's initial coloring style.
0122:                initDocument();
0123:
0124:                // put it all together and show it.
0125:                //pack();
0126:                setVisible(true);
0127:            }
0128:
0129:            /**
0130:             * Returns the text pane
0131:             * @return
0132:             */
0133:            public JTextPane getTextPane() {
0134:                return this .textPane;
0135:            }
0136:
0137:            /**
0138:             * Returns the selected text or the text in the text area if no text has been selected
0139:             * @return
0140:             */
0141:            public String getText() {
0142:                //Get the selected text or if there is no selection, get all the text in the text area
0143:                String sql = this .textPane.getSelectedText();
0144:                if (sql == null) {
0145:                    sql = this .textPane.getText();
0146:                }
0147:
0148:                //Strip the newline characters from the sql
0149:                sql = sql.replaceAll("\r\n", " ");
0150:                sql = sql.replaceAll("\n", " ");
0151:
0152:                return sql;
0153:            }
0154:
0155:            /**
0156:             * Append this text
0157:             * @param text
0158:             */
0159:            public void append(String text) {
0160:                this .textPane.setText(this .textPane.getText() + text);
0161:            }
0162:
0163:            public void setText(String text) {
0164:                this .textPane.setText(text);
0165:            }
0166:
0167:            /**
0168:             * Run the Syntax Highlighting as a separate thread.
0169:             * Things that need to be colored are messaged to the
0170:             * thread and put in a list.
0171:             */
0172:            private class Colorer extends Thread {
0173:
0174:                /**
0175:                 * Keep a list of places in the file that it is safe to restart the
0176:                 * highlighting.  This happens whenever the lexer reports that it has
0177:                 * returned to its initial state.  Since this list needs to be sorted
0178:                 * and we need to be able to retrieve ranges from it, it is stored in a
0179:                 * balanced tree.
0180:                 */
0181:                private TreeSet iniPositions = new TreeSet(
0182:                        new DocPositionComparator());
0183:
0184:                /**
0185:                 * As we go through and remove invalid positions we will also be finding
0186:                 * new valid positions. 
0187:                 * Since the position list cannot be deleted from and written to at the same
0188:                 * time, we will keep a list of the new positions and simply add it to the
0189:                 * list of positions once all the old positions have been removed.
0190:                 */
0191:                private HashSet newPositions = new HashSet();
0192:
0193:                /**
0194:                 * A simple wrapper representing something that needs to be colored.
0195:                 * Placed into an object so that it can be stored in a Vector.
0196:                 */
0197:                private class RecolorEvent {
0198:                    public int position;
0199:                    public int adjustment;
0200:
0201:                    public RecolorEvent(int position, int adjustment) {
0202:                        this .position = position;
0203:                        this .adjustment = adjustment;
0204:                    }
0205:                }
0206:
0207:                /**
0208:                 * Vector that stores the communication between the two threads.
0209:                 */
0210:                private volatile Vector v = new Vector();
0211:
0212:                /**
0213:                 * The amount of change that has occurred before the place in the
0214:                 * document that we are currently highlighting (lastPosition).
0215:                 */
0216:                private volatile int change = 0;
0217:
0218:                /**
0219:                 * The last position colored
0220:                 */
0221:                private volatile int lastPosition = -1;
0222:
0223:                private volatile boolean asleep = false;
0224:
0225:                /**
0226:                 * When accessing the vector, we need to create a critical section.
0227:                 * we will synchronize on this object to ensure that we don't get
0228:                 * unsafe thread behavior.
0229:                 */
0230:                private Object lock = new Object();
0231:
0232:                /**
0233:                 * Tell the Syntax Highlighting thread to take another look at this
0234:                 * section of the document.  It will process this as a FIFO.
0235:                 * This method should be done inside a doclock.
0236:                 */
0237:                public void color(int position, int adjustment) {
0238:                    // figure out if this adjustment effects the current run.
0239:                    // if it does, then adjust the place in the document
0240:                    // that gets highlighted.
0241:                    if (position < lastPosition) {
0242:                        if (lastPosition < position - adjustment) {
0243:                            change -= lastPosition - position;
0244:                        } else {
0245:                            change += adjustment;
0246:                        }
0247:                    }
0248:                    synchronized (lock) {
0249:                        v.add(new RecolorEvent(position, adjustment));
0250:                        if (asleep) {
0251:                            this .interrupt();
0252:                        }
0253:                    }
0254:                }
0255:
0256:                /**
0257:                 * The colorer runs forever and may sleep for long
0258:                 * periods of time.  It should be interrupted every
0259:                 * time there is something for it to do.
0260:                 */
0261:                public void run() {
0262:                    int position = -1;
0263:                    int adjustment = 0;
0264:                    // if we just finish, we can't go to sleep until we
0265:                    // ensure there is nothing else for us to do.
0266:                    // use try again to keep track of this.
0267:                    boolean tryAgain = false;
0268:                    for (;;) { // forever
0269:                        synchronized (lock) {
0270:                            if (v.size() > 0) {
0271:                                RecolorEvent re = (RecolorEvent) (v
0272:                                        .elementAt(0));
0273:                                v.removeElementAt(0);
0274:                                position = re.position;
0275:                                adjustment = re.adjustment;
0276:                            } else {
0277:                                tryAgain = false;
0278:                                position = -1;
0279:                                adjustment = 0;
0280:                            }
0281:                        }
0282:                        if (position != -1) {
0283:                            SortedSet workingSet;
0284:                            Iterator workingIt;
0285:                            DocPosition startRequest = new DocPosition(position);
0286:                            DocPosition endRequest = new DocPosition(position
0287:                                    + ((adjustment >= 0) ? adjustment
0288:                                            : -adjustment));
0289:                            DocPosition dp;
0290:                            DocPosition dpStart = null;
0291:                            DocPosition dpEnd = null;
0292:
0293:                            // find the starting position.  We must start at least one
0294:                            // token before the current position
0295:                            try {
0296:                                // all the good positions before
0297:                                workingSet = iniPositions.headSet(startRequest);
0298:                                // the last of the stuff before
0299:                                dpStart = ((DocPosition) workingSet.last());
0300:                            } catch (NoSuchElementException x) {
0301:                                // if there were no good positions before the requested start,
0302:                                // we can always start at the very beginning.
0303:                                dpStart = new DocPosition(0);
0304:                            }
0305:
0306:                            // if stuff was removed, take any removed positions off the list.
0307:                            if (adjustment < 0) {
0308:                                workingSet = iniPositions.subSet(startRequest,
0309:                                        endRequest);
0310:                                workingIt = workingSet.iterator();
0311:                                while (workingIt.hasNext()) {
0312:                                    workingIt.next();
0313:                                    workingIt.remove();
0314:                                }
0315:                            }
0316:
0317:                            // adjust the positions of everything after the insertion/removal.
0318:                            workingSet = iniPositions.tailSet(startRequest);
0319:                            workingIt = workingSet.iterator();
0320:                            while (workingIt.hasNext()) {
0321:                                ((DocPosition) workingIt.next())
0322:                                        .adjustPosition(adjustment);
0323:                            }
0324:
0325:                            // now go through and highlight as much as needed
0326:                            workingSet = iniPositions.tailSet(dpStart);
0327:                            workingIt = workingSet.iterator();
0328:                            dp = null;
0329:                            if (workingIt.hasNext()) {
0330:                                dp = (DocPosition) workingIt.next();
0331:                            }
0332:                            try {
0333:                                Token t;
0334:                                boolean done = false;
0335:                                dpEnd = dpStart;
0336:                                synchronized (doclock) {
0337:                                    // we are playing some games with the lexer for efficiency.
0338:                                    // we could just create a new lexer each time here, but instead,
0339:                                    // we will just reset it so that it thinks it is starting at the
0340:                                    // beginning of the document but reporting a funny start position.
0341:                                    // Reseting the lexer causes the close() method on the reader
0342:                                    // to be called but because the close() method has no effect on the
0343:                                    // DocumentReader, we can do this.
0344:                                    syntaxLexer.reset(documentReader, 0,
0345:                                            dpStart.getPosition(), 0);
0346:                                    // After the lexer has been set up, scroll the reader so that it
0347:                                    // is in the correct spot as well.
0348:                                    documentReader.seek(dpStart.getPosition());
0349:                                    // we will highlight tokens until we reach a good stopping place.
0350:                                    // the first obvious stopping place is the end of the document.
0351:                                    // the lexer will return null at the end of the document and wee
0352:                                    // need to stop there.
0353:                                    t = syntaxLexer.getNextToken();
0354:                                }
0355:                                newPositions.add(dpStart);
0356:                                while (!done && t != null) {
0357:                                    // this is the actual command that colors the stuff.
0358:                                    // Color stuff with the description of the style matched
0359:                                    // to the hash table that has been set up ahead of time.
0360:                                    synchronized (doclock) {
0361:                                        if (t.getCharEnd() <= document
0362:                                                .getLength()) {
0363:                                            document
0364:                                                    .setCharacterAttributes(
0365:                                                            t.getCharBegin()
0366:                                                                    + change,
0367:                                                            t.getCharEnd()
0368:                                                                    - t
0369:                                                                            .getCharBegin(),
0370:                                                            getStyle(t
0371:                                                                    .getDescription()),
0372:                                                            true);
0373:                                            // record the position of the last bit of text that we colored
0374:                                            dpEnd = new DocPosition(t
0375:                                                    .getCharEnd());
0376:                                        }
0377:                                        lastPosition = (t.getCharEnd() + change);
0378:                                    }
0379:                                    // The other more complicated reason for doing no more highlighting
0380:                                    // is that all the colors are the same from here on out anyway.
0381:                                    // We can detect this by seeing if the place that the lexer returned
0382:                                    // to the initial state last time we highlighted is the same as the
0383:                                    // place that returned to the initial state this time.
0384:                                    // As long as that place is after the last changed text, everything
0385:                                    // from there on is fine already.
0386:                                    if (t.getState() == Token.INITIAL_STATE) {
0387:                                        //System.out.println(t);
0388:                                        // look at all the positions from last time that are less than or
0389:                                        // equal to the current position
0390:                                        while (dp != null
0391:                                                && dp.getPosition() <= t
0392:                                                        .getCharEnd()) {
0393:                                            if (dp.getPosition() == t
0394:                                                    .getCharEnd()
0395:                                                    && dp.getPosition() >= endRequest
0396:                                                            .getPosition()) {
0397:                                                // we have found a state that is the same
0398:                                                done = true;
0399:                                                dp = null;
0400:                                            } else if (workingIt.hasNext()) {
0401:                                                // didn't find it, try again.
0402:                                                dp = (DocPosition) workingIt
0403:                                                        .next();
0404:                                            } else {
0405:                                                // didn't find it, and there is no more info from last
0406:                                                // time.  This means that we will just continue
0407:                                                // until the end of the document.
0408:                                                dp = null;
0409:                                            }
0410:                                        }
0411:                                        // so that we can do this check next time, record all the
0412:                                        // initial states from this time.
0413:                                        newPositions.add(dpEnd);
0414:                                    }
0415:                                    synchronized (doclock) {
0416:                                        t = syntaxLexer.getNextToken();
0417:                                    }
0418:                                }
0419:
0420:                                // remove all the old initial positions from the place where
0421:                                // we started doing the highlighting right up through the last
0422:                                // bit of text we touched.
0423:                                workingIt = iniPositions.subSet(dpStart, dpEnd)
0424:                                        .iterator();
0425:                                while (workingIt.hasNext()) {
0426:                                    workingIt.next();
0427:                                    workingIt.remove();
0428:                                }
0429:
0430:                                // Remove all the positions that are after the end of the file.:
0431:                                workingIt = iniPositions.tailSet(
0432:                                        new DocPosition(document.getLength()))
0433:                                        .iterator();
0434:                                while (workingIt.hasNext()) {
0435:                                    workingIt.next();
0436:                                    workingIt.remove();
0437:                                }
0438:
0439:                                // and put the new initial positions that we have found on the list.
0440:                                iniPositions.addAll(newPositions);
0441:                                newPositions.clear();
0442:
0443:                                /*workingIt = iniPositions.iterator();
0444:                                while (workingIt.hasNext()){
0445:                                    System.out.println(workingIt.next());
0446:                                }
0447:                                
0448:                                System.out.println("Started: " + dpStart.getPosition() + " Ended: " + dpEnd.getPosition());*/
0449:                            } catch (IOException x) {
0450:                            }
0451:                            synchronized (doclock) {
0452:                                lastPosition = -1;
0453:                                change = 0;
0454:                            }
0455:                            // since we did something, we should check that there is
0456:                            // nothing else to do before going back to sleep.
0457:                            tryAgain = true;
0458:                        }
0459:                        asleep = true;
0460:                        if (!tryAgain) {
0461:                            try {
0462:                                sleep(0xffffff);
0463:                            } catch (InterruptedException x) {
0464:                            }
0465:
0466:                        }
0467:                        asleep = false;
0468:                    }
0469:                }
0470:            }
0471:
0472:            /**
0473:             * Color or recolor the entire document
0474:             */
0475:            public void colorAll() {
0476:                color(0, document.getLength());
0477:            }
0478:
0479:            /**
0480:             * Color a section of the document.
0481:             * The actual coloring will start somewhere before
0482:             * the requested position and continue as long
0483:             * as needed.
0484:             *
0485:             * @param position the starting point for the coloring.
0486:             * @param adjustment amount of text inserted or removed
0487:             *    at the starting point.
0488:             */
0489:            public void color(int position, int adjustment) {
0490:                colorer.color(position, adjustment);
0491:            }
0492:
0493:            /**
0494:             * Create the style menu.
0495:             *
0496:             * @return the style menu.
0497:             */
0498:            private JMenu createStyleMenu() {
0499:                ActionListener actionListener = new ActionListener() {
0500:                    public void actionPerformed(ActionEvent e) {
0501:                        if (e.getActionCommand().equals("Java")) {
0502:                            syntaxLexer = new JavaLexer(documentReader);
0503:                            colorAll();
0504:                        } else if (e.getActionCommand().equals("C/C++")) {
0505:                            syntaxLexer = new CLexer(documentReader);
0506:                            colorAll();
0507:                        } else if (e.getActionCommand().equals("LaTeX")) {
0508:                            syntaxLexer = new LatexLexer(documentReader);
0509:                            colorAll();
0510:                        } else if (e.getActionCommand().equals("SQL")) {
0511:                            syntaxLexer = new SQLLexer(documentReader);
0512:                            colorAll();
0513:                        } else if (e.getActionCommand().equals(
0514:                                "Java Properties")) {
0515:                            syntaxLexer = new PropertiesLexer(documentReader);
0516:                            colorAll();
0517:                        } else if (e.getActionCommand().equals("HTML (Simple)")) {
0518:                            syntaxLexer = new HTMLLexer(documentReader);
0519:                            colorAll();
0520:                        } else if (e.getActionCommand()
0521:                                .equals("HTML (Complex)")) {
0522:                            syntaxLexer = new HTMLLexer1(documentReader);
0523:                            colorAll();
0524:                        } else if (e.getActionCommand().equals("Gray Out")) {
0525:                            SimpleAttributeSet style = new SimpleAttributeSet();
0526:                            StyleConstants.setFontFamily(style, "Monospaced");
0527:                            StyleConstants.setFontSize(style, 12);
0528:                            StyleConstants.setBackground(style, Color.gray);
0529:                            StyleConstants.setForeground(style, Color.black);
0530:                            StyleConstants.setBold(style, false);
0531:                            StyleConstants.setItalic(style, false);
0532:                            document.setCharacterAttributes(0, document
0533:                                    .getLength(), style, true);
0534:                        }
0535:                    }
0536:                };
0537:
0538:                JMenu menu = new JMenu("Style");
0539:                ButtonGroup group = new ButtonGroup();
0540:                JRadioButtonMenuItem item;
0541:                item = new JRadioButtonMenuItem("Java", true);
0542:                group.add(item);
0543:                item.addActionListener(actionListener);
0544:                menu.add(item);
0545:                item = new JRadioButtonMenuItem("C/C++", false);
0546:                group.add(item);
0547:                item.addActionListener(actionListener);
0548:                menu.add(item);
0549:                item = new JRadioButtonMenuItem("HTML (Simple)", false);
0550:                group.add(item);
0551:                item.addActionListener(actionListener);
0552:                menu.add(item);
0553:                item = new JRadioButtonMenuItem("HTML (Complex)", false);
0554:                group.add(item);
0555:                item.addActionListener(actionListener);
0556:                menu.add(item);
0557:                item = new JRadioButtonMenuItem("LaTeX", false);
0558:                group.add(item);
0559:                item.addActionListener(actionListener);
0560:                menu.add(item);
0561:                item = new JRadioButtonMenuItem("SQL", false);
0562:                group.add(item);
0563:                item.addActionListener(actionListener);
0564:                menu.add(item);
0565:                item = new JRadioButtonMenuItem("Java Properties", false);
0566:                group.add(item);
0567:                item.addActionListener(actionListener);
0568:                menu.add(item);
0569:
0570:                JMenuItem i = new JMenuItem("Gray Out");
0571:                i.addActionListener(actionListener);
0572:                menu.add(i);
0573:
0574:                return menu;
0575:            }
0576:
0577:            /**
0578:             * Initialize the document with some default text and set
0579:             * they initial type of syntax highlighting.
0580:             */
0581:            private void initDocument() {
0582:                syntaxLexer = new SQLLexer(documentReader);
0583:
0584:                try {
0585:                    document.insertString(document.getLength(), "",
0586:                            getStyle("text"));
0587:                } catch (BadLocationException ble) {
0588:                    System.err.println("Couldn't insert initial text.");
0589:                }
0590:            }
0591:
0592:            /**
0593:             * A hash table containing the text styles.
0594:             * Simple attribute sets are hashed by name (String)
0595:             */
0596:            private Hashtable styles = new Hashtable();
0597:
0598:            /**
0599:             * retrieve the style for the given type of text.
0600:             *
0601:             * @param styleName the label for the type of text ("tag" for example) 
0602:             *      or null if the styleName is not known.
0603:             * @return the style
0604:             */
0605:            private SimpleAttributeSet getStyle(String styleName) {
0606:                return ((SimpleAttributeSet) styles.get(styleName));
0607:            }
0608:
0609:            /**
0610:             * Create the styles and place them in the hash table.
0611:             */
0612:            private void initStyles() {
0613:                SimpleAttributeSet style;
0614:
0615:                style = new SimpleAttributeSet();
0616:                StyleConstants.setFontFamily(style, "Monospaced");
0617:                StyleConstants.setFontSize(style, 12);
0618:                StyleConstants.setBackground(style, Color.white);
0619:                StyleConstants.setForeground(style, Color.black);
0620:                StyleConstants.setBold(style, false);
0621:                StyleConstants.setItalic(style, false);
0622:                styles.put("body", style);
0623:
0624:                style = new SimpleAttributeSet();
0625:                StyleConstants.setFontFamily(style, "Monospaced");
0626:                StyleConstants.setFontSize(style, 12);
0627:                StyleConstants.setBackground(style, Color.white);
0628:                StyleConstants.setForeground(style, Color.blue);
0629:                StyleConstants.setBold(style, true);
0630:                StyleConstants.setItalic(style, false);
0631:                styles.put("tag", style);
0632:
0633:                style = new SimpleAttributeSet();
0634:                StyleConstants.setFontFamily(style, "Monospaced");
0635:                StyleConstants.setFontSize(style, 12);
0636:                StyleConstants.setBackground(style, Color.white);
0637:                StyleConstants.setForeground(style, Color.blue);
0638:                StyleConstants.setBold(style, false);
0639:                StyleConstants.setItalic(style, false);
0640:                styles.put("endtag", style);
0641:
0642:                style = new SimpleAttributeSet();
0643:                StyleConstants.setFontFamily(style, "Monospaced");
0644:                StyleConstants.setFontSize(style, 12);
0645:                StyleConstants.setBackground(style, Color.white);
0646:                StyleConstants.setForeground(style, Color.black);
0647:                StyleConstants.setBold(style, false);
0648:                StyleConstants.setItalic(style, false);
0649:                styles.put("reference", style);
0650:
0651:                style = new SimpleAttributeSet();
0652:                StyleConstants.setFontFamily(style, "Monospaced");
0653:                StyleConstants.setFontSize(style, 12);
0654:                StyleConstants.setBackground(style, Color.white);
0655:                StyleConstants
0656:                        .setForeground(style, new Color(0xB03060)/*Color.maroon*/);
0657:                StyleConstants.setBold(style, true);
0658:                StyleConstants.setItalic(style, false);
0659:                styles.put("name", style);
0660:
0661:                style = new SimpleAttributeSet();
0662:                StyleConstants.setFontFamily(style, "Monospaced");
0663:                StyleConstants.setFontSize(style, 12);
0664:                StyleConstants.setBackground(style, Color.white);
0665:                StyleConstants
0666:                        .setForeground(style, new Color(0xB03060)/*Color.maroon*/);
0667:                StyleConstants.setBold(style, false);
0668:                StyleConstants.setItalic(style, true);
0669:                styles.put("value", style);
0670:
0671:                style = new SimpleAttributeSet();
0672:                StyleConstants.setFontFamily(style, "Monospaced");
0673:                StyleConstants.setFontSize(style, 12);
0674:                StyleConstants.setBackground(style, Color.white);
0675:                StyleConstants.setForeground(style, Color.black);
0676:                StyleConstants.setBold(style, true);
0677:                StyleConstants.setItalic(style, false);
0678:                styles.put("text", style);
0679:
0680:                style = new SimpleAttributeSet();
0681:                StyleConstants.setFontFamily(style, "Monospaced");
0682:                StyleConstants.setFontSize(style, 12);
0683:                StyleConstants.setBackground(style, Color.white);
0684:                StyleConstants.setForeground(style, Color.blue);
0685:                StyleConstants.setBold(style, false);
0686:                StyleConstants.setItalic(style, false);
0687:                styles.put("reservedWord", style);
0688:
0689:                style = new SimpleAttributeSet();
0690:                StyleConstants.setFontFamily(style, "Monospaced");
0691:                StyleConstants.setFontSize(style, 12);
0692:                StyleConstants.setBackground(style, Color.white);
0693:                StyleConstants.setForeground(style, Color.black);
0694:                StyleConstants.setBold(style, false);
0695:                StyleConstants.setItalic(style, false);
0696:                styles.put("identifier", style);
0697:
0698:                style = new SimpleAttributeSet();
0699:                StyleConstants.setFontFamily(style, "Monospaced");
0700:                StyleConstants.setFontSize(style, 12);
0701:                StyleConstants.setBackground(style, Color.white);
0702:                StyleConstants
0703:                        .setForeground(style, new Color(0xB03060)/*Color.maroon*/);
0704:                StyleConstants.setBold(style, false);
0705:                StyleConstants.setItalic(style, false);
0706:                styles.put("literal", style);
0707:
0708:                style = new SimpleAttributeSet();
0709:                StyleConstants.setFontFamily(style, "Monospaced");
0710:                StyleConstants.setFontSize(style, 12);
0711:                StyleConstants.setBackground(style, Color.white);
0712:                StyleConstants
0713:                        .setForeground(style, new Color(0x000080)/*Color.navy*/);
0714:                StyleConstants.setBold(style, false);
0715:                StyleConstants.setItalic(style, false);
0716:                styles.put("separator", style);
0717:
0718:                style = new SimpleAttributeSet();
0719:                StyleConstants.setFontFamily(style, "Monospaced");
0720:                StyleConstants.setFontSize(style, 12);
0721:                StyleConstants.setBackground(style, Color.white);
0722:                StyleConstants.setForeground(style, Color.black);
0723:                StyleConstants.setBold(style, true);
0724:                StyleConstants.setItalic(style, false);
0725:                styles.put("operator", style);
0726:
0727:                style = new SimpleAttributeSet();
0728:                StyleConstants.setFontFamily(style, "Monospaced");
0729:                StyleConstants.setFontSize(style, 12);
0730:                StyleConstants.setBackground(style, Color.white);
0731:                StyleConstants.setForeground(style, Color.green.darker());
0732:                StyleConstants.setBold(style, false);
0733:                StyleConstants.setItalic(style, false);
0734:                styles.put("comment", style);
0735:
0736:                style = new SimpleAttributeSet();
0737:                StyleConstants.setFontFamily(style, "Monospaced");
0738:                StyleConstants.setFontSize(style, 12);
0739:                StyleConstants.setBackground(style, Color.white);
0740:                StyleConstants.setForeground(style, new Color(0xA020F0)
0741:                        .darker()/*Color.purple*/);
0742:                StyleConstants.setBold(style, false);
0743:                StyleConstants.setItalic(style, false);
0744:                styles.put("preprocessor", style);
0745:
0746:                style = new SimpleAttributeSet();
0747:                StyleConstants.setFontFamily(style, "Monospaced");
0748:                StyleConstants.setFontSize(style, 12);
0749:                StyleConstants.setBackground(style, Color.white);
0750:                StyleConstants.setForeground(style, Color.black);
0751:                StyleConstants.setBold(style, false);
0752:                StyleConstants.setItalic(style, false);
0753:                styles.put("whitespace", style);
0754:
0755:                style = new SimpleAttributeSet();
0756:                StyleConstants.setFontFamily(style, "Monospaced");
0757:                StyleConstants.setFontSize(style, 12);
0758:                StyleConstants.setBackground(style, Color.white);
0759:                StyleConstants.setForeground(style, Color.red);
0760:                StyleConstants.setBold(style, false);
0761:                StyleConstants.setItalic(style, false);
0762:                styles.put("error", style);
0763:
0764:                style = new SimpleAttributeSet();
0765:                StyleConstants.setFontFamily(style, "Monospaced");
0766:                StyleConstants.setFontSize(style, 12);
0767:                StyleConstants.setBackground(style, Color.white);
0768:                StyleConstants.setForeground(style, Color.orange);
0769:                StyleConstants.setBold(style, false);
0770:                StyleConstants.setItalic(style, false);
0771:                styles.put("unknown", style);
0772:            }
0773:
0774:            /**
0775:             * Just like a DefaultStyledDocument but intercepts inserts and
0776:             * removes to color them.
0777:             */
0778:            private class HighLightedDocument extends DefaultStyledDocument {
0779:                public void insertString(int offs, String str, AttributeSet a)
0780:                        throws BadLocationException {
0781:                    synchronized (doclock) {
0782:                        super .insertString(offs, str, a);
0783:                        color(offs, str.length());
0784:                        documentReader.update(offs, str.length());
0785:                    }
0786:                }
0787:
0788:                public void remove(int offs, int len)
0789:                        throws BadLocationException {
0790:                    synchronized (doclock) {
0791:                        super .remove(offs, len);
0792:                        color(offs, -len);
0793:                        documentReader.update(offs, -len);
0794:                    }
0795:                }
0796:            }
0797:        }
0798:
0799:        /**
0800:         * A wrapper for a position in a document appropriate for storing
0801:         * in a collection.
0802:         */
0803:        class DocPosition {
0804:
0805:            /**
0806:             * The actual position
0807:             */
0808:            private int position;
0809:
0810:            /**
0811:             * Get the position represented by this DocPosition
0812:             *
0813:             * @return the position
0814:             */
0815:            int getPosition() {
0816:                return position;
0817:            }
0818:
0819:            /**
0820:             * Construct a DocPosition from the given offset into the document.
0821:             *
0822:             * @param position The position this DocObject will represent
0823:             */
0824:            public DocPosition(int position) {
0825:                this .position = position;
0826:            }
0827:
0828:            /**
0829:             * Adjust this position.
0830:             * This is useful in cases that an amount of text is inserted
0831:             * or removed before this position.
0832:             *
0833:             * @param adjustment amount (either positive or negative) to adjust this position.
0834:             * @return the DocPosition, adjusted properly.
0835:             */
0836:            public DocPosition adjustPosition(int adjustment) {
0837:                position += adjustment;
0838:                return this ;
0839:            }
0840:
0841:            /**
0842:             * Two DocPositions are equal iff they have the same internal position.
0843:             *
0844:             * @return if this DocPosition represents the same position as another.
0845:             */
0846:            public boolean equals(Object obj) {
0847:                if (obj instanceof  DocPosition) {
0848:                    DocPosition d = (DocPosition) (obj);
0849:                    if (this .position == d.position) {
0850:                        return true;
0851:                    } else {
0852:                        return false;
0853:                    }
0854:                } else {
0855:                    return false;
0856:                }
0857:            }
0858:
0859:            /**
0860:             * A string representation useful for debugging.
0861:             *
0862:             * @return A string representing the position.
0863:             */
0864:            public String toString() {
0865:                return "" + position;
0866:            }
0867:        }
0868:
0869:        /**
0870:         * A comparator appropriate for use with Collections of
0871:         * DocPositions.
0872:         */
0873:        class DocPositionComparator implements  Comparator {
0874:            /**
0875:             * Does this Comparator equal another?
0876:             * Since all DocPositionComparators are the same, they
0877:             * are all equal.
0878:             *
0879:             * @return true for DocPositionComparators, false otherwise.
0880:             */
0881:            public boolean equals(Object obj) {
0882:                if (obj instanceof  DocPositionComparator) {
0883:                    return true;
0884:                } else {
0885:                    return false;
0886:                }
0887:            }
0888:
0889:            /**
0890:             * Compare two DocPositions
0891:             *
0892:             * @param o1 first DocPosition
0893:             * @param o2 second DocPosition
0894:             * @return negative if first < second, 0 if equal, positive if first > second
0895:             */
0896:            public int compare(Object o1, Object o2) {
0897:                if (o1 instanceof  DocPosition && o2 instanceof  DocPosition) {
0898:                    DocPosition d1 = (DocPosition) (o1);
0899:                    DocPosition d2 = (DocPosition) (o2);
0900:                    return (d1.getPosition() - d2.getPosition());
0901:                } else if (o1 instanceof  DocPosition) {
0902:                    return -1;
0903:                } else if (o2 instanceof  DocPosition) {
0904:                    return 1;
0905:                } else if (o1.hashCode() < o2.hashCode()) {
0906:                    return -1;
0907:                } else if (o2.hashCode() > o1.hashCode()) {
0908:                    return 1;
0909:                } else {
0910:                    return 0;
0911:                }
0912:            }
0913:        }
0914:
0915:        /**
0916:         * A reader interface for an abstract document.  Since
0917:         * the syntax highlighting packages only accept Stings and
0918:         * Readers, this must be used.
0919:         * Since the close() method does nothing and a seek() method
0920:         * has been added, this allows us to get some performance
0921:         * improvements through reuse.  It can be used even after the
0922:         * lexer explicitly closes it by seeking to the place that
0923:         * we want to read next, and reseting the lexer.
0924:         */
0925:        class DocumentReader extends Reader {
0926:
0927:            /**
0928:             * Modifying the document while the reader is working is like
0929:             * pulling the rug out from under the reader.  Alerting the
0930:             * reader with this method (in a nice thread safe way, this
0931:             * should not be called at the same time as a read) allows
0932:             * the reader to compensate.
0933:             */
0934:            public void update(int position, int adjustment) {
0935:                if (position < this .position) {
0936:                    if (this .position < position - adjustment) {
0937:                        this .position = position;
0938:                    } else {
0939:                        this .position += adjustment;
0940:                    }
0941:                }
0942:            }
0943:
0944:            /**
0945:             * Current position in the document. Incremented
0946:             * whenever a character is read.
0947:             */
0948:            private long position = 0;
0949:
0950:            /**
0951:             * Saved position used in the mark and reset methods.
0952:             */
0953:            private long mark = -1;
0954:
0955:            /**
0956:             * The document that we are working with.
0957:             */
0958:            private AbstractDocument document;
0959:
0960:            /**
0961:             * Construct a reader on the given document.
0962:             *
0963:             * @param document the document to be read.
0964:             */
0965:            public DocumentReader(AbstractDocument document) {
0966:                this .document = document;
0967:            }
0968:
0969:            /**
0970:             * Has no effect.  This reader can be used even after
0971:             * it has been closed.
0972:             */
0973:            public void close() {
0974:            }
0975:
0976:            /**
0977:             * Save a position for reset.
0978:             *
0979:             * @param readAheadLimit ignored.
0980:             */
0981:            public void mark(int readAheadLimit) {
0982:                mark = position;
0983:            }
0984:
0985:            /**
0986:             * This reader support mark and reset.
0987:             *
0988:             * @return true
0989:             */
0990:            public boolean markSupported() {
0991:                return true;
0992:            }
0993:
0994:            /**
0995:             * Read a single character.
0996:             *
0997:             * @return the character or -1 if the end of the document has been reached.
0998:             */
0999:            public int read() {
1000:                if (position < document.getLength()) {
1001:                    try {
1002:                        char c = document.getText((int) position, 1).charAt(0);
1003:                        position++;
1004:                        return c;
1005:                    } catch (BadLocationException x) {
1006:                        return -1;
1007:                    }
1008:                } else {
1009:                    return -1;
1010:                }
1011:            }
1012:
1013:            /**
1014:             * Read and fill the buffer.
1015:             * This method will always fill the buffer unless the end of the document is reached.
1016:             *
1017:             * @param cbuf the buffer to fill.
1018:             * @return the number of characters read or -1 if no more characters are available in the document.
1019:             */
1020:            public int read(char[] cbuf) {
1021:                return read(cbuf, 0, cbuf.length);
1022:            }
1023:
1024:            /**
1025:             * Read and fill the buffer.
1026:             * This method will always fill the buffer unless the end of the document is reached.
1027:             *
1028:             * @param cbuf the buffer to fill.
1029:             * @param off offset into the buffer to begin the fill.
1030:             * @param len maximum number of characters to put in the buffer.
1031:             * @return the number of characters read or -1 if no more characters are available in the document.
1032:             */
1033:            public int read(char[] cbuf, int off, int len) {
1034:                if (position < document.getLength()) {
1035:                    int length = len;
1036:                    if (position + length >= document.getLength()) {
1037:                        length = document.getLength() - (int) position;
1038:                    }
1039:                    if (off + length >= cbuf.length) {
1040:                        length = cbuf.length - off;
1041:                    }
1042:                    try {
1043:                        String s = document.getText((int) position, length);
1044:                        position += length;
1045:                        for (int i = 0; i < length; i++) {
1046:                            cbuf[off + i] = s.charAt(i);
1047:                        }
1048:                        return length;
1049:                    } catch (BadLocationException x) {
1050:                        return -1;
1051:                    }
1052:                } else {
1053:                    return -1;
1054:                }
1055:            }
1056:
1057:            /**
1058:             * @return true
1059:             */
1060:            public boolean ready() {
1061:                return true;
1062:            }
1063:
1064:            /**
1065:             * Reset this reader to the last mark, or the beginning of the document if a mark has not been set.
1066:             */
1067:            public void reset() {
1068:                if (mark == -1) {
1069:                    position = 0;
1070:                } else {
1071:                    position = mark;
1072:                }
1073:                mark = -1;
1074:            }
1075:
1076:            /**
1077:             * Skip characters of input.
1078:             * This method will always skip the maximum number of characters unless
1079:             * the end of the file is reached.
1080:             *
1081:             * @param n number of characters to skip.
1082:             * @return the actual number of characters skipped.
1083:             */
1084:            public long skip(long n) {
1085:                if (position + n <= document.getLength()) {
1086:                    position += n;
1087:                    return n;
1088:                } else {
1089:                    long oldPos = position;
1090:                    position = document.getLength();
1091:                    return (document.getLength() - oldPos);
1092:                }
1093:            }
1094:
1095:            /**
1096:             * Seek to the given position in the document.
1097:             *
1098:             * @param n the offset to which to seek.
1099:             */
1100:            public void seek(long n) {
1101:                if (n <= document.getLength()) {
1102:                    position = n;
1103:                } else {
1104:                    position = document.getLength();
1105:                }
1106:            }
1107:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.