IRS Form 1040

Like a cross between a lonely golden retriever and a hungry pit bull, this old dog is probably not a welcome sight. But it provides lots of challenges for FormLayout, and demonstrates many of its weaknesses. Notice how close the separator is from the field in line 7, the text boxes on the right of the "Exemptions" section don't easily line up with the multi-line labels, and the "Presidential Election Campaign" label in the lower left corner of the first section is floating awkwardly. FormLayout is not very flexible with spacing inside the form, unless you resort to using invisible components. The field for 8b is intentionally floating there in the "Income" section, and it appears to be nicely aligned aligned against the left side of the rest of the fields. Actually, this alignment is only circumstantial: the field shares a column with the labels for 15b and 16b ("b Taxable amount (see page 22)"). If these labels were not conveniently marking that column position, field 8b would just be sitting in some aimless location between its label and the main column of fields. None of these faults strike me as a major problem, however, because this sort of alignment is part of the paper worksheet repertoire, and is not necessary for tidy online forms. The truncation below the buttons was caused by a shortage of screen space; this will not occur for sane and reasonable forms. I count 300 lines of code for most of page 1 of the real 1040 form (the last section wouldn't fit on my monitor, and I omitted a few labels because they constitute data validation that would be done automatically).

Panel Construction Code

m_formPanel = new FormPanel(5, 3, 8, 5);
// FormPanel extends JPanel,
// has FormLayout as the default layout manager,
// and exposes all the methods of FormLayout


m_formPanel.addMultiRow(new hLabel("1040", 32), 0, 199, 0);
m_formPanel.add(new hLabel("Department of the Treasury--Internal Revenue Service", 10), 0, 1000);
m_formPanel.addMultiRow(new hLabel("1998", 32), 0, 199, 1200);
m_formPanel.add(new hLabel("U.S. Individual Income Tax Return", 16), 100, 1000);
m_formPanel.add(new hLabel("(L)"), 100, 1000);


m_formPanel.add(new hLabel("For the year Jan. 1-Dec. 31, 1998, or other tax year beginning", 10), new hTextField(6, 10), 300, 1000);
m_formPanel.add(new hLabel(", 1998, ending", 10), new hTextField(6, 10), 300, 1000);
m_formPanel.add(new hLabel(", 19", 10), new hTextField(2, 10), 300, 1000);
m_formPanel.add(new hLabel("OMB No. 1545-0074", 10), 300, 2000);


m_formPanel.add(new hLabel("Your first name and initial", 10), new hTextField(22), 400, 1000, FormLayout.LABEL_ON_TOP);
m_formPanel.add(new hLabel("Last name", 10), new hTextField(22), 400, 1100, FormLayout.LABEL_ON_TOP);
m_formPanel.add(new hLabel("Your social security number", 10), new hTextField(3), 400, 2000, FormLayout.LABEL_ON_TOP);
m_formPanel.add(new hTextField(2), 401, 2000);
m_formPanel.add(new hTextField(4), 401, 2000);


m_formPanel.add(new hLabel("If a joint return, spouse's first name and initial", 10), new hTextField(22), 500, 1000, FormLayout.LABEL_ON_TOP);
m_formPanel.add(new hLabel("Last name", 10), new hTextField(22), 500, 1100, FormLayout.LABEL_ON_TOP);
m_formPanel.add(new hLabel("Spouse's social security number", 10), new hTextField(3), 500, 2000, FormLayout.LABEL_ON_TOP);
m_formPanel.add(new hTextField(2), 501, 2000);
m_formPanel.add(new hTextField(4), 501, 2000);


m_formPanel.add(new hLabel("Home address (number and street). If you have a P.O. box, see page 18.", 10), new hTextField(36), 600, 1000, FormLayout.LABEL_ON_TOP);
m_formPanel.add(new hLabel("Apt. no.", 10), new hTextField(8), 600, 1101, FormLayout.LABEL_ON_TOP);


m_formPanel.addMultiRow(new hLabel("City, town or post office, state, and ZIP code. If you have a foreign address, see page 18.", 10), new hTextField(44), 700, 899, 1000, FormLayout.LABEL_ON_TOP);


m_formPanel.add(new hLabel("Presidential"), 800, 0);
m_formPanel.add(new hLabel("Election Campaign"), 900, 0);
m_formPanel.add(new hLabel("(See page 18.)", 9), 1000, 0);


m_formPanel.add(new hLabel("Yes"), 800, 2000);
m_formPanel.add(new hLabel("No"), 800, 2010);


m_formPanel.add(new hLabel("Do you want $3 to go to this fund?"), 900, 1050);
m_formPanel.add(new JRadioButton(), 900, 2000);
m_formPanel.add(new JRadioButton(), 900, 2010);


m_formPanel.add(new hLabel("If a joint return, does your spouse want $3 to go to this fund?"), 1000, 1050);
m_formPanel.add(new JRadioButton(), 1000, 2000);
m_formPanel.add(new JRadioButton(), 1000, 2010);


FormPanel notePanel = new FormPanel();
notePanel.setLayout(new FormLayout(2, 0, 0, 0));
notePanel.add(new hLabel("Note: Selecting", 10), 0, 0);
notePanel.add(new hLabel("\"Yes\" will not", 10), 1, 0);
notePanel.add(new hLabel("change your tax or", 10), 2, 0);
notePanel.add(new hLabel("reduce your refund.", 10), 3, 0);
m_formPanel.addMultiRow(notePanel, 800, 1099, 2020);


// Filing Status


m_formPanel.addMultiRow(new hLabel("Filing Status", 16), 1250, 1399, 0);
m_formPanel.add(new hLabel(" "), 1300, 999);


m_formPanel.add(new hLabel("1"), 1200, 1000);
m_formPanel.add(new JRadioButton(), 1200, 1050);
m_formPanel.add(new JLabel("Single"), 1200, 1070);


m_formPanel.add(new hLabel("2"), 1300, 1000);
m_formPanel.add(new JRadioButton(), 1300, 1050);
m_formPanel.add(new JLabel("Married filing joint return (even if only one had income)"), 1300, 1070);


m_formPanel.add(new hLabel("3"), 1400, 1000);
m_formPanel.add(new JRadioButton(), 1400, 1050);
m_formPanel.add(new JLabel("Married filing separate return. Enter spouse's social security no. above and full name here."), 1400, 1070);
m_formPanel.add(new hTextField(14,10), 1400, 2001);


m_formPanel.add(new hLabel("4"), 1500, 1000);
m_formPanel.add(new JRadioButton(), 1500, 1050);
m_formPanel.add(new JLabel("Head of household (with qualifying person). (See page 18.) If the qualifying person is a child but not your dependent,"), 1500, 1070);
m_formPanel.add(new JLabel("enter this child's name here."), 1600, 1070);
m_formPanel.add(new hTextField(30,10), 1600, 1070);


m_formPanel.add(new hLabel("5"), 1700, 1000);
m_formPanel.add(new JRadioButton(), 1700, 1050);
m_formPanel.add(new JLabel("Qualifying widow(er) with dependent child (year spouse died 19"), new hTextField(2,10), 1700, 1070);
m_formPanel.add(new JLabel(" ). (See page 18.)"), 1700, 1070);


// Exemptions


m_formPanel.addMultiRow(new hLabel("Exemptions", 16), 1850, 1999, 0);


m_formPanel.add(new hLabel("6"), 1800, 1000);
m_formPanel.add(new hLabel("a"), 1800, 1020);
m_formPanel.add(new JCheckBox(), 1800, 1050);
m_formPanel.add(new hLabel("Yourself."), 1800, 1050);
m_formPanel.add(new hLabel("If your parent (or someone else) can claim you as a dependent on his or her tax"), 1800, 1080);
m_formPanel.add(new hLabel("return, do not check box 6a"), 1900, 1080);


m_formPanel.add(new hLabel("b"), 2000, 1020);
m_formPanel.add(new JCheckBox(), 2000, 1050);
m_formPanel.add(new hLabel("Spouse"), 2000, 1050);


m_formPanel.add(new hLabel("c"), 2100, 1020);
m_formPanel.add(new hLabel("Dependents:"), 2100, 1050);


JTable dependentTable = new JTable(6,1);
dependentTable.getColumn("A").setPreferredWidth(200);
m_formPanel.addMultiRow(dependentTable, 2300, 2399, 1050);


m_formPanel.add(new hLabel("(1) First and last name", 10), 2200, 1050);


FormPanel dependentSSNPanel = new FormPanel(0, 0, 0, 0);
dependentSSNPanel.add(new hLabel("(2) Dependent's", 10), 0, 0);
dependentSSNPanel.add(new hLabel("social security number", 10), 1, 0);
m_formPanel.addMultiRow(dependentSSNPanel, 2100, 2299, 1150);


JTable ssnTable = new JTable(6,3);
ssnTable.getColumn("A").setPreferredWidth(30);
ssnTable.getColumn("B").setPreferredWidth(22);
ssnTable.getColumn("C").setPreferredWidth(42);
m_formPanel.addMultiRow(ssnTable, 2300, 2399, 1150);


FormPanel dependentRelationshipPanel = new FormPanel(0, 0, 0, 0);
dependentRelationshipPanel.add(new hLabel("(3) Dependent's", 10), 0, 0);
dependentRelationshipPanel.add(new hLabel("relationship to", 10), 1, 0);
dependentRelationshipPanel.add(new hLabel("you", 10), 2, 0);
m_formPanel.addMultiRow(dependentRelationshipPanel, 2100, 2299, 1250);


JTable relationshipTable = new JTable(6,1);
relationshipTable.getColumn("A").setPreferredWidth(150);
m_formPanel.addMultiRow(relationshipTable, 2300, 2399, 1250);


FormPanel taxCreditPanel = new FormPanel(0, 0, 0, 0);
taxCreditPanel.add(new hLabel("(4) Child qualifies", 10), 0, 0);
taxCreditPanel.add(new hLabel("for child tax", 10), 1, 0);
taxCreditPanel.add(new hLabel("credit (see page 19)", 10), 2, 0);
m_formPanel.addMultiRow(taxCreditPanel, 2100, 2299, 1350);


JTable creditTable = new JTable(6,1);
creditTable.setDefaultEditor(creditTable.getColumnClass(0), new DefaultCellEditor(new JCheckBox()));
m_formPanel.addMultiRow(creditTable, 2300, 2399, 1350);


m_formPanel.add(new hLabel("d"), 2400, 1020);
m_formPanel.add(new hLabel("Total number of exemptions claimed"), 2400, 1050);


FormPanel sumChecked6Panel = new FormPanel(0,0,0,0);
sumChecked6Panel.add(new hLabel("No. of boxes", 10), 0, 0);
sumChecked6Panel.add(new hLabel("checked on", 10), 1, 0);
sumChecked6Panel.add(new hLabel("6a and 6b", 10), 2, 0);
m_formPanel.addMultiRow(sumChecked6Panel, 1800, 1950, 2101);
m_formPanel.addMultiRow(new JTextField(2), 1800, 1950, 2200);


FormPanel residentChildrenPanel = new FormPanel(0,0,0,0);
residentChildrenPanel.add(new hLabel("No. of your", 10), 0, 0);
residentChildrenPanel.add(new hLabel("children on 6c", 10), 1, 0);
residentChildrenPanel.add(new hLabel("who:", 10), 2, 0);
residentChildrenPanel.add(new hLabel("* lived with you", 10), 3, 0);
m_formPanel.addMultiRow(residentChildrenPanel, 1951, 2200, 2101);
m_formPanel.addMultiRow(new JTextField(2), 2200, 2299, 2200);


FormPanel nonResidentChildrenPanel = new FormPanel(0,0,0,0);
nonResidentChildrenPanel.add(new hLabel("* did not live with", 10), 0, 0);
nonResidentChildrenPanel.add(new hLabel("you due to divorce", 10), 1, 0);
nonResidentChildrenPanel.add(new hLabel("or separation", 10), 2, 0);
nonResidentChildrenPanel.add(new hLabel("(see page 19)", 10), 3, 0);
m_formPanel.addMultiRow(nonResidentChildrenPanel, 2201, 2310, 2101);
m_formPanel.addMultiRow(new JTextField(2), 2300, 2310, 2200);


FormPanel otherDependentsPanel = new FormPanel(0,0,0,0);
otherDependentsPanel.add(new hLabel("Dependents on 6c", 10), 0, 0);
otherDependentsPanel.add(new hLabel("not entered above", 10), 1, 0);
m_formPanel.add(otherDependentsPanel, 2320, 2101);
m_formPanel.add(new JTextField(2), 2320, 2200);


FormPanel exemptionsTotalPanel = new FormPanel(0,0,0,0);
exemptionsTotalPanel.add(new hLabel("Add numbers", 10), 0, 0);
exemptionsTotalPanel.add(new hLabel("entered on", 10), 1, 0);
exemptionsTotalPanel.add(new hLabel("lines above", 10), 2, 0);
m_formPanel.addMultiRow(exemptionsTotalPanel, 2330, 2499, 2101);
m_formPanel.add(new JTextField(2), 2330, 2200);


// Income


m_formPanel.addMultiRow(new hLabel("Income", 16), 2650, 2799, 0);


FormPanel linkPanel = new FormPanel(0,0,0,0);
linkPanel.add(new hLabel("Link"), 0, 0);
linkPanel.add(new hLabel("Forms W-2,"), 1, 0);
linkPanel.add(new hLabel("W-2G, and"), 2, 0);
linkPanel.add(new hLabel("1099-R here."), 3, 0);
m_formPanel.addMultiRow(linkPanel, 2850, 3199, 0);


m_formPanel.add(new hLabel("7"), 2600, 1000);
m_formPanel.add(new hLabel("Wages, salaries, tips, etc. Link Form(s) W-2"), 2600, 1050);
m_formPanel.add(new hLabel("7"), 2600, 2000);
m_formPanel.add(new JTextField(12), new JTextField(2), 2600, 2100);


m_formPanel.add(new hLabel("8"), 2700, 1000);
m_formPanel.add(new hLabel("a"), 2700, 1020);
m_formPanel.add(new hLabel("Taxable interest, Link Schedule B if required"), 2700, 1050);
m_formPanel.add(new hLabel("8a"), 2700, 2000);
m_formPanel.add(new JTextField(12), new JTextField(2), 2700, 2100);


m_formPanel.add(new hLabel("b"), 2800, 1020);
m_formPanel.add(new hLabel("Tax-exempt interest. (DO NOT include on line 8a)"), 2800, 1050);
m_formPanel.add(new hLabel("8b"), 2800, 1500);
m_formPanel.add(new JTextField(12), new JTextField(2), 2800, 1500, FormLayout.FREE_FIELD);
m_formPanel.add(new hLabel(), 2800, 2000);


m_formPanel.add(new hLabel("9"), 2900, 1000);
m_formPanel.add(new hLabel("Ordinary dividends. Link Schedule B if required"), 2900, 1050);
m_formPanel.add(new hLabel("9"), 2900, 2000);
m_formPanel.add(new JTextField(12), new JTextField(2), 2900, 2100);


m_formPanel.add(new hLabel("10"), 3000, 1000);
m_formPanel.add(new hLabel("Taxable refunds, credits, or offsets of state and local income taxes (see page 21)"), 3000, 1050);
m_formPanel.add(new hLabel("10"), 3000, 2000);
m_formPanel.add(new JTextField(12), new JTextField(2), 3000, 2100);


m_formPanel.add(new hLabel("11"), 3100, 1000);
m_formPanel.add(new hLabel("Alimony received"), 3100, 1050);
m_formPanel.add(new hLabel("11"), 3100, 2000);
m_formPanel.add(new JTextField(12), new JTextField(2), 3100, 2100);


m_formPanel.add(new hLabel("12"), 3200, 1000);
m_formPanel.add(new hLabel("Business income (or loss). Link Schedule C or C-EZ"), 3200, 1050);
m_formPanel.add(new hLabel("12"), 3200, 2000);
m_formPanel.add(new JTextField(12), new JTextField(2), 3200, 2100);


m_formPanel.add(new hLabel("13"), 3300, 1000);
m_formPanel.add(new hLabel("Capital gain (or loss). Link Schedule D"), 3300, 1050);
m_formPanel.add(new hLabel("13"), 3300, 2000);
m_formPanel.add(new JTextField(12), new JTextField(2), 3300, 2100);


m_formPanel.add(new hLabel("14"), 3400, 1000);
m_formPanel.add(new hLabel("Other gains (or losses). Link form 4797"), 3400, 1050);
m_formPanel.add(new hLabel("14"), 3400, 2000);
m_formPanel.add(new JTextField(12), new JTextField(2), 3400, 2100);


m_formPanel.add(new hLabel("15"), 3500, 1000);
m_formPanel.add(new hLabel("a"), 3500, 1020);
m_formPanel.add(new hLabel("Total IRA distributions"), 3500, 1050);
m_formPanel.add(new hLabel("15a"), 3500, 1400);
m_formPanel.add(new JTextField(12), new JTextField(2), 3500, 1450);
m_formPanel.add(new hLabel("b"), 3500, 1500);
m_formPanel.add(new hLabel("Taxable amount (see page 22)", 10), 3500, 1550);
m_formPanel.add(new hLabel("15b"), 3500, 2000);
m_formPanel.add(new JTextField(12), new JTextField(2), 3500, 2100);


m_formPanel.add(new hLabel("16"), 3600, 1000);
m_formPanel.add(new hLabel("a"), 3600, 1020);
m_formPanel.add(new hLabel("Total pensions and annuities", 10), 3600, 1050);
m_formPanel.add(new hLabel("16a"), 3600, 1400);
m_formPanel.add(new JTextField(12), new JTextField(2), 3600, 1450);
m_formPanel.add(new hLabel("b"), 3600, 1500);
m_formPanel.add(new hLabel("Taxable amount (see page 22)", 10), 3600, 1550);
m_formPanel.add(new hLabel("16b"), 3600, 2000);
m_formPanel.add(new JTextField(12), new JTextField(2), 3600, 2100);


m_formPanel.add(new hLabel("17"), 3700, 1000);
m_formPanel.add(new hLabel("Rental real estate, royalties, partnerships, S corporations, trusts, etc. Link Schedule E"), 3700, 1050);
m_formPanel.add(new hLabel("17"), 3700, 2000);
m_formPanel.add(new JTextField(12), new JTextField(2), 3700, 2100);


m_formPanel.add(new hLabel("18"), 3800, 1000);
m_formPanel.add(new hLabel("Farm income (or loss). Link Schedule F"), 3800, 1050);
m_formPanel.add(new hLabel("18"), 3800, 2000);
m_formPanel.add(new JTextField(12), new JTextField(2), 3800, 2100);


m_formPanel.add(new hLabel("19"), 3900, 1000);
m_formPanel.add(new hLabel("Unemployment compensation"), 3900, 1050);
m_formPanel.add(new hLabel("19"), 3900, 2000);
m_formPanel.add(new JTextField(12), new JTextField(2), 3900, 2100);


m_formPanel.add(new hLabel("20"), 4000, 1000);
m_formPanel.add(new hLabel("a"), 4000, 1020);
m_formPanel.add(new hLabel("Social ssecurity benefits", 10), 4000, 1050);
m_formPanel.add(new hLabel("20a"), 4000, 1400);
m_formPanel.add(new JTextField(12), new JTextField(2), 4000, 1450);
m_formPanel.add(new hLabel("Taxable amount (see page 24)", 10), 4000, 1550);
m_formPanel.add(new hLabel("20b"), 4000, 2000);
m_formPanel.add(new JTextField(12), new JTextField(2), 4000, 2100);


m_formPanel.add(new hLabel("21"), 4100, 1000);
m_formPanel.add(new hLabel("Other income. List type and amount--see page 24"), new JTextField(14), 4100, 1050, 1.0);
m_formPanel.add(new hLabel("21"), 4100, 2000);
m_formPanel.add(new JTextField(12), new JTextField(2), 4100, 2100);


m_formPanel.add(new hLabel("22"), 4200, 1000);
m_formPanel.add(new hLabel("Add the amounts in the far right column for lines 7 through 21. This is your total income"), 4200, 1050);
m_formPanel.add(new hLabel("22"), 4200, 2000);
m_formPanel.add(new JTextField(12), new JTextField(2), 4200, 2100);


m_formPanel.setPreferredSize(m_formPanel.getPreferredSize());


JSeparator separator = new JSeparator();
int panelPreferredWidth = m_formPanel.getPreferredSize().width - 16; // 2 * externalHGap
separator.setPreferredSize(new Dimension(panelPreferredWidth, separator.getPreferredSize().height));
m_formPanel.add(separator, 1100, 1);


separator = new JSeparator();
separator.setPreferredSize(new Dimension(panelPreferredWidth, separator.getPreferredSize().height));
m_formPanel.add(separator, 1750, 1);


separator = new JSeparator();
separator.setPreferredSize(new Dimension(panelPreferredWidth, separator.getPreferredSize().height));
m_formPanel.add(separator, 2500, 1);