/* * [PowCost.java] * * Summary: Calculates the cost of various activities that consume electricity. * * Copyright: (c) 2010-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 2010-12-04 initial version. * 1.1 2010-12-06 add duty cycle. * 1.2 2010-12-23 fix integer overflow bug for large consumption. * 1.3 2011-05-19 tweak the layout. Add more energy-using items. * 1.4 2013-01-19 add more items, sort by total cost, fix bug that was chopping a 0, polish alignments. * 1.5 2014-06-01 correct bug displaying duration, add cell phone and ipad. */ package com.mindprod.powcost; import com.mindprod.common18.Build; import com.mindprod.common18.CMPAboutJBox; import com.mindprod.common18.EIO; import com.mindprod.common18.FontFactory; import com.mindprod.common18.HybridJ; import com.mindprod.common18.Laf; import com.mindprod.common18.Misc; import com.mindprod.common18.VersionCheck; import com.mindprod.currcon.Exch; import javax.swing.ImageIcon; import javax.swing.JApplet; import javax.swing.JComboBox; 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.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.io.ObjectInputStream; import java.text.DecimalFormat; import java.util.Arrays; import java.util.HashMap; import java.util.Locale; import java.util.Vector; import static java.lang.System.*; /** * Calculates the cost of various activities that consume electricity. *

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

* * @author Roedy Green, Canadian Mind Products * @version 1.5 2014-06-01 correct bug displaying duration, add cell phone and ipad. * @noinspection FieldCanBeLocal * @since 2010-12-02 */ public final class PowCost extends JApplet { /** * true if you want debugging output */ private static final boolean DEBUGGING = false; /** * height of Applet in pixels. Does not include bar at top, but does include menu bar. */ private static final int APPLET_HEIGHT = 395; /** * Width of Applet in pixels. */ private static final int APPLET_WIDTH = 790; /** * when this app was first copyrighted */ private static final int FIRST_COPYRIGHT_YEAR = 2010; /** * undisplayed copyright notice * * @noinspection UnusedDeclaration */ private static final String EMBEDDED_COPYRIGHT = "Copyright: (c) 2010-2017 Roedy Green, Canadian Mind Products, http://mindprod.com"; /** * Activity user sees initially */ private static final String INITIAL_ACTIVITY = "run a 1 kw appliance for an hour (i.e. 1 kwh)"; /** * Location user sees initially */ private static final String INITIAL_LOCATION = "ca BC British Columbia"; /** * date this version released. */ private static final String RELEASE_DATE = "2014-06-01"; /** * Title of the Applet */ private static final String TITLE_STRING = "Electric Power Cost Calculator"; /** * Version of the Applet */ private static final String VERSION_STRING = "1.5"; /** * background colour, pale green to match website */ private static final Color BACKGROUND_FOR_BODY = Build.BACKGROUND_FOR_BLENDING; /** * background where for data entry where user enters a value. */ private static final Color BACKGROUND_FOR_EDITABLE = Color.WHITE; /** * background colour for instructions. Default grey is too dark */ private static final Color BACKGROUND_FOR_INSTRUCTIONS = new Color( 0xf8f8f8 ); /** * background colour for labels */ private static final Color BACKGROUND_FOR_LABEL = Build.BACKGROUND_FOR_BLENDING; /** * darker green resultColor background, don't enter data here. */ private static final Color BACKGROUND_FOR_RESULT_DARK = new Color( 0xa8ffef ); /** * medium green resultColor background, don't enter data here. */ private static final Color BACKGROUND_FOR_RESULT_MEDIUM = new Color( 0xc4ffef ); /** * don't enter data here. raw data. */ private static final Color BACKGROUND_FOR_RESULT_PALE = new Color( 0xe4ffef ); /** * data entry text field colour */ private static final Color FOREGROUND_FOR_EDITABLE = Color.BLACK; /** * instruction normal color */ private static final Color FOREGROUND_FOR_INSTRUCTIONS = new Color( 0x339911 ); /** * foreground colour for label */ private static final Color FOREGROUND_FOR_LABEL = Color.BLUE; /** * don't enter data here foreground */ private static final Color FOREGROUND_FOR_RESULT_DARK = Color.BLACK; /** * /** * don't enter data here foreground */ private static final Color FOREGROUND_FOR_RESULT_MEDIUM = Color.BLACK; /** * don't enter data here. raw data. */ private static final Color FOREGROUND_FOR_RESULT_PALE = new Color( 0x226622 ); /** * for titles */ private static final Color FOREGROUND_FOR_TITLE = new Color( 0xdc143c ); /** * helps format the amount display , for 0 to 4 decimal places DecimalFormat is not thread Safe. That should not * matter since all Applets run on the same thread, but just in case... Actual display is Locale dependent, e.g. * comma or decimal point. */ private static final DecimalFormat[] df = { new DecimalFormat( "###,##0" ) /* 0 */, new DecimalFormat( "###,##0.0" ) /* 1 */, new DecimalFormat( "###,##0.00" ) /* 2 */, new DecimalFormat( "###,##0.000" ) /* 3 */, new DecimalFormat( "###,##0.0000" ) /* 4 */, new DecimalFormat( "###,##0.00000" ) /* 5 */, new DecimalFormat( "###,##0.000000" ) /* 6 */ }; /** * instructions font */ private static final Font FONT_FOR_INSTRUCTIONS = FontFactory.build( "Dialog", Font.PLAIN, 12 ); /** * label font */ private static final Font FONT_FOR_LABEL = FontFactory.build( "Dialog", Font.PLAIN, 13 ); /** * label font */ private static final Font FONT_FOR_LABEL_BOLD = FontFactory.build( "Dialog", Font.BOLD, 14 ); /** * label font */ private static final Font FONT_FOR_LABEL_UNITS = FontFactory.build( "Dialog", Font.PLAIN, 11 ); /** * title font */ private static final Font FONT_FOR_TITLE = FontFactory.build( "Dialog", Font.BOLD, 15 ); /** * for for title second line */ private static final Font FONT_FOR_TITLE2 = FontFactory.build( "Dialog", Font.PLAIN, 14 ); /** * Reddy Kilowatt icon */ private static final ImageIcon LOGO_ICON = new ImageIcon( PowCost.class.getResource( "image/reddy.png" ) ); /** * conversion constant Megajoules per kwh,(1 gallon gasoline = 130 mj) */ private static final double MJ_PER_KWH = 3.6; /** * Lets us look up 3-letter currency code given 2-letter country code. Final, but compiler does not know that */ private static HashMap countryToCurr; /** * list of objects that describe a country, its currency and exchange rate. */ private static Exch[] exchs; static { // should happen once, only one and before any init method runs. fetchCurrencyInfo(); } /** * contentPane for the whole Applet */ private Container contentPane; /** * index Exch record about this currency and its current exchang rate. */ private Exch userExch; /* select an electricity-using activity */ private JComboBox activity; /** * select the cost by selecting the location */ private JComboBox location; /** * "activity" label */ private JLabel activityLabel; /** * "cost" label */ private JLabel costLabel; /** * "duration" label */ private JLabel durationLabel; /** * "dutyCycle" label */ private JLabel dutyCycleLabel; /** * "energy" label */ private JLabel energyLabel; /** * "kwh" label */ private JLabel kwhLabel; /** * "location" label */ private JLabel locationLabel; /** * Reddy Kilowatt logo */ private JLabel logo; // will have a setIcon /** * "megajoules" label */ private JLabel megajoulesLabel; /** * "power" label */ private JLabel powerLabel; /** * name of app */ private JLabel title; /** * build and version */ private JLabel title2; /** * "watts" label */ private JLabel wattsLabel; /** * where cost result displayed */ private JTextField cost; /** * display duration of the activity */ private JTextField duration; /** * display duty cycle in % */ private JTextField dutyCycle; /** * display instructions for use */ private JTextField instructions; /** * display energy consumed in kwh */ private JTextField kwh; /** * display energy consumed kwh */ private JTextField megajoules; /** * display power in watts */ private JTextField watts; /** * code for the user's currency e.g.USD CAD */ private String userCurrAbbr; /** * read the resource containing country->currency and exchange rates */ private static void fetchCurrencyInfo() { try { // O P E N // get resources "/com/mindprod/currcon/exchs.ser" final ObjectInputStream ois = EIO.getObjectInputStream( PowCost.class.getResourceAsStream( "exchs.ser" ), 4 * 1024, true ); // R E A D long wasResourceVersion = ( Long ) ois.readObject(); if ( wasResourceVersion != Exch.getSerialVersionUID() ) { throw new IllegalArgumentException( "Wrong version of exchs.ser file. Was:" + wasResourceVersion + " wanted:" + Exch.getSerialVersionUID() ); } // consistency with Geom is not required. final String[] country = ( String[] ) ois.readObject(); final String[] currency = ( String[] ) ois.readObject(); exchs = ( Exch[] ) ois.readObject(); // C L O S E ois.close(); countryToCurr = new HashMap<>( 250 * 130 / 100 ); for ( int i = 0; i < country.length; i++ ) { countryToCurr.put( country[ i ], currency[ i ] ); } } catch ( Exception e ) { err.println( "Missing or damaged exchs.ser " + e + "\n" ); } } /** * Find a given currency abbreviation in the list and return the index of it. * * @param currAbbr 3-letter ISO code for currency * * @return corresponding Exch record or null if not found. */ private static Exch findExchangeInfoForCurrency( String currAbbr ) { assert currAbbr != null && currAbbr.length() == 3 : "malformed currency Abbreviation:" + currAbbr; /* search for currAbbr in list of currencies */ for ( Exch exch : exchs ) { if ( exch.getCurrAbbr().equals( currAbbr ) ) { return exch; } } /* did not find it */ return null; } /** * build all the Swing components. */ private void buildComponents() { contentPane.setBackground( BACKGROUND_FOR_BODY ); title = new JLabel( TITLE_STRING + " " + VERSION_STRING, JLabel.LEFT ); title.setFont( FONT_FOR_TITLE ); title.setForeground( FOREGROUND_FOR_TITLE ); title2 = new JLabel( "released:" + RELEASE_DATE + " build:" + Build.BUILD_NUMBER, JLabel.LEFT ); title2.setFont( FONT_FOR_TITLE2 ); title2.setForeground( FOREGROUND_FOR_TITLE ); activityLabel = new JLabel( "Activity (sorted by cost)" ); activityLabel.setBackground( BACKGROUND_FOR_LABEL ); activityLabel.setFont( FONT_FOR_LABEL_BOLD ); activityLabel.setForeground( FOREGROUND_FOR_LABEL ); costLabel = new JLabel( "C o s t" ); costLabel.setBackground( BACKGROUND_FOR_LABEL ); costLabel.setFont( FONT_FOR_LABEL_BOLD ); costLabel.setForeground( FOREGROUND_FOR_LABEL ); durationLabel = new JLabel( "duration" ); durationLabel.setBackground( BACKGROUND_FOR_LABEL ); durationLabel.setFont( FONT_FOR_LABEL ); durationLabel.setForeground( FOREGROUND_FOR_LABEL ); dutyCycleLabel = new JLabel( "duty cycle" ); dutyCycleLabel.setBackground( BACKGROUND_FOR_LABEL ); dutyCycleLabel.setFont( FONT_FOR_LABEL ); dutyCycleLabel.setForeground( FOREGROUND_FOR_LABEL ); energyLabel = new JLabel( "energy" ); activityLabel.setBackground( BACKGROUND_FOR_LABEL ); energyLabel.setFont( FONT_FOR_LABEL ); energyLabel.setForeground( FOREGROUND_FOR_LABEL ); megajoulesLabel = new JLabel( "megajoules" ); megajoulesLabel.setBackground( BACKGROUND_FOR_LABEL ); megajoulesLabel.setFont( FONT_FOR_LABEL_UNITS ); megajoulesLabel.setForeground( FOREGROUND_FOR_LABEL ); kwhLabel = new JLabel( "kwh" ); kwhLabel.setBackground( BACKGROUND_FOR_LABEL ); kwhLabel.setFont( FONT_FOR_LABEL_UNITS ); kwhLabel.setForeground( FOREGROUND_FOR_LABEL ); locationLabel = new JLabel( "Location", JLabel.LEFT ); locationLabel.setBackground( BACKGROUND_FOR_LABEL ); locationLabel.setFont( FONT_FOR_LABEL_BOLD ); locationLabel.setForeground( FOREGROUND_FOR_LABEL ); logo = new JLabel( "" ); logo.setIcon( LOGO_ICON ); powerLabel = new JLabel( "power" ); powerLabel.setBackground( BACKGROUND_FOR_LABEL ); powerLabel.setFont( FONT_FOR_LABEL ); powerLabel.setForeground( FOREGROUND_FOR_LABEL ); wattsLabel = new JLabel( "watts" ); wattsLabel.setBackground( BACKGROUND_FOR_LABEL ); wattsLabel.setFont( FONT_FOR_LABEL_UNITS ); wattsLabel.setForeground( FOREGROUND_FOR_LABEL ); ActivityItem[] activities = null; try { // O P E N // get resources "/com/mindprod/powcost/activities.ser" // look in jar, on classpath, locally or server as appropriate, will // have package name prepended final ObjectInputStream ois = EIO.getObjectInputStream( PowCost.class.getResourceAsStream( "activities.ser" ), 4 * 1024, true ); // R E A D activities = ( ActivityItem[] ) ois.readObject(); // C L O S E ois.close(); } catch ( Exception e ) { err.println( "Missing activities.ser " + e + "\n" ); } // must be Vector, not ArrayList. JComboBox is legacy. activity = new JComboBox<>( new Vector<>( Arrays.asList( activities ) ) ); activity.setBackground( BACKGROUND_FOR_EDITABLE ); activity.setEditable( true ); activity.setFocusable( true ); activity.setForeground( FOREGROUND_FOR_EDITABLE ); activity.setMaximumSize( activity.getPreferredSize() ); assert activities != null; for ( int i = 0; i < activities.length; i++ ) { if ( activities[ i ].toString().equals( INITIAL_ACTIVITY ) ) { activity.setSelectedIndex( i ); break; } } activity.setToolTipText( "Select an activity to find out its cost in your region." ); cost = new JTextField( 20 ); cost.setBackground( BACKGROUND_FOR_RESULT_DARK ); cost.setEditable( false ); cost.setFocusable( false ); cost.setForeground( FOREGROUND_FOR_RESULT_DARK ); cost.setHorizontalAlignment( JTextField.RIGHT ); duration = new JTextField( 20 ); duration.setBackground( BACKGROUND_FOR_RESULT_PALE ); duration.setEditable( false ); duration.setFocusable( false ); duration.setForeground( FOREGROUND_FOR_RESULT_PALE ); duration.setHorizontalAlignment( JTextField.RIGHT ); dutyCycle = new JTextField( 20 ); dutyCycle.setBackground( BACKGROUND_FOR_RESULT_PALE ); dutyCycle.setEditable( false ); dutyCycle.setFocusable( false ); dutyCycle.setForeground( FOREGROUND_FOR_RESULT_PALE ); dutyCycle.setHorizontalAlignment( JTextField.RIGHT ); megajoules = new JTextField( 20 ); megajoules.setBackground( BACKGROUND_FOR_RESULT_MEDIUM ); megajoules.setEditable( false ); megajoules.setFocusable( false ); megajoules.setForeground( FOREGROUND_FOR_RESULT_MEDIUM ); megajoules.setHorizontalAlignment( JTextField.RIGHT ); kwh = new JTextField( 20 ); kwh.setBackground( BACKGROUND_FOR_RESULT_MEDIUM ); kwh.setEditable( false ); kwh.setFocusable( false ); kwh.setForeground( FOREGROUND_FOR_RESULT_MEDIUM ); kwh.setHorizontalAlignment( JTextField.RIGHT ); CostLocItem[] costs = null; try { // O P E N // get resources "/com/mindprod/powcost/costs.ser" // look in jar, on classpath, locally or server as appropriate, will // have package name prepended final ObjectInputStream ois = EIO.getObjectInputStream( PowCost.class.getResourceAsStream( "costs.ser" ), 4 * 1024, true ); // R E A D costs = ( CostLocItem[] ) ois.readObject(); // C L O S E ois.close(); } catch ( Exception e ) { err.println( "Missing costs.ser " + e + "\n" ); } // must be Vector, not ArrayList. JComboBox is legacy. location = new JComboBox<>( new Vector<>( Arrays.asList( costs ) ) ); location.setBackground( BACKGROUND_FOR_EDITABLE ); location.setEditable( true ); location.setFocusable( true ); location.setForeground( FOREGROUND_FOR_EDITABLE ); location.setMaximumSize( location.getPreferredSize() ); assert costs != null; for ( int i = 0; i < costs.length; i++ ) { if ( costs[ i ].toString().equals( INITIAL_LOCATION ) ) { location.setSelectedIndex( i ); break; } } location.setToolTipText( "Select your location since electricity prices vary wildly by region." ); watts = new JTextField( 20 ); watts.setBackground( BACKGROUND_FOR_RESULT_PALE ); watts.setEditable( false ); watts.setFocusable( false ); watts.setForeground( FOREGROUND_FOR_RESULT_PALE ); watts.setHorizontalAlignment( JTextField.RIGHT ); instructions = new JTextField( "Select a location, then an electricity-using activity to find out how much that activity will cost " + "in your local currency." ); instructions.setBackground( BACKGROUND_FOR_INSTRUCTIONS ); instructions.setEditable( false ); instructions.setFocusable( false ); instructions.setFont( FONT_FOR_INSTRUCTIONS ); instructions.setForeground( FOREGROUND_FOR_INSTRUCTIONS ); instructions.setMargin( new Insets( 2, 2, 2, 2 ) ); } /** * build a menu with Look & Feel and About across the top */ private void buildMenu() { // turn on anti-alias System.setProperty( "swing.aatext", "true" ); final JMenuBar menubar = new JMenuBar(); setJMenuBar( menubar ); final JMenu lafMenu = Laf.buildLookAndFeelMenu(); if ( lafMenu != null ) { menubar.add( lafMenu ); } 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( Misc.getParentFrame( PowCost.this ), TITLE_STRING, VERSION_STRING, "Calculates cost of electric watts for various activities", "", "freeware", RELEASE_DATE, FIRST_COPYRIGHT_YEAR, "Roedy Green", "POWCOST", "1.8" ); } } ); } /** * when user selects different options, recompute the cost. */ private void calcCost() { /* get selected info from the selected activity and cost/location */ final ActivityItem activityChoice = ( ActivityItem ) activity.getSelectedItem(); final double powerInWatts = activityChoice.getWatts(); final double dutyCycleInPercent = activityChoice.getDutyCycle(); final double seconds = activityChoice.getSeconds(); final CostLocItem costChoice = ( CostLocItem ) location.getSelectedItem(); final String currencyAbbrForLocation = costChoice.getCurrencyAbbr(); final Exch locationExch = findExchangeInfoForCurrency( currencyAbbrForLocation ); if ( locationExch == null ) { throw new IllegalArgumentException( "No exchange rate defined for " + currencyAbbrForLocation ); } int decimalPlaces = userExch.getDecimalPlaces(); // In Swing we can render pretty well any symbol, so we don't meddle with it as we do in CurrCon final String currencySymbol = userExch.getSymbol(); final double costPerKwh = costChoice.getCostPerKwh(); /* calculate */ final double energyInKwh = ( powerInWatts * seconds * dutyCycleInPercent ) / ( double ) ( 60 * 60 * 1000 * 100 ); // div 1000 convert watts to kwatts // div 60 * 60 convert seconds to hours. // div 100 to convert percent to ratio // the more the location currency is worth, the higher the cost. // the lower the users currency is worth, the higher the cost. double exchangeAdjust = locationExch.getExchangeRate() / userExch.getExchangeRate(); final double costOfActivity = energyInKwh * costPerKwh * exchangeAdjust; final double energyInMJ = energyInKwh * MJ_PER_KWH; if ( DEBUGGING ) { out.println( "powerInWatts:" + powerInWatts + " dutyCycle:" + dutyCycleInPercent + " costPerKwh:" + costPerKwh + " seconds:" + seconds + " energyInKwh:" + energyInKwh + " costPerKwh:" + costPerKwh + " exchangeAdjust:" + exchangeAdjust + " costOfActivity:" + costOfActivity ); } /* display calculations */ watts.setText( df[ powerInWatts < 10 ? 1 : 0 ].format( powerInWatts ) ); dutyCycle.setText( df[ 0 ].format( dutyCycleInPercent ) + '%' ); duration.setText( activityChoice.getDuration() ); kwh.setText( df[ 2 ].format( energyInKwh ) ); megajoules.setText( df[ 2 ].format( energyInMJ ) ); if ( costOfActivity > 0 ) { // if less than a penny, show an extra decimal place, and analogously for other currencies final int decade = ( int ) Math.floor( Math.log10( costOfActivity ) ); decimalPlaces = Math.min( Math.max( decimalPlaces, -decade ), decimalPlaces + 3 ); } assert ( 0 <= decimalPlaces && decimalPlaces <= 6 ) : "too many decimal places requested. Problem in currency" + " configuration file."; cost.setText( currencySymbol + df[ decimalPlaces ].format( costOfActivity ) + " " + userCurrAbbr ); } /** * guess at user's preferred viewing currency based on his country locale * Calculates both userCurrCode and userExch */ private void guessUserCurrency() { try { String countryAbbr = Locale.getDefault().getCountry(); userCurrAbbr = countryToCurr.get( countryAbbr ); userExch = findExchangeInfoForCurrency( userCurrAbbr ); } catch ( Exception e ) { userExch = null; } if ( userExch == null ) { /* user in a country for which we have no exchange rate data */ /* Show him US$ */ userCurrAbbr = "USD"; userExch = findExchangeInfoForCurrency( userCurrAbbr ); } } /** * hook up the listeners */ private void hookListeners() { location.addItemListener( new ItemListener() { /** * Notice any change to one of the list box selectors. * @param e details of just what the user clicked. */ public void itemStateChanged( ItemEvent e ) { calcCost(); } } ); activity.addItemListener( new ItemListener() { /** * Notice any change to one of the list box selectors. * @param e details of just what the user clicked. */ public void itemStateChanged( ItemEvent e ) { calcCost(); } } ); } /** * layout fields in GridBag */ private void layoutComponents() { contentPane.setLayout( new GridBagLayout() ); // _____ 0________1______2___________3 ________4____5___6___ // 0 Title---------------- ------title2------- --logo-- 0 // 1 ~location------ ~activity-------- -- -"---- 1 // 2 location------ activity-------------------- 2 // 3 ~duty ~power ~duration ~energy ~cost 3 // 4 duty watts ~watts duration kwh ~kwh cost 4 // 5 mj ~mj 5 // 6 instructions----------------------------------------- 6 // // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( title, new GridBagConstraints( 0, 0, 3, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 20, 10, 5, 5 ), // top, left, bottom, right 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( title2, new GridBagConstraints( 3, 0, 2, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 20, 5, 5, 5 ), // top, left, bottom, right 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( locationLabel, new GridBagConstraints( 0, 1, 2, 1, 0.0, 0.0, GridBagConstraints.SOUTHWEST, GridBagConstraints.NONE, new Insets( 5, 10, 5, 5 ), // top, left, bottom, right 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( activityLabel, new GridBagConstraints( 3, 1, 1, 1, 0.0, 0.0, GridBagConstraints.SOUTHWEST, GridBagConstraints.NONE, new Insets( 5, 5, 5, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( logo, new GridBagConstraints( 5, 0, 2, 2, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets( 10, 5, 5, 10 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( location, new GridBagConstraints( 0, 2, 2, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 5, 10, 5, 5 ), 5, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( activity, new GridBagConstraints( 3, 2, 4, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 5, 5, 5, 10 ), 5, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( dutyCycleLabel, new GridBagConstraints( 0, 3, 1, 1, 0.0, 0.0, GridBagConstraints.SOUTHEAST, GridBagConstraints.NONE, new Insets( 10, 10, 5, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( powerLabel, new GridBagConstraints( 1, 3, 1, 1, 0.0, 0.0, GridBagConstraints.SOUTHEAST, GridBagConstraints.NONE, new Insets( 10, 5, 5, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( durationLabel, new GridBagConstraints( 3, 3, 1, 1, 0.0, 0.0, GridBagConstraints.SOUTHEAST, GridBagConstraints.NONE, new Insets( 10, 5, 5, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( energyLabel, new GridBagConstraints( 4, 3, 1, 1, 0.0, 0.0, GridBagConstraints.SOUTHEAST, GridBagConstraints.NONE, new Insets( 10, 5, 5, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( costLabel, new GridBagConstraints( 6, 3, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets( 10, 5, 5, 10 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( dutyCycle, new GridBagConstraints( 0, 4, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets( 5, 10, 5, 5 ), 60, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( watts, new GridBagConstraints( 1, 4, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets( 5, 5, 5, 2 ), 60, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( wattsLabel, new GridBagConstraints( 2, 4, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 5, 0, 5, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( duration, new GridBagConstraints( 3, 4, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 5, 5, 5, 5 ), 110, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( kwh, new GridBagConstraints( 4, 4, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 5, 5, 5, 2 ), 75, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( kwhLabel, new GridBagConstraints( 5, 4, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 5, 0, 5, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( cost, new GridBagConstraints( 6, 4, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets( 5, 5, 5, 10 ), 100, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( megajoules, new GridBagConstraints( 4, 5, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 5, 5, 5, 2 ), 75, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( megajoulesLabel, new GridBagConstraints( 5, 5, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 5, 0, 5, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( instructions, new GridBagConstraints( 0, 6, 7, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.BOTH, 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 PowCost(), 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. */ @Override public void destroy() { activity = null; activityLabel = null; contentPane = null; cost = null; costLabel = null; duration = null; durationLabel = null; dutyCycle = null; dutyCycleLabel = null; energyLabel = null; instructions = null; kwh = null; kwhLabel = null; location = null; locationLabel = null; logo = null; megajoules = null; megajoulesLabel = null; powerLabel = null; userExch = null; title2 = null; title = null; userCurrAbbr = null; watts = null; wattsLabel = null; } /** * Called by the browser or Applet viewer to inform * this Applet that it has been loaded into the system. */ @Override public void init() { contentPane = getContentPane(); if ( !VersionCheck.isJavaVersionOK( 1, 7, 0, contentPane ) ) { // abort stop(); destroy(); } buildMenu(); // also initial L&F buildComponents(); layoutComponents(); hookListeners(); guessUserCurrency(); calcCost(); this.validate(); this.setVisible( true ); } }