code: public String[] getAppearanceStates(String fieldName) {
          Item fd = (Item)fields.get(fieldName);
          if (fd == null)
              return null;
          HashMap names = new HashMap();
          PdfDictionary vals = fd.getValue(0);
          PdfString stringOpt = vals.getAsString( PdfName.OPT );
          if (stringOpt != null) {
          	names.put(stringOpt.toUnicodeString(), null);
          }
          else {
              PdfArray arrayOpt = vals.getAsArray(PdfName.OPT);
              if (arrayOpt != null) {
              	for (int k = 0; k < arrayOpt.size(); ++k) {
              		PdfString valStr = arrayOpt.getAsString( k );
              		if (valStr != null)
              			names.put(valStr.toUnicodeString(), null);
              	}
              }
          }
          for (int k = 0; k < fd.size(); ++k) {
              PdfDictionary dic = fd.getWidget( k );
              dic = dic.getAsDict(PdfName.AP);
              if (dic == null)
                  continue;
              dic = dic.getAsDict(PdfName.N);
              if (dic == null)
                  continue;
              for (Iterator it = dic.getKeys().iterator(); it.hasNext();) {
                  String name = PdfName.decodeName(((PdfName)it.next()).toString());
                  names.put(name, null);
              }
          }
          String out[] = new String[names.size()];
          return (String[])names.keySet().toArray(out);
      }
docs: Gets the list of appearance names. Use it to get the names allowed
  with radio and checkbox fields. If the /Opt key exists the values will
  also be included. The name 'Off' may also be valid
  even if not returned in the list.
  
  @param fieldName the fully qualified field name
  @return the list of names or <CODE>null</CODE> if the field does not exist