001: /*
002: * Copyright (c) 2005-2008 Substance Kirill Grouchnikov. All Rights Reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * o Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: *
010: * o Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * o Neither the name of Substance Kirill Grouchnikov nor the names of
015: * its contributors may be used to endorse or promote products derived
016: * from this software without specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
020: * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
021: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
022: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
025: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
026: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
027: * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
028: * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029: */
030: package org.jvnet.substance;
031:
032: import java.awt.Graphics;
033: import java.awt.Graphics2D;
034: import java.beans.PropertyChangeEvent;
035: import java.beans.PropertyChangeListener;
036:
037: import javax.swing.*;
038: import javax.swing.border.Border;
039: import javax.swing.plaf.*;
040: import javax.swing.plaf.basic.BasicBorders;
041: import javax.swing.plaf.basic.BasicTextAreaUI;
042: import javax.swing.text.*;
043:
044: import org.jvnet.lafwidget.animation.FadeStateListener;
045: import org.jvnet.substance.text.*;
046: import org.jvnet.substance.utils.SubstanceCoreUtilities;
047: import org.jvnet.substance.utils.SubstanceSizeUtils;
048:
049: /**
050: * UI for text areas in <b>Substance</b> look and feel.
051: *
052: * @author Kirill Grouchnikov
053: */
054: public class SubstanceTextAreaUI extends BasicTextAreaUI {
055: /**
056: * Listener for fade animations.
057: */
058: protected FadeStateListener substanceFadeStateListener;
059:
060: /**
061: * The associated text area.
062: */
063: protected JTextArea textArea;
064:
065: /**
066: * Property change listener.
067: */
068: protected PropertyChangeListener substancePropertyChangeListener;
069:
070: /*
071: * (non-Javadoc)
072: *
073: * @see javax.swing.plaf.ComponentUI#createUI(javax.swing.JComponent)
074: */
075: public static ComponentUI createUI(JComponent c) {
076: return new SubstanceTextAreaUI(c);
077: }
078:
079: /**
080: * Simple constructor.
081: *
082: * @param c
083: * Component (text area).
084: */
085: public SubstanceTextAreaUI(JComponent c) {
086: super ();
087: this .textArea = (JTextArea) c;
088: }
089:
090: /*
091: * (non-Javadoc)
092: *
093: * @see javax.swing.plaf.basic.BasicTextUI#installListeners()
094: */
095: @Override
096: protected void installListeners() {
097: super .installListeners();
098:
099: this .substanceFadeStateListener = new FadeStateListener(
100: this .textArea, null, null);
101: this .substanceFadeStateListener.registerListeners(false);
102:
103: this .substancePropertyChangeListener = new PropertyChangeListener() {
104: public void propertyChange(PropertyChangeEvent evt) {
105: if ("font".equals(evt.getPropertyName())) {
106: SwingUtilities.invokeLater(new Runnable() {
107: public void run() {
108: textArea.updateUI();
109: }
110: });
111: }
112: }
113: };
114: this .textArea
115: .addPropertyChangeListener(this .substancePropertyChangeListener);
116: }
117:
118: /*
119: * (non-Javadoc)
120: *
121: * @see javax.swing.plaf.basic.BasicTextUI#uninstallListeners()
122: */
123: @Override
124: protected void uninstallListeners() {
125: this .substanceFadeStateListener.unregisterListeners();
126: this .substanceFadeStateListener = null;
127:
128: this .textArea
129: .removePropertyChangeListener(this .substancePropertyChangeListener);
130: this .substancePropertyChangeListener = null;
131:
132: super .uninstallListeners();
133: }
134:
135: /*
136: * (non-Javadoc)
137: *
138: * @see javax.swing.plaf.basic.BasicTextAreaUI#installDefaults()
139: */
140: @Override
141: protected void installDefaults() {
142: super .installDefaults();
143: Border b = this .textArea.getBorder();
144: if (b == null || b instanceof UIResource) {
145: Border newB = new BorderUIResource.CompoundBorderUIResource(
146: new SubstanceBorder(
147: SubstanceSizeUtils
148: .getTextBorderInsets(SubstanceSizeUtils
149: .getComponentFontSize(this .textArea))),
150: new BasicBorders.MarginBorder());
151: this .textArea.setBorder(newB);
152: }
153: }
154:
155: // /*
156: // * (non-Javadoc)
157: // *
158: // * @see
159: // javax.swing.plaf.basic.BasicTextUI#paintBackground(java.awt.Graphics)
160: // */
161: // @Override
162: // protected void paintBackground(Graphics g) {
163: // SubstanceCoreUtilities.paintCompBackground(g, this.textArea);
164: // }
165: //
166: /*
167: * (non-Javadoc)
168: *
169: * @see javax.swing.plaf.basic.BasicTextUI#createHighlighter()
170: */
171: @Override
172: protected Highlighter createHighlighter() {
173: return new SubstanceHighlighter();
174: }
175:
176: /*
177: * (non-Javadoc)
178: *
179: * @see javax.swing.plaf.basic.BasicTextAreaUI#create(javax.swing.text.Element)
180: */
181: @Override
182: public View create(Element elem) {
183: View super Result = super .create(elem);
184: if (super Result instanceof PlainView) {
185: return new SubstancePlainView(elem);
186: }
187: if (super Result instanceof WrappedPlainView) {
188: return new SubstanceWrappedPlainView(elem,
189: ((JTextArea) getComponent()).getWrapStyleWord());
190: }
191: return super Result;
192: }
193:
194: /*
195: * (non-Javadoc)
196: *
197: * @see javax.swing.plaf.basic.BasicTextUI#modelChanged()
198: */
199: @Override
200: protected void modelChanged() {
201: super .modelChanged();
202:
203: JTextComponent component = this .getComponent();
204: View currView = getRootView(component);
205: Element defaultRootElement = component.getDocument()
206: .getDefaultRootElement();
207: if (currView instanceof PlainView) {
208: setView(new SubstancePlainView(defaultRootElement));
209: }
210: if (currView instanceof WrappedPlainView) {
211: setView(new SubstanceWrappedPlainView(defaultRootElement,
212: ((JTextArea) getComponent()).getWrapStyleWord()));
213: }
214: }
215:
216: /*
217: * (non-Javadoc)
218: *
219: * @see javax.swing.plaf.basic.BasicTextUI#paintSafely(java.awt.Graphics)
220: */
221: @Override
222: protected void paintSafely(Graphics _g) {
223: // // Have to call the super implementation since it sets a
224: // // private "painted" flag which affects many other places.
225: // // Without this there will be many visual artifacts with
226: // // painting the caret and highlights
227: // super.paintSafely(_g);
228: //
229: // SubstanceTextPainter textPainter = SubstanceLookAndFeel
230: // .getCurrentTextPainter();
231: //
232: // SubstanceTextPainter.BackgroundPaintingCallback callback = new
233: // SubstanceTextPainter.BackgroundPaintingCallback() {
234: // public void paintBackground(Graphics g) {
235: // Highlighter highlighter = getComponent().getHighlighter();
236: //
237: // // paint the background
238: // if (getComponent().isOpaque()) {
239: // SubstanceTextAreaUI.this.paintBackground(g);
240: // }
241: //
242: // // paint the highlights
243: // if (highlighter != null) {
244: // highlighter.paint(g);
245: // }
246: // }
247: // };
248: // textPainter.init(textArea, null, true);
249: // if (textPainter.needsBackgroundImage()) {
250: // textPainter.setBackgroundFill(textArea, textArea.getBackground(),
251: // false, 0, 0);
252: // textPainter.attachCallback(callback);
253: // } else {
254: // callback.paintBackground(_g);
255: // }
256: //
257: // // paint the view hierarchy
258: // Rectangle alloc = getVisibleEditorRect();
259: // if (alloc != null) {
260: // getRootView(textArea).paint(_g, alloc);
261: // }
262: // textPainter.renderSurface(_g);
263: //
264: // // paint the caret
265: // Caret caret = getComponent().getCaret();
266: // if (caret != null) {
267: // caret.paint(_g);
268: // }
269: // Have to call the super implementation since it sets a
270: // private "painted" flag which affects many other places.
271: // Without this there will be many visual artifacts with
272: // painting the caret and highlights
273: Graphics2D dummy = (Graphics2D) _g.create(0, 0, 0, 0);
274: super.paintSafely(dummy);
275: dummy.dispose();
276:
277: SubstanceCoreUtilities.paintTextComponent(_g, this.textArea,
278: this.getRootView(this.textArea), this
279: .getVisibleEditorRect());
280: }
281: }
|