Dear Aspose Developers!
Could you please suggest how to change style of form fields?
For example, in code below I wanted to change color of form field to RED if field name starts with letter ‘A’:
Document doc = new Document(args[0]);
for (Node n: doc.getRange().getFormFields())
{
FormField field = (FormField) n;
if (field.getName().startsWith("A"))
{
field.getFont().setColor(Color.RED);
if (field.getType() == FieldType.FIELD_FORM_TEXT_INPUT)
{
field.setResult("*");
}
else if (field.getType() == FieldType.FIELD_FORM_CHECK_BOX)
{
field.setChecked(true);
}
}
}
All works file except setting new color.
The attachment contains Java source, Java complied class and 3 doc-files:
- Input file
- Output file
- Expected file (created manually)
Best regards, Evgeniy
Hi Evgeniy,
Thanks for your request. This problem is logged in our defect database as issue #830. I will notify you as soon as it is fixed.
Best regards.
Hi Alexey,
Thank for quick reply.
Could you suggest a workaround how to set new color? I tried to use DocumentVisitor and overwrite method visitRun() (for mark checkbox), visitSpecialChar() (for mark text field).
The code below works but I’m afraid this is not a system appoach. We could find it only by empiric way.
private class TextFieldColorChanger extends DocumentVisitor
{
public int visitSpecialChar(SpecialChar specialChar) throws Exception
{
specialChar.getFont().setColor(Color.RED);
return super.visitSpecialChar(specialChar);
}
}
private class CheckboxColorChanger extends DocumentVisitor
{
public int visitRun(Run run) throws Exception
{
run.getFont().setColor(Color.RED);
return super.visitRun(run);
}
}
then, field.getParentNode().accept(visitor)
private static void markEmptyField(FormField field) throws Exception
{
boolean mark = false;
for (Object o: field.getParentNode().getChildNodes())
{
Node node = (Node)o;
if (node.getNodeType() == NodeType.BOOKMARK_START && ((BookmarkStart)node).getName().equals(field.getName()))
{
mark = true;
}
else if (node.getNodeType() == NodeType.BOOKMARK_END && ((BookmarkEnd)node).getName().equals(field.getName()))
{
mark = false;
}
if (mark)
{
if (node instanceof Inline)
{
((Inline)node).getFont().setColor(Color.RED);
}
}
If you can comment how this works - why using method visitSpecialChar() and suggest some simplified code - this would be appreciated.
Best regards, Evgeniy
Hi Evgeniy,
Thanks for your inquiry. I created Document visitor that will highlight formfields in your document. Please see code below:
Document doc = new Document("C:\\Temp\\Doc1.doc");
// set values of formfields
for (Node n: doc.getRange().getFormFields())
{
FormField field = (FormField) n;
if (field.getName().startsWith("A"))
{
if (field.getType() == FieldType.FIELD_FORM_TEXT_INPUT)
{
field.setResult("*");
}
else if (field.getType() == FieldType.FIELD_FORM_CHECK_BOX)
{
field.setChecked(true);
}
}
}
// Accept visitor that will change formating of formfields
FormFieldHighlighter visitor = new FormFieldHighlighter();
doc.accept(visitor);
doc.save("C:\\Temp\\out.doc");
public class FormFieldHighlighter extends DocumentVisitor
{
///
/// Called when a Run node is encountered in the document.
///
public int visitRun(Run run)
{
// Change formatign of run
if (mIsFormatChangeNeeded)
{
// Change formatign of run
run.getFont().setColor(Color.RED);
}
// Let the visitor continue visiting other nodes.
return VisitorAction.CONTINUE;
}
public int visitSpecialChar(SpecialChar specialChar)
{
// Change formatign of spacial characters. this is needed
// because empty formafields is represented as sequence of non-breaking spaces
if (mIsFormatChangeNeeded)
{
// Change formatign of run
specialChar.getFont().setColor(Color.RED);
}
return VisitorAction.CONTINUE;
}
///
/// Called when a FieldStart node is encountered in the document.
///
public int visitFieldStart(FieldStart fieldStart)
{
// If field start is start of formfield
if (fieldStart.getFieldType() == FieldType.FIELD_FORM_TEXT_INPUT ||
fieldStart.getFieldType() == FieldType.FIELD_FORM_CHECK_BOX ||
fieldStart.getFieldType() == FieldType.FIELD_FORM_DROP_DOWN)
{
// We should change formatign of runs that epresents field code.
// It seesm color of Checkboxes is inherited from field code
// Search for formfield node to check its name
Node curentNode = fieldStart;
while (curentNode.getNodeType() != NodeType.FORM_FIELD)
{
curentNode = curentNode.getNextSibling();
if (curentNode == null)
break;
}
// Set flagg that indicates that we should change formatign of formfield
if (curentNode != null)
{
try
{
mIsFormatChangeNeeded = IsFormattignChangesNeeded((FormField) curentNode);
}
catch (Exception ex)
{
mIsFormatChangeNeeded = false;
}
}
}
return VisitorAction.CONTINUE;
}
///
/// Called when a FieldEnd node is encountered in the document.
///
public int visitFieldEnd(FieldEnd fieldEnd)
{
if (fieldEnd.getFieldType() == FieldType.FIELD_FORM_TEXT_INPUT ||
fieldEnd.getFieldType() == FieldType.FIELD_FORM_CHECK_BOX ||
fieldEnd.getFieldType() == FieldType.FIELD_FORM_DROP_DOWN)
mIsFormatChangeNeeded = false;
return VisitorAction.CONTINUE;
}
///
/// Called when a FormField node is encountered in the document.
///
public int visitFormField(FormField formField)
{
try
{
mIsFormatChangeNeeded = IsFormattignChangesNeeded(formField);
}
catch (Exception ex)
{
mIsFormatChangeNeeded = false;
}
return VisitorAction.CONTINUE;
}
private boolean IsFormattignChangesNeeded(FormField formField) throws Exception
{
return formField.getName().startsWith("A");
}
// flag that indicates that this is formfield and we need to change formatign of text
private boolean mIsFormatChangeNeeded = false;
}
Hope this helps.
Best regards.
Thank you very much, Alexey!
Your comments and code are great!
The issues you have found earlier (filed as WORDSNET-522) have been fixed in this Aspose.Words for .NET 20.9 update and this Aspose.Words for Java 20.9 update.