001    /*
002     * $Id: MacOSXErrorPaneUI.java 3100 2008-10-14 22:33:10Z rah003 $
003     *
004     * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
005     * Santa Clara, California 95054, U.S.A. All rights reserved.
006     *
007     * This library is free software; you can redistribute it and/or
008     * modify it under the terms of the GNU Lesser General Public
009     * License as published by the Free Software Foundation; either
010     * version 2.1 of the License, or (at your option) any later version.
011     *
012     * This library is distributed in the hope that it will be useful,
013     * but WITHOUT ANY WARRANTY; without even the implied warranty of
014     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015     * Lesser General Public License for more details.
016     *
017     * You should have received a copy of the GNU Lesser General Public
018     * License along with this library; if not, write to the Free Software
019     * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
020     */
021    
022    package org.jdesktop.swingx.plaf.macosx;
023    
024    import java.awt.Component;
025    import java.awt.Dimension;
026    import java.awt.Font;
027    import java.awt.GridBagConstraints;
028    import java.awt.GridBagLayout;
029    import java.awt.Insets;
030    import java.awt.LayoutManager;
031    
032    import javax.swing.BorderFactory;
033    import javax.swing.JComponent;
034    import javax.swing.JDialog;
035    import javax.swing.JEditorPane;
036    import javax.swing.JFrame;
037    import javax.swing.JInternalFrame;
038    import javax.swing.JLabel;
039    import javax.swing.UIManager;
040    import javax.swing.plaf.ComponentUI;
041    
042    import org.jdesktop.swingx.JXEditorPane;
043    import org.jdesktop.swingx.action.AbstractActionExt;
044    import org.jdesktop.swingx.error.ErrorInfo;
045    import org.jdesktop.swingx.error.ErrorLevel;
046    import org.jdesktop.swingx.plaf.UIManagerExt;
047    import org.jdesktop.swingx.plaf.basic.BasicErrorPaneUI;
048    
049    /**
050     * 
051     * Ok, the Title becomes the first line in the error dialog
052     * 
053     * The text immediately follows. Then come the "Details". This is a 
054     * toggle button with an icon and text but no border and no background. The icon
055     * looks like a tree toggle (arrow right or down).
056     * 
057     * There is then more optional text. The best way to support this is to look
058     * in the client properties of the JXErrorPane for any "sub text". Ideally this
059     * sub text would be part of the ErrorInfo. Maybe I should just add it there?
060     * 
061     * Finally come the buttons. If there is no report action and the error < fatal,
062     * the shown ok button should say "close". Otherwise, if there is no report action
063     * but the error >= fatal, it should say "Exit Application". If there is a report
064     * action but error < fatal, it should say "Don't Send" for ok, "Send Report" for
065     * the report button. If there is a report action and the error >= fatal, then
066     * one button should say "Exit", and the report button should say
067     * "Send Report and Exit".
068     * 
069     * Whenever either button is clicked (ok button or report button), the "close dialog"
070     * procedure should occur.
071     *
072     * @author rbair
073     */
074    public class MacOSXErrorPaneUI extends BasicErrorPaneUI {
075        private JLabel titleLabel;
076        private JEditorPane disclaimerText; // this is actually part of the details!!!
077        
078        //---------------------------------------------------------- constructor
079        /** Creates a new instance of BasicErrorPanelUI */
080        public MacOSXErrorPaneUI() {
081            super();
082        }
083    
084        protected void configureDetailsButton(boolean expanded) {
085            if (expanded) {
086                detailButton.setText(UIManagerExt.getString(CLASS_NAME + ".details_contract_text", detailButton.getLocale()));
087                detailButton.setIcon(UIManager.getIcon("Tree.expandedIcon"));
088            } else {
089                detailButton.setText(UIManagerExt.getString(CLASS_NAME + ".details_expand_text", detailButton.getLocale()));
090                detailButton.setIcon(UIManager.getIcon("Tree.collapsedIcon"));
091            }
092        }
093        
094        protected void configureReportAction(AbstractActionExt reportAction) {
095            reportAction.setName(UIManagerExt.getString(CLASS_NAME + ".report_button_text", pane.getLocale()));
096    //        reportButton.setText("Send Report To Apple");
097    //        reportButton.setPreferredSize(new Dimension(100, 30));
098    //        reportButton.setMinimumSize(new Dimension(100, 30));
099        }
100        
101        public static ComponentUI createUI(JComponent c) {
102            return new MacOSXErrorPaneUI();
103        }
104    
105        /**
106         * {@inheritDoc}
107         */
108        @Override
109        public JFrame getErrorFrame(Component owner) {
110            JFrame frame = super.getErrorFrame(owner);
111            frame.setTitle(" ");
112            return frame;
113        }
114    
115        /**
116         * {@inheritDoc}
117         */
118        @Override
119        public JDialog getErrorDialog(Component owner) {
120            JDialog dlg = super.getErrorDialog(owner);
121            dlg.setTitle(" ");
122            return dlg;
123        }
124    
125        /**
126         * {@inheritDoc}
127         */
128        @Override
129        public JInternalFrame getErrorInternalFrame(Component owner) {
130            JInternalFrame frame = super.getErrorInternalFrame(owner);
131            frame.setTitle(" ");
132            return frame;
133        }
134        
135        /**
136         * {@inheritDoc}
137         */
138        @Override
139        protected LayoutManager createErrorPaneLayout() {
140            createExtraComponents();
141            GridBagLayout layout = new GridBagLayout();
142            try {
143                layout.addLayoutComponent(iconLabel,      new GridBagConstraints(0, 0, 1, 2, 0.0, 0.0, GridBagConstraints.NORTH, GridBagConstraints.NONE, new Insets(0, 0, 0, 17), 0, 0));
144                layout.addLayoutComponent(titleLabel,     new GridBagConstraints(1, 0, 2, 1, 1.0, 0.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 12, 0), 0 ,0));
145                layout.addLayoutComponent(errorScrollPane,new GridBagConstraints(1, 1, 2, 1, 1.0, 1.0, GridBagConstraints.NORTH, GridBagConstraints.BOTH, new Insets(0, 0, 10, 0), 0, 0));
146                layout.addLayoutComponent(detailButton,   new GridBagConstraints(0, 2, 3, 1, 1.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.NONE, new Insets(0, 0, 6, 0), 0, 0));
147                layout.addLayoutComponent(detailsPanel,   new GridBagConstraints(0, 3, 3, 1, 1.0, 1.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(0, 0, 6, 0), 0 ,0));
148                layout.addLayoutComponent(disclaimerText, new GridBagConstraints(0, 4, 3, 1, 1.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 6, 0), 0, 0));
149                layout.addLayoutComponent(closeButton,    new GridBagConstraints(1, 5, 1, 1, 1.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.NONE, new Insets(0, 0, 0, 5), 0, 0));
150                layout.addLayoutComponent(reportButton,   new GridBagConstraints(2, 5, 1, 1, 0.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
151            } catch (Exception e) {
152                e.printStackTrace();
153            }
154            return layout;
155        }
156        
157        /**
158         * {@inheritDoc}
159         */
160        protected LayoutManager createDetailPanelLayout() {
161            GridBagLayout layout = new GridBagLayout();
162            layout.addLayoutComponent(detailsScrollPane, new GridBagConstraints(0,0,1,1,1.0,1.0,GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0,0,0,0),0,0));
163            copyToClipboardButton.setVisible(false);
164            return layout;
165        }
166        
167        /**
168         * {@inheritDoc}
169         */
170        protected void reinit() {
171            super.reinit();
172            ErrorInfo info = pane == null ? null : pane.getErrorInfo();
173            titleLabel.setText(info == null ? "Unknown Error" : info.getTitle());
174            
175            Object finePrint = pane.getClientProperty("fine-print");
176            String text = finePrint == null ? null : finePrint.toString();
177            disclaimerText.setText(text);
178            disclaimerText.setVisible(text != null);
179            
180            if (info != null && info.getErrorLevel() == ErrorLevel.FATAL) {
181                closeButton.setText(UIManagerExt.getString(CLASS_NAME + ".fatal_button_text", closeButton.getLocale()));
182            } else {
183                closeButton.setText(UIManagerExt.getString(CLASS_NAME + ".ok_button_text", closeButton.getLocale()));
184            }
185        }
186    
187        /**
188         * {@inheritDoc}
189         */
190        protected int getDetailsHeight() {
191            return 150;
192        }
193        
194        private void createExtraComponents() {
195            titleLabel = new JLabel("Unknown Error");
196            titleLabel.setFont(titleLabel.getFont().deriveFont(Font.BOLD));
197            pane.add(titleLabel);
198            
199            Font f = errorMessage.getFont();
200            if (f != null) {
201                errorMessage.setFont(f.deriveFont(f.getSize() - 2f));
202            }
203            
204            disclaimerText = new JEditorPane();
205            disclaimerText.setContentType("text/html");
206            disclaimerText.setVisible(false);
207            disclaimerText.setEditable(false);
208            disclaimerText.setOpaque(false);
209            disclaimerText.putClientProperty(JXEditorPane.HONOR_DISPLAY_PROPERTIES, Boolean.TRUE);
210            if (f != null) {
211                disclaimerText.setFont(f.deriveFont(f.getSize() - 2f));
212            }
213            pane.add(disclaimerText);
214            
215            detailButton.setBorderPainted(false);
216            detailButton.setContentAreaFilled(false);
217            detailButton.setBorder(BorderFactory.createEmptyBorder());
218            detailButton.setMargin(new Insets(0, 0, 0 ,0));
219            detailButton.setIcon(UIManager.getIcon("Tree.collapsedIcon"));
220            detailButton.setText(UIManagerExt.getString(CLASS_NAME + ".details_expand_text", detailButton.getLocale()));
221            
222            closeButton.setText(UIManagerExt.getString(CLASS_NAME + ".ok_button_text", closeButton.getLocale()));
223        }
224    }