/* * [AmericanTax.java] * * Summary: American State and County Sales Tax Calculator. * * Copyright: (c) 1999-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 1999-08-31 cloned from CanadianTaxCalculator. * 1.1 1999-09-01 getStateChoices - District taxes for CA, * CO, NY * 1.2 1999-09-01 ensure DistrictItem.class is included in * jar. * 1.3 1999-09-05 tax depends on buyer's district, not * vendor's - add report errors line - document missing local taxes. * 1.4 2000-05-05 NM 5.0000 -> allow 4 digits to right of * decimal version * 1.5 2001-01-01 * 1.6 2002-04-23 moved to package com.mindprod.americantax * version * 1.7 2004-06-06 add about box and version check - renamed class * to AmericanTax and AmericanTaxTable. * 1.8 2005-12-16 add Javadoc * 1.9 2006-03-04 reformat with IntelliJ. Distribute Javadoc. * 2.0 2007-06-07 convert to JDK 1.5/Swing, add * spinner, add PAD, icon. Update and extend tax tables. * 2.1 2007-06-09 add FL and TX tables. * 2.2 2007-06-16 convert to JApplet and contentpane. * 2.3 2008-03-03 correct spelling mistakes, display build and release date. * 2.4 2008-05-18 display state and district taxes separately. Update tax tables. * Major redesign. All reverse tax calculation to got from total payable back to sale amount. * 2.5 2008-05-22 complete tables for AK, AL, CA, CO, CT, DC, DE, FL, GA, HI, IL, IN, KY, * MA, MD, ME, MI, MN, MS, MT, NH, NJ, NY, OH, OR, PA, RI, TX, VA, VT, WA, WV. * 2.6 2008-06-01 add TN support for counties and cities. * 2.7 2008-06-01 add WI support for counties. * 2.8 2008-06-01 add AZ support for counties and cities * 2.9 2010-05-10 update state tax tables, better rounding, massive refactoring. * 3.0 2010-12-08 update Alabama and Tennessee tax tables. * 3.1 2010-12-09 update California, Georgia, Illinois, Missouri and North Carolina tax tables. * 3.2 2010-12-11 updated Arizona, Colorado, Hawaii, Iowa, Ohio, Texas, Washington, Wisconsin tax tables. * 3.3 2010-12-12 updated Florida, Louisiana, New York, Wyoming. New streamlined PrepStateBase skeleton. * 3.4 2010-12-14 updated Arkansas, Kansas, South Carolina, Oklahoma. * 3.5 2010-12-15 updated Nebraska, Nevada, North Dakota, Utah * 3.6 2010-12-17 updated Alabama. Can look up city without needing to know county. * 3.7 2010-12-18 updated South Dakota, Minnesota, New Mexico * 3.8 2010-12-19 update Idaho, Vermont * 3.9 2013-04-01 update tables for Alabama, Arkansis and Arizona. * 4.0 2013-04-03 update tables for California, Florida, Georgia * 4.1 2013-04-04 update tables for Idaho, Illinois, Iowa. */ package com.mindprod.americantax; import com.mindprod.common18.Build; 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 com.mindprod.fastcat.FastCat; import com.mindprod.spinner.DollarNumberFormatter; import javax.swing.DefaultComboBoxModel; import javax.swing.JApplet; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JEditorPane; import javax.swing.JLabel; import javax.swing.JSpinner; import javax.swing.JTextField; import javax.swing.SpinnerNumberModel; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; 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.text.DecimalFormat; import java.text.ParseException; import static java.lang.System.*; /** * American State and County Sales Tax Calculator. *

* AmericanTax.java is the GUI shell portion, AmericanTaxTable.java are the driving tables. *

* * @author Roedy Green, Canadian Mind Products * @version 4.1 2013-04-04 update tables for Idaho, Illinois, Iowa. * @noinspection FieldCanBeLocal * @since 1999-08-31 */ public final class AmericanTax extends JApplet { /** * true if debugging * * @noinspection UnusedDeclaration */ static final boolean DEBUGGING = false; /** * height of Applet box in pixels. Does not include surrounding frame. */ private static final int APPLET_HEIGHT = 552; /** * Width of Applet box in pixels. */ private static final int APPLET_WIDTH = 756; private static final int FIRST_COPYRIGHT_YEAR = 1999; /** * California, most populous state */ private static final String DEFAULT_VENDOR_STATE = "CA"; /** * undisplayed copyright notice */ @SuppressWarnings( { "UnusedDeclaration" } ) private static final String EMBEDDED_COPYRIGHT = "Copyright: (c) 1999-2017 Roedy Green, Canadian Mind Products, http://mindprod.com"; private static final String RELEASE_DATE = "2013-04-04"; private static final String TITLE_STRING = "American Sales Tax Calculator"; private static final String VERSION_STRING = "4.1"; /** * background where for data entry where user enters a value. */ private static final Color BACKGROUND_FOR_EDITABLE = Color.WHITE; /** * darker green resultColor background, don't enter data here. */ private static final Color BACKGROUND_FOR_RESULT_DARK = new Color( 0x9fffd4 ); /** * medium green resultColor background, don't enter data here. */ private static final Color BACKGROUND_FOR_RESULT_MEDIUM = new Color( 0xafffe4 ); /** * pale green resultColor background, don't enter data here. */ private static final Color BACKGROUND_FOR_RESULT_PALE = new Color( 0xf6fff6 ); private static final Color BLACK = Color.BLACK; private static final Color DARK_GREEN = new Color( 0x008000 ); /** * data entry text field colour */ private static final Color FOREGROUND_FOR_ENTER = Color.BLACK; private static final Color FOREGROUND_FOR_LABEL = new Color( 0x0000b0 ); /** * for titles */ private static final Color FOREGROUND_FOR_TITLE = new Color( 0xdc143c ); private static final Color WHITE = Color.WHITE; /** * format for display and input of sale amount */ private static final DecimalFormat DOLLARFORMAT = new DecimalFormat( "'$'###,###,###,###,##0.00" ); private static final Font FONT_FOR_LABELS = FontFactory.build( "Dialog", Font.BOLD, 15 ); /** * 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 ); /** * about */ private JButton about; /** * calc ^ reverse calc */ private JButton calcSaleAmountButton; /** * calc v */ private JButton calcTotalPayableButton; /** * district within state where buyer lives */ private JComboBox buyerDistrict; /** * state in USA where buyer lives */ private JComboBox buyerState; /** * instructions for use */ private JEditorPane instructions; /** * label for buyer's district */ private JLabel buyerDistrictLabel; /** * label for buyer's state */ private JLabel buyerStateLabel; /** * label ford district sales tax */ private JLabel districtSalesTaxLabel; /** * please report problems instructions */ private JLabel report; /** * amount of the sale in US$ */ private JLabel saleAmountLabel; /** * label for state sales tax */ private JLabel stateSalesTaxLabel; /** * title */ private JLabel title; /** * title, second line */ private JLabel title2; /** * label for totalPayable */ private JLabel totalPayableLabel; /** * label for total state+ district sales tax */ private JLabel totalSalesTaxLabel; /** * formats output of saleAmount spinner. */ private JSpinner.NumberEditor saleAmountNumberEditor; /** * dollar amount of sale with a spinner to increment/decrement by pennies * setValue ( double ); (Double) getValue. */ private JSpinner saleAmountSpinner; /** * total district sales tax payable */ private JTextField districtSalesTaxText; /** * total state sales tax payable */ private JTextField stateSalesTaxText; /** * total amount payable. */ private JTextField totalPayableText; /** * total sales tax payable */ private JTextField totalSalesTaxText; /** * tracks value of the sale amount spinner. */ private SpinnerNumberModel saleAmountSpinnerModel; /** * convert long pennies to string with decorative decimal point. e.g. 1.00 -> $1.00 5 -> $0.05 -90000.00 -> * -$90,000.00 * * @param amount value to be converted. * @param bz true for blank if zero * * @return String showing pennies as a dollar value */ private static String toDollar( double amount, boolean bz ) { if ( bz && amount == 0 ) { return ""; } else { return DOLLARFORMAT.format( amount ); } } // end toDollar /** * starting from totalPayable, work backwards to sale amount. */ private void calcAndDisplaySaleAmount() { final DistrictItem districtItem = ( DistrictItem ) buyerDistrict.getSelectedItem(); final String totalPayableString = totalPayableText.getText(); // fancy parse that ignores $ double totalPayable; try { totalPayable = ( Double ) new DollarNumberFormatter().stringToValue( totalPayableString ); } catch ( ParseException event ) { totalPayable = 0; } // will already be rounded. final double saleAmount = AmericanTaxTable.calcSaleAmount( districtItem, totalPayable ); saleAmountSpinner.setValue( saleAmount ); } /** * Calculate and display SalesTaxt based on current screen values */ private void calcAndDisplayTaxes() { // find out values on screen double saleAmount = saleAmountSpinnerModel.getNumber().doubleValue(); // Don't need stateItem since all is encapsulated in DistrictItem // StateItem stateItem = (StateItem) buyerState.getSelectedItem(); DistrictItem districtItem = ( DistrictItem ) buyerDistrict.getSelectedItem(); // calculate tax components and totals. double stateSalesTaxAmount = AmericanTaxTable.calcStateSalesTax( districtItem, saleAmount ); double districtSalesTaxAmount = AmericanTaxTable.calcDistrictSalesTax( districtItem, saleAmount ); double totalSalesTaxAmount = AmericanTaxTable.calcTotalSalesTax( districtItem, saleAmount ); double totalPayableAmount = AmericanTaxTable.calcTotalPayable( districtItem, saleAmount ); // display results stateSalesTaxText.setText( toDollar( stateSalesTaxAmount, true/* bz */ ) ); districtSalesTaxText.setText( toDollar( districtSalesTaxAmount, true/* bz */ ) ); totalSalesTaxText.setText( toDollar( totalSalesTaxAmount, true/* bz */ ) ); totalPayableText.setText( toDollar( totalPayableAmount, false ) ); } // end calcAndDisplayTaxes /** * create all the Swing Components */ private void createComponents() { title = new JLabel( TITLE_STRING + " " + VERSION_STRING ); title.setFont( FONT_FOR_TITLE ); title.setForeground( FOREGROUND_FOR_TITLE ); title2 = new JLabel( "released:" + RELEASE_DATE + " build:" + Build.BUILD_NUMBER ); title2.setFont( FONT_FOR_TITLE2 ); title2.setForeground( FOREGROUND_FOR_TITLE ); about = new JEButton( "About" ); about.setToolTipText( "About " + TITLE_STRING + " " + VERSION_STRING ); /* use array of StateItems, not just state names */ buyerState = new JComboBox<>( StateItem.getStateChoices() ); // Start display off at something interesting: buyerState.setSelectedItem( StateItem.findStateItem( DEFAULT_VENDOR_STATE ) ); buyerStateLabel = new JLabel( "Buyer's State", JLabel.RIGHT ); buyerStateLabel.setFont( FONT_FOR_LABELS ); buyerStateLabel.setForeground( FOREGROUND_FOR_LABEL ); buyerDistrict = new JComboBox<>( StateItem.findStateItem( DEFAULT_VENDOR_STATE ).getDistrictItems () ); // leave default at first one. buyerDistrictLabel = new JLabel( "Buyer's District", JLabel.RIGHT ); buyerDistrictLabel.setFont( FONT_FOR_LABELS ); buyerDistrictLabel.setForeground( FOREGROUND_FOR_LABEL ); saleAmountSpinner = new JSpinner(); saleAmountSpinner.setFont( FONT_FOR_LABELS ); saleAmountSpinner.setForeground( FOREGROUND_FOR_ENTER ); saleAmountSpinner.setBackground( BACKGROUND_FOR_EDITABLE ); saleAmountSpinner.setValue( 100.00 ); saleAmountSpinnerModel = new SpinnerNumberModel( /* initial value */ 100.00d, /* min */ 0.00d, /* max */ 999999.99d, /* step */ 0.01d ); // wants a String, not a DecimalFormat. saleAmountNumberEditor = new JSpinner.NumberEditor( saleAmountSpinner, "'$'###,###,##0.00" ); saleAmountSpinner.setModel( saleAmountSpinnerModel ); saleAmountSpinner.setEditor( saleAmountNumberEditor ); saleAmountLabel = new JLabel( "Amount of Sale", JLabel.RIGHT ); saleAmountLabel.setFont( FONT_FOR_LABELS ); saleAmountLabel.setForeground( FOREGROUND_FOR_LABEL ); final boolean usingMac = System.getProperty( "os.name" ).equals( "Mac OS X" ); // prefer double to single arrow, must use single arrow on some Macs final char downArrow = usingMac ? '\u2193' : '\u21d3'; final char upArrow = usingMac ? '\u2191' : '\u21d1'; calcTotalPayableButton = new JEButton( "Calc " + downArrow ); calcTotalPayableButton.setToolTipText( "Calculate sales tax" ); calcSaleAmountButton = new JEButton( "Calc " + upArrow ); calcSaleAmountButton.setToolTipText( "Reverse calculate sale amount" ); stateSalesTaxLabel = new JLabel( "State Sales Tax", JLabel.RIGHT ); stateSalesTaxLabel.setFont( FONT_FOR_LABELS ); stateSalesTaxLabel.setForeground( FOREGROUND_FOR_LABEL ); stateSalesTaxText = new JTextField( "", 16 ); stateSalesTaxText.setEditable( false ); stateSalesTaxText.setFont( FONT_FOR_LABELS ); stateSalesTaxText.setForeground( BLACK ); stateSalesTaxText.setBackground( BACKGROUND_FOR_RESULT_PALE ); stateSalesTaxText.setHorizontalAlignment( JTextField.RIGHT ); districtSalesTaxLabel = new JLabel( "District Sales Tax", JLabel.RIGHT ); districtSalesTaxLabel.setFont( FONT_FOR_LABELS ); districtSalesTaxLabel.setForeground( FOREGROUND_FOR_LABEL ); districtSalesTaxText = new JTextField( "", 16 ); districtSalesTaxText.setEditable( false ); districtSalesTaxText.setFont( FONT_FOR_LABELS ); districtSalesTaxText.setForeground( BLACK ); districtSalesTaxText.setBackground( BACKGROUND_FOR_RESULT_PALE ); districtSalesTaxText.setHorizontalAlignment( JTextField.RIGHT ); totalSalesTaxLabel = new JLabel( "Total sales Tax", JLabel.RIGHT ); totalSalesTaxLabel.setFont( FONT_FOR_LABELS ); totalSalesTaxLabel.setForeground( FOREGROUND_FOR_LABEL ); totalSalesTaxText = new JTextField( "", 16 ); totalSalesTaxText.setEditable( false ); totalSalesTaxText.setFont( FONT_FOR_LABELS ); totalSalesTaxText.setForeground( BLACK ); totalSalesTaxText.setBackground( BACKGROUND_FOR_RESULT_MEDIUM ); totalSalesTaxText.setHorizontalAlignment( JTextField.RIGHT ); totalPayableLabel = new JLabel( "Total Payable", JLabel.RIGHT ); totalPayableLabel.setFont( FONT_FOR_LABELS ); totalPayableLabel.setForeground( FOREGROUND_FOR_LABEL ); totalPayableText = new JTextField( "", 16 ); totalPayableText.setEditable( true ); totalPayableText.setFont( FONT_FOR_LABELS ); totalPayableText.setForeground( BLACK ); totalPayableText.setBackground( BACKGROUND_FOR_RESULT_DARK ); totalPayableText.setHorizontalAlignment( JTextField.RIGHT ); // cannot use any css, HTML 3.2 only final FastCat sb = new FastCat( 15 ); sb.append( "" ); sb.append( "" ); sb.append( "Select buyer's state/district, then either:" ); sb.append( "

" ); sb.append( "" ); final String instructionsHTML = sb.toString(); instructions = new JEditorPane(); instructions.setContentType( "text/html" ); instructions.setEditable( false ); instructions.setMargin( new Insets( 5, 5, 5, 5 ) ); try { instructions.setText( instructionsHTML ); } catch ( Exception e ) { err.println( "Because of Sun bug, unable to display instructions, please exit browser and restart" ); e.printStackTrace( err ); err.println( instructionsHTML ); } report = new JLabel( "Please report tax changes, errors and omissions to roedyg@mindprod.com." ); report.setForeground( DARK_GREEN ); } /** * hook up the listeners */ private void hookListeners() { // engage the listeners about.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { // open aboutbox frame new CMPAboutJBox( TITLE_STRING, VERSION_STRING, "Calculates American state sales taxes", "and some regional sales taxes.", "freeware", RELEASE_DATE, FIRST_COPYRIGHT_YEAR, "Roedy Green", "AMERICANTAX", "1.8" ); } } ); TheListener theListener = new TheListener(); calcTotalPayableButton.addActionListener( theListener ); buyerState.addItemListener( theListener ); buyerDistrict.addItemListener( theListener ); saleAmountSpinnerModel.addChangeListener( theListener ); saleAmountSpinner.addChangeListener( theListener ); calcSaleAmountButton.addActionListener( new ActionListener() { /** * user clicked calc ^ * @param e button push event */ public void actionPerformed( ActionEvent e ) { // work backwards then forward again calcAndDisplaySaleAmount(); calcAndDisplayTaxes(); } // end actionPerformed } ); } /** * layout the components * * @param contentPane where to add components */ private void layoutGridBag( Container contentPane ) { // basic layout: // 0-----0--------- -- 1------- ----- 2 ------ ----3----- // 0 -----------TITLE------------------------ -----about // 1 ---------- title2 ---------------------- // 2 buyerState district----------------- // 3 buyerStateLabel districtlabel // 4 --------- saleAmountLabel saleAmount ---calc // 5 ------- stateSalesTaxLabel stateSalesTax // 6 ------ districtsaleTaxLabel dictrictSalesTax // 7 ------ totalSalesTaxLabel totalSalesTax // 8 ------ totalPayableLabel totalPayable --calc^ // 9 -----instructions--------------------- // 10 -----report--------------------------- // 0-----0--------- -- 1------- ----- 2 ------ ----3----- // 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( 15, 15, 0, 5 ), 0, 0 ) ); contentPane.add( title2, new GridBagConstraints( 0, 1, 3, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 0, 15, 5, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( about, new GridBagConstraints( 3, 0, 1, 2, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets( 15, 5, 5, 15 ), 10, 2 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( buyerState, new GridBagConstraints( 0, 2, 1, 1, 20.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets( 5, 15, 5, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( buyerStateLabel, new GridBagConstraints( 0, 3, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 0, 15, 5, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( buyerDistrict, new GridBagConstraints( 1, 2, 2, 1, 50.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets( 5, 5, 5, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( buyerDistrictLabel, new GridBagConstraints( 1, 3, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 0, 5, 5, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( saleAmountLabel, new GridBagConstraints( 1, 4, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, 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( saleAmountSpinner, new GridBagConstraints( 2, 4, 1, 1, 30.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL, new Insets( 5, 5, 5, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( calcTotalPayableButton, new GridBagConstraints( 3, 4, 1, 1, 0.0, 0.0, GridBagConstraints.SOUTHEAST, GridBagConstraints.NONE, new Insets( 5, 5, 5, 15 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( stateSalesTaxLabel, new GridBagConstraints( 1, 5, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, 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( stateSalesTaxText, new GridBagConstraints( 2, 5, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL, new Insets( 5, 5, 5, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( districtSalesTaxLabel, new GridBagConstraints( 1, 6, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, 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( districtSalesTaxText, new GridBagConstraints( 2, 6, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL, new Insets( 5, 5, 5, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( totalSalesTaxLabel, new GridBagConstraints( 1, 7, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, 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( totalSalesTaxText, new GridBagConstraints( 2, 7, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL, new Insets( 5, 5, 5, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( totalPayableLabel, new GridBagConstraints( 1, 8, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, 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( totalPayableText, new GridBagConstraints( 2, 8, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL, new Insets( 5, 5, 5, 5 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( calcSaleAmountButton, new GridBagConstraints( 3, 8, 1, 1, 0.0, 0.0, GridBagConstraints.SOUTHEAST, GridBagConstraints.NONE, new Insets( 5, 5, 5, 15 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( instructions, new GridBagConstraints( 0, 9, 4, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets( 5, 15, 5, 15 ), 0, 0 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( report, new GridBagConstraints( 0, 10, 4, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets( 5, 15, 15, 15 ), 0, 0 ) ); } /** * refresh District Choice possibilities on screen based on the buyer state */ private void setDistrictChoices() { buyerDistrict.setModel( new DefaultComboBoxModel<>( ( ( StateItem ) buyerState .getSelectedItem() ).getDistrictItems() ) ); } // end setDistrictChoices /** * 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 AmericanTax(), 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() { about = null; buyerDistrict = null; buyerDistrictLabel = null; buyerState = null; buyerStateLabel = null; calcSaleAmountButton = null; calcTotalPayableButton = null; districtSalesTaxLabel = null; districtSalesTaxText = null; instructions = null; report = null; saleAmountLabel = null; saleAmountNumberEditor = null; saleAmountSpinner = null; saleAmountSpinnerModel = null; stateSalesTaxLabel = null; stateSalesTaxText = null; title = null; title2 = null; totalPayableLabel = null; totalPayableText = null; totalSalesTaxLabel = null; totalSalesTaxText = 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(); StateItem.load(); Container contentPane = this.getContentPane(); contentPane.setBackground( WHITE ); contentPane.setLayout( new GridBagLayout() ); createComponents(); // add legal choices to boxes setDistrictChoices(); calcAndDisplayTaxes(); layoutGridBag( contentPane ); hookListeners(); this.validate(); this.setVisible( true ); } // end init /** * Inner class to act as listener to respond to all end-user actions. */ private final class TheListener implements ItemListener, ActionListener, ChangeListener { /** * user clicked calc * * @param e button push event */ public void actionPerformed( ActionEvent e ) { final Object object = e.getSource(); if ( object == calcTotalPayableButton ) { calcAndDisplayTaxes(); } } // end actionPerformed /** * Notice any change to one of the list box selectors. * * @param e details of just what the user clicked. */ public void itemStateChanged( ItemEvent e ) { final Object object = e.getSource(); if ( object == buyerState ) { setDistrictChoices(); calcAndDisplayTaxes(); } else if ( object == buyerDistrict ) { calcAndDisplayTaxes(); } } // end itemStateChanged /** * spinner changed value * * @param e event from spinner */ public void stateChanged( ChangeEvent e ) { final Object object = e.getSource(); if ( object == saleAmountSpinnerModel ) { calcAndDisplayTaxes(); } } // end actionPerformed } // end TheListener }