/* * [GoldenCoin.java] * * Summary: Compute odds of throwing heads N times in a row, with a given weighted coin. * * Copyright: (c) 2011-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.0 2011-06-12 initial version */ package com.mindprod.goldencoin; import com.mindprod.common18.CMPAboutJBox; import com.mindprod.common18.Common18; import com.mindprod.common18.FontFactory; import com.mindprod.common18.HybridJ; import com.mindprod.common18.JEButton; import com.mindprod.common18.VersionCheck; import javax.swing.JApplet; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextField; import java.awt.Color; import java.awt.Container; import java.awt.Font; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.text.DecimalFormat; /** * Compute odds of throwing heads N times in a row, with a given weighted coin. *

* GoldenCoin * * @author Roedy Green, Canadian Mind Products * @version 1.0 2011-06-12 initial version * @since 2011-06-12 */ public final class GoldenCoin extends JApplet { /** * height of Applet box in pixels. Does not include surrounding frame. */ private static final int APPLET_HEIGHT = 440; /** * Width of Applet box in pixels. */ private static final int APPLET_WIDTH = 440; private static final int FIRST_COPYRIGHT_YEAR = 2011; /** * initial value for trials */ private static final int INITIAL_TRIALS = 20; /** * maximum number of trials we allow */ private static final int MAX_TRIALS = 1000000; /** * undisplayed copyright notice */ private static final String EMBEDDED_COPYRIGHT = "Copyright: (c) 2011-2017 Roedy Green, Canadian Mind Products, http://mindprod.com"; private static final String RELEASE_DATE = "2011-06-12"; private static final String TITLE_STRING = "Golden Coin Probability Calculator"; /** * embedded version string. */ private static final String VERSION_STRING = "1.0"; /** * background colour for window. */ private static final Color BACKGROUND_FOR_APP = new Color( 0xeee8aa/* pale goldenrod */ ); /** * background where for data entry where user enters a value. */ private static final Color BACKGROUND_FOR_EDITABLE = Color.WHITE; /** * for instruction on how to use program */ private static final Color BACKGROUND_FOR_INSTRUCTIONS = Color.WHITE; /** * for final result */ private static final Color BACKGROUND_FOR_RESULT = Color.WHITE; /** * foreground colour for window text */ private static final Color FOREGROUND_FOR_APP = Color.BLACK; /** * data entry text field colour */ private static final Color FOREGROUND_FOR_EDITABLE = Color.BLACK; /** * for instruction on how to use program */ private static final Color FOREGROUND_FOR_INSTRUCTIONS = new Color( 0x008000 ); /** * for final result */ private static final Color FOREGROUND_FOR_RESULT = Color.BLACK; /** * for titles */ private static final Color FOREGROUND_FOR_TITLE = new Color( 0xdc143c ); /** * format for display and input of sale amount */ private static final DecimalFormat PROBABILITY_FORMAT = new DecimalFormat( "#0.000" ); /** * for spinner */ private static final Font FONT_FOR_EDITABLE_FIELDS; /** * for for titles and About buttons */ private static final Font FONT_FOR_INSTRUCTIONS; /** * for final result */ private static final Font FONT_FOR_RESULTS; /** * for for titles and About buttons */ private static final Font FONT_FOR_TITLE; /** * initial value for probability */ private static final double INITIAL_PROBABILITY = .75; static { FONT_FOR_EDITABLE_FIELDS = FontFactory.build( "Monospaced", Font.BOLD, 15 ); FONT_FOR_INSTRUCTIONS = FontFactory.build( "Dialog", Font.PLAIN, 15 ); FONT_FOR_RESULTS = FontFactory.build( "Dialog", Font.PLAIN, 15 ); FONT_FOR_TITLE = FontFactory.build( "Dialog", Font.BOLD, 16 ); } /** * about */ private JButton about; private JLabel instructions; /** * label for probabilityText */ private JLabel probabilityLabel; /** * first line of result as a sentence. */ private JLabel resultLabel; /** * title of applet */ private JLabel title; /** * label for probabilityText */ private JLabel trialsLabel; /** * graph, placeholder */ private JPanel graph; /** * text for probability */ private JTextField probabilityText; /** * first line of result as a sentence. */ private JTextField resultText; /** * annual growth in consumption as a percent */ private JTextField trialsText; /** * constructor */ public GoldenCoin() { } /** * compute end probability */ private void compute() { double p; try { p = Double.parseDouble( probabilityText.getText() ); } catch ( NumberFormatException e ) { instructions.setText( "Malformed probability. No commas, spaces allowed." ); return; } if ( !( 0 <= p && p <= 1 ) ) { instructions.setText( "Probability out of range. Enter a number 0..1, e.g. 0.5." ); } int trials; try { trials = Integer.parseInt( trialsText.getText() ); } catch ( NumberFormatException e ) { instructions.setText( "Malformed trials. No commas, decimal points, spaces allowed." ); return; } if ( !( 0 <= trials && trials <= MAX_TRIALS ) ) { instructions.setText( "Trials out of range. Enter a number 0.." + MAX_TRIALS ); } double result = Math.pow( p, trials ); resultText.setText( PROBABILITY_FORMAT.format( result ) ); } /** * create gui components */ private void createComponents() { title = new JLabel( TITLE_STRING + " " + VERSION_STRING ); title.setFont( FONT_FOR_TITLE ); title.setForeground( FOREGROUND_FOR_TITLE ); // leave background app background about = new JEButton( "About" ); about.setToolTipText( "About " + TITLE_STRING + " " + VERSION_STRING ); graph = new JPanel(); graph.setBackground( Color.WHITE ); probabilityLabel = new JLabel( "Probability of throwing heads once:", JLabel.RIGHT ); probabilityLabel.setFont( FONT_FOR_INSTRUCTIONS ); probabilityLabel.setBackground( BACKGROUND_FOR_INSTRUCTIONS ); probabilityLabel.setForeground( FOREGROUND_FOR_INSTRUCTIONS ); probabilityText = new JTextField(); probabilityText.setFont( FONT_FOR_EDITABLE_FIELDS ); probabilityText.setBackground( BACKGROUND_FOR_EDITABLE ); probabilityText.setForeground( FOREGROUND_FOR_EDITABLE ); probabilityText.setText( Double.toString( INITIAL_PROBABILITY ) ); trialsLabel = new JLabel( "number of trials:", JLabel.RIGHT ); trialsLabel.setFont( FONT_FOR_INSTRUCTIONS ); trialsLabel.setBackground( BACKGROUND_FOR_INSTRUCTIONS ); trialsLabel.setForeground( FOREGROUND_FOR_INSTRUCTIONS ); trialsText = new JTextField(); trialsText.setFont( FONT_FOR_EDITABLE_FIELDS ); trialsText.setBackground( BACKGROUND_FOR_EDITABLE ); trialsText.setForeground( FOREGROUND_FOR_EDITABLE ); trialsText.setText( Integer.toString( INITIAL_TRIALS ) ); resultLabel = new JLabel( "result probability:", JLabel.RIGHT ); resultLabel.setFont( FONT_FOR_INSTRUCTIONS ); resultLabel.setBackground( BACKGROUND_FOR_INSTRUCTIONS ); resultLabel.setForeground( FOREGROUND_FOR_INSTRUCTIONS ); resultText = new JTextField(); resultText.setEditable( false ); resultText.setFont( FONT_FOR_RESULTS ); resultText.setBackground( BACKGROUND_FOR_RESULT ); resultText.setForeground( FOREGROUND_FOR_RESULT ); instructions = new JLabel(); instructions.setFont( FONT_FOR_INSTRUCTIONS ); instructions.setBackground( BACKGROUND_FOR_INSTRUCTIONS ); instructions.setForeground( FOREGROUND_FOR_INSTRUCTIONS ); instructions.setText( "Enter \"once\" probability 0..1, and number of trials 1.." + MAX_TRIALS ); } /** * hook up the listeners */ private void hookListeners() { // engage the listeners about.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { // open about box frame new CMPAboutJBox( TITLE_STRING, VERSION_STRING, "Calculates probability of throwing heads N times in a row", "given a given weighted coin.", "freeware", RELEASE_DATE, FIRST_COPYRIGHT_YEAR, "Roedy Green", "GOLDENCOIN", "1.8" ); } } ); } /** * layout the components * * @param contentPane where to add components */ private void layoutGridBag( Container contentPane ) { // basic layout: // -----0----1--------------------------2---- // 0 -----------TITLE-----------------about // 1 ----------------graph------------------ // 2 ~prob prob // 3 ~trials trials // 4 ~result result // 5 instructions ------------------------------- // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( title, new GridBagConstraints( 0, 0, 2, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 10, 10, 0, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( about, new GridBagConstraints( 2, 0, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets( 10, 5, 5, 10 ), 10, 2 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( graph, new GridBagConstraints( 0, 1, 3, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( 10, 10, 10, 10 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( probabilityLabel, new GridBagConstraints( 0, 2, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets( 5, 10, 5, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( probabilityText, new GridBagConstraints( 1, 2, 2, 1, 10.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets( 5, 5, 5, 10 ), 20, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( trialsLabel, new GridBagConstraints( 0, 3, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets( 5, 10, 5, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( trialsText, new GridBagConstraints( 1, 3, 2, 1, 10.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets( 5, 5, 5, 10 ), 20, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( resultLabel, new GridBagConstraints( 0, 4, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets( 5, 10, 5, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( resultText, new GridBagConstraints( 1, 4, 2, 1, 10.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets( 5, 5, 5, 10 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( instructions, new GridBagConstraints( 0, 5, 3, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 5, 10, 10, 10 ), 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 GoldenCoin(), TITLE_STRING + " " + VERSION_STRING, APPLET_WIDTH, APPLET_HEIGHT ); } // end main /** * Called by the browser or Applet viewer to inform * this Applet that it is being reclaimed and that it should destroy * any resources that it has allocated. */ public void destroy() { about = null; probabilityLabel = null; probabilityText = null; trialsLabel = null; trialsText = null; resultLabel = null; resultText = null; title = null; instructions = null; } /** * Called by the browser or Applet viewer to inform * this Applet that it has been loaded into the system. */ @Override public void init() { if ( !VersionCheck.isJavaVersionOK( 1, 8, 0, this ) ) { return; } Common18.setLaf(); Container contentPane = this.getContentPane(); contentPane.setBackground( BACKGROUND_FOR_APP ); contentPane.setForeground( FOREGROUND_FOR_APP ); contentPane.setLayout( new GridBagLayout() ); createComponents(); compute(); layoutGridBag( contentPane ); hookListeners(); this.validate(); this.setVisible( true ); } // end init } // end GoldenCoin