/* * [OTP.java] * * Summary: Produces pngs with email address in them to deter spam harvesting from websites. * * Copyright: (c) 2005-2017 Roedy Green, Canadian Mind Products, http://mindprod.com * * Licence: This software may be copied and used freely for any purpose but military. * http://mindprod.com/contact/nonmil.html * * Requires: JDK 1.8+ * * Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/ * * Version History: * 1.2 2005-06-24 documents align="top" to handle gif and text alignment. * RELEASE_DATE, made vars static final. * 1.3 2006-03-06 reformat with IntelliJ, add Javadoc. * 1.4 2007-07-18 standard swing buttons. Courier removed as preferred font. * trim email entered, change name generated to not use mailto. * Fix problem with background not getting cleared all the time. * Changed list of preferred fonts. * 1.5 2008-01-22 JDK 1.3 to 1.4 since that is needed for Preferences. * 1.6 2008-03-11 add build number to title. * 1.7 2009-04-04 get rid of artifacts on screen. Suggest lower case filename. * 1.8 2009-04-04 Mask, command line version of Masker. * 1.9 2010-03-23 user selectable look and feel. */ package com.mindprod.opt; import com.mindprod.common18.Build; import com.mindprod.common18.CMPAboutJBox; import com.mindprod.common18.FontFactory; import com.mindprod.common18.HybridJ; import com.mindprod.common18.JEButton; import com.mindprod.common18.Laf; import com.mindprod.common18.VersionCheck; import javax.swing.JApplet; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JTextField; import java.awt.Color; import java.awt.Container; import java.awt.Font; import java.awt.GraphicsEnvironment; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Arrays; import java.util.HashSet; /** * Produces pngs with email address in them to deter spam harvesting from websites. *

* This is both an Applet and a standalone application. *

* * @author Roedy Green, Canadian Mind Products * @version 1.9 2010-03-23 user selectable look and feel. * @noinspection FieldCanBeLocal * @since 2005 */ public final class OTP extends JApplet { // ------------------------------ CONSTANTS ------------------------------ /** * undisplayed copyright notice * * @noinspection UnusedDeclaration */ public static final String EMBEDDED_COPYRIGHT = "Copyright: (c) 2005-2017 Roedy Green, Canadian Mind Products, http://mindprod.com"; /** * height of applet in pixels. Does not include bar at top, but does include menu bar. */ private static final int APPLET_HEIGHT = 275; /** * Width of applet in pixels. */ private static final int APPLET_WIDTH = 636; private static final int FIRST_COPYRIGHT_YEAR = 2005; /** * font size to use in the generated PNG images. */ private static final int pngFontSize = 18; /** * date this version released. */ private static final String RELEASE_DATE = "2010-03-23"; /** * Title of the Applet */ private static final String TITLE_STRING = "CMP Email Masker"; /** * Version of the Applet */ private static final String VERSION_STRING = "1.9"; /** * Best fonts to use. Takes the first one that is supported on the given system. For official names * see http://mindprod.com/fontshower.html */ private static final String[] pngFonts = new String[] { "Tiresias PCfont Z", "Tiresias PCfont", "TiresiasScreenfont", "Verdana", "Lucida Console", "Lucida Sans" };// if none of these supported, will use Dialog. /** * Applet background */ private static final Color BACKGROUND_FOR_APPLET = new Color( 0xfff4ff ); /** * background colour for input fields */ private static final Color BACKGROUND_FOR_INPUT = new Color( 0xffffff ); /** * default foreground colour for images */ private static final Color FOREGROUND_FOR_DEFAULT = new Color( 0x777777 )/* grey */; /** * foreground colour for input fields */ private static final Color FOREGROUND_FOR_INPUT = new Color( 0x1e90ff )/* dodger blue */; private static final Color FOREGROUND_FOR_LABEL = new Color( 0x0000b0 ); /** * for titles */ private static final Color FOREGROUND_FOR_TITLE = new Color( 0xdc143c ); /** * default transparent background colour for images. */ private static final Color transparent = new Color( 0x00ffffff, true ); /** * font for input fields */ private static final Font FONT_FOR_EDITABLE_FIELDS = FontFactory.build( "Dialog", Font.BOLD, 17 ); /** * for for titles and About buttons */ private static final Font FONT_FOR_TITLE = FontFactory.build( "Dialog", Font.BOLD, 16 ); /** * for for titles and About buttons */ private static final Font FONT_FOR_TITLE2 = FontFactory.build( "Dialog", Font.PLAIN, 14 ); /** * HashSet of names of all supported font families */ private static final HashSet allFontFamilies; // ------------------------------ FIELDS ------------------------------ // -------------------------- OTHER METHODS -------------------------- // -------------------------- STATIC METHODS -------------------------- static { String[] names = ( GraphicsEnvironment.getLocalGraphicsEnvironment() ) .getAvailableFontFamilyNames(); // convert to lower case for case-insensitive lookup for ( int i = 0, n = names.length; i < n; i++ ) { names[ i ] = names[ i ].toLowerCase(); } allFontFamilies = new HashSet( Arrays.asList( names ) ); } /** * save button */ private JButton save; /** * "email:" */ private JLabel emailLabel; /** * instruction on how to use the program */ private JLabel instructions; /** * title on screen */ private JLabel title; /** * title, second line */ private JLabel title2; /** * where you fill in email address on screen */ private JTextField email; /** * // -------------------------- PUBLIC INSTANCE METHODS -------------------------- * /** * Constructor */ public OTP() { } /** * Get the most preferred supported font from a list * * @param preferredFontNames list of font names, best one first. * @param fontStyle e.g. Font.PLAIN * @param fontSize size of font in points. * * @return best font that is supported, or a Dialog font if none are. * @noinspection SameParameterValue */ private static Font bestFont( String[] preferredFontNames, int fontStyle, int fontSize ) { // find first font in that is supported for ( String preferredFontName : preferredFontNames ) { if ( allFontFamilies.contains( preferredFontName.toLowerCase() ) ) { return FontFactory.build( preferredFontName, fontStyle, fontSize ); } }// end for return FontFactory.build( "Dialog", fontStyle, fontSize ); } /** * allocate all the components */ private void buildComponents() { title = new JLabel( TITLE_STRING + " " + VERSION_STRING ); title.setForeground( FOREGROUND_FOR_TITLE ); title.setFont( FONT_FOR_TITLE ); title2 = new JLabel( "released:" + RELEASE_DATE + " build:" + Build.BUILD_NUMBER ); title2.setFont( FONT_FOR_TITLE2 ); title2.setForeground( FOREGROUND_FOR_TITLE ); emailLabel = new JLabel( "email:" ); emailLabel.setForeground( FOREGROUND_FOR_LABEL ); email = new JTextField( "roedyg@mindprod.com", 40 ); email.setEditable( true ); email.setMargin( new Insets( 2, 2, 2, 2 ) ); email.setFont( FONT_FOR_EDITABLE_FIELDS ); email.setBackground( BACKGROUND_FOR_INPUT ); email.setForeground( FOREGROUND_FOR_INPUT ); save = new JEButton( "Save" ); save.setToolTipText( "Save Email image as a PNG file" ); instructions = new JLabel( "Fill in your email address and hit Save to create a png image of your email address." ); instructions.setForeground( FOREGROUND_FOR_LABEL ); } /** * build a menu with Look & Feel and About across the top */ private void buildMenu() { final JMenuBar menubar = new JMenuBar(); setJMenuBar( menubar ); menubar.add( Laf.buildLookAndFeelMenu() ); final JMenu menuHelp = new JMenu( "Help" ); menubar.add( menuHelp ); final JMenuItem aboutItem = new JMenuItem( "About" ); menuHelp.add( aboutItem ); aboutItem.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { // open about frame new CMPAboutJBox( TITLE_STRING, VERSION_STRING, "Creates png files (like gifs but smaller)", "to hide your email address from spam harvesters.", "freeware", RELEASE_DATE, FIRST_COPYRIGHT_YEAR, "Roedy Green", "MASKER", "1.6" ); } } ); } /** * layout fields in GridBag * * @param contentPane where to place the components */ private void layoutFields( Container contentPane ) { // 0________1_____ 2 // title ------------- 0 // title2 ------------ 1 // label email address 2 // what png looks like 3 // -------SAVE ------- 4 // instructions 5 // // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( title, new GridBagConstraints( 1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 5, 2, 0, 2 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( title2, new GridBagConstraints( 1, 1, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 0, 2, 0, 2 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( emailLabel, new GridBagConstraints( 0, 2, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets( 7, 5, 0, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( email, new GridBagConstraints( 1, 2, 2, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets( 7, 2, 0, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( save, new GridBagConstraints( 2, 4, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets( 5, 2, 0, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( instructions, new GridBagConstraints( 1, 5, 2, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 5, 2, 5, 5 ), 0, 0 ) ); } /** * Allow this applet to run as as application as well. * * @param args command line arguments ignored. */ public static void main( String args[] ) { HybridJ.fireup( new OTP(), TITLE_STRING + " " + VERSION_STRING, APPLET_WIDTH, APPLET_HEIGHT ); }// end main // --------------------------- main() method --------------------------- /** * Called by the browser or applet viewer to inform * this applet that it has been loaded into the system. * * @override */ @Override public void init() { Container contentPane = this.getContentPane(); if ( !VersionCheck.isJavaVersionOK( 1, 6, 1, contentPane ) ) { // effectively abort return; } buildMenu(); // also initial L&F contentPane.setLayout( new GridBagLayout() ); contentPane.setBackground( BACKGROUND_FOR_APPLET ); buildComponents(); layoutFields( contentPane ); this.validate(); this.setVisible( true ); } }// end Masker