How to get specific types from AcroFields? Like PushButtonField, RadioCheckField, etc

Tags: formsInspect fieldsfield typescheck boxradio fieldtext fieldiText 7
Form with radio buttons and check boxes
Form with radio buttons and check boxes

When I call AcroFields.GetField(string name); all I get is a string. When I call AcroFields.GetFieldItem(string name); I get an object but cannot cast it to the specific type.

I have also tried: AcroFields.SetFieldProperty("myfield", "CheckType", RadioCheckField.TYPE_STAR, null); This returned false every time.

To better explain my scenario: I have an existing PDF (I am NOT generating this file ). There is a checkbox in it. I want to change the "CheckType" like this:

myRadioCheckField.CheckType = RadioCheckField.TYPE_STAR
But since I cannot cast the AcroField to the specific type I cannot access that property "CheckType". Is there a way to achieve this?

Posted on StackOverflow on Oct 20, 2015 by anonymous

Your post contains two different questions. Let's start with the first question:

How to get specific types from AcroFields? Like PushButtonField, RadioCheckField, etc

This is explained in the FormInformation example:

 PdfReader reader = new PdfReader(src);
 PdfDocument pdfDoc = new PdfDocument(reader);
 // Get the fields from the reader (read-only!!!)
 PdfAcroForm form = PdfAcroForm.getAcroForm(pdfDoc, true);
 // Loop over the fields and get info about them
 Set<String> fields = form.getFormFields().keySet();
 for (String key : fields) {
     writer.print(key + ": ");
     PdfName type = form.getField(key).getFormType();
     if (0 == PdfName.Btn.compareTo(type)) {
         if(((PdfButtonFormField)form.getField(key)).isPushButton()){
             writer.println("Pushbutton");
         } else {
             if(((PdfButtonFormField)form.getField(key)).isRadio()){
                 writer.println("Radiobutton");                   
             }else {
                 writer.println("Checkbox");
             }
         }
     } else if (0 == PdfName.Ch.compareTo(type)) {
         writer.println("Choicebox");
     } else if (0 == PdfName.Sig.compareTo(type)) {
         writer.println("Signature");
     } else if (0 == PdfName.Tx.compareTo(type)) {
         writer.println("Text");
 
     }else {
         writer.println("?");
     }
 }
 // Get possible values for field "CP_1"
 writer.println("Possible values for CP_1:");
 String[] states = form.getField("CP_1").getAppearanceStates();
 for (int i = 0; i < states.length; i++) {
     writer.print(" - ");
     writer.println(states[i]);
 }
 // Get possible values for field "category"
 writer.println("Possible values for category:");
 states = form.getField("category").getAppearanceStates();
 for (int i = 0; i < states.length - 1; i++) {
     writer.print(states[i]);
     writer.print(", ");
 }
 
writer.println(states[states.length - 1]);

This code snippet stores the types of the fields, as well as the possible values of a radio field and a checkbox.

If you execute it on datasheet.pdf, you get the following result:

title: Text
director: Text
CP_1: Checkbox
CP_2: Checkbox
CP_3: Checkbox
GP_3: Checkbox
GP_4: Checkbox
GP_7: Checkbox
GP_8: Checkbox
MA_2: Checkbox
MA_3: Checkbox
category: Radiobutton
category.1: Radiobutton
category.2: Radiobutton
category.3: Radiobutton
category.4: Radiobutton
category.5: Radiobutton
category.6: Radiobutton
category.7: Radiobutton
category.8: Radiobutton
category.9: Radiobutton
category.10: Radiobutton
category.11: Radiobutton
category.12: Radiobutton
category.13: Radiobutton
category.14: Radiobutton
category.15: Radiobutton
category.16: Radiobutton
category.17: Radiobutton
category.18: Radiobutton
category.19: Radiobutton
duration: Text
year: Text
Possible values for CP_1:
 - Off
 - Yes
Possible values for category:
spec, toro, anim, comp, hero, Off, worl, rive, teen, kim, kauf, zha, fest, s-am, fdir, lee, kubr, kuro, fran, scan

So far so good, but then comes the second question:

How do I find the check type? How do I change it?

That question reveals a lack of understanding of PDF. When we looked for the possible values of a check box (or radio button) in the previous answer, we asked for the different appearance states. These appearance states are small pieces of content that are expressed in PDF syntax.

For instance: take a look at a form with some radio buttons and check boxes.

When we look at it on the outside, we see:

Form with radio buttons and check boxes
Form with radio buttons and check boxes

The check box next to "English" can be an empty square or a square with a pinkish background and a cross. Now let's take a look at the inside:

Looking under the hood of a form
Looking under the hood of a form

We see that this is the table check box, and we see that there are two appearance states: /Yes and /Off. What these states look like when selected, is described in a stream.

The stream of the /Off state is rather simple:

Syntax off state
Syntax off state

You immediately see that we are constructing a rectangle (re) and drawing it without filling it (S).

The /Yes state is slightly more complex:

Syntax yes state
Syntax yes state

We see that the fill color is being changed (rg), and that we stroke the rectangle in black and fill it using the fill color that was defined (B). Then we define two lines with moveTo (m) and lineTo (l) operations and we stroke them (S).

If you are proficient in PDF syntax, it is easy to see that we're drawing a cross inside a colored rectangle. So that answers your question on condition that you're proficient in PDF...

If you want to replace the appearance, then you have to replace the stream that draws the rectangle and the cross.. In IText 7 we added some popular appearances, so you can easily use them while creating elements like:

createCheckBox(PdfDocument doc, Rectangle rect, String name, String value, int checkType)

Where checkType can be: TYPE_CHECK, TYPE_CIRCLE, TYPE_CROSS, TYPE_DIAMOND, TYPE_SQUARE, TYPE_STAR. Or you can also change the appearance of existing element using:

setCheckType(int checkType).

Click this link if you want to see how to answer this question in iText 5.