001/*
002 * $Id: MacOSXErrorPaneUI.java 3475 2009-08-28 08:30:47Z kleopatra $
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
022package org.jdesktop.swingx.plaf.macosx;
023
024import java.awt.Component;
025import java.awt.Font;
026import java.awt.GridBagConstraints;
027import java.awt.GridBagLayout;
028import java.awt.Insets;
029import java.awt.LayoutManager;
030
031import javax.swing.BorderFactory;
032import javax.swing.JComponent;
033import javax.swing.JDialog;
034import javax.swing.JEditorPane;
035import javax.swing.JFrame;
036import javax.swing.JInternalFrame;
037import javax.swing.JLabel;
038import javax.swing.UIManager;
039import javax.swing.plaf.ComponentUI;
040
041import org.jdesktop.swingx.JXEditorPane;
042import org.jdesktop.swingx.action.AbstractActionExt;
043import org.jdesktop.swingx.error.ErrorInfo;
044import org.jdesktop.swingx.error.ErrorLevel;
045import org.jdesktop.swingx.plaf.UIManagerExt;
046import org.jdesktop.swingx.plaf.basic.BasicErrorPaneUI;
047
048/**
049 * 
050 * Ok, the Title becomes the first line in the error dialog
051 * 
052 * The text immediately follows. Then come the "Details". This is a 
053 * toggle button with an icon and text but no border and no background. The icon
054 * looks like a tree toggle (arrow right or down).
055 * 
056 * There is then more optional text. The best way to support this is to look
057 * in the client properties of the JXErrorPane for any "sub text". Ideally this
058 * sub text would be part of the ErrorInfo. Maybe I should just add it there?
059 * 
060 * Finally come the buttons. If there is no report action and the error < fatal,
061 * the shown ok button should say "close". Otherwise, if there is no report action
062 * but the error >= fatal, it should say "Exit Application". If there is a report
063 * action but error < fatal, it should say "Don't Send" for ok, "Send Report" for
064 * the report button. If there is a report action and the error >= fatal, then
065 * one button should say "Exit", and the report button should say
066 * "Send Report and Exit".
067 * 
068 * Whenever either button is clicked (ok button or report button), the "close dialog"
069 * procedure should occur.
070 *
071 * @author rbair
072 */
073public class MacOSXErrorPaneUI extends BasicErrorPaneUI {
074    private JLabel titleLabel;
075    private JEditorPane disclaimerText; // this is actually part of the details!!!
076    
077    //---------------------------------------------------------- constructor
078    /** Creates a new instance of BasicErrorPanelUI */
079    public MacOSXErrorPaneUI() {
080        super();
081    }
082
083    @Override
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    @Override
095    protected void configureReportAction(AbstractActionExt reportAction) {
096        reportAction.setName(UIManagerExt.getString(CLASS_NAME + ".report_button_text", pane.getLocale()));
097//        reportButton.setText("Send Report To Apple");
098//        reportButton.setPreferredSize(new Dimension(100, 30));
099//        reportButton.setMinimumSize(new Dimension(100, 30));
100    }
101    
102    public static ComponentUI createUI(JComponent c) {
103        return new MacOSXErrorPaneUI();
104    }
105
106    /**
107     * {@inheritDoc}
108     */
109    @Override
110    public JFrame getErrorFrame(Component owner) {
111        JFrame frame = super.getErrorFrame(owner);
112        frame.setTitle(" ");
113        return frame;
114    }
115
116    /**
117     * {@inheritDoc}
118     */
119    @Override
120    public JDialog getErrorDialog(Component owner) {
121        JDialog dlg = super.getErrorDialog(owner);
122        dlg.setTitle(" ");
123        return dlg;
124    }
125
126    /**
127     * {@inheritDoc}
128     */
129    @Override
130    public JInternalFrame getErrorInternalFrame(Component owner) {
131        JInternalFrame frame = super.getErrorInternalFrame(owner);
132        frame.setTitle(" ");
133        return frame;
134    }
135    
136    /**
137     * {@inheritDoc}
138     */
139    @Override
140    protected LayoutManager createErrorPaneLayout() {
141        createExtraComponents();
142        GridBagLayout layout = new GridBagLayout();
143        try {
144            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));
145            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));
146            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));
147            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));
148            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));
149            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));
150            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));
151            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));
152        } catch (Exception e) {
153            e.printStackTrace();
154        }
155        return layout;
156    }
157    
158    /**
159     * {@inheritDoc}
160     */
161    @Override
162    protected LayoutManager createDetailPanelLayout() {
163        GridBagLayout layout = new GridBagLayout();
164        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));
165        copyToClipboardButton.setVisible(false);
166        return layout;
167    }
168    
169    /**
170     * {@inheritDoc}
171     */
172    @Override
173    protected void reinit() {
174        super.reinit();
175        ErrorInfo info = pane == null ? null : pane.getErrorInfo();
176        titleLabel.setText(info == null ? "Unknown Error" : info.getTitle());
177        
178        Object finePrint = pane.getClientProperty("fine-print");
179        String text = finePrint == null ? null : finePrint.toString();
180        disclaimerText.setText(text);
181        disclaimerText.setVisible(text != null);
182        
183        if (info != null && info.getErrorLevel() == ErrorLevel.FATAL) {
184            closeButton.setText(UIManagerExt.getString(CLASS_NAME + ".fatal_button_text", closeButton.getLocale()));
185        } else {
186            closeButton.setText(UIManagerExt.getString(CLASS_NAME + ".ok_button_text", closeButton.getLocale()));
187        }
188    }
189
190    /**
191     * {@inheritDoc}
192     */
193    @Override
194    protected int getDetailsHeight() {
195        return 150;
196    }
197    
198    private void createExtraComponents() {
199        titleLabel = new JLabel("Unknown Error");
200        titleLabel.setFont(titleLabel.getFont().deriveFont(Font.BOLD));
201        pane.add(titleLabel);
202        
203        Font f = errorMessage.getFont();
204        if (f != null) {
205            errorMessage.setFont(f.deriveFont(f.getSize() - 2f));
206        }
207        
208        disclaimerText = new JEditorPane();
209        disclaimerText.setContentType("text/html");
210        disclaimerText.setVisible(false);
211        disclaimerText.setEditable(false);
212        disclaimerText.setOpaque(false);
213        disclaimerText.putClientProperty(JXEditorPane.HONOR_DISPLAY_PROPERTIES, Boolean.TRUE);
214        if (f != null) {
215            disclaimerText.setFont(f.deriveFont(f.getSize() - 2f));
216        }
217        pane.add(disclaimerText);
218        
219        detailButton.setBorderPainted(false);
220        detailButton.setContentAreaFilled(false);
221        detailButton.setBorder(BorderFactory.createEmptyBorder());
222        detailButton.setMargin(new Insets(0, 0, 0 ,0));
223        detailButton.setIcon(UIManager.getIcon("Tree.collapsedIcon"));
224        detailButton.setText(UIManagerExt.getString(CLASS_NAME + ".details_expand_text", detailButton.getLocale()));
225        
226        closeButton.setText(UIManagerExt.getString(CLASS_NAME + ".ok_button_text", closeButton.getLocale()));
227    }
228}