Below is an address book program I am working on. The way it stands now, when the data is entered and writes to a text file it writes the line of data like,

John Doe 1234 Help Me Avenue Dallas Texas 98956
Johnathan Doe 2345 Derby Lane Omaha Nebraska 45678

What I would like it to do is keep all the data evenly spaced and with headings for each column...

First Name   Last Name         Address             City      State       Zipcode

John         Smith       1234   Help Me Avenue     Dallas    Texas       98956
Johnathan    Doe         2345   Derby Lane         Omaha     Nebraska    45678

All Help will be greatly appreciated. Thanks!

import java.io.*;
import java.util.*;
import java.lang.*;
import javax.swing.*;
import javax.swing.JTextField.*;
import javax.swing.JOptionPane.*;
import java.awt.*;
import java.awt.event.*;

public class AddressBookProgram extends JFrame
{


   //public static void main(String[] args) throws FileNotFoundException


   private JLabel blankL, fnameL, lnameL, addressL, cityL, stateL, zipL, hphoneL, mphoneL; 
    //left column of GUI component for field names

   private JTextField blankTF, fnameTF, lnameTF, addressTF, cityTF, stateTF, zipTF, hphoneTF, mphoneTF;
    //right column of GUI component for entering information in the fields

   private JButton resetB, addB, exitB; //Buttons listed on GUI component


    private ResetButtonHandler rbHandler;
    private AddButtonHandler abHandler;
   private ExitButtonHandler ebHandler;
    //methods objects for submit buttons on GUI

   private static final int WIDTH = 600;
   private static final int HEIGHT = 400;
    //height and width of GUI component

   public AddressBookProgram()
   {


    JMenuBar menuBar = new JMenuBar();

// Add the menubar to the frame
    setJMenuBar(menuBar);

// Define and add two drop down menu to the menubar
    JMenu fileMenu = new JMenu("File");
    JMenu editMenu = new JMenu("About");
    menuBar.add(fileMenu);
    menuBar.add(editMenu);

// Create and add simple menu item to one of the drop down menu
    JMenuItem newAction = new JMenuItem("New");
    JMenuItem openAction = new JMenuItem("Open");
    JMenuItem saveAction = new JMenuItem("Save");

    JMenuItem closeAction = new JMenuItem("Close");

    fileMenu.add(newAction);
    fileMenu.add(openAction);
    fileMenu.add (saveAction);
     fileMenu.addSeparator();
     fileMenu.add(closeAction);

             //Create the labels, right justified
      fnameL = new JLabel("First Name: ",SwingConstants.RIGHT);
      lnameL = new JLabel("Last Name: ",SwingConstants.RIGHT);
      addressL = new JLabel("Address: ", SwingConstants.RIGHT);
      cityL = new JLabel("City: ", SwingConstants.RIGHT);
      stateL = new JLabel("State: ", SwingConstants.RIGHT);
      zipL = new JLabel("Zip Code: ", SwingConstants.RIGHT);
      hphoneL = new JLabel("Home Phone: ", SwingConstants.RIGHT);
       mphoneL = new JLabel("Mobile Phone: ", SwingConstants.RIGHT);


      //Create the text fields
      fnameTF = new JTextField(10);
      lnameTF = new JTextField(10);
      addressTF = new JTextField(40);
      cityTF = new JTextField(10);
      stateTF = new JTextField(10);
      zipTF = new JTextField(5);
        hphoneTF = new JTextField(10);
        mphoneTF = new JTextField(10);


                //Create Reset Button to clear text in field and re-enter information
        resetB = new JButton("Reset");
        rbHandler = new ResetButtonHandler();
        resetB.addActionListener(rbHandler);

                //Create Add to File Button which will print all informatio to a file
        addB = new JButton("Add to File");
        abHandler = new AddButtonHandler();
        addB.addActionListener(abHandler);

             //Create Exit Button closes the GUI screen when complete
      exitB = new JButton("Exit");
      ebHandler = new ExitButtonHandler();
      exitB.addActionListener(ebHandler);

             //Set the title of the window
      setTitle("Address Book");

             //Get the container
      Container pane = getContentPane();


             //Set the layout of rows and columns

      pane.setLayout(new FlowLayout(1,5,10));



             //Place the components in the pane
      pane.add(fnameL);
      pane.add(fnameTF);
      pane.add(lnameL);
      pane.add(lnameTF);
      pane.add(addressL);
      pane.add(addressTF);
      pane.add(cityL);
      pane.add(cityTF);
        pane.add(stateL);
        pane.add(stateTF);
      pane.add(zipL);
      pane.add(zipTF);
      pane.add(hphoneL);
      pane.add(hphoneTF);
        pane.add(mphoneL);
        pane.add(mphoneTF);



        pane.add(addB);
        pane.add(resetB);
      pane.add(exitB);

             //Set the size of the window and display it
      setSize(WIDTH, HEIGHT);
      setVisible(true);
      setDefaultCloseOperation(EXIT_ON_CLOSE);
   }


    private class ResetButtonHandler implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
        //resets JTextFields
        fnameTF.setText("");
        lnameTF.setText("");
        addressTF.setText("");
        cityTF.setText("");
        stateTF.setText("");
        zipTF.setText("");
        hphoneTF.setText("");
        mphoneTF.setText("");
    }




    }
    //Add to File code
    private class AddButtonHandler implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            if (fnameTF.getText().length() == 0)
    {
    JOptionPane.showMessageDialog(null, "First Name is required ",

        "ERROR",JOptionPane.ERROR_MESSAGE);

        fnameTF.requestFocusInWindow();
    }   

    else if(lnameTF.getText().length() == 0)
    {

    JOptionPane.showMessageDialog(null, "Last Name is required ",

        "ERROR",JOptionPane.ERROR_MESSAGE);

    lnameTF.requestFocusInWindow();
    }

    else if(addressTF.getText().length() == 0)
    {

    JOptionPane.showMessageDialog(null, "Address is required ",

        "ERROR",JOptionPane.ERROR_MESSAGE);

    addressTF.requestFocusInWindow();
    }

    else if(cityTF.getText().length() == 0)
    {

    JOptionPane.showMessageDialog(null, "City is required ",

        "ERROR",JOptionPane.ERROR_MESSAGE);

    cityTF.requestFocusInWindow();
    }

    else if(stateTF.getText().length() == 0)
    {

    JOptionPane.showMessageDialog(null, "State is reqired ",

        "ERROR",JOptionPane.ERROR_MESSAGE);

    stateTF.requestFocusInWindow();
    }

    else if(zipTF.getText().length() == 0)
    {

    JOptionPane.showMessageDialog(null, "Zip Code is reqired ",

        "ERROR",JOptionPane.ERROR_MESSAGE);

    zipTF.requestFocusInWindow();
    }

    else if(hphoneTF.getText().length() == 0)
    {

    JOptionPane.showMessageDialog(null, "Home Phone is reqired ",

        "ERROR",JOptionPane.ERROR_MESSAGE);

    hphoneTF.requestFocusInWindow();
    }

    else if(mphoneTF.getText().length() == 0)
    {

    JOptionPane.showMessageDialog(null, "Mobile Phone is reqired ",

        "ERROR",JOptionPane.ERROR_MESSAGE);

    mphoneTF.requestFocusInWindow();
    }

        // Stream to write file
        FileOutputStream fout;      

        try
    {       

    boolean exists = (new File("myfile.txt")).exists();
    if (exists) 
     {
    // File or directory exists
     // Print a line of text

    FileOutputStream ps = new FileOutputStream("myfile.txt", true);


     new PrintStream(ps).print ("" + fnameTF.getText() + " " + lnameTF.getText()); 
     new PrintStream(ps).print (", " + addressTF.getText());
     new PrintStream(ps).print (", " + cityTF.getText());
     new PrintStream(ps).print (", " + stateTF.getText());
     new PrintStream(ps).print (", " + zipTF.getText());
    new PrintStream(ps).print (", " + hphoneTF.getText());
    new PrintStream(ps).print (", " + mphoneTF.getText());
    new PrintStream(ps).println ();

         ps.close();        

     fnameTF.setText("");
     lnameTF.setText("");
     addressTF.setText("");
     cityTF.setText("");
     stateTF.setText("");
     zipTF.setText("");
     hphoneTF.setText("");
     mphoneTF.setText("");

     } 
     else 
     {
    // File or directory does not exist
     // Open an output stream
    fout = new FileOutputStream ("myfile.txt");

    // Print a line of text
    new PrintStream(fout).print ("" + fnameTF.getText() + " " + lnameTF.getText()); 
     new PrintStream(fout).print (", " + addressTF.getText());
     new PrintStream(fout).print (", " + cityTF.getText());
     new PrintStream(fout).print (", " + stateTF.getText());
    new PrintStream(fout).print (", " + zipTF.getText());
    new PrintStream(fout).print (", " + hphoneTF.getText());
    new PrintStream(fout).print (", " + mphoneTF.getText());
    new PrintStream(fout).println ();

     fnameTF.setText("");
     lnameTF.setText("");
     addressTF.setText("");
     cityTF.setText("");
     stateTF.setText("");
     zipTF.setText("");
     hphoneTF.setText("");
     mphoneTF.setText("");


    // Close the output stream
    fout.close();       
        }
        }
        catch (IOException f)
        {
     System.err.println ("Unable to write to file");
     System.exit(-1);
        }

        }
    }

   private class ExitButtonHandler implements ActionListener
   {
       public void actionPerformed(ActionEvent e)
       {
           System.exit(0);
       }
   }


   public static void main(String[] args) throws FileNotFoundException
   {



        try 
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} 
catch (Exception e) 
{ 
}
   AddressBookProgram rectObject = new AddressBookProgram();



   }

}

Edited 3 Years Ago by Dani: Formatting fixed

just giving a possible solution, will be a lot better out there.
remember, when you are writing a 'line' into your file, you're actually writing a String object (it's contents anyway) that you have stored in your memory.
it may not be very easy to 'format' the contents of a file, it is pretty easy to format a String before you write it to the file, getting the same results.

for instance:

String firstName = "John";
String lastName = "Doe";

let's say you want to print it like lastname - firstname, where you have 50 char chars reserved for the lastname:

String output = lastName + " " + firstName;
System.out.println(output);

the above wouldn't help you, you would get something like what you're getting now, I assume.

so, try something like this:

String output = lastName;
for ( int i = lastName.length(); i < 50; i++ )
  output += " ";
output += " " + firstName; // you have the chars for the lastname and
// an additional one, to separate last and firstname.
System.out.println(output);

if you write this last String to a file, it will write the spaces along with the rest.

EDIT: just a tip: when you're showing big parts of code, adding code tags

// your code here


without the ' s off course, will make it lot easier for us to read.

Edited 4 Years Ago by stultuske: mentioning Code tags

If you use printf then you can specify the formats for the printed items, including their width. If you set the width for each field >= longest actual data then the columns will line up (assuming you display them with a mono-spaced font like courier).

You have missed a semicolon on line 143.

(No, not really, but what on earth do you think anyone is supposed to do with anything as unhelpful as "Still not working"?)

Comments
aaah ... well placed sarcasm :)

Alright, how do I get the printf to work and print the JTextfield from the form into the file? Do I have to do away with all the PrintStream lines of code? or What?

No, you just need to enhance them a bit to include formatting info. When you print to your printstream you need to use the printf (formatted print) method rather than the ordinary print method. Then you add one new parameter, which is a format specification. Eg

print(name); // prints the contents of name without any formatting
printf("%-8s", name);  //prints the contents of name left aligned in a column 8 chars wide

That example format works like this:
% this is a format item
- left-aligned
8 column width
s string format

Just try executing these two lines to see it working in pratice:

System.out.printf("|%-8s|%5s|\n","hello", "me");
      System.out.printf("|%-8s|%5s|\n","goodbye", "you");

Google java printf for lots more examples

ps You don't need to create new PrintStream for every print, just create one at the start and use it for all the print/printf calls.

Edited 4 Years Ago by JamesCherrill: n/a

So your saying to write the code like this...

new PrintStream(ps).printf("%-20s", fnameTF);
new PrintStream(ps).printf("%-20s", lnameTF);
new PrintStream(ps).printf ("%20s", addressTF);

When I do have it like this how do I get it to get the text from input?

No, he's just been telling you not do that.

try something like:

PrintStream myOnlyPrintStream = new PrintStream(ps);
myOnlyPrintStream.printf("%-20s", fnameTF);
myOnlyPrintStream.printf("%-20s", lnameTF);
myOnlyPrintStream.printf("%-20s", addressTF);

by saying : new PrintStream(ps) you are instantiating a new PrintStream, while you can just as easy reuse the one you had.

Okay, when I have the like the following,

new PrintStream(ps).printf("%-20s", fnameTF.getText);
new PrintStream(ps).printf("%-20s", lnameTF.getText);
new PrintStream(ps).printf("%20s", addressTF.getText);

It won't compile. I get the following error message,

AddressBookProgram.java:267: cannot find symbol
symbol : variable getText
location: class javax.swing.JTextField
new PrintStream(ps).printf("%-20s", fnameTF.getText);

because if you call it like that, it looks like you're calling a variable (a constant maybe)
it's a method you're calling, so you 'll need to add the brackets

new PrintStream(ps).printf("%-20s", fnameTF.getText());

but, once again, you're using resources you don't need to use, by creating a new instance of PrintStream every time you print something. do it like this:

PrintStream onlyPS = new PrintStream(ps);
onlyPS.printf("%-20s", fnameTF.getText());
onlyPS.printf("%-20s", lnameTF.getText());
onlyPS.printf("%-20s", addressTF.getText());

Thanks For all your help. After a little lining up with the formatting it is working fine. Thanks again!

This question has already been answered. Start a new discussion instead.