1 /*
2 * Copyright (c) 2003-2008 by Cosylab d. d.
3 *
4 * This file is part of CosyBeans-Common.
5 *
6 * CosyBeans-Common is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * CosyBeans-Common is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with CosyBeans-Common. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 package com.cosylab.gui.components;
21
22 import javax.swing.text.AttributeSet;
23 import javax.swing.text.BadLocationException;
24
25 /**
26 * An extension of the <code>JTextArea</code> providing features commonly needed
27 * when using a text area to report large amounts of information to the screen.
28 *
29 * @author <a href="mailto:miha.kadunc@cosylab.com">Miha Kadunc</a>
30 * @version $id$
31 */
32 public class ReportTextArea extends javax.swing.JTextArea {
33
34 private static final long serialVersionUID = 1L;
35 private int maxLines = 500;
36 private boolean autoScroll = true;
37 private boolean autoCut = true;
38 private javax.swing.JFileChooser fileChooser = null;
39 EventProcessor ivjEventHandler = new EventProcessor();
40 private boolean popupInitialized = false;
41 private javax.swing.JMenuItem ivjJMenuItem1 = null;
42 private javax.swing.JPopupMenu ivjJPopupMenu1 = null;
43
44 class EventProcessor
45 implements java.awt.event.ActionListener, java.awt.event.MouseListener {
46 public void actionPerformed(java.awt.event.ActionEvent e) {
47 if (e.getSource() == ReportTextArea.this.getJMenuItem1())
48 connEtoC2(e);
49 };
50 public void mouseClicked(java.awt.event.MouseEvent e) {
51 if (e.getSource() == ReportTextArea.this)
52 connEtoC1(e);
53 };
54 public void mouseEntered(java.awt.event.MouseEvent e) {
55 };
56 public void mouseExited(java.awt.event.MouseEvent e) {
57 };
58 public void mousePressed(java.awt.event.MouseEvent e) {
59 };
60 public void mouseReleased(java.awt.event.MouseEvent e) {
61 };
62 };
63
64 /**
65 * Constructs an empty ReportTextArea.
66 */
67 public ReportTextArea() {
68 super();
69 initialize();
70 }
71 /**
72 * Constructs a text area with the specified number of rows and columns.
73 *
74 * @param rows int
75 * @param columns int
76 */
77 public ReportTextArea(int rows, int columns) {
78 super(rows, columns);
79 }
80 /**
81 * Constructs a ReportTextArea containing the specified text.
82 *
83 * @param text java.lang.String
84 */
85 public ReportTextArea(String text) {
86 super(text);
87 }
88 /**
89 * Constructs a ReportTextArea containing the specified text and number of
90 * rows and columns.
91 *
92 * @param text java.lang.String
93 * @param rows int
94 * @param columns int
95 */
96 public ReportTextArea(String text, int rows, int columns) {
97 super(text, rows, columns);
98 }
99 /**
100 * Constructs a new <code>ReportTextArea</code> with the specified document.
101 *
102 * @param doc javax.swing.text.Document
103 */
104 public ReportTextArea(javax.swing.text.Document doc) {
105 super(doc);
106 }
107 /**
108 * Constructs a new <code>ReportTextArea</code> with the specified document,
109 * text, and number of rows and columns.
110 *
111 * @param doc javax.swing.text.Document
112 * @param text java.lang.String
113 * @param rows int
114 * @param columns int
115 */
116 public ReportTextArea(
117 javax.swing.text.Document doc,
118 String text,
119 int rows,
120 int columns) {
121 super(doc, text, rows, columns);
122 }
123 /**
124 * Appends a string to the end of the text area.
125 *
126 * @param text java.lang.String
127 */
128 public void append(String text) {
129 super.append(text);
130 textInserted();
131 }
132 /**
133 * Appends a string to the end of the text area with ginven text style.
134 * @param text appended text
135 * @param style a style of appended text
136 */
137 public void append(String text,AttributeSet style) {
138 try {
139 getDocument().insertString(getDocument().getLength(), text, style);
140 } catch (BadLocationException e) {
141 handleException(e);
142 }
143 textInserted();
144 }
145 /**
146 * connEtoC1: (ReportTextArea.mouse.mouseClicked(java.awt.event.MouseEvent) --> ReportTextArea.showPopup(Ljava.awt.event.MouseEvent;)V)
147 * @param arg1 java.awt.event.MouseEvent
148 */
149 /* WARNING: THIS METHOD WILL BE REGENERATED. */
150 private void connEtoC1(java.awt.event.MouseEvent arg1) {
151 try {
152 // user code begin {1}
153 // user code end
154 this.showPopup(arg1);
155 // user code begin {2}
156 // user code end
157 } catch (java.lang.Throwable ivjExc) {
158 // user code begin {3}
159 // user code end
160 handleException(ivjExc);
161 }
162 }
163 /**
164 * connEtoC2: (JMenuItem1.action.actionPerformed(java.awt.event.ActionEvent) --> ReportTextArea.saveTextToFile()V)
165 * @param arg1 java.awt.event.ActionEvent
166 */
167 /* WARNING: THIS METHOD WILL BE REGENERATED. */
168 private void connEtoC2(java.awt.event.ActionEvent arg1) {
169 try {
170 // user code begin {1}
171 // user code end
172 this.saveTextToFile();
173 // user code begin {2}
174 // user code end
175 } catch (java.lang.Throwable ivjExc) {
176 // user code begin {3}
177 // user code end
178 handleException(ivjExc);
179 }
180 }
181 /**
182 * connEtoM1: (ReportTextArea.initialize() --> ReportTextArea.registerActionsForKeyStroke()V)
183 */
184 /* WARNING: THIS METHOD WILL BE REGENERATED. */
185 private void connEtoM1() {
186 try {
187 // user code begin {1}
188 // user code end
189 this.registerActionsForKeyStroke();
190 // user code begin {2}
191 // user code end
192 } catch (java.lang.Throwable ivjExc) {
193 // user code begin {3}
194 // user code end
195 handleException(ivjExc);
196 }
197 }
198 /**
199 * Returns the <code>JFileChooser</code> that this component uses to save
200 * the text to a file.
201 *
202 * @return javax.swing.JFileChooser
203 * @see #saveTextToFile()
204 */
205 public javax.swing.JFileChooser getFileChooser() {
206 if (fileChooser == null)
207 fileChooser = new javax.swing.JFileChooser();
208 return fileChooser;
209 }
210 /**
211 * Return the JMenuItem1 property value.
212 * @return javax.swing.JMenuItem
213 */
214 /* WARNING: THIS METHOD WILL BE REGENERATED. */
215 private javax.swing.JMenuItem getJMenuItem1() {
216 if (ivjJMenuItem1 == null) {
217 try {
218 ivjJMenuItem1 = new javax.swing.JMenuItem();
219 ivjJMenuItem1.setName("JMenuItem1");
220 ivjJMenuItem1.setText("Save...");
221 // user code begin {1}
222 // user code end
223 } catch (java.lang.Throwable ivjExc) {
224 // user code begin {2}
225 // user code end
226 handleException(ivjExc);
227 }
228 }
229 return ivjJMenuItem1;
230 }
231 /**
232 * Return the JPopupMenu1 property value.
233 * @return javax.swing.JPopupMenu
234 */
235 /* WARNING: THIS METHOD WILL BE REGENERATED. */
236 javax.swing.JPopupMenu getJPopupMenu1() {
237 if (ivjJPopupMenu1 == null) {
238 try {
239 ivjJPopupMenu1 = new javax.swing.JPopupMenu();
240 ivjJPopupMenu1.setName("JPopupMenu1");
241 ivjJPopupMenu1.add(getJMenuItem1());
242 // user code begin {1}
243 // user code end
244 } catch (java.lang.Throwable ivjExc) {
245 // user code begin {2}
246 // user code end
247 handleException(ivjExc);
248 }
249 }
250 return ivjJPopupMenu1;
251 }
252 /**
253 * Returns the maximum number of lines that this text area displays when
254 * <code>autoCut</code> property is set to <code>true</code>
255 *
256 * @return int
257 */
258 public int getMaxLines() {
259 return maxLines;
260 }
261 /**
262 * Called whenever the part throws an exception.
263 * @param exception java.lang.Throwable
264 */
265 private void handleException(java.lang.Throwable exception) {
266 if (exception instanceof RuntimeException) {
267 throw (RuntimeException)exception;
268 }
269 else throw new RuntimeException(exception);
270 }
271 /**
272 * Initializes connections
273 * @exception java.lang.Exception The exception description.
274 */
275 /* WARNING: THIS METHOD WILL BE REGENERATED. */
276 private void initConnections() throws java.lang.Exception {
277 // user code begin {1}
278 // user code end
279 this.addMouseListener(ivjEventHandler);
280 getJMenuItem1().addActionListener(ivjEventHandler);
281 }
282 /**
283 * Initialize the class.
284 */
285 /* WARNING: THIS METHOD WILL BE REGENERATED. */
286 private void initialize() {
287 try {
288 // user code begin {1}
289 // user code end
290 setName("ReportTextArea");
291 setSize(160, 120);
292 setEditable(true);
293 initConnections();
294 connEtoM1();
295 } catch (java.lang.Throwable ivjExc) {
296 handleException(ivjExc);
297 }
298 // user code begin {2}
299 // user code end
300 }
301 /**
302 * Inserts text to this text area at the specified index.
303 *
304 * @param text java.lang.String
305 * @param pos int
306 */
307 public void insert(String text, int pos) {
308 super.insert(text, pos);
309 textInserted();
310 }
311 /**
312 * When <code>autoCut</code> property is set to true, the component
313 * automatically cuts the beginning of text when it contains more lines than
314 * specified by the <code>maxLines</code> property.
315 *
316 * @return boolean
317 */
318 public boolean isAutoCut() {
319 return autoCut;
320 }
321 /**
322 * Returns the value of the <code>autoScroll</code> property. This property
323 * determines whether the caret position should be moved to the end of the
324 * text when a string is appended to the text.
325 *
326 * @return boolean
327 */
328 public boolean isAutoScroll() {
329 return autoScroll;
330 }
331 /**
332 * main entrypoint - starts the part when it is run as an application
333 * @param args java.lang.String[]
334 */
335 public static void main(java.lang.String[] args) {
336 try {
337 javax.swing.JFrame frame = new javax.swing.JFrame();
338 ReportTextArea aSmartTextArea;
339 aSmartTextArea = new ReportTextArea();
340 frame.setContentPane(aSmartTextArea);
341 frame.setSize(aSmartTextArea.getSize());
342 frame.addWindowListener(new java.awt.event.WindowAdapter() {
343 public void windowClosing(java.awt.event.WindowEvent e) {
344 System.exit(0);
345 };
346 });
347 frame.setVisible(true);
348 java.awt.Insets insets = frame.getInsets();
349 frame.setSize(
350 frame.getWidth() + insets.left + insets.right,
351 frame.getHeight() + insets.top + insets.bottom);
352 frame.setVisible(true);
353 aSmartTextArea.append("TOLE PROBAVAMO\n");
354 aSmartTextArea.append("TOLE PROBAVAMO\n");
355 aSmartTextArea.append("TOLE PROBAVAMO\n");
356 } catch (Throwable exception) {
357 System.err.println(
358 "Exception occurred in main() of si.ijs.acs.objectexplorer.ReportTextArea");
359 exception.printStackTrace(System.out);
360 }
361 }
362 private void registerActionsForKeyStroke() {
363 try {
364 javax.swing.text.Keymap kmap = getKeymap();
365
366 javax.swing.Action cpy =
367 kmap.getAction(javax.swing.KeyStroke.getKeyStroke("control C"));
368 javax.swing.Action other =
369 kmap.getAction(javax.swing.KeyStroke.getKeyStroke("control C"));
370 kmap.removeBindings();
371 kmap.setDefaultAction(other);
372 if (cpy != null)
373 kmap.addActionForKeyStroke(
374 javax.swing.KeyStroke.getKeyStroke("control C"),
375 cpy);
376 if (cpy != null)
377 kmap.addActionForKeyStroke(
378 javax.swing.KeyStroke.getKeyStroke("control INSERT"),
379 cpy);
380 } catch (Throwable exception) {
381 handleException(exception);
382 }
383 }
384 /**
385 * Shows a dialog to prompt the user for a fileName and saves the text to
386 * a file specified by the user.
387 */
388 public void saveTextToFile() {
389 getFileChooser().showSaveDialog(this);
390 java.io.File file = getFileChooser().getSelectedFile();
391 if (file == null) return;
392 try {
393 if (!file.getParentFile().exists()) {
394 file.getParentFile().mkdirs();
395 }
396 java.io.BufferedWriter bw =
397 new java.io.BufferedWriter(new java.io.FileWriter(file));
398 write(bw);
399 bw.close();
400 //System.out.println("written to:" + file + " text:" + getText());
401 } catch (java.io.IOException e) {
402 System.out.println(
403 "exception while writing " + e + " " + file + " " + getText());
404 e.printStackTrace();
405 }
406 return;
407 }
408 /**
409 * Sets the <code>autoCut</code> property.
410 * @param newAutocut boolean
411 * @see #isAutoCut()
412 */
413 public void setAutoCut(boolean newAutocut) {
414 autoCut = newAutocut;
415 }
416 /**
417 * Sets the value of the <code>autoScroll</code> property.
418 *
419 * @param newAutoScroll boolean
420 * @see #isAutoScroll()
421 */
422 public void setAutoScroll(boolean newAutoScroll) {
423 autoScroll = newAutoScroll;
424 }
425 /**
426 * Sets the <code>JFileChooser</code> that this component should use when
427 * saving text to a file.
428 *
429 * @param newFileChooser javax.swing.JFileChooser
430 */
431 public void setFileChooser(javax.swing.JFileChooser newFileChooser) {
432 fileChooser = newFileChooser;
433 }
434 /**
435 * Sets the <code>maxLines</code> property.
436 *
437 * @param newMaxLines int
438 */
439 public void setMaxLines(int newMaxLines) {
440 maxLines = newMaxLines;
441 }
442
443 /* (non-Javadoc)
444 * @see javax.swing.text.JTextComponent#setText(java.lang.String)
445 */
446 public void setText(String t) {
447 super.setText(t);
448 textInserted();
449 }
450
451 /**
452 * Comment
453 */
454 private synchronized void showPopup(java.awt.event.MouseEvent mouseEvent) {
455 if (mouseEvent.getModifiers() == java.awt.event.MouseEvent.META_MASK) {
456 if (getJPopupMenu1().getComponents().length < 2) {
457 java.awt.Component p = getParent().getParent().getParent();
458 popupInitialized = true;
459 }
460 getJPopupMenu1().show(this, mouseEvent.getX(), mouseEvent.getY());
461 }
462 }
463 /**
464 * Method should be called when text was inserted
465 */
466 private void textInserted() {
467 try {
468 if (autoCut && (getLineCount() > maxLines))
469 replaceRange(
470 "",
471 0,
472 getLineStartOffset(getLineCount() - maxLines + 1));
473 if (autoScroll)
474 setCaretPosition(getDocument().getLength());
475 } catch (Exception e) {
476 handleException(e);
477 }
478 }
479 }