|
What this is
Other links
The source code/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun * Microsystems, Inc. All Rights Reserved. */ package org.netbeans.core; import java.awt.*; import java.awt.event.*; import java.beans.*; import java.io.File; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; import java.util.ResourceBundle; import javax.swing.*; import org.openide.windows.*; import org.openide.*; import org.openide.util.NbBundle; /** * Notifies exceptions. * * @author Jaroslav Tulach */ final class NotifyException extends JPanel implements ActionListener { static final long serialVersionUID =3680397500573480127L; /** the instance */ private static NotifyException INSTANCE = null; /** max text of exception */ private static final int MAXIMUM_TEXT_WIDTH = 40; /** preferred width of this component */ private static final int SIZE_PREFERRED_WIDTH=550; /** preferred height of this component */ private static final int SIZE_PREFERRED_HEIGHT=250; /** enumeration of NbExceptionManager.Exc to notify */ private static ArrayListPos exceptions; /** current exception */ private NbErrorManager.Exc current; /** dialog descriptor */ private DialogDescriptor descriptor; /** dialog that displayes the exceptions */ private java.awt.Dialog dialog; /** button to show next exceptions */ private JButton next; /** button to show previous exceptions */ private JButton previous; /** details button */ private JButton details; /** details window */ //XXX reconsider: private OutTermPane output; private JEditorPane output; /** boolean to show/hide details */ private boolean showDetails; /** Constructor. */ private NotifyException () { setPreferredSize(new Dimension(SIZE_PREFERRED_WIDTH,SIZE_PREFERRED_HEIGHT)); exceptions=new ArrayListPos(); java.util.ResourceBundle bundle = org.openide.util.NbBundle.getBundle(NotifyException.class); next = new JButton (bundle.getString("CTL_NextException")); // bugfix 25684, don't set Previous/Next as default capable next.setDefaultCapable (false); previous = new JButton (bundle.getString("CTL_PreviousException")); previous.setDefaultCapable (false); details = new JButton (); details.setDefaultCapable (false); /* output = new OutTermPane (); output.getTerm ().setScrollOnOutput(false); output.getTerm ().setTrackCursor(false); */ output = new JEditorPane(); output.setEditable(false); output.setFont(new Font("Monospaced", Font.PLAIN, output.getFont().getSize() + 1)); // NOI18N output.setForeground(UIManager.getColor("Label.foreground")); // NOI18N output.setBackground(UIManager.getColor("Label.background")); // NOI18N setLayout( new BorderLayout() ); //add ( output ); add(new JScrollPane(output)); setBorder( new javax.swing.border.BevelBorder(javax.swing.border.BevelBorder.LOWERED)); //setViewportView (output); next.setMnemonic(bundle.getString("CTL_NextException_Mnemonic").charAt(0)); previous.setMnemonic(bundle.getString("CTL_PreviousException_Mnemonic").charAt(0)); next.getAccessibleContext().setAccessibleDescription(bundle.getString("ACSD_NextException")); previous.getAccessibleContext().setAccessibleDescription(bundle.getString("ACSD_PreviousException")); output.getAccessibleContext().setAccessibleName(bundle.getString("ACSN_ExceptionStackTrace")); output.getAccessibleContext().setAccessibleDescription(bundle.getString("ACSD_ExceptionStackTrace")); getAccessibleContext().setAccessibleDescription(bundle.getString("ACSD_NotifyExceptionPanel")); descriptor = new DialogDescriptor ("", ""); // NOI18N descriptor.setMessageType (DialogDescriptor.ERROR_MESSAGE); descriptor.setOptions (new Object[] { previous, next, DialogDescriptor.OK_OPTION }); descriptor.setAdditionalOptions (new Object[] { details }); descriptor.setClosingOptions (new Object[0]); descriptor.setButtonListener (this); // bugfix #27176, create dialog in modal state if some other modal // dialog is opened at the time descriptor.setModal(isModalDialogPresent()); dialog = org.openide.DialogDisplayer.getDefault ().createDialog (descriptor); } private static boolean isModalDialogPresent() { return hasModalDialog(WindowManager.getDefault().getMainWindow()) // XXX Trick to get the shared frame instance. || hasModalDialog(new JDialog().getOwner()); } private static boolean hasModalDialog(Window w) { Window[] ws = w.getOwnedWindows(); for(int i = 0; i < ws.length; i++) { if(ws[i] instanceof Dialog && ((Dialog)ws[i]).isModal() && ws[i].isVisible()) { return true; } else if(hasModalDialog(ws[i])) { return true; } } return false; } private static final boolean printLogToConsole = Boolean.getBoolean("netbeans.logger.console"); // NOI18N /** Adds new exception into the queue. */ public static void notify ( final NbErrorManager.Exc t ) { SwingUtilities.invokeLater (new Runnable () { public void run() { String glm = t.getLocalizedMessage(); int gs = t.getSeverity(); boolean loc = t.isLocalized(); if (gs == ErrorManager.WARNING && loc) org.openide.DialogDisplayer.getDefault().notify( new NotifyDescriptor.Message(glm, NotifyDescriptor.WARNING_MESSAGE)); else if (gs == ErrorManager.USER && loc) org.openide.DialogDisplayer.getDefault().notify( new NotifyDescriptor.Message(glm, NotifyDescriptor.INFORMATION_MESSAGE)); else if (gs == ErrorManager.ERROR && loc) if (printLogToConsole) { org.openide.DialogDisplayer.getDefault().notify( new NotifyDescriptor.Message(glm, NotifyDescriptor.ERROR_MESSAGE)); } else { String htmlmsg = "" + glm + ""; // NO18N org.openide.awt.StatusDisplayer.getDefault().setStatusText(htmlmsg); } else { if (INSTANCE==null) INSTANCE = new NotifyException(); INSTANCE.updateState(t); } } }); } /** * updates the state of the dialog. called only in AWT thread. */ private void updateState (NbErrorManager.Exc t) { exceptions.add(t); if (!exceptions.existsNextElement()) { // it can be commented out while INSTANCE is not cached // (see the comment in actionPerformed) /*// be modal if some modal dialog is already opened, nonmodal otherwise boolean isModalDialogOpened = NbPresenter.currentModalDialog != null; if (descriptor.isModal() != isModalDialogOpened) { descriptor.setModal(isModalDialogOpened); // bugfix #27176, old dialog is disposed before recreating if (dialog != null) dialog.dispose (); // so we can safely send it to gc and recreate dialog // dialog = org.openide.DialogDisplayer.getDefault ().createDialog (descriptor); }*/ // the dialog is not shown current = t; update (); } else { // add the exception to the queue next.setVisible (true); } try { //Dialog.show() will pump events for the AWT thread. If the //exception happened because of a paint, it will trigger opening //another dialog, which will trigger another exception, endlessly. //Catch any exceptions and append them to the list instead. ensurePreferredSize(); dialog.show (); //throw new RuntimeException ("I am not so exceptional"); //uncomment to test } catch (Exception e) { exceptions.add(new NbErrorManager().createExc( e, ErrorManager.EXCEPTION)); next.setVisible(true); } } private void ensurePreferredSize() { Dimension sz = dialog.getSize(); Dimension pref = dialog.getPreferredSize(); if (pref.height == 0) pref.height = SIZE_PREFERRED_HEIGHT; if (pref.width == 0) pref.width = SIZE_PREFERRED_WIDTH; if (!sz.equals(pref)) { dialog.setSize(pref.width, pref.height); dialog.validate(); dialog.repaint(); } } /** Updates the visual state of the dialog. */ private void update () { // JST: this can be improved in future... boolean isLocalized = current.isLocalized(); next.setVisible (exceptions.existsNextElement()); previous.setVisible (exceptions.existsPreviousElement()); if (showDetails) { details.setText (org.openide.util.NbBundle.getBundle(NotifyException.class).getString("CTL_Exception_Hide_Details")); details.setMnemonic(org.openide.util.NbBundle.getBundle(NotifyException.class).getString("CTL_Exception_Hide_Details_Mnemonic").charAt(0)); details.getAccessibleContext().setAccessibleDescription( org.openide.util.NbBundle.getBundle(NotifyException.class).getString("ACSD_Exception_Hide_Details")); } else { details.setText(org.openide.util.NbBundle.getBundle(NotifyException.class).getString("CTL_Exception_Show_Details")); details.setMnemonic(org.openide.util.NbBundle.getBundle(NotifyException.class).getString("CTL_Exception_Show_Details_Mnemonic").charAt(0)); details.getAccessibleContext().setAccessibleDescription( org.openide.util.NbBundle.getBundle(NotifyException.class).getString("ACSD_Exception_Show_Details")); } // setText (current.getLocalizedMessage ()); String title = org.openide.util.NbBundle.getBundle(NotifyException.class).getString("CTL_Title_Exception"); if (showDetails) { descriptor.setMessage (this); // XXX(-ttran) we want to prevent a Term from scrolling to the bottom // of the stack trace. It should be achieved by calling // Term.setScrollOnOutput(false) and Term.setTrackCursor(false). // It does not work because Term also scrolls on COMPONENT_RESIZED // event. Using invokeLater we print the new contents into Term // _after_ the COMPONENT_RESIZED event has been handled. // See also bug #23047 SwingUtilities.invokeLater(new Runnable() { public void run() { // XXX #28191: some other piece of code should underline these, etc. /* try { output.getOut ().reset (); current.printStackTrace (output.getOut ()); */ StringWriter wr = new StringWriter(); current.printStackTrace(new PrintWriter(wr, true)); output.setText(wr.toString()); output.getCaret().setDot(0); output.requestFocus (); /* } catch (java.io.IOException ex) { } */ } }); } else { if (isLocalized) { String msg = current.getLocalizedMessage (); if (msg != null) { descriptor.setMessage (msg); } } else { ResourceBundle curBundle = NbBundle.getBundle (NotifyException.class); if (current.getSeverity() == ErrorManager.WARNING) { // less scary message for warning level descriptor.setMessage ( java.text.MessageFormat.format( curBundle.getString("NTF_ExceptionWarning"), new Object[] { current.getClassName () } ) ); title = curBundle.getString("NTF_ExceptionWarningTitle"); // NOI18N } else { // emphasize user-non-friendly exceptions // if (this.getMessage() == null || "".equals(this.getMessage())) { // NOI18N descriptor.setMessage ( java.text.MessageFormat.format( curBundle.getString("NTF_ExceptionalException"), new Object[] { current.getClassName (), NonGui.getLogDir () } ) ); title = curBundle.getString("NTF_ExceptionalExceptionTitle"); // NOI18N } } } descriptor.setTitle (title); } // // Handlers // public void actionPerformed(final java.awt.event.ActionEvent ev) { if (ev.getSource () == next && exceptions.setNextElement() || ev.getSource () == previous && exceptions.setPreviousElement()) { current = (NbErrorManager.Exc)exceptions.get(); update (); // bugfix #27266, don't change the dialog's size when jumping Next<->Previous //ensurePreferredSize(); return; } if (ev.getSource () == details) { showDetails = !showDetails; try { update (); ensurePreferredSize(); //throw new RuntimeException ("I am reallly exceptional!"); //uncomment to test } catch (Exception e) { //Do not allow an exception thrown here to trigger an endless //loop exceptions.add(new NbErrorManager().createExc(e, //ugly but works ErrorManager.EXCEPTION)); next.setVisible(true); } return; } // bugfix #40834, remove all exceptions to notify when close a dialog if (ev.getSource () == DialogDescriptor.OK_OPTION || ev.getSource () == DialogDescriptor.CLOSED_OPTION) { try { exceptions.removeAll(); //Fixed bug #9435, call of setVisible(false) replaced by call of dispose() //It did not work on Linux when JDialog is reused. //dialog.setVisible (false); // XXX(-ttran) no, it still doesn't work, getPreferredSize() on the // reused dialog returns (0,0). We stop caching the dialog // completely by setting INSTANCE to null here. dialog.dispose(); INSTANCE = null; //throw new RuntimeException ("You must be exceptional"); //uncomment to test } catch (RuntimeException e) { //Do not allow window of opportunity when dialog in a possibly //inconsistent state may be reuse INSTANCE = null; throw e; } finally { INSTANCE = null; } } } protected static class ArrayListPos extends ArrayList { protected int position; protected ArrayListPos () { super(); position=0; } protected boolean existsElement () { return size()>0; } protected boolean existsNextElement () { return position+1 |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.