/*
* [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 );
}
}