001: /*
002: * Copyright 2006-2007 Pentaho Corporation. All rights reserved.
003: * This software was developed by Pentaho Corporation and is provided under the terms
004: * of the Mozilla Public License, Version 1.1, or any later version. You may not use
005: * this file except in compliance with the license. If you need a copy of the license,
006: * please go to http://www.mozilla.org/MPL/MPL-1.1.txt.
007: *
008: * Software distributed under the Mozilla Public License is distributed on an "AS IS"
009: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. Please refer to
010: * the license for the specific language governing your rights and limitations.
011: *
012: * Additional Contributor(s): Martin Schmid gridvision engineering GmbH
013: */
014: package org.pentaho.reportdesigner.crm.report;
015:
016: import com.jgoodies.forms.layout.CellConstraints;
017: import com.jgoodies.forms.layout.FormLayout;
018: import org.jetbrains.annotations.NonNls;
019: import org.jetbrains.annotations.NotNull;
020: import org.jetbrains.annotations.Nullable;
021: import org.pentaho.reportdesigner.crm.report.util.JOptionPaneHelper;
022: import org.pentaho.reportdesigner.lib.client.components.CenterPanelDialog;
023: import org.pentaho.reportdesigner.lib.client.components.TextComponentHelper;
024: import org.pentaho.reportdesigner.lib.client.i18n.TranslationManager;
025: import org.pentaho.reportdesigner.lib.client.util.GUIUtils;
026: import org.pentaho.reportdesigner.lib.client.util.IOUtil;
027: import org.pentaho.reportdesigner.lib.client.util.UncaughtExceptionModelListener;
028: import org.pentaho.reportdesigner.lib.client.util.UncaughtExcpetionsModel;
029: import org.pentaho.reportdesigner.lib.client.util.UndoHelper;
030: import org.pentaho.reportdesigner.lib.client.util.WindowUtils;
031:
032: import javax.swing.*;
033: import javax.swing.event.ListSelectionEvent;
034: import javax.swing.event.ListSelectionListener;
035: import java.awt.*;
036: import java.awt.event.ActionEvent;
037: import java.awt.event.ActionListener;
038: import java.awt.event.MouseAdapter;
039: import java.awt.event.MouseEvent;
040: import java.io.BufferedReader;
041: import java.io.InputStreamReader;
042: import java.io.OutputStreamWriter;
043: import java.io.PrintWriter;
044: import java.io.StringWriter;
045: import java.lang.reflect.InvocationTargetException;
046: import java.net.URL;
047: import java.net.URLConnection;
048: import java.net.URLEncoder;
049: import java.util.ArrayList;
050: import java.util.Date;
051: import java.util.logging.Level;
052: import java.util.logging.Logger;
053:
054: /**
055: * User: Martin
056: * Date: 03.02.2006
057: * Time: 10:40:31
058: */
059: public class StatusBar extends JPanel implements
060: UncaughtExceptionModelListener {
061: @NonNls
062: @NotNull
063: private static final Logger LOG = Logger.getLogger(StatusBar.class
064: .getName());
065:
066: @NotNull
067: private JLabel statusLabel;
068: @NotNull
069: private ExceptionStatusGadget exceptionStatusGadget;
070: @NotNull
071: private MemoryStatusGadget memoryStatusGadget;
072:
073: public StatusBar() {
074: @NonNls
075: FormLayout formLayout = new FormLayout(
076: "2dlu, fill:1dlu:grow, 4dlu, pref, 4dlu, pref, 4dlu, pref, 15dlu, fill:max(60dlu;pref), 0dlu",
077: "0dlu, fill:pref, 0dlu");
078: setLayout(formLayout);
079: @NonNls
080: CellConstraints cc = new CellConstraints();
081:
082: statusLabel = new JLabel(" ");
083: statusLabel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4,
084: 4));
085: add(statusLabel, cc.xy(2, 2));
086: add(new JSeparator(JSeparator.VERTICAL), cc.xy(4, 2));
087: exceptionStatusGadget = new ExceptionStatusGadget();
088: add(exceptionStatusGadget, cc.xy(6, 2));
089: add(new JSeparator(JSeparator.VERTICAL), cc.xy(8, 2));
090: memoryStatusGadget = new MemoryStatusGadget();
091: add(memoryStatusGadget, cc.xy(10, 2));
092:
093: setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0,
094: Color.LIGHT_GRAY));
095: }
096:
097: public void dispose() {
098: exceptionStatusGadget.timer.stop();
099: memoryStatusGadget.dispose();
100: }
101:
102: public void setGeneralInfoText(@Nullable
103: String text) {
104: if (text == null || text.length() == 0) {
105: statusLabel.setText(" ");
106: } else {
107: statusLabel.setText(text);
108: }
109: }
110:
111: public void exceptionCaught(@NotNull
112: Throwable throwable) {
113: if (LOG.isLoggable(Level.SEVERE))
114: LOG.log(Level.SEVERE, "StatusBar.exceptionCaught ",
115: throwable);
116: exceptionStatusGadget.exceptionCaught();
117: }
118:
119: public void exceptionsCleared() {
120: exceptionStatusGadget.firstTime = true;
121: exceptionStatusGadget.timer.stop();
122: exceptionStatusGadget.setIcon(IconLoader.getInstance()
123: .getNoErrorIcon());
124: }
125:
126: public void exceptionsViewed() {
127: exceptionStatusGadget.timer.stop();
128: exceptionStatusGadget.setIcon(IconLoader.getInstance()
129: .getNoErrorIcon());
130: }
131:
132: private static class ExceptionStatusGadget extends JLabel {
133: @NotNull
134: private Timer timer;
135: private boolean firstTime;
136:
137: private ExceptionStatusGadget() {
138: firstTime = true;
139:
140: setHorizontalAlignment(JLabel.CENTER);
141: setIcon(IconLoader.getInstance().getNoErrorIcon());
142: setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
143:
144: timer = new Timer(500, new ActionListener() {
145: public void actionPerformed(@NotNull
146: ActionEvent e) {
147: //noinspection ObjectEquality
148: if (getIcon() == IconLoader.getInstance()
149: .getNoErrorIcon()) {
150: setIcon(IconLoader.getInstance().getErrorIcon());
151: } else {
152: setIcon(IconLoader.getInstance()
153: .getNoErrorIcon());
154: }
155: }
156: });
157:
158: timer.setRepeats(true);
159: timer.stop();
160:
161: addMouseListener(new MouseAdapter() {
162: public void mouseClicked(@NotNull
163: MouseEvent e) {
164: timer.stop();
165: setIcon(IconLoader.getInstance().getNoErrorIcon());
166:
167: UncaughtExcpetionsModel.getInstance()
168: .exceptionsViewed();
169:
170: final CenterPanelDialog centerPanelDialog = CenterPanelDialog
171: .createDialog(
172: ExceptionStatusGadget.this ,
173: TranslationManager
174: .getInstance()
175: .getTranslation("R",
176: "ExceptionStatusGadget.Title"),
177: CenterPanelDialog.ModalityType.DOCUMENT_MODAL);
178: ArrayList<UncaughtExcpetionsModel.ThrowableInfo> throwableInfos = new ArrayList<UncaughtExcpetionsModel.ThrowableInfo>(
179: UncaughtExcpetionsModel.getInstance()
180: .getThrowables());
181:
182: final ChangeableListModel defaultListModel = new ChangeableListModel();
183: for (UncaughtExcpetionsModel.ThrowableInfo throwableInfo : throwableInfos) {
184: defaultListModel.addElement(throwableInfo);
185: }
186:
187: final JList list = new JList(defaultListModel);
188: list.getSelectionModel().setSelectionMode(
189: ListSelectionModel.SINGLE_SELECTION);
190:
191: final JTextArea stacktraceTextArea = new JTextArea();
192: stacktraceTextArea.setEditable(false);
193: TextComponentHelper
194: .installDefaultPopupMenu(stacktraceTextArea);
195:
196: final JTextArea descriptionTextArea = new JTextArea();
197: TextComponentHelper
198: .installDefaultPopupMenu(descriptionTextArea);
199: UndoHelper.installUndoSupport(descriptionTextArea);
200:
201: final JButton submitButton = new JButton(
202: TranslationManager.getInstance()
203: .getTranslation("R",
204: "Button.sumbit"));
205: JButton okButton = new JButton(TranslationManager
206: .getInstance().getTranslation("R",
207: "Button.close"));
208: JButton clearButton = new JButton(
209: TranslationManager
210: .getInstance()
211: .getTranslation("R", "Button.clear"));
212:
213: submitButton.setEnabled(false);
214:
215: submitButton
216: .addActionListener(new ActionListener() {
217: public void actionPerformed(@NotNull
218: ActionEvent e) {
219: OutputStreamWriter wr = null;
220: BufferedReader rd = null;
221: try {
222: UncaughtExcpetionsModel.ThrowableInfo throwableInfo = (UncaughtExcpetionsModel.ThrowableInfo) list
223: .getSelectedValue();
224: // Construct data
225: String title = throwableInfo
226: .getThrowable()
227: + " occured at "
228: + new Date(
229: throwableInfo
230: .getMillis());//NON-NLS
231: String description = (descriptionTextArea
232: .getText()
233: + "\n\n" + getStacktraceText(throwableInfo));
234:
235: String data = URLEncoder
236: .encode("title",
237: "UTF-8")
238: + "="
239: + URLEncoder.encode(
240: title, "UTF-8");//NON-NLS
241: data += "&"
242: + URLEncoder.encode(
243: "description",
244: "UTF-8")
245: + "="
246: + URLEncoder.encode(
247: description,
248: "UTF-8");//NON-NLS
249:
250: // Send data
251: //TODO change to pentaho tracker
252: URL url = new URL(
253: "http://www.gridvision.ch/ReportDesigner/SubmitBug.php");//NON-NLS
254: URLConnection conn = url
255: .openConnection();
256: conn.setDoOutput(true);
257: //noinspection IOResourceOpenedButNotSafelyClosed
258: wr = new OutputStreamWriter(
259: conn.getOutputStream());
260: wr.write(data);
261: wr.flush();
262:
263: // Get the response
264: //noinspection IOResourceOpenedButNotSafelyClosed
265: rd = new BufferedReader(
266: new InputStreamReader(
267: conn
268: .getInputStream()));
269: String line;
270: StringBuilder sb = new StringBuilder(
271: 100);
272: boolean submitted = false;
273: while ((line = rd.readLine()) != null) {
274: if (line
275: .contains("The Bug has been submitted"))//NON-NLS
276: {
277: submitted = true;
278: }
279: sb.append(line);
280: sb.append('\n');
281: }
282: if (LOG.isLoggable(Level.FINE))
283: LOG.log(Level.FINE,
284: "StatusBar$ExceptionStatusGadget.actionPerformed sb = "
285: + sb);
286:
287: if (submitted) {
288: JOptionPaneHelper
289: .showMessageDialog(
290: centerPanelDialog,
291: TranslationManager
292: .getInstance()
293: .getTranslation(
294: "R",
295: "ExceptionStatusGadget.Submitted.Message"),
296: TranslationManager
297: .getInstance()
298: .getTranslation(
299: "R",
300: "ExceptionStatusGadget.Submitted.Title"),
301: JOptionPaneHelper.INFORMATION_MESSAGE,
302: CenterPanelDialog.ModalityType.DOCUMENT_MODAL);
303:
304: throwableInfo
305: .setSubmitted(true);
306: defaultListModel
307: .fireElementChanged(list
308: .getSelectedIndex());
309: submitButton
310: .setEnabled(false);
311: }
312: } catch (Exception ex) {
313: if (LOG
314: .isLoggable(Level.WARNING))
315: LOG
316: .log(
317: Level.WARNING,
318: "StatusBar$ExceptionStatusGadget.actionPerformed ",
319: ex);
320:
321: JOptionPaneHelper
322: .showMessageDialog(
323: centerPanelDialog,
324: TranslationManager
325: .getInstance()
326: .getTranslation(
327: "R",
328: "ExceptionStatusGadget.Error.Message"),
329: TranslationManager
330: .getInstance()
331: .getTranslation(
332: "R",
333: "ExceptionStatusGadget.Error.Title"),
334: JOptionPaneHelper.ERROR_MESSAGE,
335: CenterPanelDialog.ModalityType.DOCUMENT_MODAL);
336: } finally {
337: IOUtil.closeStream(wr);
338: IOUtil.closeStream(rd);
339: }
340: }
341: });
342:
343: okButton.addActionListener(new ActionListener() {
344: public void actionPerformed(@NotNull
345: ActionEvent e) {
346: centerPanelDialog.dispose();
347: }
348: });
349:
350: clearButton.addActionListener(new ActionListener() {
351: public void actionPerformed(@NotNull
352: ActionEvent e) {
353:
354: UncaughtExcpetionsModel.getInstance()
355: .clearExceptions();
356:
357: list.setModel(new DefaultListModel());
358: stacktraceTextArea.setText("");
359: firstTime = true;
360: }
361: });
362:
363: list
364: .addListSelectionListener(new ListSelectionListener() {
365: public void valueChanged(@NotNull
366: ListSelectionEvent e) {
367: if (!e.getValueIsAdjusting()) {
368: Object selectedValue = list
369: .getSelectedValue();
370: if (selectedValue instanceof UncaughtExcpetionsModel.ThrowableInfo) {
371: UncaughtExcpetionsModel.ThrowableInfo throwableInfo = (UncaughtExcpetionsModel.ThrowableInfo) selectedValue;
372: String text = getStacktraceText(throwableInfo);
373: stacktraceTextArea
374: .setText(text);
375: stacktraceTextArea
376: .setCaretPosition(0);
377: } else {
378: stacktraceTextArea
379: .setText("");
380: }
381:
382: Object sv = list
383: .getSelectedValue();
384: if (sv instanceof UncaughtExcpetionsModel.ThrowableInfo) {
385: UncaughtExcpetionsModel.ThrowableInfo throwableInfo = (UncaughtExcpetionsModel.ThrowableInfo) sv;
386: submitButton
387: .setEnabled(!throwableInfo
388: .isSubmitted());
389: } else {
390: submitButton
391: .setEnabled(false);
392: }
393: }
394: }
395: });
396:
397: if (!throwableInfos.isEmpty()) {
398: list.getSelectionModel().addSelectionInterval(
399: throwableInfos.size() - 1,
400: throwableInfos.size() - 1);
401: centerPanelDialog
402: .executeAfterMakingVisible(new Runnable() {
403: public void run() {
404: list
405: .ensureIndexIsVisible(list
406: .getMaxSelectionIndex());
407: }
408: });
409: }
410:
411: @NonNls
412: FormLayout layout = new FormLayout(
413: "0dlu, fill:10dlu:grow, 0dlu",
414: "4dlu, pref, 4dlu, fill:50dlu, 2dlu, fill:10dlu:grow, 0dlu");
415: @NonNls
416: CellConstraints cc = new CellConstraints();
417:
418: JPanel lowerPanel = new JPanel(layout);
419: //lowerPanel.add(new JLabel(TranslationManager.getInstance().getTranslation("R", "ExceptionStatusGadget.DescriptionLabel")), cc.xy(2, 2));
420: lowerPanel.add(
421: new JScrollPane(descriptionTextArea), cc
422: .xy(2, 4));
423: lowerPanel.add(new JScrollPane(stacktraceTextArea),
424: cc.xy(2, 6));
425:
426: JSplitPane splitPane = new JSplitPane(
427: JSplitPane.VERTICAL_SPLIT, true,
428: new JScrollPane(list), lowerPanel);
429: splitPane.setDividerLocation(150);
430: JPanel centerPanel = new JPanel(new BorderLayout());
431: centerPanel.add(splitPane, BorderLayout.CENTER);
432:
433: descriptionTextArea.setEnabled(false);//TODO
434:
435: centerPanelDialog.setCenterPanel(centerPanel);
436: //centerPanelDialog.setButtons(submitButton, okButton, submitButton, okButton, clearButton);
437: centerPanelDialog.setButtons(okButton, okButton,
438: okButton, clearButton);
439:
440: centerPanelDialog.pack();
441: GUIUtils.ensureMinimumDialogSize(centerPanelDialog,
442: 800, 600);
443:
444: WindowUtils.setLocationRelativeTo(
445: centerPanelDialog,
446: ExceptionStatusGadget.this );
447: centerPanelDialog.setVisible(true);
448: }
449: });
450: }
451:
452: @NotNull
453: private String getStacktraceText(@NotNull
454: UncaughtExcpetionsModel.ThrowableInfo throwableInfo) {
455: StringWriter sw = new StringWriter();
456: String text;
457: PrintWriter pw = null;
458: try {
459: //noinspection IOResourceOpenedButNotSafelyClosed
460: pw = new PrintWriter(sw);
461: throwableInfo.getThrowable().printStackTrace(pw);
462: text = sw.getBuffer().toString();
463: } finally {
464: IOUtil.closeStream(pw);
465: }
466: return text;
467: }
468:
469: public void exceptionCaught() {
470: if (firstTime) {
471: firstTime = false;
472:
473: Component rootPane = getParent();
474: while (rootPane != null
475: && !(rootPane instanceof JRootPane)) {
476: rootPane = rootPane.getParent();
477: }
478: if (rootPane != null) {
479: final JRootPane jRootPane = (JRootPane) rootPane;
480:
481: final JLabel label = new JLabel(TranslationManager
482: .getInstance().getTranslation("R",
483: "StatusBar.InternalError.Message"));
484: label.setForeground(new Color(120, 0, 0));
485: label.setBorder(BorderFactory
486: .createCompoundBorder(BorderFactory
487: .createLineBorder(Color.RED),
488: BorderFactory.createEmptyBorder(8,
489: 8, 8, 8)));
490: label.setBackground(new Color(255, 0, 0, 125));
491: label.setOpaque(true);
492:
493: jRootPane.getLayeredPane().add(label);
494: jRootPane.getLayeredPane().setLayer(label,
495: JLayeredPane.POPUP_LAYER.intValue());
496: Rectangle rectangle = SwingUtilities
497: .convertRectangle(getParent(), getBounds(),
498: jRootPane.getLayeredPane());
499: label.setBounds((int) (rectangle.getX() - label
500: .getPreferredSize().width),
501: (int) (rectangle.getY() - label
502: .getPreferredSize().height), label
503: .getPreferredSize().width, label
504: .getPreferredSize().height);
505: jRootPane.getLayeredPane().revalidate();
506: jRootPane.getLayeredPane().repaint();
507:
508: Timer t = new Timer(5000, new ActionListener() {
509: public void actionPerformed(@NotNull
510: ActionEvent e) {
511: jRootPane.getLayeredPane().remove(label);
512: jRootPane.getLayeredPane().repaint();
513: }
514: });
515: t.setRepeats(false);
516: t.start();
517: }
518: }
519: timer.restart();
520: }
521:
522: }
523:
524: private static class ChangeableListModel extends DefaultListModel {
525: private ChangeableListModel() {
526: }
527:
528: public void fireElementChanged(int index) {
529: fireContentsChanged(this , index, index);
530: }
531: }
532:
533: private static class MemoryStatusGadget extends JLabel {
534: @NotNull
535: private static final Color BG = new Color(220, 220, 220);
536:
537: private double tm;
538: private double fm;
539:
540: private boolean disposed;
541:
542: private MemoryStatusGadget() {
543: disposed = false;
544:
545: setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
546:
547: setHorizontalAlignment(JLabel.CENTER);
548:
549: Thread t = new Thread(new Runnable() {
550: public void run() {
551: //noinspection InfiniteLoopStatement
552: while (!disposed) {
553: final long totalMemory = Runtime.getRuntime()
554: .totalMemory();
555: final long freeMemory = Runtime.getRuntime()
556: .freeMemory();
557:
558: try {
559: EventQueue.invokeAndWait(new Runnable() {
560: public void run() {
561: tm = (totalMemory / (1024. * 1024));
562: fm = (freeMemory / (1024. * 1024));
563:
564: setText(TranslationManager
565: .getInstance()
566: .getTranslation(
567: "R",
568: "MemoryStatusGadget.Text",
569: Double.valueOf(tm
570: - fm),
571: Double.valueOf(tm)));
572: }
573: });
574:
575: Thread.sleep(1000);
576: } catch (InterruptedException e) {
577: //ignore
578: } catch (InvocationTargetException e) {
579: UncaughtExcpetionsModel.getInstance()
580: .addException(e);
581: }
582: }
583: }
584: });
585:
586: t.setDaemon(true);
587: t.setPriority(Thread.MIN_PRIORITY);
588: t.start();
589:
590: addMouseListener(new MouseAdapter() {
591: public void mouseClicked(@NotNull
592: MouseEvent e) {
593: System.gc();
594: }
595: });
596: }
597:
598: protected void paintComponent(@NotNull
599: Graphics g) {
600: Color origColor = g.getColor();
601:
602: g.setColor(Color.WHITE);
603: g.fillRect(0, 0, getWidth(), getHeight());
604: int w = (int) (getWidth() * ((tm - fm) / tm));
605: g.setColor(BG);
606: g.fillRect(0, 0, w, getHeight());
607:
608: g.setColor(origColor);
609: super .paintComponent(g);
610: }
611:
612: public void dispose() {
613: disposed = true;
614: }
615: }
616:
617: }
|