View Javadoc

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 }