/* GPLAboutDialog.java * * A generic handler for About events for GPL'd Java programs * * Written by Erskin L. Cherry (erskin@eldritch.org) * Copyright © 1999 Eldritch Enterprises * * 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. * * Optionally, you may find a copy of the GNU General Public License * from http://www.fsf.org/copyleft/gpl.txt */ package org.eldritch; import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; import javax.swing.*; /** * GPLAboutDialog is an extension of AbstractAction which will * display an "About" dialog and/or the GPL when actionPerformed is invoked. * * GPLAboutDialog assumes the GPL is kept in the current folder and * called license.txt *

* If the file cannot be read, the user will be asked if the program * should try and download a new copy of the GPL from the internet. *

* The icon for the dialog that displays the GPL defaults to the * local file gnu-logo.jpeg *

* The source and class files can be found at * http://www.eldritch.org/erskin/GPLAboutDialog/GPLAboutDialog.java * and http://www.eldritch.org/erskin/GPLAboutDialog/GPLAboutDialog.class *

* Naturally, this program is licensed under the GPL as well. * Which is availble at http://www.fsf.org/copyleft/gpl.txt * or from the GPLAboutDialog site. *

* The java source, the class file, the default gnu-logo, and the GNU license * can be downloaded in one file from * http://www.eldritch.org/erskin/GPLAboutDialog/GPLAboutDialog.tar.bz2 (~13k) * * @author Erskin L. Cherry * @version 1.3 */ public class GPLAboutDialog extends AbstractAction { // Default parent component private Component parent = null; // Set when we have a dialog open, so we don't open more than one at // a time private boolean alreadyOpen = false; /** * Returns the current parent Component the dialog will use when * displayed. * * @return the parent {@link Component} the dialog will be attached to */ public Component getParent() { return parent; } /** * Assigns the parent Component the dialog will use when displayed. * * @param parent the new parent objects */ public void setParent(Component parent) { this.parent = parent; } // Default name string, in case we don't get passed one // from the constructor private String name = ""; /** * Returns the current program name the about dialog will display. * * @return the program name that will be displayed */ public String getName() { return name; } /** * Assigns the program name the about dialog will display. * * @param name the new program name that will be displayed */ public void setName(String name) { this.name = name; } // Default version string, in case we don't get passed one // from the constructor private String version = ""; /** * Returns the current version number the about dialog will display. * * @return the version number that will be displayed */ public String getVersion() { return version; } /** * Assigns the version number the about dialog will display. * * @param version the new version number that will be displayed */ public void setVersion(String version) { this.version = version; }; // Default blurb string, in case we don't get passed one // from the constructor private String blurb = ""; /** * Returns the current program purpose blurb the about dialog * will display. * * @return the program blurb that will be displayed */ public String getBlurb() { return blurb; } /** * Assigns the program purpose blurb the about dialog will display. * * @param blurb the new that will be displayed */ public void setBlurb(String blurb) { this.blurb = blurb; } // Default author/copyright string, in case we don't get passed one // from the constructor private String copyright = ""; /** * Returns the current author/copyright string the about dialog * will display. * * @return the copyright string that will be displayed */ public String getCopyright() { return copyright; } /** * Assigns the author/copyright string the about dialog will display. * Generally of the form "by John Doe\nCopyright 1999 John Doe" * * @param copyright the new author/copyright that will be displayed */ public void setCopyright(String copyright) { this.copyright = copyright; } // Default internal frames flag, we assume that we shouldn't // just to be safe private boolean internalFrames = false; /** * Returns true if the about dialog will open internal * frames. * * @return true if internal frames will be displayed */ public boolean isInternalFrames() { return internalFrames; } /** * Determines if the about diaog should be displayed using * internal frames. * * @param newInternalFrames true if internal frames * should be used */ public void setInternalFrames(boolean newInternalFrames) { internalFrames = newInternalFrames; } // The default icon for the GPL display dialog private Icon gnuLogo = new ImageIcon("gnu-logo.jpeg", "GNU's Not Unix Logo"); /** * Returns the current Icon that will be displayed on the GPL dialog * if requested. * * The internal default is the local file "gnu-logo.jpeg" * * @return the {@link Icon} that will be displayed on the GPL dialog */ public Icon getGnuLogo() { return gnuLogo; } /** * Assigns the Icon that will be displayed on the GPL dialog if * requested. * * @param gnuLogo the new Icon for the GPL dialog */ public void setGnuLogo(Icon gnuLogo) { this.gnuLogo = gnuLogo; } // Default program Icon for the about window // If the constructor doesn't override it, JOptionPane will use // an 'i' in a blue circle private Icon programLogo = null; /** * Returns the current Icon that will be displayed on the about dialog * for the program. * * The default is null which should result in * {@link JOptionPane} using it's internal information icon * * @return the {@link Icon} that will be displayed on the GPL dialog */ public Icon getProgramLogo() { return programLogo; } /** * Assigns the Icon that will be displayed on the about dialog for * the program. * * @param programLogo the new program Icon for the about dialog */ public void setProgramLogo(Icon programLogo) { this.programLogo = programLogo; } /** * Constructs a new GPLAboutDialog with absolutely all options. * * @param parent the parent Component for the dialog * @param name the program name * @param version the program version number * @param blurb the program purpose text * @param copyright the author/copyright text * @param programLogo the Icon for the about dialog * @param gnuLogo the Icon for the GPL dialog * @param internalFrames true if internal frames * should be used */ public GPLAboutDialog(Component parent, String name, String version, String blurb, String copyright, Icon programLogo, Icon gnuLogo, boolean internalFrames) { // The overly complete constructor including GNU logo option this.parent = parent; this.name = name; this.version = version; this.blurb = blurb; this.copyright = copyright; this.programLogo = programLogo; this.gnuLogo = gnuLogo; this.internalFrames = internalFrames; } /** * Constructs a new GPLAboutDialog with default gnu_logo.jpeg. * * @param parent the parent Component for the dialog * @param name the program name * @param version the program version number * @param blurb the program purpose text * @param copyright the author/copyright text * @param programLogo the Icon for the about dialog * @param internalFrames true if internal frames * should be used */ public GPLAboutDialog(Component parent, String name, String version, String blurb, String copyright, Icon programLogo, boolean internalFrames) { // The general constructor this.parent = parent; this.name = name; this.version = version; this.blurb = blurb; this.copyright = copyright; this.programLogo = programLogo; this.internalFrames = internalFrames; } /** * Constructs a new GPLAboutDialog with default gnu_logo * and assumes we are not using internal frames. * * @param parent the parent Component for the dialog * @param name the program name * @param version the program version number * @param blurb the program purpose text * @param copyright the author/copyright text * @param programLogo the Icon for the about dialog */ public GPLAboutDialog(Component parent, String name, String version, String blurb, String copyright, Icon programLogo) { // The same constructor without the last boolean option this.parent = parent; this.name = name; this.version = version; this.blurb = blurb; this.copyright = copyright; this.programLogo = programLogo; } /** * Constructs a new GPLAboutDialog with the default gnu_logo * and the default program icon. * * @param parent the parent Component for the dialog * @param name the program name * @param version the program version number * @param blurb the program purpose text * @param copyright the author/copyright text * @param internalFrames true if internal frames * should be used */ public GPLAboutDialog(Component parent, String name, String version, String blurb, String copyright, boolean internalFrames) { // The same constructor without the program icon option this.parent = parent; this.name = name; this.version = version; this.blurb = blurb; this.copyright = copyright; this.internalFrames = internalFrames; } /** * Constructs a new GPLAboutDialog with the default gnu_logo, * default program icon, and the assumption that we are not * using internal frames. * * @param parent the parent Component for the dialog * @param name the program name * @param version the program version number * @param blurb the program purpose text * @param copyright the author/copyright text */ public GPLAboutDialog(Component parent, String name, String version, String blurb, String copyright) { // The same constructor without the last boolean // or the program icon this.parent = parent; this.name = name; this.version = version; this.blurb = blurb; this.copyright = copyright; } /** * Displays and about dialog box, regardless of the event, and offers * to display the GNU GPL, offering to download it if it is not found * locally. * * @param e ignored action event */ public void actionPerformed(ActionEvent e) { // We only want to open one About Dialog at a time // So if we already have, stop right here if(alreadyOpen) { return; } // Set aleadyOpen to true so we won't open another dialog // if this method is called again while we're still displaying // something alreadyOpen = true; // Open a standard about dialog with the option to // view the GPL or just say OK String message = name + " v" + version + "\n" + blurb + "\n\n" + copyright + "\n\nThis program is Open Source software, or more" + "\nspecifically, free software. You can redistribute" + "\nit and/or modify it under the terms of the GNU" + "\nGeneral Public License (GPL) as published by the " + "\nFree Software Foundation; either version 2 of the" + "\nLicense, or (at your option) any later version.\n"; int viewGPL; Object[] optionButtons = { "View GPL", "OK" }; if(internalFrames) { viewGPL = JOptionPane.showInternalOptionDialog(parent, message, "About " + name, 0, JOptionPane.INFORMATION_MESSAGE, programLogo, optionButtons, optionButtons[1]); } else { viewGPL = JOptionPane.showOptionDialog(parent, message, "About " + name, 0, JOptionPane.INFORMATION_MESSAGE, programLogo, optionButtons, optionButtons[1]); } // If they wanted to view the GPL, try and read the file // from the current directory if(viewGPL == JOptionPane.YES_OPTION) { // Set up the scrollpane to hold the GPL once we read it JTextArea textArea = new JTextArea(15, 81); textArea.setEditable(false); textArea.setLineWrap(true); textArea.setFont(new Font("Courier", Font.PLAIN, 10)); JScrollPane scrollPane = new JScrollPane(textArea); // The URL for the Free Software foundation // in case we need to download a new copy of the GPL URL gplURL = null; try { gplURL = new URL("http://www.fsf.org/copyleft/gpl.txt"); } catch(MalformedURLException urlException) {} boolean loadedGPL = false; BufferedReader inGPL = null; // This while loop allows me to reuse the code to // load from a local file if I have to download the // GPL from the net while((viewGPL == JOptionPane.YES_OPTION) && (loadedGPL == false)) { // Then try and read it locally try { inGPL = new BufferedReader( new FileReader("license.txt")); textArea.read(inGPL, "GNU General Public License"); // I don't close this in the finally statement // because I may need it again before I get there inGPL.close(); loadedGPL = true; } catch(IOException ioException) { // I don't put this in the finally statement // because I may need it again before I get there if(inGPL != null) { try { inGPL.close(); } catch(IOException closeException) {} } // If we have a problem, bring up a dialog // and ask if we should grab it from the net if(internalFrames) { viewGPL = JOptionPane.showInternalConfirmDialog( parent, "Error reading file license.txt\n\n" + ioException.getLocalizedMessage() + "\n\nDownload a new copy of the GPL from " + gplURL.getProtocol() + "://" + gplURL.getHost() + "?", "Error reading file", JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE); } else { viewGPL = JOptionPane.showConfirmDialog( parent, "Error reading file license.txt\n\n" + ioException.getLocalizedMessage() + "\n\nDownload a new copy of the GPL from " + gplURL.getProtocol() + "://" + gplURL.getHost() + "?", "Error reading file", JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE); } if(viewGPL == JOptionPane.YES_OPTION) { // Try and grab the GPL from the net BufferedWriter outGPL = null; try { inGPL = new BufferedReader(new InputStreamReader(gplURL.openStream())); outGPL = new BufferedWriter(new FileWriter("license.txt")); String textLine = null; while((textLine = inGPL.readLine()) != null) { outGPL.write(textLine); outGPL.newLine(); } } catch(Exception netException) { // Tell them if we failed viewGPL = JOptionPane.NO_OPTION; if(internalFrames) { JOptionPane.showInternalMessageDialog(parent, "Error downloading file " + gplURL.getProtocol() + "://" + gplURL.getHost() + gplURL.getRef() + "\n\n" + netException.getMessage(), "Error downloading file", JOptionPane.ERROR_MESSAGE); } else { JOptionPane.showMessageDialog(parent, "Error downloading file " + gplURL.getProtocol() + "://" + gplURL.getHost() + gplURL.getRef() + "\n\n" + netException.getMessage(), "Error downloading file", JOptionPane.ERROR_MESSAGE); } } finally { try { if(outGPL != null) { outGPL.close(); } if(inGPL != null) { inGPL.close(); } } catch(IOException closeException) {} } } } } // If we actually got a hold of the file, // display it if(loadedGPL == true) { scrollPane.setPreferredSize( textArea.getPreferredScrollableViewportSize()); if(internalFrames) { JOptionPane.showInternalMessageDialog(parent, scrollPane, "GNU General Public License", JOptionPane.INFORMATION_MESSAGE, gnuLogo); } else { JOptionPane.showMessageDialog(parent, scrollPane, "GNU General Public License", JOptionPane.INFORMATION_MESSAGE, gnuLogo); } } } // We're done, so if they want to open the window up again, // it's okay alreadyOpen = false; } }