KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > rice > cs > drjava > ui > AbstractDJPane


1 /*BEGIN_COPYRIGHT_BLOCK
2  *
3  * This file is part of DrJava. Download the current version of this project from http://www.drjava.org/
4  * or http://sourceforge.net/projects/drjava/
5  *
6  * DrJava Open Source License
7  *
8  * Copyright (C) 2001-2005 JavaPLT group at Rice University (javaplt@rice.edu). All rights reserved.
9  *
10  * Developed by: Java Programming Languages Team, Rice University, http://www.cs.rice.edu/~javaplt/
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
13  * documentation files (the "Software"), to deal with the Software without restriction, including without limitation
14  * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
15  * to permit persons to whom the Software is furnished to do so, subject to the following conditions:
16  *
17  * - Redistributions of source code must retain the above copyright notice, this list of conditions and the
18  * following disclaimers.
19  * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
20  * following disclaimers in the documentation and/or other materials provided with the distribution.
21  * - Neither the names of DrJava, the JavaPLT, Rice University, nor the names of its contributors may be used to
22  * endorse or promote products derived from this Software without specific prior written permission.
23  * - Products derived from this software may not be called "DrJava" nor use the term "DrJava" as part of their
24  * names without prior written permission from the JavaPLT group. For permission, write to javaplt@rice.edu.
25  *
26  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
27  * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28  * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
29  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
30  * WITH THE SOFTWARE.
31  *
32  END_COPYRIGHT_BLOCK*/

33
34 package edu.rice.cs.drjava.ui;
35
36 import edu.rice.cs.drjava.DrJava;
37 import edu.rice.cs.drjava.config.*;
38 import edu.rice.cs.drjava.model.*;
39 import edu.rice.cs.drjava.model.definitions.indent.Indenter;
40
41 import edu.rice.cs.util.swing.*;
42 import edu.rice.cs.util.swing.Utilities;
43 import edu.rice.cs.util.text.SwingDocument;
44
45 import java.awt.*;
46 import javax.swing.*;
47 import javax.swing.event.*;
48 import javax.swing.text.*;
49
50 /** This class is misnamed!!! The associated document is NOT necessarily a DJDocument! It
51  * can be a ConsoleDocument. */

52 public abstract class AbstractDJPane extends JTextPane implements OptionConstants {
53   
54   // ------------ FIELDS -----------
55

56   /* The amount of the visible pane to scroll on a single click (Swing's default is .1) */
57   private static final double SCROLL_UNIT = .05;
58   
59   /** Paren/brace/bracket matching highlight color. */
60   static ReverseHighlighter.DefaultHighlightPainter MATCH_PAINTER;
61
62   static {
63     Color highColor = DrJava.getConfig().getSetting(DEFINITIONS_MATCH_COLOR);
64     MATCH_PAINTER = new ReverseHighlighter.DefaultHighlightPainter(highColor);
65   }
66   
67   /** Highlight painter for selected errors in the defs doc. */
68   static ReverseHighlighter.DefaultHighlightPainter ERROR_PAINTER =
69     new ReverseHighlighter.DefaultHighlightPainter(DrJava.getConfig().getSetting(COMPILER_ERROR_COLOR));
70   
71   protected volatile HighlightManager _highlightManager;
72   
73   /** Looks for changes in the caret position to see if a paren/brace/bracket highlight is needed. */
74   protected final CaretListener _matchListener = new CaretListener() {
75     
76     /** Checks caret position to see if it needs to set or remove a highlight from the document. When the cursor
77       * is immediately right of ')', '}', or ']', it highlights up to the matching open paren/brace/bracket.
78       * This method must execute as part of the document update. If deferred using invokeLater, it does not work.
79       * Only modifies the document--not any GUI classes.
80       * @param e the event fired by the caret position change
81       */

82     public void caretUpdate(CaretEvent e) {
83       getDJDocument().setCurrentLocation(getCaretPosition());
84       _removePreviousHighlight();
85       _updateMatchHighlight();
86     }
87   };
88   
89   /** Our current paren/brace/bracket matching highlight. */
90   protected volatile HighlightManager.HighlightInfo _matchHighlight = null;
91   
92   protected final SwingDocument NULL_DOCUMENT = new SwingDocument();
93   
94   //--------- CONSTRUCTOR ----------
95

96   AbstractDJPane(SwingDocument doc) {
97     super(doc);
98     setContentType("text/java");
99     
100     // Add listener that checks if highlighting matching braces must be updated
101
addCaretListener(_matchListener);
102   }
103   
104   //--------- METHODS -----------
105

106   /** Adds a highlight to the document. Called by _updateMatchHighlight().
107    * @param from start of highlight
108    * @param to end of highlight
109    */

110   protected void _addHighlight(int from, int to) {
111     _matchHighlight = _highlightManager.addHighlight(from, to, MATCH_PAINTER);
112   }
113   
114   protected abstract void _updateMatchHighlight();
115
116   /** Removes the previous highlight so document is cleared when caret position changes. Can be executed from outside
117     * the event thread. */

118   protected void _removePreviousHighlight() {
119     if (_matchHighlight != null) {
120       _matchHighlight.remove();
121       //_highlightManager.removeHighlight((HighlightManager.HighlightInfo)_matchHighlight);
122
_matchHighlight = null;
123     }
124   }
125   
126   /** Be sure to update the document (and thus the reduced model) any time the caret position changes.
127    * @param pos
128    */

129   public void setCaretPosition(int pos) {
130     super.setCaretPosition(pos);
131     getDJDocument().setCurrentLocation(pos);
132 // _doc.setCurrentLocation(pos);
133
}
134   
135   public int getScrollableUnitIncrement(Rectangle visibleRectangle, int orientation, int direction) {
136     return (int) (visibleRectangle.getHeight() * SCROLL_UNIT);
137   }
138   
139   /** What is this for? The override does not nothing! */
140   public void moveCaretPosition(int pos) { super.moveCaretPosition(pos); }
141   
142   /** Runs indent(int) with a default value of Indenter.OTHER */
143   public void indent() { indent(Indenter.OTHER); }
144
145   /** Perform an indent either on the current line or on the given selected box of text. Calls are sent to GlobalModel
146    * which are then forwarded on to the document. Hopefully the indent code will be fixed and corrected so this
147    * doesn't look so ugly. The purpose is to divorce the pane from the document so we can just pass a document to
148    * DefinitionsPane and that's all it cares about.
149    * @param reason the action that spawned this indent action. Enter presses are special, so that stars are inserted
150    * when lines in a multiline comment are broken up.
151    */

152   public void indent(final int reason) {
153
154     /** Because indent() is a function called directly by the Keymap, it does not go through the regular insertString
155      * channels and thus it may not be in sync with the document's position. For that reason, we must grab the
156      * caretPostion and set the current location to that value before calling the insertLine operation. The logic
157      * for a single line insert is very dependent on the current location.
158      */

159     
160     // Is this action still necessary? Answer: yes! Without this line, the caret often moves when the user hits "tab"
161
getDJDocument().setCurrentLocation(getCaretPosition());
162     
163     // The _reduced lock within DefinitionsDocument should be probably be set as well
164

165     final int selStart = getSelectionStart();
166     final int selEnd = getSelectionEnd();
167     
168     ProgressMonitor pm = null;
169     //= new ProgressMonitor(_mainFrame, "Indenting...",
170
// null, 0, selEnd - selStart);
171

172     //pm.setProgress(0);
173
// 3 seconds before displaying the progress bar.
174
//pm.setMillisToDecideToPopup(3000);
175

176     // XXX: Temporary hack because of slow indent...
177
// Prompt if more than 10000 characters to be indented, then do the indent
178
if (shouldIndent(selStart,selEnd)) { indentLines(selStart, selEnd, reason, pm); }
179
180   }
181
182   /** Indent the given selection, for the given reason, in the current document.
183    * @param selStart - the selection start
184    * @param selEnd - the selection end
185    * @param reason - the reason for the indent
186    * @param pm - the ProgressMonitor used by the indenter
187    */

188   protected abstract void indentLines(int selStart, int selEnd, int reason, ProgressMonitor pm);
189      
190   /**
191    * Returns true if the indent is to be performed.
192    * @param selStart - the selection start
193    * @param selEnd - the selection end
194    */

195   protected abstract boolean shouldIndent(int selStart, int selEnd);
196   
197   /** Returns the DJDocument held by the pane. */
198   public abstract DJDocument getDJDocument();
199 }
Popular Tags