001/* Utilities for managing the background color.
002
003 Copyright (c) 2009-2014 The Regents of the University of California.
004 All rights reserved.
005 Permission is hereby granted, without written agreement and without
006 license or royalty fees, to use, copy, modify, and distribute this
007 software and its documentation for any purpose, provided that the above
008 copyright notice and the following two paragraphs appear in all copies
009 of this software.
010
011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
015 SUCH DAMAGE.
016
017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
022 ENHANCEMENTS, OR MODIFICATIONS.
023
024 PT_COPYRIGHT_VERSION_2
025 COPYRIGHTENDKEY
026 */
027package ptolemy.gui;
028
029import java.awt.Color;
030
031import javax.swing.UIManager;
032import javax.swing.text.AttributeSet;
033import javax.swing.text.Style;
034import javax.swing.text.html.HTMLEditorKit;
035import javax.swing.text.html.StyleSheet;
036
037///////////////////////////////////////////////////////////////////
038//// JFileChooserBugFix
039
040/**
041 A workaround for a JFileChooser bug.
042 <p>This class is necessary to work around a bug under Windows where
043 the "common places" portion of the JFileChooser dialog is affected
044 by the background color of a component.  Sun has acknowledged the
045 bug as <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6817933">#6817933</a>.
046 See also
047 "<a href="http://bugzilla.ecoinformatics.org/show_bug.cgi?id=3801">open dialog, common places pane has white box instead of text</a>."
048
049 <p> Every time JFileChooser is instantiated, saveBackground() should
050 be called so that the background is properly set.  Then, in a finally
051 clause, restoreBackground() should be called.  For example:
052 <pre>
053  // Swap backgrounds and avoid white boxes in "common places" dialog
054  JFileChooserBugFix jFileChooserBugFix = new JFileChooserBugFix();
055  Color background = null;
056  try {
057      background = jFileChooserBugFix.saveBackground();
058      PtFileChooser ptFileChooser = new PtFileChooser();
059      // Do the usual JFileChooser song and dance . . .
060  } finally {
061      jFileChooserBugFix.restoreBackground(background);
062  }
063 </pre>
064
065 <p>Note that Java under Mac OS X has a much better
066 implementation of the file chooser that uses java.awt.FileDialog
067 instead of javax.swing.JFileChooser.  Thus, under Mac OS X,
068 this class is typically <b>not</b> invoked.  Under Mac OS X,
069 to invoke this class, either
070 {@link ptolemy.gui.PtGUIUtilities#useFileDialog()} or
071 {@link ptolemy.gui.PtGUIUtilities#macOSLookAndFeel()} should
072 return false.  To do this, set either the
073 ptolemy.ptII.useFileDialog property to false or
074 set the ptolemy.ptII.MacOS property to false. See
075 {@link ptolemy.gui.PtGUIUtilities} for how to set these properties.
076 </p>
077
078
079 @author Christopher Brooks
080 @version $Id$
081 @since Ptolemy II 8.0
082 @Pt.ProposedRating Red (cxh)
083 @Pt.AcceptedRating Red (cxh)
084 */
085public class JFileChooserBugFix {
086
087    /** Instantiate a JFileChooserBugFix object. */
088    public JFileChooserBugFix() {
089        _HTMLEditorKit = new HTMLEditorKit();
090    }
091
092    /** Restore the background.
093     *  <p>This method is not typically called on the Mac, see
094     *  the class comment.</p>
095     *  @param background The background to be restored.
096     *  @see #saveBackground()
097     */
098    public void restoreBackground(Color background) {
099        try {
100            if (background != null) {
101                // Restore the background color.
102                String rgb = Integer.toHexString(background.getRGB());
103                String rule = "body {background: #"
104                        + rgb.substring(2, rgb.length()) + ";}";
105                StyleSheet styleSheet = _HTMLEditorKit.getStyleSheet();
106                styleSheet.addRule(rule);
107                _HTMLEditorKit.setStyleSheet(styleSheet);
108            }
109        } catch (Exception ex) {
110            System.out.println("Problem restoring background color.");
111            ex.printStackTrace();
112        }
113    }
114
115    /** Set the background to the value of the ToolBar.shadow property
116     *  and return the previous background.
117     *  <p>Avoid a problem under Windows where the common places pane
118     *  on the left of the file browser dialog has white boxes
119     *  because the background is set to white.
120     *  http://bugzilla.ecoinformatics.org/show_bug.cgi?id=3801
121     *  <p>Call this method before instantiating a JFileChooser.
122     *  <p>This method is not typically called on the Mac, see
123     *  the class comment.</p>
124     *  @return the value of the previous background.
125     */
126    public Color saveBackground() {
127        if (_HTMLEditorKit == null) {
128            _HTMLEditorKit = new HTMLEditorKit();
129        }
130        StyleSheet styleSheet = _HTMLEditorKit.getStyleSheet();
131        Color background = null;
132
133        try {
134            // Get the background color of the HTML widget.
135            Style style = styleSheet.getStyle("body");
136            if (style != null) {
137                AttributeSet bodyAttribute = (AttributeSet) style.getAttribute(
138                        javax.swing.text.StyleConstants.ResolveAttribute);
139                if (bodyAttribute != null) {
140                    background = styleSheet.getBackground(bodyAttribute);
141                }
142            }
143        } catch (Exception ex) {
144            if (!_printedMessage) {
145                _printedMessage = true;
146                System.out.println(
147                        "Failed to set the background of the file dialog:"
148                                + ex);
149
150            }
151        }
152
153        try {
154            // Get the color of the ToolBar shadow and use it.
155            Color shadow = UIManager.getColor("ToolBar.shadow");
156            String rgb = Integer.toHexString(shadow.getRGB());
157            String rule = "body {background: #" + rgb.substring(2, rgb.length())
158                    + ";}";
159            styleSheet.addRule(rule);
160            _HTMLEditorKit.setStyleSheet(styleSheet);
161        } catch (Exception ex) {
162            System.err.println("Problem setting background color");
163            ex.printStackTrace();
164        }
165        return background;
166    }
167
168    ///////////////////////////////////////////////////////////////////
169    ////                         private variables                 ////
170
171    /** The HTMLEditorKit*/
172    private HTMLEditorKit _HTMLEditorKit;
173
174    /** True if we have printed the message about failing to set the
175     *  background.
176     */
177    private boolean _printedMessage;
178}