JXTipOfTheDay.java
上传用户:zhengdagz
上传日期:2014-03-06
资源大小:1956k
文件大小:15k
源码类别:

xml/soap/webservice

开发平台:

Java

  1. /*
  2.  * $Id: JXTipOfTheDay.java,v 1.5 2005/10/10 18:01:56 rbair Exp $
  3.  *
  4.  * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
  5.  * Santa Clara, California 95054, U.S.A. All rights reserved.
  6.  *
  7.  * This library is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2.1 of the License, or (at your option) any later version.
  11.  * 
  12.  * This library is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Lesser General Public License for more details.
  16.  * 
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with this library; if not, write to the Free Software
  19.  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  20.  */
  21. package org.jdesktop.swingx;
  22. import java.awt.Component;
  23. import java.awt.HeadlessException;
  24. import java.util.prefs.Preferences;
  25. import javax.swing.JDialog;
  26. import org.jdesktop.swingx.plaf.JXTipOfTheDayAddon;
  27. import org.jdesktop.swingx.plaf.LookAndFeelAddons;
  28. import org.jdesktop.swingx.plaf.TipOfTheDayUI;
  29. import org.jdesktop.swingx.tips.DefaultTipOfTheDayModel;
  30. import org.jdesktop.swingx.tips.TipOfTheDayModel;
  31. import org.jdesktop.swingx.tips.TipOfTheDayModel.Tip;
  32. /**
  33.  * Provides the "Tip of The Day" pane and dialog.<br>
  34.  * 
  35.  * <p>
  36.  * Tips are retrieved from the {@link org.jdesktop.swingx.tips.TipOfTheDayModel}.
  37.  * In the most common usage, a tip (as returned by
  38.  * {@link org.jdesktop.swingx.tips.TipOfTheDayModel.Tip#getTip()}) is just a
  39.  * <code>String</code>. However, the return type of this method is actually
  40.  * <code>Object</code>. Its interpretation depends on its type:
  41.  * <dl compact>
  42.  * <dt>Component
  43.  * <dd>The <code>Component</code> is displayed in the dialog.
  44.  * <dt>Icon
  45.  * <dd>The <code>Icon</code> is wrapped in a <code>JLabel</code> and
  46.  * displayed in the dialog.
  47.  * <dt>others
  48.  * <dd>The object is converted to a <code>String</code> by calling its
  49.  * <code>toString</code> method. The result is wrapped in a
  50.  * <code>JEditorPane</code> or <code>JTextArea</code> and displayed.
  51.  * </dl>
  52.  * 
  53.  * <p>
  54.  * <code>JXTipOfTheDay<code> finds its tips in its {@link org.jdesktop.swingx.tips.TipOfTheDayModel}.
  55.  * Such model can be programmatically built using {@link org.jdesktop.swingx.tips.DefaultTipOfTheDayModel}
  56.  * and {@link org.jdesktop.swingx.tips.DefaultTip} but
  57.  * the {@link org.jdesktop.swingx.tips.TipLoader} provides a convenient method to
  58.  * build a model and its tips from a {@link java.util.Properties} object.
  59.  *
  60.  * <p>
  61.  * Example:
  62.  * <p>
  63.  * Let's consider a file <i>tips.properties</i> with the following content:
  64.  * <pre>
  65.  * <code>
  66.  * tip.1.description=This is the first time! Plain text.
  67.  * tip.2.description=&lt;html&gt;This is &lt;b&gt;another tip&lt;/b&gt;, it uses HTML!
  68.  * tip.3.description=A third one
  69.  * </code>
  70.  * </pre>
  71.  *
  72.  * To load and display the tips:
  73.  * 
  74.  * <pre>
  75.  * <code>
  76.  * Properties tips = new Properties();
  77.  * tips.load(new FileInputStream("tips.properties"));
  78.  * 
  79.  * TipOfTheDayModel model = TipLoader.load(tips);
  80.  * JXTipOfTheDay totd = new JXTipOfTheDay(model);
  81.  * 
  82.  * totd.showDialog(someParentComponent);
  83.  * </code>
  84.  * </pre>
  85.  * 
  86.  * <p>
  87.  * Additionally, <code>JXTipOfTheDay</code> features an option enabling the end-user
  88.  * to choose to not display the "Tip Of The Day" dialog. This user choice can be stored
  89.  * in the user {@link java.util.prefs.Preferences} but <code>JXTipOfTheDay</code> also
  90.  * supports custom storage through the {@link org.jdesktop.swingx.JXTipOfTheDay.ShowOnStartupChoice} interface.
  91.  * 
  92.  * <pre>
  93.  * <code>
  94.  * Preferences userPreferences = Preferences.userRoot().node("myApp");
  95.  * totd.showDialog(someParentComponent, userPreferences);
  96.  * </code>
  97.  * </pre>
  98.  * In this code, the first time showDialog is called, the dialog will be made 
  99.  * visible and the user will have the choice to not display it again in the future
  100.  * (usually this is controlled by a checkbox "Show tips on startup"). If the user
  101.  * unchecks the option, subsequent calls to showDialog will not display the dialog.
  102.  * As the choice is saved in the user Preferences, it will persist when the application is relaunched.
  103.  * 
  104.  * @see org.jdesktop.swingx.tips.TipLoader
  105.  * @see org.jdesktop.swingx.tips.TipOfTheDayModel
  106.  * @see org.jdesktop.swingx.tips.TipOfTheDayModel.Tip
  107.  * @see #showDialog(Component, Preferences)
  108.  * @see #showDialog(Component, ShowOnStartupChoice)
  109.  * 
  110.  * @author <a href="mailto:fred@L2FProd.com">Frederic Lavigne</a>
  111.  */
  112. public class JXTipOfTheDay extends JXPanel {
  113.   /**
  114.    * JXTipOfTheDay pluggable UI key <i>swingx/TipOfTheDayUI</i> 
  115.    */
  116.   public final static String uiClassID = "swingx/TipOfTheDayUI";
  117.   // ensure at least the default ui is registered
  118.   static {
  119.     LookAndFeelAddons.contribute(new JXTipOfTheDayAddon());
  120.   }
  121.   /**
  122.    * Key used to store the status of the "Show tip on startup" checkbox"
  123.    */
  124.   public static final String PREFERENCE_KEY = "ShowTipOnStartup";
  125.   /**
  126.    * Used when generating PropertyChangeEvents for the "currentTip" property
  127.    */
  128.   public static final String CURRENT_TIP_CHANGED_KEY = "currentTip";
  129.   private TipOfTheDayModel model;
  130.   private int currentTip = 0;
  131.   /**
  132.    * Constructs a new <code>JXTipOfTheDay</code> with an empty
  133.    * TipOfTheDayModel
  134.    */
  135.   public JXTipOfTheDay() {
  136.     this(new DefaultTipOfTheDayModel(new Tip[0]));
  137.   }
  138.   
  139.   /**
  140.    * Constructs a new <code>JXTipOfTheDay</code> showing tips from the given
  141.    * TipOfTheDayModel.
  142.    * 
  143.    * @param model
  144.    */
  145.   public JXTipOfTheDay(TipOfTheDayModel model) {
  146.     this.model = model;
  147.     updateUI();
  148.   }
  149.   /**
  150.    * Notification from the <code>UIManager</code> that the L&F has changed.
  151.    * Replaces the current UI object with the latest version from the
  152.    * <code>UIManager</code>.
  153.    * 
  154.    * @see javax.swing.JComponent#updateUI
  155.    */
  156.   public void updateUI() {
  157.     setUI((TipOfTheDayUI)LookAndFeelAddons.getUI(this, TipOfTheDayUI.class));
  158.   }
  159.   /**
  160.    * Sets the L&F object that renders this component.
  161.    * 
  162.    * @param ui
  163.    *          the <code>TipOfTheDayUI</code> L&F object
  164.    * @see javax.swing.UIDefaults#getUI
  165.    * 
  166.    * @beaninfo bound: true hidden: true description: The UI object that
  167.    *           implements the taskpane group's LookAndFeel.
  168.    */
  169.   public void setUI(TipOfTheDayUI ui) {
  170.     super.setUI(ui);
  171.   }
  172.   /**
  173.    * Gets the UI object which implements the L&F for this component.
  174.    * 
  175.    * @return the TipOfTheDayUI object that implements the TipOfTheDayUI L&F
  176.    */
  177.   public TipOfTheDayUI getUI() {
  178.     return (TipOfTheDayUI)ui;
  179.   }
  180.   /**
  181.    * Returns the name of the L&F class that renders this component.
  182.    * 
  183.    * @return the string {@link #uiClassID}
  184.    * @see javax.swing.JComponent#getUIClassID
  185.    * @see javax.swing.UIDefaults#getUI
  186.    */
  187.   public String getUIClassID() {
  188.     return uiClassID;
  189.   }
  190.   public TipOfTheDayModel getModel() {
  191.     return model;
  192.   }
  193.   public void setModel(TipOfTheDayModel model) {
  194.     if (model == null) {
  195.       throw new IllegalArgumentException("model can not be null");
  196.     }
  197.     TipOfTheDayModel old = this.model;
  198.     this.model = model;
  199.     firePropertyChange("model", old, model);
  200.   }
  201.   public int getCurrentTip() {
  202.     return currentTip;
  203.   }
  204.   /**
  205.    * Sets the index of the tip to show
  206.    * 
  207.    * @param currentTip
  208.    * @throw IllegalArgumentException if currentTip is not within the bounds [0,
  209.    *        getModel().getTipCount()[.
  210.    */
  211.   public void setCurrentTip(int currentTip) {
  212.     if (currentTip < 0 || currentTip >= getModel().getTipCount()) {
  213.       throw new IllegalArgumentException(
  214.       "Current tip must be within the bounds [0, " + getModel().getTipCount()
  215.         + "[");
  216.     }
  217.     int oldTip = this.currentTip;
  218.     this.currentTip = currentTip;
  219.     firePropertyChange(CURRENT_TIP_CHANGED_KEY, oldTip, currentTip);
  220.   }
  221.   /**
  222.    * Shows the next tip in the list. It cycles the tip list.
  223.    */
  224.   public void nextTip() {
  225.     int count = getModel().getTipCount();
  226.     if (count == 0) { return; }
  227.     int nextTip = currentTip + 1;
  228.     if (nextTip >= count) {
  229.       nextTip = 0;
  230.     }
  231.     setCurrentTip(nextTip);
  232.   }
  233.   /**
  234.    * Shows the previous tip in the list. It cycles the tip list.
  235.    */
  236.   public void previousTip() {
  237.     int count = getModel().getTipCount();
  238.     if (count == 0) { return; }
  239.     int previousTip = currentTip - 1;
  240.     if (previousTip < 0) {
  241.       previousTip = count - 1;
  242.     }
  243.     setCurrentTip(previousTip);
  244.   }
  245.   /**
  246.    * Pops up a "Tip of the day" dialog.
  247.    * 
  248.    * @param parentComponent
  249.    * @exception HeadlessException
  250.    *              if GraphicsEnvironment.isHeadless() returns true.
  251.    * @see java.awt.GraphicsEnvironment#isHeadless
  252.    */
  253.   public void showDialog(Component parentComponent) throws HeadlessException {
  254.     showDialog(parentComponent, (ShowOnStartupChoice)null);
  255.   }
  256.   /**
  257.    * Pops up a "Tip of the day" dialog. Additionally, it saves the state of the
  258.    * "Show tips on startup" checkbox in a key named "ShowTipOnStartup" in the
  259.    * given Preferences.
  260.    * 
  261.    * @param parentComponent
  262.    * @param showOnStartupPref
  263.    * @exception HeadlessException
  264.    *              if GraphicsEnvironment.isHeadless() returns true.
  265.    * @throws IllegalArgumentException
  266.    *           if showOnStartupPref is null
  267.    * @see java.awt.GraphicsEnvironment#isHeadless
  268.    * @return true if the user chooses to see the tips again, false otherwise.
  269.    */
  270.   public boolean showDialog(Component parentComponent,
  271.     Preferences showOnStartupPref) throws HeadlessException {
  272.     return showDialog(parentComponent, showOnStartupPref, false);
  273.   }
  274.   
  275.   /**
  276.    * Pops up a "Tip of the day" dialog. Additionally, it saves the state of the
  277.    * "Show tips on startup" checkbox in a key named "ShowTipOnStartup" in the
  278.    * given Preferences.
  279.    * 
  280.    * @param parentComponent
  281.    * @param showOnStartupPref
  282.    * @param force
  283.    *          if true, the dialog is displayed even if the Preferences is set to
  284.    *          hide the dialog
  285.    * @exception HeadlessException
  286.    *              if GraphicsEnvironment.isHeadless() returns true.
  287.    * @throws IllegalArgumentException
  288.    *           if showOnStartupPref is null
  289.    * @see java.awt.GraphicsEnvironment#isHeadless
  290.    * @return true if the user chooses to see the tips again, false
  291.    *         otherwise.
  292.    */
  293.   public boolean showDialog(Component parentComponent,
  294.     final Preferences showOnStartupPref, boolean force) throws HeadlessException {
  295.     if (showOnStartupPref == null) { throw new IllegalArgumentException(
  296.       "Preferences can not be null"); }
  297.     ShowOnStartupChoice store = new ShowOnStartupChoice() {
  298.       public boolean isShowingOnStartup() {
  299.         return showOnStartupPref.getBoolean(PREFERENCE_KEY, true);
  300.       }
  301.       public void setShowingOnStartup(boolean showOnStartup) {
  302.         // only save the choice if it is negative
  303.         if (!showOnStartup) {
  304.           showOnStartupPref.putBoolean(PREFERENCE_KEY, showOnStartup);
  305.         }
  306.       }
  307.     };
  308.     return showDialog(parentComponent, store, force);
  309.   }
  310.   /**
  311.    * Pops up a "Tip of the day" dialog.
  312.    * 
  313.    * If <code>choice</code> is not null, the method first checks if
  314.    * {@link ShowOnStartupChoice#isShowingOnStartup()} is true before showing the
  315.    * dialog.
  316.    * 
  317.    * Additionally, it saves the state of the "Show tips on startup" checkbox
  318.    * using the given {@link ShowOnStartupChoice} object.
  319.    * 
  320.    * @param parentComponent
  321.    * @param choice
  322.    * @exception HeadlessException
  323.    *              if GraphicsEnvironment.isHeadless() returns true.
  324.    * @see java.awt.GraphicsEnvironment#isHeadless
  325.    * @return true if the user chooses to see the tips again, false otherwise.
  326.    */
  327.   public boolean showDialog(Component parentComponent,
  328.     ShowOnStartupChoice choice) {
  329.     return showDialog(parentComponent, choice, false);
  330.   }
  331.   /**
  332.    * Pops up a "Tip of the day" dialog.
  333.    * 
  334.    * If <code>choice</code> is not null, the method first checks if
  335.    * <code>force</code> is true or if
  336.    * {@link ShowOnStartupChoice#isShowingOnStartup()} is true before showing the
  337.    * dialog.
  338.    * 
  339.    * Additionally, it saves the state of the "Show tips on startup" checkbox
  340.    * using the given {@link ShowOnStartupChoice} object.
  341.    * 
  342.    * @param parentComponent
  343.    * @param choice
  344.    * @param force
  345.    *          if true, the dialog is displayed even if
  346.    *          {@link ShowOnStartupChoice#isShowingOnStartup()} is false
  347.    * @exception HeadlessException
  348.    *              if GraphicsEnvironment.isHeadless() returns true.
  349.    * @see java.awt.GraphicsEnvironment#isHeadless
  350.    * @return true if the user chooses to see the tips again, false otherwise.
  351.    */
  352.   public boolean showDialog(Component parentComponent,
  353.     ShowOnStartupChoice choice, boolean force) {    
  354.     if (choice == null) {
  355.       JDialog dialog = createDialog(parentComponent, choice);
  356.       dialog.setVisible(true);
  357.       dialog.dispose();
  358.       return true;
  359.     } else if (force || choice.isShowingOnStartup()) {
  360.       JDialog dialog = createDialog(parentComponent, choice);
  361.       dialog.setVisible(true);
  362.       dialog.dispose();
  363.       return choice.isShowingOnStartup();
  364.     } else {
  365.       return false;
  366.     }
  367.   }
  368.   
  369.   /**
  370.    * @param showOnStartupPref
  371.    * @return true if the key named "ShowTipOnStartup" is not set to false
  372.    */
  373.   public static boolean isShowingOnStartup(Preferences showOnStartupPref) {
  374.     return showOnStartupPref.getBoolean(PREFERENCE_KEY, true);
  375.   }
  376.   /**
  377.    * Removes the value set for "ShowTipOnStartup" in the given Preferences to
  378.    * ensure the dialog shown by a later call to
  379.    * {@link #showDialog(Component, Preferences)} will be visible to the user.
  380.    * 
  381.    * @param showOnStartupPref
  382.    */
  383.   public static void forceShowOnStartup(Preferences showOnStartupPref) {
  384.     showOnStartupPref.remove(PREFERENCE_KEY);
  385.   }
  386.   /**
  387.    * Calls
  388.    * {@link TipOfTheDayUI#createDialog(Component, JXTipOfTheDay.ShowOnStartupChoice)}.
  389.    * 
  390.    * This method can be overriden in order to control things such as the
  391.    * placement of the dialog or its title.
  392.    * 
  393.    * @param parentComponent
  394.    * @param choice
  395.    * @return a JDialog to show this TipOfTheDay pane
  396.    */
  397.   protected JDialog createDialog(Component parentComponent,
  398.     ShowOnStartupChoice choice) {
  399.     return getUI().createDialog(parentComponent, choice);
  400.   }
  401.   /**
  402.    * Used in conjunction with the
  403.    * {@link JXTipOfTheDay#showDialog(Component, ShowOnStartupChoice)} to save the
  404.    * "Show tips on startup" choice.
  405.    */
  406.   public static interface ShowOnStartupChoice {
  407.     
  408.     /**
  409.      * Persists the user choice
  410.      * @param showOnStartup the user choice
  411.      */
  412.     void setShowingOnStartup(boolean showOnStartup);
  413.     
  414.     /**
  415.      * @return the previously stored user choice
  416.      */
  417.     boolean isShowingOnStartup();
  418.   }
  419. }