001/* ---------------------------------------------------------------------------- 002 The Kiwi Toolkit - A Java Class Library 003 Copyright (C) 1998-2004 Mark A. Lindner 004 005 This library is free software; you can redistribute it and/or 006 modify it under the terms of the GNU General Public License as 007 published by the Free Software Foundation; either version 2 of the 008 License, or (at your option) any later version. 009 010 This library is distributed in the hope that it will be useful, 011 but WITHOUT ANY WARRANTY; without even the implied warranty of 012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 General Public License for more details. 014 015 You should have received a copy of the GNU General Public License 016 along with this library; if not, write to the Free Software 017 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 018 02111-1307, USA. 019 020 The author may be contacted at: mark_a_lindner@yahoo.com 021 ---------------------------------------------------------------------------- 022 $Log: KTextArea.java,v $ 023 Revision 1.2 2004/05/14 00:15:52 markl 024 automatically turn on word wrapping 025 026 Revision 1.1 2004/03/22 07:00:32 markl 027 new class 028 ---------------------------------------------------------------------------- 029*/ 030 031package kiwi.ui; 032 033import javax.swing.*; 034import javax.swing.event.*; 035import javax.swing.text.*; 036 037import kiwi.event.*; 038import kiwi.ui.model.KDocument; 039 040/** A specialization of <code>JTextArea</code> that can constrain the 041 * length of its input. The text area is preconfigured to have 042 * word-style line wrapping. 043 * 044 * @author Mark Lindner 045 * @since Kiwi 2.0 046 */ 047 048public class KTextArea extends JTextArea 049 { 050 private ChangeSupport csupport; 051 private _DocumentListener documentListener = null; 052 private boolean adjusting = false; 053 054 /** Construct a new <code>KTextArea</code>. 055 */ 056 057 public KTextArea() 058 { 059 super(); 060 _init(KDocument.NO_LIMIT); 061 } 062 063 /** Construct a new <code>KTextArea</code> with the specified size. 064 * 065 * @param rows The number of rows. 066 * @param columns The number of columns. 067 */ 068 069 public KTextArea(int rows, int columns) 070 { 071 super(rows, columns); 072 _init(KDocument.NO_LIMIT); 073 } 074 075 /** Construct a new <code>KTextArea</code> with the specified text. 076 * 077 * @param text The text to display. 078 */ 079 080 public KTextArea(String text) 081 { 082 super(text); 083 _init(KDocument.NO_LIMIT); 084 } 085 086 /** Construct a new <code>KTextArea</code> with the specified size and 087 * text. 088 * 089 * @param text The text to display. 090 * @param rows The number of rows. 091 * @param columns The number of columns. 092 */ 093 094 public KTextArea(String text, int rows, int columns) 095 { 096 super(text, rows, columns); 097 _init(KDocument.NO_LIMIT); 098 } 099 100 /* 101 */ 102 103 private void _init(int maxLength) 104 { 105 documentListener = new _DocumentListener(); 106 csupport = new ChangeSupport(this); 107 KDocument doc = new KDocument(maxLength); 108 setDocument(doc); 109 doc.addDocumentListener(documentListener); 110 111 setLineWrap(true); 112 setWrapStyleWord(true); 113 } 114 115 /** Set the editable state of this text area. 116 * 117 * @param flag A flag specifying whether this text area should be editable. 118 * Non-editable text areas are made transparent. 119 */ 120 121 public void setEditable(boolean flag) 122 { 123 super.setEditable(flag); 124 setOpaque(flag); 125 } 126 127 /** Set the maximum number of characters that may be entered into 128 * this text area. This method will have no effect if the document 129 * has been changed from a <code>KDocument</code> via a call to 130 * <code>setDocument()</code>. 131 * 132 * @param length The new maximum length, or <code>KDocument.NO_LIMIT</code> 133 * for unlimited length. 134 * @see kiwi.ui.model.KDocument 135 */ 136 137 public void setMaximumLength(int length) 138 { 139 Document d = getDocument(); 140 if(d instanceof KDocument) 141 ((KDocument)d).setMaximumLength(length); 142 } 143 144 /** Get the maxmium number of characters that may be entered into this text 145 * area. 146 * 147 * @return The maximum length, or <code>KDocument.NO_LIMIT</code> if there 148 * is no limit. 149 */ 150 151 public int getMaximumLength() 152 { 153 Document d = getDocument(); 154 if(d instanceof KDocument) 155 return(((KDocument)d).getMaximumLength()); 156 else 157 return(KDocument.NO_LIMIT); 158 } 159 160 /** Set the document model for this text area. 161 * 162 * @param doc The new document model. 163 */ 164 165 public void setDocument(Document doc) 166 { 167 super.setDocument(doc); 168 169 Document oldDoc = getDocument(); 170 171 if((documentListener != null) && (oldDoc != null)) 172 { 173 oldDoc.removeDocumentListener(documentListener); 174 doc.addDocumentListener(documentListener); 175 } 176 } 177 178 /** Add a <code>ChangeListener</code> to this component's list of listeners. 179 * <code>ChangeEvent</code>s are fired when this text area's document model 180 * changes. 181 * 182 * @param listener The listener to add. 183 */ 184 185 public void addChangeListener(ChangeListener listener) 186 { 187 csupport.addChangeListener(listener); 188 } 189 190 /** Remove a <code>ChangeListener</code> from this component's list 191 * of listeners. 192 * 193 * @param listener The listener to remove. 194 */ 195 196 public void removeChangeListener(ChangeListener listener) 197 { 198 csupport.removeChangeListener(listener); 199 } 200 201 /* document listener */ 202 203 private class _DocumentListener implements DocumentListener 204 { 205 public void changedUpdate(DocumentEvent evt) 206 { 207 _fireChange(); 208 } 209 210 public void insertUpdate(DocumentEvent evt) 211 { 212 _fireChange(); 213 } 214 215 public void removeUpdate(DocumentEvent evt) 216 { 217 _fireChange(); 218 } 219 } 220 221 /* Delay-fire a change event, but only if the current DocumentEvent is not 222 * the result of a call to setText(). 223 */ 224 225 private void _fireChange() 226 { 227 if(adjusting) 228 return; 229 230 SwingUtilities.invokeLater(new Runnable() 231 { 232 public void run() 233 { 234 csupport.fireChangeEvent(); 235 } 236 }); 237 } 238 239 /** Set the text to be displayed by this text area. A 240 * <code>ChangeEvent</code> will <i>not</i> be fired when the data 241 * in the text area is modified via this call. 242 * 243 * @param text The text to set. 244 */ 245 246 public final synchronized void setText(String text) 247 { 248 adjusting = true; 249 super.setText(text); 250 adjusting = false; 251 } 252 253 } 254 255/* end of source file */