001: /*BEGIN_COPYRIGHT_BLOCK
002: *
003: * Copyright (c) 2001-2007, JavaPLT group at Rice University (javaplt@rice.edu)
004: * All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions are met:
008: * * Redistributions of source code must retain the above copyright
009: * notice, this list of conditions and the following disclaimer.
010: * * Redistributions in binary form must reproduce the above copyright
011: * notice, this list of conditions and the following disclaimer in the
012: * documentation and/or other materials provided with the distribution.
013: * * Neither the names of DrJava, the JavaPLT group, Rice University, nor the
014: * names of its contributors may be used to endorse or promote products
015: * derived from this software without specific prior written permission.
016: *
017: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
018: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
019: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
020: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
021: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
022: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
023: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
024: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
025: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
026: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
027: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028: *
029: * This software is Open Source Initiative approved Open Source Software.
030: * Open Source Initative Approved is a trademark of the Open Source Initiative.
031: *
032: * This file is part of DrJava. Download the current version of this project
033: * from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/
034: *
035: * END_COPYRIGHT_BLOCK*/
036:
037: package edu.rice.cs.drjava.model.definitions;
038:
039: import javax.swing.text.*;
040: import java.awt.*;
041: import javax.swing.event.DocumentEvent; // TODO: Check synchronization.
042: import java.util.Vector;
043:
044: import edu.rice.cs.drjava.DrJava;
045: import edu.rice.cs.drjava.model.*;
046: import edu.rice.cs.drjava.model.repl.InteractionsDJDocument;
047: import edu.rice.cs.drjava.config.OptionConstants;
048: import edu.rice.cs.drjava.config.OptionEvent;
049: import edu.rice.cs.drjava.config.OptionListener;
050: import edu.rice.cs.drjava.model.definitions.reducedmodel.*;
051: import edu.rice.cs.util.text.EditDocumentInterface;
052:
053: /**
054: * This view class renders text on the screen using the reduced model info.
055: * By extending WrappedPlainView, we only have to override the parts we want to.
056: * Here we only override drawUnselectedText. We may want to override
057: * drawSelectedText at some point. As of 2002/06/17, we now extend PlainView because
058: * WrappedPlainView was causing bugs related to resizing the viewport of the
059: * definitions scroll pane.
060: *
061: * @version $Id: ColoringView.java 4255 2007-08-28 19:17:37Z mgricken $
062: */
063: public class ColoringView extends PlainView implements OptionConstants {
064:
065: public static Color COMMENTED_COLOR = DrJava.getConfig()
066: .getSetting(DEFINITIONS_COMMENT_COLOR);
067: public static Color DOUBLE_QUOTED_COLOR = DrJava.getConfig()
068: .getSetting(DEFINITIONS_DOUBLE_QUOTED_COLOR);
069: public static Color SINGLE_QUOTED_COLOR = DrJava.getConfig()
070: .getSetting(DEFINITIONS_SINGLE_QUOTED_COLOR);
071: public static Color NORMAL_COLOR = DrJava.getConfig().getSetting(
072: DEFINITIONS_NORMAL_COLOR);
073: public static Color KEYWORD_COLOR = DrJava.getConfig().getSetting(
074: DEFINITIONS_KEYWORD_COLOR);
075: public static Color NUMBER_COLOR = DrJava.getConfig().getSetting(
076: DEFINITIONS_NUMBER_COLOR);
077: public static Color TYPE_COLOR = DrJava.getConfig().getSetting(
078: DEFINITIONS_TYPE_COLOR);
079: public static Font MAIN_FONT = DrJava.getConfig().getSetting(
080: FONT_MAIN);
081:
082: //Interactions only colors
083: public static Color INTERACTIONS_SYSTEM_ERR_COLOR = DrJava
084: .getConfig().getSetting(SYSTEM_ERR_COLOR);
085: public static Color INTERACTIONS_SYSTEM_IN_COLOR = DrJava
086: .getConfig().getSetting(SYSTEM_IN_COLOR);
087: public static Color INTERACTIONS_SYSTEM_OUT_COLOR = DrJava
088: .getConfig().getSetting(SYSTEM_OUT_COLOR);
089: //Renamed as to avoid confusion with the one in option constants
090: public static Color ERROR_COLOR = DrJava.getConfig().getSetting(
091: INTERACTIONS_ERROR_COLOR);
092: public static Color DEBUGGER_COLOR = DrJava.getConfig().getSetting(
093: DEBUG_MESSAGE_COLOR);
094:
095: /** Constructs a new coloring view.
096: * @param elem the element
097: */
098: public ColoringView(Element elem) {
099: super (elem);
100:
101: // Listen for updates to configurable colors
102: final ColorOptionListener col = new ColorOptionListener();
103: final FontOptionListener fol = new FontOptionListener();
104:
105: Document doc = getDocument();
106: if (doc instanceof AbstractDJDocument) {
107: // delete the old color listeners, because they're hanging onto the wrong coloringview
108: // add color listeners to highlight keywords etc
109: DrJava.getConfig().addOptionListener(
110: OptionConstants.DEFINITIONS_COMMENT_COLOR, col);
111: DrJava.getConfig().addOptionListener(
112: OptionConstants.DEFINITIONS_DOUBLE_QUOTED_COLOR,
113: col);
114: DrJava.getConfig().addOptionListener(
115: OptionConstants.DEFINITIONS_SINGLE_QUOTED_COLOR,
116: col);
117: DrJava.getConfig().addOptionListener(
118: OptionConstants.DEFINITIONS_NORMAL_COLOR, col);
119: DrJava.getConfig().addOptionListener(
120: OptionConstants.DEFINITIONS_KEYWORD_COLOR, col);
121: DrJava.getConfig().addOptionListener(
122: OptionConstants.DEFINITIONS_NUMBER_COLOR, col);
123: DrJava.getConfig().addOptionListener(
124: OptionConstants.DEFINITIONS_TYPE_COLOR, col);
125: DrJava.getConfig().addOptionListener(
126: OptionConstants.FONT_MAIN, fol);
127:
128: DrJava.getConfig().addOptionListener(
129: OptionConstants.SYSTEM_ERR_COLOR, col);
130: DrJava.getConfig().addOptionListener(
131: OptionConstants.SYSTEM_IN_COLOR, col);
132: DrJava.getConfig().addOptionListener(
133: OptionConstants.SYSTEM_OUT_COLOR, col);
134: DrJava.getConfig().addOptionListener(
135: OptionConstants.INTERACTIONS_ERROR_COLOR, col);
136: DrJava.getConfig().addOptionListener(
137: OptionConstants.DEBUG_MESSAGE_COLOR, col);
138:
139: }
140:
141: if (doc instanceof DefinitionsDocument) {
142: // remove the listeners when the document closes
143: ((DefinitionsDocument) doc)
144: .addDocumentClosedListener(new DocumentClosedListener() {
145: public void close() {
146: DrJava
147: .getConfig()
148: .removeOptionListener(
149: OptionConstants.DEFINITIONS_COMMENT_COLOR,
150: col);
151: DrJava
152: .getConfig()
153: .removeOptionListener(
154: OptionConstants.DEFINITIONS_DOUBLE_QUOTED_COLOR,
155: col);
156: DrJava
157: .getConfig()
158: .removeOptionListener(
159: OptionConstants.DEFINITIONS_SINGLE_QUOTED_COLOR,
160: col);
161: DrJava
162: .getConfig()
163: .removeOptionListener(
164: OptionConstants.DEFINITIONS_NORMAL_COLOR,
165: col);
166: DrJava
167: .getConfig()
168: .removeOptionListener(
169: OptionConstants.DEFINITIONS_KEYWORD_COLOR,
170: col);
171: DrJava
172: .getConfig()
173: .removeOptionListener(
174: OptionConstants.DEFINITIONS_NUMBER_COLOR,
175: col);
176: DrJava
177: .getConfig()
178: .removeOptionListener(
179: OptionConstants.DEFINITIONS_TYPE_COLOR,
180: col);
181: DrJava.getConfig().removeOptionListener(
182: OptionConstants.FONT_MAIN, fol);
183: DrJava.getConfig().removeOptionListener(
184: OptionConstants.SYSTEM_ERR_COLOR,
185: col);
186: DrJava.getConfig().removeOptionListener(
187: OptionConstants.SYSTEM_IN_COLOR,
188: col);
189: DrJava.getConfig().removeOptionListener(
190: OptionConstants.SYSTEM_OUT_COLOR,
191: col);
192: DrJava
193: .getConfig()
194: .removeOptionListener(
195: OptionConstants.INTERACTIONS_ERROR_COLOR,
196: col);
197: DrJava
198: .getConfig()
199: .removeOptionListener(
200: OptionConstants.DEBUG_MESSAGE_COLOR,
201: col);
202: }
203: });
204: }
205: }
206:
207: /** Renders the given range in the model as normal unselected text.
208: * Note that this is text that's all on one line. The superclass deals
209: * with breaking lines and such. So all we have to do here is draw the
210: * text on [p0,p1) in the model. We have to start drawing at (x,y), and
211: * the function returns the x coordinate when we're done.
212: *
213: * @param g The graphics context
214: * @param x The starting X coordinate
215: * @param y The starting Y coordinate
216: * @param start The beginning position in the model
217: * @param end The ending position in the model
218: * @return The x coordinate at the end of the range
219: * @throws BadLocationException If the range is invalid
220: */
221: protected int drawUnselectedText(Graphics g, int x, int y,
222: int start, int end) throws BadLocationException {
223:
224: // Might be a PlainDocument (when AbstractDJPane is first constructed).
225: // See comments for DefinitionsEditorKit.createNewDocument() for details.
226: Document doc = getDocument();
227: AbstractDJDocument _doc = null;
228: if (doc instanceof AbstractDJDocument)
229: _doc = (AbstractDJDocument) doc;
230: else
231: return x; // return if there is no AbstracDJDocument
232:
233: // If there's nothing to show, don't do anything!
234: // For some reason I don't understand we tend to get called sometimes to render a zero-length area.
235: if (start == end)
236: return x;
237:
238: Vector<HighlightStatus> stats = _doc.getHighlightStatus(start,
239: end);
240: if (stats.size() < 1)
241: throw new RuntimeException(
242: "GetHighlightStatus returned nothing!");
243:
244: for (int i = 0; i < stats.size(); i++) {
245: HighlightStatus stat = stats.get(i);
246: int length = stat.getLength();
247: int location = stat.getLocation();
248: // If this highlight status extends past p1, end at p1
249: if (location + length > end)
250: length = end - stat.getLocation();
251:
252: Segment text = getLineBuffer();
253:
254: if (!(_doc instanceof InteractionsDJDocument)
255: || !((InteractionsDJDocument) _doc).setColoring(
256: (start + end) / 2, g))
257: setFormattingForState(g, stat.getState());
258: // else
259: // DrJava.consoleErr().println("Highlight: p0="+p0+"; p1="+p1+"; location="+location+"; color="+g.getColor()+"; text="+text);
260:
261: //
262: // DrJava.consoleErr().println("Highlight: loc=" + location + " length=" +
263: // length + " state=" + stat.getState() +
264: // " text=" + text);
265: //
266: _doc.getText(location, length, text);
267: x = Utilities.drawTabbedText(text, x, y, g, this , location);
268: }
269: //DrJava.consoleErr().println("returning x: " + x);
270: return x;
271: }
272:
273: /** Draws the selected text image at the specified location.
274: * @param g The text image
275: * @param x The x coordinate for the drawn text
276: * @param y The y coordinate for the drawn text
277: * @param start The beginning position in the model
278: * @param end The end position in the model
279: * @return The location of the end of the image (range)
280: * @throws BadLocationException
281: */
282: protected int drawSelectedText(Graphics g, int x, int y, int start,
283: int end) throws BadLocationException {
284: /*
285: DrJava.consoleErr().println("drawSelected: " + p0 + "-" + p1 +
286: " doclen=" + _doc.getLength() +" x="+x+" y="+y);
287: */
288: EditDocumentInterface doc = (EditDocumentInterface) getDocument();
289: if (doc instanceof InteractionsDJDocument)
290: ((InteractionsDJDocument) doc).setBoldFonts(end, g);
291:
292: return super .drawSelectedText(g, x, y, start, end);
293: }
294:
295: /** Given a particular state, assign it a color.
296: * @param g Graphics object
297: * @param state a given state
298: */
299: private void setFormattingForState(Graphics g, int state) {
300: switch (state) {
301: case HighlightStatus.NORMAL:
302: g.setColor(NORMAL_COLOR);
303: break;
304: case HighlightStatus.COMMENTED:
305: g.setColor(COMMENTED_COLOR);
306: break;
307: case HighlightStatus.SINGLE_QUOTED:
308: g.setColor(SINGLE_QUOTED_COLOR);
309: break;
310: case HighlightStatus.DOUBLE_QUOTED:
311: g.setColor(DOUBLE_QUOTED_COLOR);
312: break;
313: case HighlightStatus.KEYWORD:
314: g.setColor(KEYWORD_COLOR);
315: break;
316: case HighlightStatus.NUMBER:
317: g.setColor(NUMBER_COLOR);
318: break;
319: case HighlightStatus.TYPE:
320: g.setColor(TYPE_COLOR);
321: break;
322: default:
323: throw new RuntimeException(
324: "Can't get color for invalid state: " + state);
325: }
326: g.setFont(MAIN_FONT);
327: }
328:
329: /** Called when a change occurs.
330: * @param changes document changes
331: * @param a a Shape
332: * @param f a ViewFactory
333: */
334: public void changedUpdate(DocumentEvent changes, Shape a,
335: ViewFactory f) {
336: super .changedUpdate(changes, a, f);
337: // Make sure we redraw since something changed in the formatting
338: Container c = getContainer();
339: if (c != null)
340: c.repaint();
341: }
342:
343: /** Called when an OptionListener perceives a change in any of the colors */
344: public void updateColors() {
345:
346: COMMENTED_COLOR = DrJava.getConfig().getSetting(
347: DEFINITIONS_COMMENT_COLOR);
348: DOUBLE_QUOTED_COLOR = DrJava.getConfig().getSetting(
349: DEFINITIONS_DOUBLE_QUOTED_COLOR);
350: SINGLE_QUOTED_COLOR = DrJava.getConfig().getSetting(
351: DEFINITIONS_SINGLE_QUOTED_COLOR);
352: NORMAL_COLOR = DrJava.getConfig().getSetting(
353: DEFINITIONS_NORMAL_COLOR);
354: KEYWORD_COLOR = DrJava.getConfig().getSetting(
355: DEFINITIONS_KEYWORD_COLOR);
356: NUMBER_COLOR = DrJava.getConfig().getSetting(
357: DEFINITIONS_NUMBER_COLOR);
358: TYPE_COLOR = DrJava.getConfig().getSetting(
359: DEFINITIONS_TYPE_COLOR);
360:
361: INTERACTIONS_SYSTEM_ERR_COLOR = DrJava.getConfig().getSetting(
362: SYSTEM_ERR_COLOR);
363: INTERACTIONS_SYSTEM_IN_COLOR = DrJava.getConfig().getSetting(
364: SYSTEM_IN_COLOR);
365: INTERACTIONS_SYSTEM_OUT_COLOR = DrJava.getConfig().getSetting(
366: SYSTEM_OUT_COLOR);
367: ERROR_COLOR = DrJava.getConfig().getSetting(
368: INTERACTIONS_ERROR_COLOR);
369: DEBUGGER_COLOR = DrJava.getConfig().getSetting(
370: DEBUG_MESSAGE_COLOR);
371:
372: // Avoid the ColoringView that does not have a container.
373: if (getContainer() != null)
374: getContainer().repaint();
375: }
376:
377: /** The OptionListeners for DEFINITIONS COLORs */
378: private class ColorOptionListener implements OptionListener<Color> {
379: public void optionChanged(OptionEvent<Color> oce) {
380: updateColors();
381: }
382: }
383:
384: private static class FontOptionListener implements
385: OptionListener<Font> {
386: public void optionChanged(OptionEvent<Font> oce) {
387: MAIN_FONT = DrJava.getConfig().getSetting(FONT_MAIN);
388: }
389: }
390: }
|