Encrypting/decrypting using RC4

RC4 (Ron’s Code) is a symmetric key encryption algorithm. Developed in 1987 by Ronald Rivest, it is used in SSL and many applications such as Lotus Notes and Oracle Secure SQL.

RC4 is a stream cipher, meaning that it encrypts one byte at a time. With RC4, the key is variable, from 1 to 2048 bits. RC4 is about 10 times as fast as DES. The algorithm is small and simple to implement. Here’s an unreadable version of it written in Perl.

Main.java:

import javax.crypto.spec.*;
import java.security.*;
import javax.crypto.*;
 
public class Main
{
   private static String algorithm = "RC4";
 
   public static void main(String []args) throws Exception {
      String toEncrypt = "The shorter you live, the longer you're dead!";
 
      System.out.println("Encrypting...");
      byte[] encrypted = encrypt(toEncrypt, "password");
 
      System.out.println("Decrypting...");
      String decrypted = decrypt(encrypted, "password");
    
      System.out.println("Decrypted text: " + decrypted);
   } 
 
   public static byte[] encrypt(String toEncrypt, String key) throws Exception {
      // create a binary key from the argument key (seed)
      SecureRandom sr = new SecureRandom(key.getBytes());
      KeyGenerator kg = KeyGenerator.getInstance(algorithm);
      kg.init(sr);
      SecretKey sk = kg.generateKey();
 
      // create an instance of cipher
      Cipher cipher = Cipher.getInstance(algorithm);
 
      // initialize the cipher with the key
      cipher.init(Cipher.ENCRYPT_MODE, sk);
 
      // enctypt!
      byte[] encrypted = cipher.doFinal(toEncrypt.getBytes());
 
      return encrypted;
   }
 
   public static String decrypt(byte[] toDecrypt, String key) throws Exception {
      // create a binary key from the argument key (seed)
      SecureRandom sr = new SecureRandom(key.getBytes());
      KeyGenerator kg = KeyGenerator.getInstance(algorithm);
      kg.init(sr);
      SecretKey sk = kg.generateKey();
 
      // do the decryption with that key
      Cipher cipher = Cipher.getInstance(algorithm);
      cipher.init(Cipher.DECRYPT_MODE, sk);
      byte[] decrypted = cipher.doFinal(toDecrypt);
 
      return new String(decrypted);
   }
}

Performing declarative authorization with JAAS

Authorization

Authorization is about allowing or denying access to resources to a particular subject (a user, a group, a company, …). When a subject is authenticated, it is augmented with one or more principals that identify the subject for one or more resources, for example a social security number for one resource or a role of an administrator for another. A subject can also have credentials associated with them, any Java objects that contains security-related information about the subject, for example a certificate or a password.

To go ahead with this example, first read the authentication example.

In the following example, the authentication example will be augmented with a section that is only executed when it is permitted to do so by a particular principal, in our example “johndoe”. The following policy file will grant permissions to the principal “johndoe” to read and write to the file “c:\testfile”. A policy file specifies what permissions are allowed to code coming from a specified code source and executed by a specified principal.

accesscontrol.policy:

/** User-Based Access Control Policy **/

grant Principal MyPrincipal "johndoe" {
   permission java.io.FilePermission "c:/testfile", "read,write";
};

We also have another policy file that grants permissions to read and write System properties (needed by the Swing DialogCallbackHandler), to create a LoginContext (necessary for authentication), to execute a doAsPrivileged method (necessary for executing sensitive code that requires principal permissions) and to modify principals (necessary when we add a principal to the subject). jaasmain.policy:

grant {
   permission java.util.PropertyPermission "*", "read, write";
   permission javax.security.auth.AuthPermission 
                    "createLoginContext";
   permission javax.security.auth.AuthPermission "doAsPrivileged";
   permission javax.security.auth.AuthPermission "modifyPrincipals";
};

jaas.config:

MyAuthenticationComponents {
   UsernamePasswordLoginModule required;
};

Our module that encapsulates code to do authentication has not changed from the authentication example.

UsernamePasswordLoginModule.java:

import javax.security.auth.callback.*;
import javax.security.auth.login.*;
import javax.security.auth.spi.*;
import javax.security.auth.*;
import java.security.*;
import java.util.*;
import java.io.*;
 
public class UsernamePasswordLoginModule implements LoginModule {
   private Subject subject;
   private CallbackHandler callbackHandler;
 
   private String username;
   private char[] password;
   private boolean loginSucceeded = false;
   private boolean commitSucceeded = false;
  
   private Principal principal;
 
   public void initialize(Subject subject, CallbackHandler callbackHandler, 
                          Map sharedState, Map options) {
      System.out.println("LoginModule initialize()");
      this.subject = subject;
      this.callbackHandler = callbackHandler;
      username = null;
      clearPassword();
      loginSucceeded = false;
      commitSucceeded = false;
   }
 
   public boolean login() throws LoginException {
      System.out.println("LoginModule login()");
      if (callbackHandler == null) {
         throw new LoginException("No CallbackHandler!");
      }
 
      Callback[] callbacks = new Callback[2];
      callbacks[0] = new NameCallback("Username: ");
      callbacks[1] = new PasswordCallback("Password: ", false);
 
      try {
         callbackHandler.handle(callbacks);
         username = ((NameCallback) callbacks[0]).getName();
         char[] temp = ((PasswordCallback) callbacks[1]).getPassword();
         password = new char[temp.length];
         System.arraycopy(temp, 0, password, 0, temp.length);
 
         BufferedReader br = new BufferedReader(new FileReader("passwd"));
         String line;
         while ((line = br.readLine()) != null) {
            int comma = line.indexOf(',');
            String un = line.substring(0, comma);
            String pw = line.substring(comma+1);
 
            if (username.equals(un) && new String(password).equals(pw)) {
               // succeeded!
               loginSucceeded = true;
               return true;
            }
         }
      }
      catch(IOException e) {
         throw new LoginException(e.toString());
      }
      catch(UnsupportedCallbackException e) {
         throw new LoginException(e.toString());
      }
 
      username = null;
      clearPassword();
      loginSucceeded = false;
 
      throw new FailedLoginException("Incorrect Username/Password");
   }
 
   public boolean commit() throws LoginException {
      System.out.println("LoginModule commit()");

      if (loginSucceeded == false) {
         return false;
      }
 
      principal = new MyPrincipal(username);
      if (!(subject.getPrincipals().contains(principal))) {
         subject.getPrincipals().add(principal);
      }
 
      username = null;
      clearPassword();
      commitSucceeded = true;
       
      return true;
   }
  
   public boolean abort() throws LoginException {
      System.out.println("LoginModule abort()");
 
      if (!loginSucceeded) {
         return false;
      }
      else if (loginSucceeded && commitSucceeded) {
         loginSucceeded = false;
         username = null;
         clearPassword();
         principal = null;
      }
      else {
         logout();
      }
 
      return true;
   }
 
   public boolean logout() throws LoginException {
      System.out.println("LoginModule logout()");
 
      subject.getPrincipals().remove(principal);
      loginSucceeded = false;
      commitSucceeded = false;
      username = null;
      clearPassword();
      principal = null;
 
      return true;
   }
 
   private void clearPassword() {
      if (password != null) {
         for (int i=0; i<password.length; i++) {
            password[i] = ' ';
         }
         password = null;
      }
   }
}

Our passwd “database” textfile has not changed from the authentication example.

passwd:

johndoe,sdefujm
janedoe,yuymndee

Our MyPrincipal class has also not changed from the authentication example.

MyPrincipal.java:

import java.security.*;
import java.io.*;
 
public class MyPrincipal implements Principal, Serializable
{
   private String name;

   public MyPrincipal(String name) {
      this.name = name;
   }
  
   public String getName() {
      return name;
   }
  
   public int hashCode() {
      return name.hashCode();
   }
 
   public String toString() {
      return getName();
   }
 
   public boolean equals(Object obj) {
      if (obj == null) {
         return false;
      }
 
      if (!(obj instanceof MyPrincipal)) {
         return false;
      }
 
      MyPrincipal mp = (MyPrincipal) obj;
      if (name.equals(mp.getName())) {
         return true;
      }
 
      return false;
   }
}

The code that is to be executed based on user authentication must be inside the run method of a class that implements java.security.PrivilegedAction.

WriteFileAction.java:

import java.security.PrivilegedAction;
import java.io.*;
 
public class WriteFileAction implements PrivilegedAction {
   public Object run() {
 
      try {
         BufferedWriter bw = new BufferedWriter(new FileWriter("c:\testfile"));
         bw.write("the shorter you live, the longer you're dead");
         bw.close();
         System.out.println("c:\testfile successfully written!");
      }
      catch(IOException e) {
         System.out.println(e);
      }
 
      return null;
   }
}

We want this code to be executed only when a specified principal is running it (“johndoe” as specified in the policy file). We enforce this by calling this code indirectly through the method doAs or doAsPrivileged. The difference between the two is described here.

Main.java:

import com.sun.security.auth.callback.*;
import javax.security.auth.login.*;
import javax.security.auth.*;
import java.security.*;
import java.util.*;
import java.io.*;
 
public class Main {
   public static void main(String []args) throws Exception { 
      try {
         LoginContext loginContext = new LoginContext("MyAuthenticationComponents", 
                                             new DialogCallbackHandler());
 
         // will throw a LoginException if it fails, falls through otherwise
         loginContext.login();
 
         Subject subject = loginContext.getSubject();
         System.out.println(subject);
 
         PrivilegedAction action = new WriteFileAction();
         subject.doAsPrivileged(subject, action, null);
  
         loginContext.logout();
      }
      catch(LoginException e) {
         System.out.println("Unauthorized user!");
      } 
 
      // stop AWT thread (DialogCallbackHandler)
      System.exit(0);
   }
}

To run the code, you need to specify the policy files (or change the default java.policy one):

   c:jdk1.4binjava -Djava.security.auth.policy=accesscontrol.policy
                      -Djava.security.policy=jaasmain.policy
                      -Djava.security.auth.login.config==jaas.config
                      -Djava.security.manager
                      Main

Running the code with username=”johndoe”, password=”sdefujm” results in:

LoginModule initialize()
LoginModule login()
LoginModule commit()
Subject:
	Principal: johndoe

c:testfile successfully written!
LoginModule logout()

Running the code with username=”janedoe”, password=”yuymndee” (another authenticated user, but not authorized) results in:

LoginModule initialize()
LoginModule login()
LoginModule commit()
Subject:
	Principal: janedoe
Exception in thread "main" java.security.AccessControlException: access denied
java.io.FilePermission c:testfile write)
        at java.security.AccessControlContext.checkPermission(AccessControlCont
xt.java:273)
        at java.security.AccessController.checkPermission(AccessController.java
400)
        at java.lang.SecurityManager.checkPermission(SecurityManager.java:545)
        at java.lang.SecurityManager.checkWrite(SecurityManager.java:978)
        at java.io.FileOutputStream.<init>(FileOutputStream.java:103)
        at java.io.FileOutputStream.<init>(FileOutputStream.java:69)
        at java.io.FileWriter.<init>(FileWriter.java:44)
        at WriteFileAction.run(WriteFileAction.java:8)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.Subject.doAsPrivileged(Subject.java:436)
        at Main.main(Main.java:21)

Notice that “janedoe” is correctly authenticated, but not authorized to run the privileged code as that principal is not specified in the policy file accesscontrol.policy.

Using a HashSet in Java

A HashSet holds a set of objects, but in a way that it allows you to easily and quickly determine whether an object is already in the set or not. It does so by internally managing an array and storing the object using an index which is calculated from the hashcode of the object.

For more information on hashing, check out the HashMap category.

Things to remember:
– A HashSet is not synchronized, so not thread-safe.
– Its elements are not ordered
– Add an element to the HashSet with the method add(Object o)
– Remove an element with the method remove(Object o)
– Remove all elements with the method clear()
– Get the number of elements with the method size()

Here’s an example:

import java.util.*;
import java.io.*;
    
public class Main 
{
   public static void main(String []args) throws Exception {
      String[] keywords = { "abstract", "boolean", "break", "byte", "case", "cast",
                            "catch", "char", "class", "const", "continue", "default",
                            "do", "double", "else", "extends", "final", "finally",
                            "float", "for", "future", "generic", "goto", "if",
                            "implements", "import", "inner", "instanceof", "int",
                            "interface", "long", "native", "new", "null", "operator",
                            "outer", "package", "private", "protected", "public",
                            "rest", "return", "short", "static", "super", "switch",
                            "synchronized", "this", "throw", "throws", "transient",
                            "try", "var", "void", "volatile" };
 
      // convert this array to a Collection and create a HashSet
      HashSet hs = new HashSet(Arrays.asList(keywords));
 
      BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
      
      String line;
      System.out.print("Enter keyword ('exit' to exit): ");
      line = br.readLine();
      while (!line.equals("exit")) {
         if (hs.contains(line)) {
            System.out.println("t" + line + " is a Java keyword!");
         }
         else {
            System.out.println("t" + line + " is not a Java keyword!");
         }
         System.out.print("Enter keyword ('exit' to exit): ");
         line = br.readLine();
      }
   }
}

sample output:

C:>java Main
Enter keyword ('exit' to exit): public
        public is a Java keyword!
Enter keyword ('exit' to exit): jefke
        jefke is not a Java keyword!
Enter keyword ('exit' to exit): instanceof
        instanceof is a Java keyword!
Enter keyword ('exit' to exit): coke
        coke is not a Java keyword!
Enter keyword ('exit' to exit): esus
        esus is not a Java keyword!
Enter keyword ('exit' to exit): package
        package is a Java keyword!
Enter keyword ('exit' to exit): exit

Comparing whether a date comes before or after another date in Java

The Date class has two useful methods for this: before and after.

Main.java:

import java.util.*;
import java.text.*;
   
public class Main {
   public static void main(String args[]) {
      Date date1, date2, date3;
 
      try {
         DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT);
         date1 = df.parse("20/12/72");   // date in the past
         date2 = new Date();             // current date
         date3 = df.parse("05/07/06");   // date in the future
 
         System.out.println(date2.after(date1));
         System.out.println(date2.after(date3));
         System.out.println(date2.before(date1));
         System.out.println(date2.before(date3));
      }
      catch(ParseException e) {
         e.printStackTrace();
      }
  
   }
}

outputs:

true
false
false
true

Using a java.util.logging StreamHandler

Here’s an example that will write a log message to a StreamHandler that is connected to a ByteArrayOutputStream.

Main.java:

import java.util.logging.*;
import java.io.*;
 
public class Main
{
   public static void main(String argv[]) throws IOException {
      Logger logger = Logger.getLogger("main");
      logger.setUseParentHandlers(false);
 
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      StreamHandler sh = new StreamHandler(baos, new SimpleFormatter());
      sh.setLevel(Level.ALL);
      logger.addHandler(sh);
 
      logger.severe("log message"); 
 
      sh.flush();
      baos.writeTo(System.out);
   }
}

Generating a random integer between x and y

lets say you have to int upperBound and lowerBound and you want to store the result in result.

the following code will give you
lowerBound < = result < upperBound

   int result = lowerBound + (int) ( Math.random()*(upperBound – lowerBound) )

the following code will give you
lowerBound < = result <= upperBound

   int result = lowerBound + (int) ( Math.random()*(upperBound -lowerBound) + o.5 )

Though in the second case, having a result that equals to either of lowerBound ot upperBound will be little less than other numbers in the range comparing with the algorithm in Math.random(), in most cases, that is just fine.

Hope it helps.

Calculating the checksum of a byte array

Use the Adler32 class in the java.util.zip package. It contains an implementation of an algorithm to calculate a checksum of an set of bytes.

The procedure is simple: create an instance of the Adler32 class, call its method update and provide it with set of bytes in the order they appear in the stream. If all bytes have been processed, call getValue to get the checksum.
If you need to calculate checksums of several bytestreams, you can reuse the Adler32 instance but you need to call reset in order to reset it to its original state.

Following example displays a checksum of a file provided at command line.

Main.java:

import java.util.zip.*;
import java.io.*;
 
public class Main {
   public static void main(String args[]) {
      if (args.length != 1) {
         System.err.println("Usage: java Main <file>");
         System.exit(1);
      }
 
      try {
         Adler32 adler32 = new Adler32();
         BufferedInputStream bis = new BufferedInputStream(new FileInputStream(args[0]));
 
         int l = 0;
         byte[] buffer = new byte[1024];
         while ((l = bis.read(buffer)) >= 0) {
            adler32.update(buffer, 0, l);
         }
 
         System.out.println("Checksum of file " + args[0] + ":");
         System.out.println(adler32.getValue());
      }
      catch(IOException e) {
         System.err.println(e);
      }
   }
}

Handling Hyperlink events on a JEditorPane

Add a HyperlinkListener to your JEditorPane, as shown in the following example. Note that a distinction is made between a normal hyperlink and a hyperlink activated in a frame. In the latter case, a HTMLFrameHyperlinkEvent will be posted.

import javax.swing.text.html.*;
import javax.swing.event.*;
import javax.swing.text.*;
import java.awt.event.*;
import javax.swing.*;
import java.net.*;
import java.awt.*;
import java.io.*;
 
public class Main extends JFrame
{
   // need to be final to allow the inner class to access it!
   final JTextField urlTextField = new JTextField();
   final JEditorPane htmlPane = new JEditorPane();
   JButton urlButton = new JButton("Go!");
 
   public static void main(String []args) {
      Main main = new Main();
      main.show();
   }
 
   public Main() { 
      htmlPane.setEditable(false);
      urlTextField.setText("http://www.yahoo.com");
  
      urlButton.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent ae) {
            loadPage(urlTextField.getText());
         }
      });

      htmlPane.addHyperlinkListener(new HyperlinkListener() {
         public void hyperlinkUpdate (HyperlinkEvent event) {
            if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
               urlTextField.setText(event.getURL().toString());

               if (event instanceof HTMLFrameHyperlinkEvent) {
                  HTMLDocument doc = (HTMLDocument) htmlPane.getDocument();
                  doc.processHTMLFrameHyperlinkEvent ((HTMLFrameHyperlinkEvent) event);
               }
               else {
                  loadPage(urlTextField.getText());
               }
            }
         }
      });
 
      getContentPane().setLayout(new BorderLayout());
      JPanel topPanel = new JPanel(new BorderLayout());
      topPanel.add(BorderLayout.CENTER, urlTextField);
      topPanel.add(BorderLayout.EAST, urlButton);
 
      getContentPane().add(BorderLayout.NORTH, topPanel);
      getContentPane().add(BorderLayout.CENTER, new JScrollPane(htmlPane));
 
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent e) {
            System.exit(0);
         }
      });
 
      setSize(400, 400);
   }

   public void loadPage(String url) {
      try {
         htmlPane.setPage(new URL(urlTextField.getText()));
      }
      catch(Exception e) {
         System.out.println(e);
      }
   }
}

Getting the HWND handle of a Window

Sometimes, you need the HWND handle for example to pass it on with JNI to a
native function. See related links, where the mousewheel support is implemented
using this method.
This example shows you how to get the handle of a window as well as a Canvas.
HwndCanvas:

import java.awt.*;
import sun.awt.*;
 
public class HwndCanvas extends Canvas
{
   public int getHwnd() {
      int hwnd = 0;
                            
      DrawingSurfaceInfo w = ((DrawingSurface)(getPeer())).getDrawingSurfaceInfo();
                               
      if (w != null) {
         w.lock();
         Win32DrawingSurface win32 = (Win32DrawingSurface) w.getSurface();
         hwnd = win32.getHWnd();
         w.unlock();
      }
       
      return hwnd;
   }                    
}

Main.java:

import java.awt.event.*;
import java.awt.*;
import sun.awt.*;
 
public class Main extends Frame
{
   public HwndCanvas hwndCanvas = new HwndCanvas();
 
   public Main() {
      setLayout(new BorderLayout());
      add(BorderLayout.CENTER, hwndCanvas);
 
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent e) {
            System.exit(0);
         }
      });      
 
      setSize(100, 100);
   }
 
   public int getHwnd() { 
      int hwnd = 0;
                            
      DrawingSurfaceInfo w = ((DrawingSurface)(getPeer())).getDrawingSurfaceInfo();
                               
      if (w != null) {
         w.lock();
         Win32DrawingSurface win32 = (Win32DrawingSurface) w.getSurface();
         hwnd = win32.getHWnd();
         w.unlock();
      }
      
      return hwnd;
   } 
 
   public static void main(String []args) {
      Main m = new Main();
 
      m.show();
 
      System.out.println("HWND of Frame = " + m.getHwnd());
      System.out.println("HWND of Canvas = " + m.hwndCanvas.getHwnd());
   }
}

Adding a JPanel with a null layout to a JScrollPane

Make sure you set the preferredSize of the JPanel. Invoke the method setViewportView on JScrollPane.

Main.java:

import java.awt.event.*;
import javax.swing.border.*;
import javax.swing.*;
import java.awt.*;
 
public class Main extends JFrame 
{
   public Main() {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(0);
         }
      });
 
      JPanel panel = createContactPanel();
 
      JScrollPane sp = new JScrollPane();
      sp.setViewportView(panel);
 
      getContentPane().setLayout(new BorderLayout());
      getContentPane().add(sp, BorderLayout.CENTER); 
   }
 
   public JPanel createContactPanel() {
      JLabel titleLbl      = new JLabel("Title");
      JLabel firstNameLbl  = new JLabel("First name");
      JLabel lastNameLbl   = new JLabel("Last name");
      JLabel addressLbl    = new JLabel("Address");
      JLabel cityLbl       = new JLabel("City");
      JLabel zipLbl        = new JLabel("Postal code");
      JLabel countryLbl    = new JLabel("Country");
      JLabel phoneLbl      = new JLabel("Phone number");
      JLabel faxLbl        = new JLabel("Fax number");
      JLabel emailLbl      = new JLabel("E-mail");
      JLabel birthdayLbl   = new JLabel("Birthdate");
      JLabel pickchoiceLbl = new JLabel("Pick a choice");
      JLabel creditCardTypeLbl     = new JLabel("Credit card type");
      JLabel creditCardNumberLbl   = new JLabel("Credit card number");
      JLabel expirationLbl         = new JLabel("Expiration date");
 
      JComboBox titleCombo = new JComboBox(
             new String[] { "-", "Mr", "Mrs", "Miss" });
      JTextField firstNameTf    = new JTextField();
      JTextField lastNameTf     = new JTextField();
      JTextField address1Tf     = new JTextField();
      JTextField address2Tf     = new JTextField();
      JTextField cityTf         = new JTextField();
      JTextField zipTf          = new JTextField();
      JTextField countryTf      = new JTextField();
      JTextField phoneTf        = new JTextField();
      JTextField faxTf          = new JTextField();
      JTextField emailTf        = new JTextField();
      JComboBox bd1Combo = new JComboBox();
      for (int i=1; i<=12; i++) bd1Combo.addItem(""+i);
      JComboBox bd2Combo = new JComboBox();
      for (int i=1; i<=31; i++) bd2Combo.addItem(""+i);
      JComboBox bd3Combo = new JComboBox();
      for (int i=1900; i<2000; i++) bd3Combo.addItem(""+i);
      JComboBox referCombo = new JComboBox();
      referCombo.addItem("Friend");
      referCombo.addItem("Search engine");
      referCombo.addItem("Print Media");
      referCombo.addItem("Banner Add");
      referCombo.addItem("Other");
      JComboBox creditCardTypeCombo = new JComboBox();
      creditCardTypeCombo.addItem("VISA");
      creditCardTypeCombo.addItem("MasterCard");
      creditCardTypeCombo.addItem("American Express");
      JTextField creditCardNumberTf = new JTextField();
      JComboBox expiration1Combo = new JComboBox();
      for (int i=1; i<=12; i++) expiration1Combo.addItem(""+i);
      JComboBox expiration2Combo = new JComboBox();
      for (int i=1; i<=31; i++) expiration2Combo.addItem(""+i);
      JComboBox expiration3Combo = new JComboBox();
      for (int i=1900; i<=2000; i++) expiration3Combo.addItem(""+i);
 
      JPanel panelGeneral = new JPanel();
      panelGeneral.setLayout(null);
      panelGeneral.add(titleLbl);
      panelGeneral.setBorder(new TitledBorder("General Information"));
      titleLbl.setBounds(20, 20, 150, 20);
      panelGeneral.add(firstNameLbl);
      firstNameLbl.setBounds(20, 50, 150, 20);
      panelGeneral.add(lastNameLbl);
      lastNameLbl.setBounds(20, 80, 150, 20);
      panelGeneral.add(addressLbl);
      addressLbl.setBounds(20, 110, 150, 20);
      panelGeneral.add(cityLbl);
      cityLbl.setBounds(20, 170, 150, 20);
      panelGeneral.add(zipLbl);
      zipLbl.setBounds(20, 200, 150, 20);
      panelGeneral.add(countryLbl);
      countryLbl.setBounds(20, 230, 150, 20);
      panelGeneral.add(phoneLbl);
      phoneLbl.setBounds(20, 260, 150, 20);
      panelGeneral.add(faxLbl);
      faxLbl.setBounds(20, 290, 150, 20);
      panelGeneral.add(emailLbl);
      emailLbl.setBounds(20, 320, 150, 20);
      panelGeneral.add(birthdayLbl);
      birthdayLbl.setBounds(20, 350, 150, 20); 
      panelGeneral.add(titleCombo);
      titleCombo.setBounds(150, 20, 60, 20);
      panelGeneral.add(firstNameTf);
      firstNameTf.setBounds(150, 50, 200, 20);
      panelGeneral.add(lastNameTf);
      lastNameTf.setBounds(150, 80, 200, 20);
      panelGeneral.add(address1Tf);
      address1Tf.setBounds(150, 110, 200, 20);  
      panelGeneral.add(address2Tf);
      address2Tf.setBounds(150, 140, 200, 20);  
      panelGeneral.add(cityTf);
      cityTf.setBounds(150, 170, 200, 20);
      panelGeneral.add(zipTf);
      zipTf.setBounds(150, 200, 200, 20);
      panelGeneral.add(countryTf);
      countryTf.setBounds(150, 230, 200, 20);
      panelGeneral.add(phoneTf);
      phoneTf.setBounds(150, 260, 200, 20);
      panelGeneral.add(faxTf);
      faxTf.setBounds(150, 290, 200, 20);
      panelGeneral.add(emailTf);
      emailTf.setBounds(150, 320, 200, 20);
      panelGeneral.add(bd1Combo);
      bd1Combo.setBounds(150, 350, 60, 20);
      panelGeneral.add(bd2Combo);
      bd2Combo.setBounds(220, 350, 60, 20);
      panelGeneral.add(bd3Combo);
      bd3Combo.setBounds(290, 350, 60, 20);
 
      JPanel panelReferral = new JPanel();
      panelReferral.setLayout(null);
      panelReferral.setBorder(new TitledBorder("Where did you hear about us?"));
      panelReferral.add(pickchoiceLbl);
      pickchoiceLbl.setBounds(20, 20, 150, 20);
      panelReferral.add(referCombo);
      referCombo.setBounds(150, 20, 100, 20);
 
      JPanel panelCreditCard = new JPanel();
      panelCreditCard.setLayout(null);
      panelCreditCard.setBorder(new TitledBorder("Payment method"));
      panelCreditCard.add(creditCardTypeLbl);
      creditCardTypeLbl.setBounds(20, 20, 150, 20);
      panelCreditCard.add(creditCardNumberLbl);
      creditCardNumberLbl.setBounds(20, 50, 150, 20);
      panelCreditCard.add(expirationLbl);
      expirationLbl.setBounds(20, 80, 150, 20);
 
      panelCreditCard.add(creditCardTypeCombo);
      creditCardTypeCombo.setBounds(150, 20, 100, 20);
      panelCreditCard.add(creditCardNumberTf);
      creditCardNumberTf.setBounds(150, 50, 150, 20);
      panelCreditCard.add(expiration2Combo);
      expiration2Combo.setBounds(220, 80, 60, 20);
      panelCreditCard.add(expiration3Combo);
      expiration3Combo.setBounds(290, 80, 60, 20);
 
      JPanel panel = new JPanel();
      panel.setLayout(null);
      panel.add(panelGeneral);
      panelGeneral.setBounds(10, 20, 370, 400);
      panel.add(panelReferral);
      panelReferral.setBounds(10, 430, 370, 50);
      panel.add(panelCreditCard);
      panelCreditCard.setBounds(10, 490, 370, 120);
      
      panel.setPreferredSize(new Dimension(380, 620)); 
 
      return panel;
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(400, 400);
      main.setVisible(true);
   }
}