001: /*
002: * Copyright (C) 2005 - 2008 JasperSoft Corporation. All rights reserved.
003: * http://www.jaspersoft.com.
004: *
005: * Unless you have purchased a commercial license agreement from JasperSoft,
006: * the following license terms apply:
007: *
008: * This program is free software; you can redistribute it and/or modify
009: * it under the terms of the GNU General Public License version 2 as published by
010: * the Free Software Foundation.
011: *
012: * This program is distributed WITHOUT ANY WARRANTY; and without the
013: * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
014: * See the GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, see http://www.gnu.org/licenses/gpl.txt
018: * or write to:
019: *
020: * Free Software Foundation, Inc.,
021: * 59 Temple Place - Suite 330,
022: * Boston, MA USA 02111-1307
023: *
024: *
025: *
026: *
027: * LogTextArea.java
028: *
029: * Created on 22 agosto 2005, 15.03
030: *
031: */
032:
033: package it.businesslogic.ireport.gui.logpane;
034:
035: import javax.swing.*;
036: import it.businesslogic.ireport.util.Misc;
037: import it.businesslogic.ireport.gui.*;
038: import it.businesslogic.ireport.*;
039: import java.util.*;
040: import it.businesslogic.ireport.util.I18n;
041: import it.businesslogic.ireport.util.LanguageChangedEvent;
042: import it.businesslogic.ireport.util.LanguageChangedListener;
043: import java.net.URL;
044:
045: /**
046: *
047: * @author Administrator
048: */
049: public class LogTextArea extends javax.swing.JPanel implements
050: LanguageChangedListener {
051:
052: private StringBuffer outputBuffer;
053: private String title = null;
054: private LogPane logPane = null;
055: private boolean removable = false;
056: private Properties properties;
057:
058: private int maxlines = 5000;
059:
060: /** Creates new form LogTextArea */
061: public LogTextArea(String title) {
062: initComponents();
063:
064: outputBuffer = new StringBuffer();
065: this .setTitle(title);
066:
067: this .jEditorPaneOutput.setContentType("text/html");
068:
069: this .jEditorPaneOutput
070: .addHyperlinkListener(new javax.swing.event.HyperlinkListener() {
071: public void hyperlinkUpdate(
072: javax.swing.event.HyperlinkEvent e) {
073: if (e.getEventType() == javax.swing.event.HyperlinkEvent.EventType.ACTIVATED) {
074: if (!parseError(e.getURL()))
075: JOptionPane
076: .showMessageDialog(MainFrame
077: .getMainInstance(),
078: " HyperlinkEvent "
079: + e.getURL());
080: }
081: }
082: });
083:
084: try {
085: maxlines = Integer.parseInt(System.getProperty(
086: "ireport.maxoutputlines", "5000"));
087: } catch (Exception ex) {
088: maxlines = 5000;
089: }
090: clearConsole();
091: }
092:
093: /** This method parse an error encoded using an url.
094: * The url must be in the form:
095: * http://{error|warinig}:{JReportFrame ID}/{expression}
096: *
097: * error: referred to an expression field
098: * warning: referred to an element position warning
099: *
100: * Possible expressions for error:
101: * variableInitialValue_<VARIABLE_NAME>
102: * textField_<TEXTFIELD NUMBER>
103: * printWhen_<PRINT WHEN EXPRESSION NUMBER>(*)
104: * parameterDefaultValue_<PARAMETER NAME>
105: * parameter_<PARAMETER NAME>
106: *
107: * Possible expressions for warning:
108: * y=<Y>,height=<Height>,band-height=<Band-Height>
109: *
110: * (*) The printWhen expression are considered only if not blank.
111: * The search order is this: bands, elements
112: */
113: public static boolean parseError(java.net.URL url) {
114: if (url == null)
115: return false;
116:
117: // First of all activate the right frame...
118: JInternalFrame[] frames = MainFrame.getMainInstance()
119: .getJMDIDesktopPane().getAllFrames();
120: JReportFrame jrf = null;
121: for (int k = 0; k < frames.length; k++) {
122: if (frames[k] instanceof JReportFrame) {
123: if (((JReportFrame) frames[k]).getWindowID() == url
124: .getPort()) {
125: jrf = (JReportFrame) frames[k];
126: if (!frames[k].isSelected()) {
127: try {
128: frames[k].setSelected(true);
129: } catch (Exception ex) {
130: }
131: }
132: }
133: }
134: }
135: if (jrf == null)
136: return false;
137:
138: try {
139: if (url.getHost().equalsIgnoreCase("error")) {
140: String expression = url.getFile();
141:
142: if (expression != null && expression.length() > 0) {
143: // parse expression...
144: if (expression.startsWith("/variable")) {
145:
146: }
147:
148: if (expression.startsWith("/textField_")) {
149: int index = 0;
150: int number = Integer.parseInt(expression
151: .substring(("/textField_").length())
152: .trim());
153: Enumeration e = jrf.getReport().getElements()
154: .elements();
155: while (e.hasMoreElements()) {
156: ReportElement re = (ReportElement) e
157: .nextElement();
158: if (re instanceof TextFieldReportElement) {
159: index++;
160: if (index == number) {
161: jrf.setSelectedElement(re);
162: MainFrame
163: .getMainInstance()
164: .getElementPropertiesDialog()
165: .setVisible(true);
166: MainFrame
167: .getMainInstance()
168: .getElementPropertiesDialog()
169: .gotoTab(
170: MainFrame
171: .getMainInstance()
172: .getElementPropertiesDialog().TEXTFIELD_TAB);
173: return true;
174: }
175: }
176: }
177: } else if (expression
178: .startsWith("/parameterDefaultValue_")) {
179: int index = 0;
180: String name = expression.substring(
181: ("/parameterDefaultValue_").length())
182: .trim();
183: Enumeration e = jrf.getReport().getParameters()
184: .elements();
185: while (e.hasMoreElements()) {
186: it.businesslogic.ireport.JRParameter param = (it.businesslogic.ireport.JRParameter) e
187: .nextElement();
188: if (param.getName().equals(name)) {
189: MainFrame.getMainInstance()
190: .getValuesDialog().setVisible(
191: true);
192: MainFrame.getMainInstance()
193: .getValuesDialog()
194: .modifyErrorParameter(param);
195: return true;
196: }
197: }
198:
199: }
200: }
201: } else if (url.getHost().equals("warning")) {
202: }
203: } catch (Exception ex) {
204: }
205: return false;
206: }
207:
208: /** This method is called from within the constructor to
209: * initialize the form.
210: * WARNING: Do NOT modify this code. The content of this method is
211: * always regenerated by the Form Editor.
212: */
213: // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
214: private void initComponents() {
215: jPopupMenuLog = new javax.swing.JPopupMenu();
216: jMenuItemClearLog = new javax.swing.JMenuItem();
217: jMenuItemCloseLog = new javax.swing.JMenuItem();
218: jSeparator1 = new javax.swing.JSeparator();
219: jMenuItemCopy = new javax.swing.JMenuItem();
220: jMenuItemSelectAll = new javax.swing.JMenuItem();
221: jScrollPaneOutput = new javax.swing.JScrollPane();
222: jEditorPaneOutput = new javax.swing.JEditorPane();
223:
224: jMenuItemClearLog.setText("Clear log");
225: jMenuItemClearLog
226: .addActionListener(new java.awt.event.ActionListener() {
227: public void actionPerformed(
228: java.awt.event.ActionEvent evt) {
229: jMenuItemClearLogActionPerformed(evt);
230: }
231: });
232:
233: jPopupMenuLog.add(jMenuItemClearLog);
234:
235: jMenuItemCloseLog.setText("Close log");
236: jMenuItemCloseLog
237: .addActionListener(new java.awt.event.ActionListener() {
238: public void actionPerformed(
239: java.awt.event.ActionEvent evt) {
240: jMenuItemCloseLogActionPerformed(evt);
241: }
242: });
243:
244: jPopupMenuLog.add(jMenuItemCloseLog);
245:
246: jPopupMenuLog.add(jSeparator1);
247:
248: jMenuItemCopy.setText("Copy");
249: jMenuItemCopy
250: .addActionListener(new java.awt.event.ActionListener() {
251: public void actionPerformed(
252: java.awt.event.ActionEvent evt) {
253: jMenuItemCopyActionPerformed(evt);
254: }
255: });
256:
257: jPopupMenuLog.add(jMenuItemCopy);
258:
259: jMenuItemSelectAll.setText("Select all");
260: jMenuItemSelectAll
261: .addActionListener(new java.awt.event.ActionListener() {
262: public void actionPerformed(
263: java.awt.event.ActionEvent evt) {
264: jMenuItemSelectAllActionPerformed(evt);
265: }
266: });
267:
268: jPopupMenuLog.add(jMenuItemSelectAll);
269:
270: setLayout(new java.awt.BorderLayout());
271:
272: jScrollPaneOutput
273: .setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
274: jScrollPaneOutput
275: .setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
276: jScrollPaneOutput
277: .setMinimumSize(new java.awt.Dimension(22, 75));
278: jScrollPaneOutput.setPreferredSize(new java.awt.Dimension(3,
279: 100));
280: jEditorPaneOutput.setBackground(new java.awt.Color(204, 204,
281: 204));
282: jEditorPaneOutput.setEditable(false);
283: jEditorPaneOutput.setFont(new java.awt.Font("Courier New", 0,
284: 12));
285: jEditorPaneOutput.setOpaque(false);
286: jEditorPaneOutput
287: .addMouseListener(new java.awt.event.MouseAdapter() {
288: public void mouseClicked(
289: java.awt.event.MouseEvent evt) {
290: jEditorPaneOutputMouseClicked(evt);
291: }
292: });
293:
294: jScrollPaneOutput.setViewportView(jEditorPaneOutput);
295:
296: add(jScrollPaneOutput, java.awt.BorderLayout.CENTER);
297:
298: }// </editor-fold>//GEN-END:initComponents
299:
300: private void jMenuItemSelectAllActionPerformed(
301: java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemSelectAllActionPerformed
302: jEditorPaneOutput.selectAll();
303: }//GEN-LAST:event_jMenuItemSelectAllActionPerformed
304:
305: private void jMenuItemCopyActionPerformed(
306: java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemCopyActionPerformed
307: jEditorPaneOutput.copy();
308: }//GEN-LAST:event_jMenuItemCopyActionPerformed
309:
310: private void jMenuItemCloseLogActionPerformed(
311: java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemCloseLogActionPerformed
312:
313: this .getLogPane().removeLog(this );
314: }//GEN-LAST:event_jMenuItemCloseLogActionPerformed
315:
316: private void jMenuItemClearLogActionPerformed(
317: java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemClearLogActionPerformed
318: this .clearConsole();
319: }//GEN-LAST:event_jMenuItemClearLogActionPerformed
320:
321: private void jEditorPaneOutputMouseClicked(
322: java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jEditorPaneOutputMouseClicked
323:
324: if (evt.getButton() == evt.BUTTON3 && evt.getClickCount() == 1) {
325: this .jPopupMenuLog.show(this , evt.getPoint().x, evt
326: .getPoint().y);
327: }
328:
329: }//GEN-LAST:event_jEditorPaneOutputMouseClicked
330:
331: public void logOnConsole(String noHTML) {
332:
333: noHTML = tail(noHTML, maxlines);
334: logOnConsole(noHTML, false);
335: }
336:
337: /**
338: * Print a message. If the messages starts with <html> the message is considered in HTML format.
339: * Otherwise it is formatted using the default font.
340: *
341: * Message types come from JOptionPane.... :
342: *
343: * JOptionPane.PLAIN_MESSAGE = No icon is used
344: * JOptionPane.INFORMATION_MESSAGE:
345: * JOptionPane.WARNING_MESSAGE:
346: * JOptionPane.ERROR_MESSAGE:
347: * JOptionPane.QUESTION_MESSAGE:
348: *
349: * @param text The text to print
350: * @param messageType The type of icon to put in front of the message
351: */
352: public void logOnConsole(String text, int messageType) {
353:
354: if (text == null)
355: return;
356: if (!text.startsWith("<html>")) {
357: // clean the html text..
358: text = text.replaceAll("\\>", ">");
359: text = text.replaceAll("\\<", "<");
360: text = text.replaceAll("\\t", " ");
361: text = text.replaceAll("\\n", "<br>");
362: text = text.replaceAll("\\s", " ");
363:
364: text = "<font face=\"SansSerif\" size=\"3\" color=\"#000000\">"
365: + text + "</font>";
366: } else {
367: // Strip out the <html> prefix
368: text = text.substring(6);
369: }
370:
371: URL img_url = null;
372:
373: try {
374: switch (messageType) {
375: case JOptionPane.INFORMATION_MESSAGE:
376: img_url = this
377: .getClass()
378: .getResource(
379: "/it/businesslogic/ireport/icons/log/information.png");
380: break;
381: case JOptionPane.WARNING_MESSAGE:
382: img_url = this
383: .getClass()
384: .getResource(
385: "/it/businesslogic/ireport/icons/log/warning.png");
386: break;
387: case JOptionPane.ERROR_MESSAGE:
388: img_url = this
389: .getClass()
390: .getResource(
391: "/it/businesslogic/ireport/icons/log/error.png");
392: break;
393: case JOptionPane.QUESTION_MESSAGE:
394: img_url = this
395: .getClass()
396: .getResource(
397: "/it/businesslogic/ireport/icons/log/question.png");
398: break;
399: case JOptionPane.PLAIN_MESSAGE:
400: default:
401: img_url = null;
402: }
403: } catch (Exception ex) {
404: // image not found....
405: }
406:
407: if (img_url != null) {
408: text = "<img align=\"right\" src=\"" + img_url + "\">"
409: + text;
410: }
411:
412: logOnConsole(text, true);
413: }
414:
415: public void logOnConsole(String s, boolean isHTML) {
416: try {
417:
418: //String text = Misc.string_replace("","</body></html>",this.jEditorPaneOutput.getText());
419:
420: //s = + s+"</body></html>";
421: if (this .jEditorPaneOutput == null) {
422: outputBuffer.append(s);
423: //System.out.println(outputBuffer);
424: } else {
425: this .jEditorPaneOutput.setContentType("text/html");
426: if (!isHTML) {
427:
428: s = s.replaceAll("\\>", ">");
429: s = s.replaceAll("\\<", "<");
430: s = s.replaceAll("\\t", " ");
431: s = s.replaceAll("\\n", "<br>");
432: s = s.replaceAll("\\s", " ");
433:
434: //s = Misc.string_replace(">",">",s);
435: //s = Misc.string_replace("<","<",s);
436: //s = Misc.string_replace(" "," ",s);
437: //s = Misc.string_replace(" ","\t",s);
438: //s = Misc.string_replace("<br>", "\n", s);
439: }
440:
441: /*
442: outputBuffer.append(s);
443: this.jEditorPaneOutput.setText("<html><body><table border=\"0\" cellspacing=\"0\" cellpadding=\"0\"><tr><td nowrap><font face=\"Courier New\" size=\"3\">" + outputBuffer + "</font></td></tr></table></body></html>");
444: */
445: // Perform an append instead...
446: javax.swing.text.html.HTMLDocument doc = (javax.swing.text.html.HTMLDocument) jEditorPaneOutput
447: .getDocument();
448: javax.swing.text.html.HTMLEditorKit editorKit = (javax.swing.text.html.HTMLEditorKit) jEditorPaneOutput
449: .getEditorKit();
450:
451: //javax.swing.text.Element ele = doc.get getElement("inserthere");
452:
453: if (!s.startsWith("<")) {
454: s = "<font face=\"Courier New\" size=\"3\" >" + s
455: + "</font>";
456: }
457:
458: //if (ele != null)
459: //{
460: //doc.insertBeforeEnd(ele, s); //- "".length()
461: editorKit.insertHTML(doc, doc.getLength(), s, 0, 0,
462: null);
463:
464: //}
465: //else
466: //{
467: // this.jEditorPaneOutput.setText("<body top=0><p align=\"left\" id=\"inserthere\">"+ s + "</p></body>");
468: //}
469:
470: logPane.setActiveLog(this );
471: }
472: //this.jEditorPaneOutput.getDocument().insertString(this.jEditorPaneOutput.getDocument().getLength(), s , null);
473:
474: } catch (Exception exsx) {
475: JOptionPane.showMessageDialog(this , "" + exsx.getMessage());
476: }
477: }
478:
479: /**
480: * Clear console
481: */
482: public void clearConsole() {
483: this .jEditorPaneOutput.setContentType("text/html");
484: outputBuffer.setLength(0);
485: this .jEditorPaneOutput.setText("");
486: }
487:
488: public String getTitle() {
489: return title;
490: }
491:
492: public void setTitle(String title) {
493: this .title = title;
494: fireActionListenerActionPerformed(new java.awt.event.ActionEvent(
495: this , 0, title));
496: }
497:
498: // Variables declaration - do not modify//GEN-BEGIN:variables
499: private javax.swing.JEditorPane jEditorPaneOutput;
500: private javax.swing.JMenuItem jMenuItemClearLog;
501: private javax.swing.JMenuItem jMenuItemCloseLog;
502: private javax.swing.JMenuItem jMenuItemCopy;
503: private javax.swing.JMenuItem jMenuItemSelectAll;
504: private javax.swing.JPopupMenu jPopupMenuLog;
505: private javax.swing.JScrollPane jScrollPaneOutput;
506: private javax.swing.JSeparator jSeparator1;
507: // End of variables declaration//GEN-END:variables
508:
509: /**
510: * Utility field used by event firing mechanism.
511: */
512: private javax.swing.event.EventListenerList listenerList = null;
513:
514: /**
515: * Registers ActionListener to receive events.
516: * @param listener The listener to register.
517: */
518: public synchronized void addActionListener(
519: java.awt.event.ActionListener listener) {
520:
521: if (listenerList == null) {
522: listenerList = new javax.swing.event.EventListenerList();
523: }
524: listenerList.add(java.awt.event.ActionListener.class, listener);
525: }
526:
527: /**
528: * Removes ActionListener from the list of listeners.
529: * @param listener The listener to remove.
530: */
531: public synchronized void removeActionListener(
532: java.awt.event.ActionListener listener) {
533:
534: listenerList.remove(java.awt.event.ActionListener.class,
535: listener);
536: }
537:
538: /**
539: * Notifies all registered listeners about the event.
540: *
541: * @param event The event to be fired
542: */
543: private void fireActionListenerActionPerformed(
544: java.awt.event.ActionEvent event) {
545:
546: if (listenerList == null)
547: return;
548: Object[] listeners = listenerList.getListenerList();
549: for (int i = listeners.length - 2; i >= 0; i -= 2) {
550: if (listeners[i] == java.awt.event.ActionListener.class) {
551: ((java.awt.event.ActionListener) listeners[i + 1])
552: .actionPerformed(event);
553: }
554: }
555: }
556:
557: public LogPane getLogPane() {
558: return logPane;
559: }
560:
561: public void setLogPane(LogPane logPane) {
562: this .logPane = logPane;
563: }
564:
565: public boolean isRemovable() {
566: return removable;
567: }
568:
569: public void setRemovable(boolean removable) {
570: this .removable = removable;
571: }
572:
573: //Added by Felix Firgau for I18n on Feb 10th 2006
574: public void applyI18n() {
575: // Start autogenerated code ----------------------
576: // End autogenerated code ----------------------
577: jMenuItemClearLog.setText(it.businesslogic.ireport.util.I18n
578: .getString("clearLog"));
579: jMenuItemCloseLog.setText(it.businesslogic.ireport.util.I18n
580: .getString("closeLog"));
581: jMenuItemCopy.setText(it.businesslogic.ireport.util.I18n
582: .getString("copy"));
583: jMenuItemSelectAll.setText(it.businesslogic.ireport.util.I18n
584: .getString("selectAll"));
585:
586: }
587:
588: public void languageChanged(LanguageChangedEvent evt) {
589: this .applyI18n();
590: }//End
591:
592: public static int countMatches(String str, String sub) {
593: if (str == null || str.length() == 0 || sub == null
594: || sub.length() == 0) {
595: return 0;
596: }
597: int count = 0;
598: int idx = 0;
599: while ((idx = str.indexOf(sub, idx)) != -1) {
600: count++;
601: idx += sub.length();
602: }
603: return count;
604: }
605:
606: public static String tail(String str, int lines) {
607: if (str == null || str.length() == 0) {
608: return str;
609: }
610: int total = countMatches(str, "\n");
611: int splitTo = total - lines;
612: if (splitTo <= 0)
613: return str;
614:
615: int count = 0;
616: int idx = 0;
617: while (count < splitTo && (idx = str.indexOf("\n", idx)) != -1) {
618: count++;
619: idx += 1;
620: }
621:
622: return str.substring(idx);
623: }
624:
625: }
|