/** * L2FProd.com Common Components 7.3 License. * * Copyright 2005-2007 L2FProd.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.l2fprod.common.swing; import com.l2fprod.common.swing.TipModel.Tip; import com.l2fprod.common.swing.plaf.JTipOfTheDayAddon; import com.l2fprod.common.swing.plaf.LookAndFeelAddons; import com.l2fprod.common.swing.plaf.TipOfTheDayUI; import com.l2fprod.common.swing.tips.DefaultTipModel; import javax.swing.*; import java.awt.*; import java.util.prefs.Preferences; /** * Provides the "Tip of The Day" pane and dialog.<br> * Tips are retrieved from the {@link com.l2fprod.common.swing.TipModel}. In * the most common usage, a tip (as returned by * {@link com.l2fprod.common.swing.TipModel.Tip#getTip()}) is just a * <code>String</code>. However, the return type of this method is actually * <code>Object</code>. Its interpretation depends on its type: * <dl compact> * <dt>Component * <dd>The <code>Component</code> is displayed in the dialog. * <dt>Icon * <dd>The <code>Icon</code> is wrapped in a <code>JLabel</code> and * displayed in the dialog. * <dt>others * <dd>The object is converted to a <code>String</code> by calling its * <code>toString</code> method. The result is wrapped in a * <code>JEditorPane</code> or <code>JTextArea</code> and displayed. * </dl> * * @author Frederic Lavigne */ public class JTipOfTheDay extends JComponent { public final static String uiClassID = "l2fprod/TipOfTheDayUI"; // ensure at least the default ui is registered static { LookAndFeelAddons.contribute(new JTipOfTheDayAddon()); } /** * Key used to store the status of the "Show tip on startup" checkbox" */ public static final String PREFERENCE_KEY = "ShowTipOnStartup"; /** * Used when generating PropertyChangeEvents for the "currentTip" property */ public static final String CURRENT_TIP_CHANGED_KEY = "currentTip"; private TipModel model; private int currentTip = 0; public JTipOfTheDay() { this(new DefaultTipModel(new Tip[0])); } public JTipOfTheDay(TipModel model) { this.model = model; updateUI(); } /** * Notification from the <code>UIManager</code> that the L&F has changed. * Replaces the current UI object with the latest version from the * <code>UIManager</code>. * * @see javax.swing.JComponent#updateUI */ public void updateUI() { setUI((TipOfTheDayUI) LookAndFeelAddons.getUI(this, TipOfTheDayUI.class)); } /** * Sets the L&F object that renders this component. * * @param ui the <code>TipOfTheDayUI</code> L&F object * @beaninfo bound: true hidden: true description: The UI object that * implements the taskpane group's LookAndFeel. * @see javax.swing.UIDefaults#getUI */ public void setUI(TipOfTheDayUI ui) { super.setUI(ui); } /** * Gets the UI object which implements the L&F for this component. * * @return the TipOfTheDayUI object that implements the TipOfTheDayUI L&F */ public TipOfTheDayUI getUI() { return (TipOfTheDayUI) ui; } /** * Returns the name of the L&F class that renders this component. * * @return the string {@link #uiClassID} * @see javax.swing.JComponent#getUIClassID * @see javax.swing.UIDefaults#getUI */ public String getUIClassID() { return uiClassID; } public TipModel getModel() { return model; } public void setModel(TipModel model) { TipModel old = this.model; this.model = model; firePropertyChange("model", old, model); } public int getCurrentTip() { return currentTip; } /** * Sets the index of the tip to show * * @param currentTip * @throw IllegalArgumentException if currentTip is not within the bounds [0, * getModel().getTipCount()[. */ public void setCurrentTip(int currentTip) { if (currentTip < 0 || currentTip >= getModel().getTipCount()) { throw new IllegalArgumentException("Current tip must be within the bounds [0, " + getModel().getTipCount() + "["); } int oldTip = this.currentTip; this.currentTip = currentTip; firePropertyChange(CURRENT_TIP_CHANGED_KEY, oldTip, currentTip); } /** * Shows the next tip in the list. It cycles the tip list. */ public void nextTip() { int count = getModel().getTipCount(); if (count == 0) { return; } int nextTip = currentTip + 1; if (nextTip >= count) { nextTip = 0; } setCurrentTip(nextTip); } /** * Shows the previous tip in the list. It cycles the tip list. */ public void previousTip() { int count = getModel().getTipCount(); if (count == 0) { return; } int previousTip = currentTip - 1; if (previousTip < 0) { previousTip = count - 1; } setCurrentTip(previousTip); } /** * Pops up a "Tip of the day" dialog. * * @param parentComponent * @throws HeadlessException if GraphicsEnvironment.isHeadless() returns true. * @see java.awt.GraphicsEnvironment#isHeadless */ public void showDialog(Component parentComponent) throws HeadlessException { showDialog(parentComponent, (ShowOnStartupChoice) null); } /** * Pops up a "Tip of the day" dialog. Additionally, it saves the state of the * "Show tips on startup" checkbox in a key named "ShowTipOnStartup" in the * given Preferences. * * @param parentComponent * @param showOnStartupPref * @return true if the user chooses to see the tips again, false otherwise. * @throws HeadlessException if GraphicsEnvironment.isHeadless() returns true. * @throws IllegalArgumentException if showOnStartupPref is null * @see java.awt.GraphicsEnvironment#isHeadless */ public boolean showDialog(Component parentComponent, Preferences showOnStartupPref) throws HeadlessException { return showDialog(parentComponent, showOnStartupPref, false); } /** * Pops up a "Tip of the day" dialog. Additionally, it saves the state of the * "Show tips on startup" checkbox in a key named "ShowTipOnStartup" in the * given Preferences. * * @param parentComponent * @param showOnStartupPref * @param force if true, the dialog is displayed even if the Preferences is set to * hide the dialog * @return true if the user chooses to see the tips again, false * otherwise. * @throws HeadlessException if GraphicsEnvironment.isHeadless() returns true. * @throws IllegalArgumentException if showOnStartupPref is null * @see java.awt.GraphicsEnvironment#isHeadless */ public boolean showDialog(Component parentComponent, final Preferences showOnStartupPref, boolean force) throws HeadlessException { if (showOnStartupPref == null) { throw new IllegalArgumentException("Preferences can not be null"); } ShowOnStartupChoice store = new ShowOnStartupChoice() { public boolean isShowingOnStartup() { return showOnStartupPref.getBoolean(PREFERENCE_KEY, true); } public void setShowingOnStartup(boolean showOnStartup) { // only save the choice if it is negative if (!showOnStartup) { showOnStartupPref.putBoolean(PREFERENCE_KEY, showOnStartup); } } }; return showDialog(parentComponent, store, force); } /** * Pops up a "Tip of the day" dialog. * <p/> * If <code>choice</code> is not null, the method first checks if * {@link ShowOnStartupChoice#isShowingOnStartup()} is true before showing the * dialog. * <p/> * Additionally, it saves the state of the "Show tips on startup" checkbox * using the given {@link ShowOnStartupChoice} object. * * @param parentComponent * @param choice * @return true if the user chooses to not the tips again, false otherwise. * @throws HeadlessException if GraphicsEnvironment.isHeadless() returns true. * @see java.awt.GraphicsEnvironment#isHeadless */ public boolean showDialog(Component parentComponent, ShowOnStartupChoice choice) { return showDialog(parentComponent, choice, false); } /** * Pops up a "Tip of the day" dialog. * <p/> * If <code>choice</code> is not null, the method first checks if * <code>force</code> is true or if * {@link ShowOnStartupChoice#isShowingOnStartup()} is true before showing the * dialog. * <p/> * Additionally, it saves the state of the "Show tips on startup" checkbox * using the given {@link ShowOnStartupChoice} object. * * @param parentComponent * @param choice * @param force if true, the dialog is displayed even if * {@link ShowOnStartupChoice#isShowingOnStartup()} is false * @return true if the user chooses to see the tips again, false otherwise. * @throws HeadlessException if GraphicsEnvironment.isHeadless() returns true. * @see java.awt.GraphicsEnvironment#isHeadless */ public boolean showDialog(Component parentComponent, ShowOnStartupChoice choice, boolean force) { if (choice == null) { JDialog dialog = createDialog(parentComponent, choice); dialog.setVisible(true); dialog.dispose(); return true; } else if (force || choice.isShowingOnStartup()) { JDialog dialog = createDialog(parentComponent, choice); dialog.setVisible(true); dialog.dispose(); return choice.isShowingOnStartup(); } else { return false; } } /** * @param showOnStartupPref * @return true if the key named "ShowTipOnStartup" is not set to false */ public static boolean isShowingOnStartup(Preferences showOnStartupPref) { return showOnStartupPref.getBoolean(PREFERENCE_KEY, true); } /** * Removes the value set for "ShowTipOnStartup" in the given Preferences to * ensure the dialog shown by a later call to * {@link #showDialog(Component, Preferences)} will be visible to the user. * * @param showOnStartupPref */ public static void forceShowOnStartup(Preferences showOnStartupPref) { showOnStartupPref.remove(PREFERENCE_KEY); } /** * Calls * {@link TipOfTheDayUI#createDialog(Component, JTipOfTheDay.ShowOnStartupChoice)} * * @param parentComponent * @param choice * @return a JDialog to show this TipOfTheDay pane */ protected JDialog createDialog(Component parentComponent, ShowOnStartupChoice choice) { return getUI().createDialog(parentComponent, choice); } /** * Used in conjunction with the * {@link JTipOfTheDay#showDialog(Component, ShowOnStartupChoice)} to save the * "Show tips on startup" choice. */ public static interface ShowOnStartupChoice { void setShowingOnStartup(boolean showOnStartup); boolean isShowingOnStartup(); } }