[Japi-cvs] SF.net SVN: japi: [316] libs/swing-tod/trunk/src/net/sf/japi/swing
Status: Beta
Brought to you by:
christianhujer
From: <chr...@us...> - 2007-01-20 14:44:34
|
Revision: 316 http://svn.sourceforge.net/japi/?rev=316&view=rev Author: christianhujer Date: 2007-01-20 06:44:32 -0800 (Sat, 20 Jan 2007) Log Message: ----------- Work around a bug in some Java debuggers that won't load two files with the same path from different jars by moving tod to a package of its own. Added Paths: ----------- libs/swing-tod/trunk/src/net/sf/japi/swing/tod/ libs/swing-tod/trunk/src/net/sf/japi/swing/tod/TipOfTheDayManager.java libs/swing-tod/trunk/src/net/sf/japi/swing/tod/action.properties libs/swing-tod/trunk/src/net/sf/japi/swing/tod/action_de.properties Removed Paths: ------------- libs/swing-tod/trunk/src/net/sf/japi/swing/TipOfTheDayManager.java libs/swing-tod/trunk/src/net/sf/japi/swing/action.properties libs/swing-tod/trunk/src/net/sf/japi/swing/action_de.properties Deleted: libs/swing-tod/trunk/src/net/sf/japi/swing/TipOfTheDayManager.java =================================================================== --- libs/swing-tod/trunk/src/net/sf/japi/swing/TipOfTheDayManager.java 2007-01-19 23:55:54 UTC (rev 315) +++ libs/swing-tod/trunk/src/net/sf/japi/swing/TipOfTheDayManager.java 2007-01-20 14:44:32 UTC (rev 316) @@ -1,331 +0,0 @@ -/* JAPI - (Yet another (hopefully) useful) Java API - * - * Copyright (C) 2004-2006 Christian Hujer - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -package net.sf.japi.swing; - -import java.awt.Component; -import java.awt.Dimension; -import java.awt.Font; -import java.util.ArrayList; -import java.util.List; -import java.util.MissingResourceException; -import java.util.Random; -import java.util.ResourceBundle; -import static java.util.ResourceBundle.getBundle; -import java.util.prefs.Preferences; -import static java.util.prefs.Preferences.userNodeForPackage; -import java.io.InputStream; -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.io.UnsupportedEncodingException; -import java.security.PrivilegedAction; -import java.security.AccessController; -import javax.swing.Action; -import static javax.swing.Action.ACCELERATOR_KEY; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JDialog; -import javax.swing.JEditorPane; -import javax.swing.JLabel; -import javax.swing.JOptionPane; -import javax.swing.JScrollPane; -import javax.swing.KeyStroke; -import static javax.swing.SwingConstants.TRAILING; -import org.jetbrains.annotations.Nullable; -import static net.sf.japi.swing.ActionFactory.ACCELERATOR_KEY_2; -import static net.sf.japi.swing.IconManager.getDefaultIconManager; - -/** Class that manages tips of the day. - * The tips of the day are read from a property file. - * The name of the property file is tried to retrieve in exactly the following order: - * <ol> - * <li>The System Property <code>net.sf.japi.swing.tod</code> is queried and taken as a ResourceBundle base name.</li> - * <li>The Service file <code>META-INF/services/net.sf.japi.swing.tod</code> is read and its first line taken as a ResourceBundle base name.</li> - * </ol> - * If both fails, the behaviour is undefined. - * <p/> - * Setting the ResourceBundle for the TipOfTheDayManager via services is the preferred way, because you do not need any additional coding apart from - * invoking the TipOfTheDayManager somewhere at startup. - * <p /> - * The format of that property file follows the normal Java Properties convention, with the property keys being numbered, starting at "tod.text.1". - * Example: - * <pre># Tip Of The Days, English Version - * tod.text.1=<html>For analysis with other tools you can export the symbol map to XML, MS-Excel and CSV. - * tod.text.2=<html>For analysis with other tools you can export the mapping map to XML, MS-Excel and CSV. - * tod.text.3=<html>The supported map file formats are: Intel, GCC and MSVC. - * </pre> - * @fixme The preferences properties lastTipOfTheDayNumber and showTipOfTheDayAtStartup are stored in the wrong package, they must be stored in the client package instead of this package - * @todo Allow parametrization of properties, e.g. via a String sequence like <code>${property.name}</code>, which should then be looked up using - * a defined scheme from one or perhaps more definable {@link ActionFactory ActionFactories}. - * @author <a href="mailto:ch...@ri...">Christian Hujer</a> - * @serial exclude - */ -public final class TipOfTheDayManager extends JOptionPane { - - /** Action Factory. */ - private static final ActionFactory ACTION_FACTORY = ActionFactory.getFactory("net.sf.japi.swing"); - - /** Random number generator for random tods. */ - private static final Random RND = new Random(); - - /** Preferences. */ - private static final Preferences PREFS = userNodeForPackage(TipOfTheDayManager.class); - - /** The Action keys used for accelerators. */ - private static final String[] ACCELERATOR_KEYS = new String[] { ACCELERATOR_KEY, ACCELERATOR_KEY_2 }; - - /** The static instance. */ - private static final TipOfTheDayManager INSTANCE = new TipOfTheDayManager(); - - /** JButton for close. */ - private JButton closeButton; - - /** JDialog. */ - private JDialog dialog; - - /** JCheckBox for showing at startup. */ - private JCheckBox showAtStartup = new JCheckBox(ACTION_FACTORY.createAction(false, "todShowAtStartup", null)); - - /** The JLabel showing the current number of the tod. */ - private JLabel currentTodIndex = new JLabel(); - - /** The JEditorPane displaying the tod text. */ - private JEditorPane todText = new JEditorPane("text/html", ""); - - /** List with tod texts. */ - private List<String> todTexts = new ArrayList<String>(); - - /** Number of current Tip of the day. - * In visible state, the index must range between 0 and the number of tods available - 1, inclusive. - */ - private int todIndex; - - /** Show Tip Of The Day at startup. - * This method is only a proxy for show(Component) but looks at user preferences. - * If the user chose not to see TipOfTheDays this method simply returns. - * @param parentComponent the parent component of this dialog. - */ - public static void showAtStartup(final Component parentComponent) { - if (PREFS.getBoolean("showTipOfTheDayAtStartup", true)) { - show(parentComponent); - } - } - - /** Show a Tip Of The Day. - * @param parentComponent the parent component of this dialog. - */ - public static void show(final Component parentComponent) { - if (INSTANCE.dialog == null) { - INSTANCE.dialog = INSTANCE.createDialog(parentComponent, ACTION_FACTORY.getString("tipOfTheDay.windowTitle")); - } - INSTANCE.dialog.getRootPane().setDefaultButton(INSTANCE.closeButton); - INSTANCE.dialog.setModal(false); - INSTANCE.dialog.setResizable(true); - INSTANCE.dialog.setVisible(true); - INSTANCE.closeButton.requestFocusInWindow(); - } - - /** Finds the bundle name. - * @return bundle name - */ - private static String getBundleName() { - String bundleName = System.getProperty("net.sf.japi.swing.tod"); - if (bundleName == null) { - bundleName = getServiceValue(getClassLoader()); - } - return bundleName; - } - - /** This method attempts to return the first line of the resource META_INF/services/net.sf.japi.swing.tod from the provided ClassLoader. - * @param classLoader ClassLoader, may not be <code>null</code>. - * @return first line of resource, or <code>null</code> - */ - @Nullable private static String getServiceValue(final ClassLoader classLoader) { - BufferedReader rd = null; - try { - final String serviceId = "META-INF/services/net.sf.japi.swing.tod"; - final InputStream in = getResourceAsStream(classLoader, serviceId); - if (in != null) { - try { - rd = new BufferedReader(new InputStreamReader(in, "UTF-8")); - } catch (final UnsupportedEncodingException e) { - rd = new BufferedReader(new InputStreamReader(in)); - } - return rd.readLine(); - } - } catch (final Exception e) { - /* ignore. */ - } finally { - try { rd.close(); } catch (final Exception e) { /* ignore */ } finally { rd = null; } - } - return null; - } - - /** Get a resource from a classloader as stream. - * @param classLoader ClassLoader to get resource from - * @param serviceId service file to get stream from - * @return stream for resource <var>serviceId</var> in <var>classLoader</var> - */ - private static InputStream getResourceAsStream(final ClassLoader classLoader, final String serviceId) { - return AccessController.doPrivileged(new PrivilegedAction<InputStream>() { - - /** {@inheritDoc} */ - public InputStream run() { - return classLoader == null ? - ClassLoader.getSystemResourceAsStream(serviceId) : - classLoader.getResourceAsStream(serviceId); - } - - }); - } - - /** Get the ClassLoader. - * @return ClassLoader - */ - private static ClassLoader getClassLoader() { - try { - final ClassLoader contextClassLoader = getContextClassLoader(); - if (contextClassLoader != null) { - return contextClassLoader; - } - } catch (final Exception e) { - /* ignore */ - } - return TipOfTheDayManager.class.getClassLoader(); - } - - /** Get the context ClassLoader. - * @return context ClassLoader - */ - private static ClassLoader getContextClassLoader() { - return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() { - - /** {@inheritDoc} */ - @Nullable public ClassLoader run() { - try { - return Thread.currentThread().getContextClassLoader(); - } catch (final SecurityException ex) { - return null; - } - } - - }); - } - - /** Constructor. */ - private TipOfTheDayManager() { - final String[] keys = { "todPrev", "todRand", "todNext", "todClose" }; - final Action[] actions = new Action[keys.length]; - final Object[] newOptions = new Object[keys.length]; - for (int i = 0; i < keys.length; i++) { - actions[i] = ACTION_FACTORY.createAction(false, keys[i], this); - newOptions[i] = new JButton(actions[i]); - if ("todClose".equals(keys[i])) { - closeButton = (JButton) newOptions[i]; - } - for (final String key : ACCELERATOR_KEYS) { - final KeyStroke ks = (KeyStroke) actions[i].getValue(key); - if (ks != null) { - getInputMap(WHEN_IN_FOCUSED_WINDOW).put(ks, keys[i]); - getActionMap().put(keys[i], actions[i]); - } - } - } - final Dimension size = new Dimension(512, 128); - showAtStartup.setSelected(PREFS.getBoolean("showTipOfTheDayAtStartup", true)); - final JScrollPane todTextScroller = new JScrollPane(todText); - todTextScroller.setMinimumSize(size); - todTextScroller.setPreferredSize(size); - todTextScroller.setFocusable(true); - todTextScroller.setAutoscrolls(true); - todText.setEditable(false); - todText.setRequestFocusEnabled(false); - currentTodIndex.setHorizontalAlignment(TRAILING); - loadTodTexts(); - setTodIndex(PREFS.getInt("lastTipOfTheDayNumber", -1) + 1); - setIcon(getDefaultIconManager().getIcon(ACTION_FACTORY.getString("tipOfTheDay.icon"))); - final JLabel heading = new JLabel(ACTION_FACTORY.getString("todHeading")); - final Font oldFont = heading.getFont(); - heading.setFont(oldFont.deriveFont((float) (oldFont.getSize2D() * 1.5))); - setMessage(new Object[] { heading, todTextScroller, currentTodIndex, showAtStartup }); - setMessageType(INFORMATION_MESSAGE); - setOptions(newOptions); - } - - /** Loads the Tip of the day texts. */ - private void loadTodTexts() { - final ResourceBundle todBundle = getBundle(getBundleName()); - for (int i = 1;; i++) { - try { - todTexts.add(todBundle.getString(new StringBuilder().append("tod.text.").append(i).toString())); - } catch (final MissingResourceException e) { - break; - } - } - } - - /** Sets the tod index. - * @param todIndex new todIndex - */ - private void setTodIndex(final int todIndex) { - try { - this.todIndex = (todIndex + todTexts.size()) % todTexts.size(); - todText.setText(todTexts.get(this.todIndex)); - currentTodIndex.setText(ACTION_FACTORY.format("todIndex", this.todIndex + 1, todTexts.size())); - } catch (final ArithmeticException e) { - todText.setText(ACTION_FACTORY.getString("todsUnavailable")); - currentTodIndex.setText(""); - } - } - - /** Returns number of current Tip of the day. - * In visible state, the index must range between 0 and the number of tods available - 1, inclusive. - * @return number of current Tip of the day. - */ - public int getTodIndex() { - return todIndex; - } - - /** Action method for close. */ - public void todClose() { - setValue(closeButton); - PREFS.putBoolean("showTipOfTheDayAtStartup", showAtStartup.isSelected()); - PREFS.putInt("lastTipOfTheDayNumber", todIndex); - dialog.setVisible(false); - dialog.dispose(); - dialog = null; - } - - /** Action method for next. */ - public void todNext() { - setTodIndex(todIndex + 1); - } - - /** Action method for previous. */ - public void todPrev() { - setTodIndex(todIndex - 1); - } - - /** Action method for random. */ - public void todRand() { - setTodIndex(RND.nextInt(todTexts.size())); - } - -} // class TipOfTheDayManager Deleted: libs/swing-tod/trunk/src/net/sf/japi/swing/action.properties =================================================================== --- libs/swing-tod/trunk/src/net/sf/japi/swing/action.properties 2007-01-19 23:55:54 UTC (rev 315) +++ libs/swing-tod/trunk/src/net/sf/japi/swing/action.properties 2007-01-20 14:44:32 UTC (rev 316) @@ -1,56 +0,0 @@ -# JAPI - (Yet another (hopefully) useful) Java API -# -# Copyright (C) 2004-2006 Christian Hujer -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. -# - - -todPrev.text=Previous -todPrev.mnemonic=P -todPrev.accel=P -todPrev.accel2=LEFT -todPrev.icon=navigation/Back16 -todPrev.shortdescription=Displays the previous Tip Of The Day. -todNext.text=Next -todNext.mnemonic=N -todNext.accel=N -todNext.accel2=RIGHT -todNext.icon=navigation/Forward16 -todNext.shortdescription=Displays the next Tip Of The Day. -todRand.text=Random -todRand.mnemonic=R -todRand.accel=R -todRand.shortdescription=Displays a random Tip Of The Day. -todClose.mnemonic=C -todClose.accel=C -todClose.text=Close -todClose.shortdescription=Closes the Tip Of The Day window. -tipOfTheDay.icon=general/TipOfTheDay24 -todShowAtStartup.text=Show Tip Of The Day at startup -todShowAtStartup.mnemonic=S -todShowAtStartup.shortdescription=<html>If checked, a Tip Of The Day will be shown at application startup.<br>If unchecked, a Tip Of The Day will only be shown on demand. -tipOfTheDay.windowTitle=Tip Of The Day -todsUnavailable=No Tips Of The Day available -todHeading=Did you know? -todIndex=Showing Tip Of The Day {0} of {1}. -optionsChooseFile.icon=general/Open16 -saxErrorClear.text=Clear -saxErrorClose.text=Close -saxError.title=XML Errors -dialogDontShowAgain=Show this dialog again next time. -laf=Look and Feel -ReflectionAction.nonPublicMethod=Action Methods must be accessible public. That means the declaring class as well as the method must be public.\n{0} \ No newline at end of file Deleted: libs/swing-tod/trunk/src/net/sf/japi/swing/action_de.properties =================================================================== --- libs/swing-tod/trunk/src/net/sf/japi/swing/action_de.properties 2007-01-19 23:55:54 UTC (rev 315) +++ libs/swing-tod/trunk/src/net/sf/japi/swing/action_de.properties 2007-01-20 14:44:32 UTC (rev 316) @@ -1,48 +0,0 @@ -# JAPI - (Yet another (hopefully) useful) Java API -# -# Copyright (C) 2004-2006 Christian Hujer -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. -# - - -todPrev.text=Vorheriger -todPrev.mnemonic=V -todPrev.accel=V -todPrev.shortdescription=Zeigt den vorherigen Tipp des Tages. -todNext.text=N\xE4chster -todNext.mnemonic=N -todNext.accel=N -todNext.shortdescription=Zeigt den n\xE4chsten Tipp des Tages. -todRand.text=Zuf\xE4llig -todRand.mnemonic=R -todRand.accel=R -todRand.shortdescription=Zeigt einen zuf\xE4lligen Tipp des Tages. -todClose.mnemonic=S -todClose.accel=S -todClose.text=Schlie\xDFen -todClose.shortdescription=Schlie\xDFt das Tipp des Tages Fenster. -todShowAtStartup.text=Tipp des Tages beim Start anzeigen -todShowAtStartup.mnemonic=S -todShowAtStartup.shortdescription=<html>Wenn aktiviert, wird ein Tipp des Tages automatisch bei Programmstart angezeigt.<br>Wenn nicht aktiviert, werden Tipps des Tages nur auf ausdr\xFCcklichen Wunsch angezeigt. -tipOfTheDay.windowTitle=Tipp des Tages -todsUnavailable=Keine Tipps des Tages verf\xFCgbar -todHeading=Wussten Sie schon? -todIndex=Zeige Tipp des Tages {0} aus {1}. -dialogDontShowAgain=Show this dialog again next time. -saxError.title=XML Fehler -saxErrorClear.text=L\xF6schen -saxErrorClose.text=Schlie\xDFen Copied: libs/swing-tod/trunk/src/net/sf/japi/swing/tod/TipOfTheDayManager.java (from rev 315, libs/swing-tod/trunk/src/net/sf/japi/swing/TipOfTheDayManager.java) =================================================================== --- libs/swing-tod/trunk/src/net/sf/japi/swing/tod/TipOfTheDayManager.java (rev 0) +++ libs/swing-tod/trunk/src/net/sf/japi/swing/tod/TipOfTheDayManager.java 2007-01-20 14:44:32 UTC (rev 316) @@ -0,0 +1,332 @@ +/* JAPI - (Yet another (hopefully) useful) Java API + * + * Copyright (C) 2004-2006 Christian Hujer + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +package net.sf.japi.swing.tod; + +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Font; +import java.util.ArrayList; +import java.util.List; +import java.util.MissingResourceException; +import java.util.Random; +import java.util.ResourceBundle; +import static java.util.ResourceBundle.getBundle; +import java.util.prefs.Preferences; +import static java.util.prefs.Preferences.userNodeForPackage; +import java.io.InputStream; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.security.PrivilegedAction; +import java.security.AccessController; +import javax.swing.Action; +import static javax.swing.Action.ACCELERATOR_KEY; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JDialog; +import javax.swing.JEditorPane; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JScrollPane; +import javax.swing.KeyStroke; +import static javax.swing.SwingConstants.TRAILING; +import org.jetbrains.annotations.Nullable; +import static net.sf.japi.swing.ActionFactory.ACCELERATOR_KEY_2; +import static net.sf.japi.swing.IconManager.getDefaultIconManager; +import net.sf.japi.swing.ActionFactory; + +/** Class that manages tips of the day. + * The tips of the day are read from a property file. + * The name of the property file is tried to retrieve in exactly the following order: + * <ol> + * <li>The System Property <code>net.sf.japi.swing.tod</code> is queried and taken as a ResourceBundle base name.</li> + * <li>The Service file <code>META-INF/services/net.sf.japi.swing.tod</code> is read and its first line taken as a ResourceBundle base name.</li> + * </ol> + * If both fails, the behaviour is undefined. + * <p/> + * Setting the ResourceBundle for the TipOfTheDayManager via services is the preferred way, because you do not need any additional coding apart from + * invoking the TipOfTheDayManager somewhere at startup. + * <p /> + * The format of that property file follows the normal Java Properties convention, with the property keys being numbered, starting at "tod.text.1". + * Example: + * <pre># Tip Of The Days, English Version + * tod.text.1=<html>For analysis with other tools you can export the symbol map to XML, MS-Excel and CSV. + * tod.text.2=<html>For analysis with other tools you can export the mapping map to XML, MS-Excel and CSV. + * tod.text.3=<html>The supported map file formats are: Intel, GCC and MSVC. + * </pre> + * @fixme The preferences properties lastTipOfTheDayNumber and showTipOfTheDayAtStartup are stored in the wrong package, they must be stored in the client package instead of this package + * @todo Allow parametrization of properties, e.g. via a String sequence like <code>${property.name}</code>, which should then be looked up using + * a defined scheme from one or perhaps more definable {@link ActionFactory ActionFactories}. + * @author <a href="mailto:ch...@ri...">Christian Hujer</a> + * @serial exclude + */ +public final class TipOfTheDayManager extends JOptionPane { + + /** Action Factory. */ + private static final ActionFactory ACTION_FACTORY = ActionFactory.getFactory("net.sf.japi.swing"); + + /** Random number generator for random tods. */ + private static final Random RND = new Random(); + + /** Preferences. */ + private static final Preferences PREFS = userNodeForPackage(TipOfTheDayManager.class); + + /** The Action keys used for accelerators. */ + private static final String[] ACCELERATOR_KEYS = new String[] { ACCELERATOR_KEY, ACCELERATOR_KEY_2 }; + + /** The static instance. */ + private static final TipOfTheDayManager INSTANCE = new TipOfTheDayManager(); + + /** JButton for close. */ + private JButton closeButton; + + /** JDialog. */ + private JDialog dialog; + + /** JCheckBox for showing at startup. */ + private JCheckBox showAtStartup = new JCheckBox(ACTION_FACTORY.createAction(false, "todShowAtStartup", null)); + + /** The JLabel showing the current number of the tod. */ + private JLabel currentTodIndex = new JLabel(); + + /** The JEditorPane displaying the tod text. */ + private JEditorPane todText = new JEditorPane("text/html", ""); + + /** List with tod texts. */ + private List<String> todTexts = new ArrayList<String>(); + + /** Number of current Tip of the day. + * In visible state, the index must range between 0 and the number of tods available - 1, inclusive. + */ + private int todIndex; + + /** Show Tip Of The Day at startup. + * This method is only a proxy for show(Component) but looks at user preferences. + * If the user chose not to see TipOfTheDays this method simply returns. + * @param parentComponent the parent component of this dialog. + */ + public static void showAtStartup(final Component parentComponent) { + if (PREFS.getBoolean("showTipOfTheDayAtStartup", true)) { + show(parentComponent); + } + } + + /** Show a Tip Of The Day. + * @param parentComponent the parent component of this dialog. + */ + public static void show(final Component parentComponent) { + if (INSTANCE.dialog == null) { + INSTANCE.dialog = INSTANCE.createDialog(parentComponent, ACTION_FACTORY.getString("tipOfTheDay.windowTitle")); + } + INSTANCE.dialog.getRootPane().setDefaultButton(INSTANCE.closeButton); + INSTANCE.dialog.setModal(false); + INSTANCE.dialog.setResizable(true); + INSTANCE.dialog.setVisible(true); + INSTANCE.closeButton.requestFocusInWindow(); + } + + /** Finds the bundle name. + * @return bundle name + */ + private static String getBundleName() { + String bundleName = System.getProperty("net.sf.japi.swing.tod"); + if (bundleName == null) { + bundleName = getServiceValue(getClassLoader()); + } + return bundleName; + } + + /** This method attempts to return the first line of the resource META_INF/services/net.sf.japi.swing.tod from the provided ClassLoader. + * @param classLoader ClassLoader, may not be <code>null</code>. + * @return first line of resource, or <code>null</code> + */ + @Nullable private static String getServiceValue(final ClassLoader classLoader) { + BufferedReader rd = null; + try { + final String serviceId = "META-INF/services/net.sf.japi.swing.tod"; + final InputStream in = getResourceAsStream(classLoader, serviceId); + if (in != null) { + try { + rd = new BufferedReader(new InputStreamReader(in, "UTF-8")); + } catch (final UnsupportedEncodingException e) { + rd = new BufferedReader(new InputStreamReader(in)); + } + return rd.readLine(); + } + } catch (final Exception e) { + /* ignore. */ + } finally { + try { rd.close(); } catch (final Exception e) { /* ignore */ } finally { rd = null; } + } + return null; + } + + /** Get a resource from a classloader as stream. + * @param classLoader ClassLoader to get resource from + * @param serviceId service file to get stream from + * @return stream for resource <var>serviceId</var> in <var>classLoader</var> + */ + private static InputStream getResourceAsStream(final ClassLoader classLoader, final String serviceId) { + return AccessController.doPrivileged(new PrivilegedAction<InputStream>() { + + /** {@inheritDoc} */ + public InputStream run() { + return classLoader == null ? + ClassLoader.getSystemResourceAsStream(serviceId) : + classLoader.getResourceAsStream(serviceId); + } + + }); + } + + /** Get the ClassLoader. + * @return ClassLoader + */ + private static ClassLoader getClassLoader() { + try { + final ClassLoader contextClassLoader = getContextClassLoader(); + if (contextClassLoader != null) { + return contextClassLoader; + } + } catch (final Exception e) { + /* ignore */ + } + return TipOfTheDayManager.class.getClassLoader(); + } + + /** Get the context ClassLoader. + * @return context ClassLoader + */ + private static ClassLoader getContextClassLoader() { + return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() { + + /** {@inheritDoc} */ + @Nullable public ClassLoader run() { + try { + return Thread.currentThread().getContextClassLoader(); + } catch (final SecurityException ex) { + return null; + } + } + + }); + } + + /** Constructor. */ + private TipOfTheDayManager() { + final String[] keys = { "todPrev", "todRand", "todNext", "todClose" }; + final Action[] actions = new Action[keys.length]; + final Object[] newOptions = new Object[keys.length]; + for (int i = 0; i < keys.length; i++) { + actions[i] = ACTION_FACTORY.createAction(false, keys[i], this); + newOptions[i] = new JButton(actions[i]); + if ("todClose".equals(keys[i])) { + closeButton = (JButton) newOptions[i]; + } + for (final String key : ACCELERATOR_KEYS) { + final KeyStroke ks = (KeyStroke) actions[i].getValue(key); + if (ks != null) { + getInputMap(WHEN_IN_FOCUSED_WINDOW).put(ks, keys[i]); + getActionMap().put(keys[i], actions[i]); + } + } + } + final Dimension size = new Dimension(512, 128); + showAtStartup.setSelected(PREFS.getBoolean("showTipOfTheDayAtStartup", true)); + final JScrollPane todTextScroller = new JScrollPane(todText); + todTextScroller.setMinimumSize(size); + todTextScroller.setPreferredSize(size); + todTextScroller.setFocusable(true); + todTextScroller.setAutoscrolls(true); + todText.setEditable(false); + todText.setRequestFocusEnabled(false); + currentTodIndex.setHorizontalAlignment(TRAILING); + loadTodTexts(); + setTodIndex(PREFS.getInt("lastTipOfTheDayNumber", -1) + 1); + setIcon(getDefaultIconManager().getIcon(ACTION_FACTORY.getString("tipOfTheDay.icon"))); + final JLabel heading = new JLabel(ACTION_FACTORY.getString("todHeading")); + final Font oldFont = heading.getFont(); + heading.setFont(oldFont.deriveFont((float) (oldFont.getSize2D() * 1.5))); + setMessage(new Object[] { heading, todTextScroller, currentTodIndex, showAtStartup }); + setMessageType(INFORMATION_MESSAGE); + setOptions(newOptions); + } + + /** Loads the Tip of the day texts. */ + private void loadTodTexts() { + final ResourceBundle todBundle = getBundle(getBundleName()); + for (int i = 1;; i++) { + try { + todTexts.add(todBundle.getString(new StringBuilder().append("tod.text.").append(i).toString())); + } catch (final MissingResourceException e) { + break; + } + } + } + + /** Sets the tod index. + * @param todIndex new todIndex + */ + private void setTodIndex(final int todIndex) { + try { + this.todIndex = (todIndex + todTexts.size()) % todTexts.size(); + todText.setText(todTexts.get(this.todIndex)); + currentTodIndex.setText(ACTION_FACTORY.format("todIndex", this.todIndex + 1, todTexts.size())); + } catch (final ArithmeticException e) { + todText.setText(ACTION_FACTORY.getString("todsUnavailable")); + currentTodIndex.setText(""); + } + } + + /** Returns number of current Tip of the day. + * In visible state, the index must range between 0 and the number of tods available - 1, inclusive. + * @return number of current Tip of the day. + */ + public int getTodIndex() { + return todIndex; + } + + /** Action method for close. */ + public void todClose() { + setValue(closeButton); + PREFS.putBoolean("showTipOfTheDayAtStartup", showAtStartup.isSelected()); + PREFS.putInt("lastTipOfTheDayNumber", todIndex); + dialog.setVisible(false); + dialog.dispose(); + dialog = null; + } + + /** Action method for next. */ + public void todNext() { + setTodIndex(todIndex + 1); + } + + /** Action method for previous. */ + public void todPrev() { + setTodIndex(todIndex - 1); + } + + /** Action method for random. */ + public void todRand() { + setTodIndex(RND.nextInt(todTexts.size())); + } + +} // class TipOfTheDayManager Property changes on: libs/swing-tod/trunk/src/net/sf/japi/swing/tod/TipOfTheDayManager.java ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + LF Copied: libs/swing-tod/trunk/src/net/sf/japi/swing/tod/action.properties (from rev 315, libs/swing-tod/trunk/src/net/sf/japi/swing/action.properties) =================================================================== --- libs/swing-tod/trunk/src/net/sf/japi/swing/tod/action.properties (rev 0) +++ libs/swing-tod/trunk/src/net/sf/japi/swing/tod/action.properties 2007-01-20 14:44:32 UTC (rev 316) @@ -0,0 +1,56 @@ +# JAPI - (Yet another (hopefully) useful) Java API +# +# Copyright (C) 2004-2006 Christian Hujer +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. +# + + +todPrev.text=Previous +todPrev.mnemonic=P +todPrev.accel=P +todPrev.accel2=LEFT +todPrev.icon=navigation/Back16 +todPrev.shortdescription=Displays the previous Tip Of The Day. +todNext.text=Next +todNext.mnemonic=N +todNext.accel=N +todNext.accel2=RIGHT +todNext.icon=navigation/Forward16 +todNext.shortdescription=Displays the next Tip Of The Day. +todRand.text=Random +todRand.mnemonic=R +todRand.accel=R +todRand.shortdescription=Displays a random Tip Of The Day. +todClose.mnemonic=C +todClose.accel=C +todClose.text=Close +todClose.shortdescription=Closes the Tip Of The Day window. +tipOfTheDay.icon=general/TipOfTheDay24 +todShowAtStartup.text=Show Tip Of The Day at startup +todShowAtStartup.mnemonic=S +todShowAtStartup.shortdescription=<html>If checked, a Tip Of The Day will be shown at application startup.<br>If unchecked, a Tip Of The Day will only be shown on demand. +tipOfTheDay.windowTitle=Tip Of The Day +todsUnavailable=No Tips Of The Day available +todHeading=Did you know? +todIndex=Showing Tip Of The Day {0} of {1}. +optionsChooseFile.icon=general/Open16 +saxErrorClear.text=Clear +saxErrorClose.text=Close +saxError.title=XML Errors +dialogDontShowAgain=Show this dialog again next time. +laf=Look and Feel +ReflectionAction.nonPublicMethod=Action Methods must be accessible public. That means the declaring class as well as the method must be public.\n{0} \ No newline at end of file Property changes on: libs/swing-tod/trunk/src/net/sf/japi/swing/tod/action.properties ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + LF Copied: libs/swing-tod/trunk/src/net/sf/japi/swing/tod/action_de.properties (from rev 315, libs/swing-tod/trunk/src/net/sf/japi/swing/action_de.properties) =================================================================== --- libs/swing-tod/trunk/src/net/sf/japi/swing/tod/action_de.properties (rev 0) +++ libs/swing-tod/trunk/src/net/sf/japi/swing/tod/action_de.properties 2007-01-20 14:44:32 UTC (rev 316) @@ -0,0 +1,48 @@ +# JAPI - (Yet another (hopefully) useful) Java API +# +# Copyright (C) 2004-2006 Christian Hujer +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. +# + + +todPrev.text=Vorheriger +todPrev.mnemonic=V +todPrev.accel=V +todPrev.shortdescription=Zeigt den vorherigen Tipp des Tages. +todNext.text=N\xE4chster +todNext.mnemonic=N +todNext.accel=N +todNext.shortdescription=Zeigt den n\xE4chsten Tipp des Tages. +todRand.text=Zuf\xE4llig +todRand.mnemonic=R +todRand.accel=R +todRand.shortdescription=Zeigt einen zuf\xE4lligen Tipp des Tages. +todClose.mnemonic=S +todClose.accel=S +todClose.text=Schlie\xDFen +todClose.shortdescription=Schlie\xDFt das Tipp des Tages Fenster. +todShowAtStartup.text=Tipp des Tages beim Start anzeigen +todShowAtStartup.mnemonic=S +todShowAtStartup.shortdescription=<html>Wenn aktiviert, wird ein Tipp des Tages automatisch bei Programmstart angezeigt.<br>Wenn nicht aktiviert, werden Tipps des Tages nur auf ausdr\xFCcklichen Wunsch angezeigt. +tipOfTheDay.windowTitle=Tipp des Tages +todsUnavailable=Keine Tipps des Tages verf\xFCgbar +todHeading=Wussten Sie schon? +todIndex=Zeige Tipp des Tages {0} aus {1}. +dialogDontShowAgain=Show this dialog again next time. +saxError.title=XML Fehler +saxErrorClear.text=L\xF6schen +saxErrorClose.text=Schlie\xDFen Property changes on: libs/swing-tod/trunk/src/net/sf/japi/swing/tod/action_de.properties ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + LF This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |