public class Comment extends InlineStory
To learn more, visit the Working with Comments documentation article.
Remarks:
A comment is an annotation which is anchored to a region of text or to a position in text. A comment can contain an arbitrary amount of block-level content.
If a Comment object occurs on its own, the comment is anchored to the position of the Comment object.
To anchor a comment to a region of text three objects are required: Comment, CommentRangeStart and CommentRangeEnd. All three objects need to share the same getId() / setId(int) value.
Comment is an inline-level node and can only be a child of Paragraph.
Comment can contain Paragraph and Table child nodes.
Examples:
Shows how to add a comment to a paragraph.
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
builder.write("Hello world!");
Comment comment = new Comment(doc, "John Doe", "JD", new Date());
builder.getCurrentParagraph().appendChild(comment);
builder.moveTo(comment.appendChild(new Paragraph(doc)));
builder.write("Comment text.");
Assert.assertEquals(new Date(), comment.getDateTime());
// In Microsoft Word, we can right-click this comment in the document body to edit it, or reply to it.
doc.save(getArtifactsDir() + "InlineStory.AddComment.docx");
Shows how to add a comment to a document, and then reply to it.
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
Comment comment = new Comment(doc, "John Doe", "J.D.", new Date());
comment.setText("My comment.");
// Place the comment at a node in the document's body.
// This comment will show up at the location of its paragraph,
// outside the right-side margin of the page, and with a dotted line connecting it to its paragraph.
builder.getCurrentParagraph().appendChild(comment);
// Add a reply, which will show up under its parent comment.
comment.addReply("Joe Bloggs", "J.B.", new Date(), "New reply");
// Comments and replies are both Comment nodes.
Assert.assertEquals(2, doc.getChildNodes(NodeType.COMMENT, true).getCount());
// Comments that do not reply to other comments are "top-level". They have no ancestor comments.
Assert.assertNull(comment.getAncestor());
// Replies have an ancestor top-level comment.
Assert.assertEquals(comment, comment.getReplies().get(0).getAncestor());
doc.save(getArtifactsDir() + "Comment.AddCommentWithReply.docx");
CommentRangeStart,
CommentRangeEnd| Constructor and Description |
|---|
Comment(DocumentBase doc)
Initializes a new instance of the
Comment class. |
Comment(DocumentBase doc,
java.lang.String author,
java.lang.String initial,
java.util.Date dateTime)
Initializes a new instance of the
Comment class. |
| Modifier and Type | Method and Description |
|---|---|
boolean |
accept(DocumentVisitor visitor)
Accepts a visitor.
|
int |
acceptEnd(DocumentVisitor visitor)
Accepts a visitor for visiting the end of the comment.
|
int |
acceptStart(DocumentVisitor visitor)
Accepts a visitor for visiting the start of the comment.
|
Comment |
addReply(java.lang.String author,
java.lang.String initial,
java.util.Date dateTime,
java.lang.String text)
Adds a reply to this comment.
|
Comment |
getAncestor()
Returns the parent
Comment object. |
java.lang.String |
getAuthor()
Gets the author name for a comment.
|
java.util.Date |
getDateTime()
Gets the date and time that the comment was made.
|
java.util.Date |
getDateTimeUtc()
Gets the UTC date and time that the comment was made.
|
boolean |
getDone()
Gets flag indicating that the comment has been marked done.
|
int |
getId()
Gets the comment identifier.
|
int |
getIdInternal() |
java.lang.String |
getInitial()
Gets the initials of the user associated with a specific comment.
|
int |
getNodeType()
Returns
NodeType.COMMENT. |
int |
getParentId()
Gets the parent comment ID.
|
int |
getParentIdInternal() |
CommentCollection |
getReplies()
Returns a collection of
Comment objects that are immediate children of the specified comment. |
int |
getStoryType()
Returns
StoryType.COMMENTS. |
void |
removeAllReplies()
Removes all replies to this comment.
|
void |
removeMoveRevisions() |
void |
removeReply(Comment reply)
Removes the specified reply to this comment.
|
void |
setAuthor(java.lang.String value)
Sets the author name for a comment.
|
void |
setDateTime(java.util.Date value)
Gets the date and time that the comment was made.
|
void |
setDone(boolean value)
Sets flag indicating that the comment has been marked done.
|
void |
setId(int value)
Sets the comment identifier.
|
void |
setIdInternal(int value) |
void |
setInitial(java.lang.String value)
Sets the initials of the user associated with a specific comment.
|
void |
setParentId(int value)
Sets the parent comment ID.
|
void |
setParentIdInternal(int value) |
void |
setText(java.lang.String text)
This is a convenience method that allows to easily set text of the comment.
|
clearRunAttrs, ensureMinimum, fetchInheritedRunAttr, getDirectRunAttr, getDirectRunAttr, getDocument_IInline, getFirstParagraph, getFont, getLastParagraph, getParagraphs, getParentParagraph_IInline, getParentParagraph, getTables, isDeleteRevision, isInsertRevision, isMoveFromRevision, isMoveToRevision, removeRunAttr, setRunAttracceptChildren, acceptCore, appendChild, coreRemoveSelfOnly, getChild, getChildNodes, getContainer, getCount, getCurrentNode, getFirstChild, getLastChild, getNextMatchingNode, getText, hasChildNodes, indexOf, insertAfter, insertBefore, isComposite, iterator, prependChild, removeAllChildren, removeChild, removeSmartTags, selectNodes, selectSingleNodedeepClone, getAncestor, getAncestor, getCustomNodeId, getDocument, getNextSibling, getParentNode, getPreviousSibling, getRange, memberwiseClone, nextPreOrder, nodeTypeToString, previousPreOrder, remove, setCustomNodeId, toString, toString, toString, visitorActionToBoolpublic Comment(DocumentBase doc)
Comment class.
Remarks:
When Comment is created, it belongs to the specified document, but is not yet part of the document and Node.getParentNode() is null.
To append Comment to the document use CompositeNode.insertAfter(com.aspose.words.Node, com.aspose.words.Node) or CompositeNode.insertBefore(com.aspose.words.Node, com.aspose.words.Node) on the paragraph where you want the comment inserted.
After creating a comment, don't forget to set its getAuthor() / setAuthor(java.lang.String), getInitial() / setInitial(java.lang.String) and getDateTime() / setDateTime(java.util.Date) properties.
Examples:
Shows how print the contents of all comments and their comment ranges using a document visitor.
public void createCommentsAndPrintAllInfo() throws Exception {
Document doc = new Document();
Comment newComment = new Comment(doc);
{
newComment.setAuthor("VDeryushev");
newComment.setInitial("VD");
newComment.setDateTime(new Date());
}
newComment.setText("Comment regarding text.");
// Add text to the document, warp it in a comment range, and then add your comment.
Paragraph para = doc.getFirstSection().getBody().getFirstParagraph();
para.appendChild(new CommentRangeStart(doc, newComment.getId()));
para.appendChild(new Run(doc, "Commented text."));
para.appendChild(new CommentRangeEnd(doc, newComment.getId()));
para.appendChild(newComment);
// Add two replies to the comment.
newComment.addReply("John Doe", "JD", new Date(), "New reply.");
newComment.addReply("John Doe", "JD", new Date(), "Another reply.");
printAllCommentInfo(doc.getChildNodes(NodeType.COMMENT, true));
}
/// <summary>
/// Iterates over every top-level comment and prints its comment range, contents, and replies.
/// </summary>
private static void printAllCommentInfo(NodeCollection comments) throws Exception {
CommentInfoPrinter commentVisitor = new CommentInfoPrinter();
// Iterate over all top-level comments. Unlike reply-type comments, top-level comments have no ancestor.
for (Comment comment : (Iterable<Comment>) comments) {
if (comment.getAncestor() == null) {
// First, visit the start of the comment range.
CommentRangeStart commentRangeStart = (CommentRangeStart) comment.getPreviousSibling().getPreviousSibling().getPreviousSibling();
commentRangeStart.accept(commentVisitor);
// Then, visit the comment, and any replies that it may have.
comment.accept(commentVisitor);
for (Comment reply : comment.getReplies())
reply.accept(commentVisitor);
// Finally, visit the end of the comment range, and then print the visitor's text contents.
CommentRangeEnd commentRangeEnd = (CommentRangeEnd) comment.getPreviousSibling();
commentRangeEnd.accept(commentVisitor);
System.out.println(commentVisitor.getText());
}
}
}
/// <summary>
/// Prints information and contents of all comments and comment ranges encountered in the document.
/// </summary>
public static class CommentInfoPrinter extends DocumentVisitor {
public CommentInfoPrinter() {
mBuilder = new StringBuilder();
mVisitorIsInsideComment = false;
}
/// <summary>
/// Gets the plain text of the document that was accumulated by the visitor.
/// </summary>
public String getText() {
return mBuilder.toString();
}
/// <summary>
/// Called when a Run node is encountered in the document.
/// </summary>
public int visitRun(Run run) {
if (mVisitorIsInsideComment) indentAndAppendLine("[Run] \"" + run.getText() + "\"");
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a CommentRangeStart node is encountered in the document.
/// </summary>
public int visitCommentRangeStart(CommentRangeStart commentRangeStart) {
indentAndAppendLine("[Comment range start] ID: " + commentRangeStart.getId());
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a CommentRangeEnd node is encountered in the document.
/// </summary>
public int visitCommentRangeEnd(CommentRangeEnd commentRangeEnd) {
mDocTraversalDepth--;
indentAndAppendLine("[Comment range end] ID: " + commentRangeEnd.getId() + "\n");
mVisitorIsInsideComment = false;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a Comment node is encountered in the document.
/// </summary>
public int visitCommentStart(Comment comment) {
indentAndAppendLine(MessageFormat.format("[Comment start] For comment range ID {0}, By {1} on {2}", comment.getId(),
comment.getAuthor(), comment.getDateTime()));
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when the visiting of a Comment node is ended in the document.
/// </summary>
public int visitCommentEnd(Comment comment) {
mDocTraversalDepth--;
indentAndAppendLine("[Comment end]");
mVisitorIsInsideComment = false;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Append a line to the StringBuilder and indent it depending on how deep the visitor is into the document tree.
/// </summary>
/// <param name="text"></param>
private void indentAndAppendLine(String text) {
for (int i = 0; i < mDocTraversalDepth; i++) {
mBuilder.append("| ");
}
mBuilder.append(text + "\r\n");
}
private boolean mVisitorIsInsideComment;
private int mDocTraversalDepth;
private final StringBuilder mBuilder;
}
doc - The owner document.public Comment(DocumentBase doc, java.lang.String author, java.lang.String initial, java.util.Date dateTime)
Comment class.
Examples:
Shows how to add a comment to a paragraph.
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
builder.write("Hello world!");
Comment comment = new Comment(doc, "John Doe", "JD", new Date());
builder.getCurrentParagraph().appendChild(comment);
builder.moveTo(comment.appendChild(new Paragraph(doc)));
builder.write("Comment text.");
Assert.assertEquals(new Date(), comment.getDateTime());
// In Microsoft Word, we can right-click this comment in the document body to edit it, or reply to it.
doc.save(getArtifactsDir() + "InlineStory.AddComment.docx");
doc - The owner document.author - The author name for the comment. Cannot be null.initial - The author initials for the comment. Cannot be null.dateTime - The date and time for the comment.public int getNodeType()
NodeType.COMMENT.
Examples:
Shows how to traverse a composite node's tree of child nodes.
public void recurseChildren() throws Exception {
Document doc = new Document(getMyDir() + "Paragraphs.docx");
// Any node that can contain child nodes, such as the document itself, is composite.
Assert.assertTrue(doc.isComposite());
// Invoke the recursive function that will go through and print all the child nodes of a composite node.
traverseAllNodes(doc, 0);
}
/// <summary>
/// Recursively traverses a node tree while printing the type of each node
/// with an indent depending on depth as well as the contents of all inline nodes.
/// </summary>
public void traverseAllNodes(CompositeNode parentNode, int depth) {
for (Node childNode = parentNode.getFirstChild(); childNode != null; childNode = childNode.getNextSibling()) {
System.out.println(MessageFormat.format("{0}{1}", String.format(" ", depth), Node.nodeTypeToString(childNode.getNodeType())));
// Recurse into the node if it is a composite node. Otherwise, print its contents if it is an inline node.
if (childNode.isComposite()) {
System.out.println();
traverseAllNodes((CompositeNode) childNode, depth + 1);
} else if (childNode instanceof Inline) {
System.out.println(MessageFormat.format(" - \"{0}\"", childNode.getText().trim()));
} else {
System.out.println();
}
}
}
getNodeType in class NodeNodeType.COMMENT. The returned value is one of NodeType constants.public int getStoryType()
StoryType.COMMENTS.
Examples:
Shows how to insert InlineStory nodes.
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
Footnote footnote = builder.insertFootnote(FootnoteType.FOOTNOTE, null);
// Table nodes have an "EnsureMinimum()" method that makes sure the table has at least one cell.
Table table = new Table(doc);
table.ensureMinimum();
// We can place a table inside a footnote, which will make it appear at the referencing page's footer.
Assert.assertEquals(footnote.getTables().getCount(), 0);
footnote.appendChild(table);
Assert.assertEquals(footnote.getTables().getCount(), 1);
Assert.assertEquals(footnote.getLastChild().getNodeType(), NodeType.TABLE);
// An InlineStory has an "EnsureMinimum()" method as well, but in this case,
// it makes sure the last child of the node is a paragraph,
// for us to be able to click and write text easily in Microsoft Word.
footnote.ensureMinimum();
Assert.assertEquals(footnote.getLastChild().getNodeType(), NodeType.PARAGRAPH);
// Edit the appearance of the anchor, which is the small superscript number
// in the main text that points to the footnote.
footnote.getFont().setName("Arial");
footnote.getFont().setColor(Color.GREEN);
// All inline story nodes have their respective story types.
Assert.assertEquals(footnote.getStoryType(), StoryType.FOOTNOTES);
// A comment is another type of inline story.
Comment comment = (Comment) builder.getCurrentParagraph().appendChild(new Comment(doc, "John Doe", "J. D.", new Date()));
// The parent paragraph of an inline story node will be the one from the main document body.
Assert.assertEquals(doc.getFirstSection().getBody().getFirstParagraph(), comment.getParentParagraph());
// However, the last paragraph is the one from the comment text contents,
// which will be outside the main document body in a speech bubble.
// A comment will not have any child nodes by default,
// so we can apply the EnsureMinimum() method to place a paragraph here as well.
Assert.assertNull(comment.getLastParagraph());
comment.ensureMinimum();
Assert.assertEquals(comment.getLastChild().getNodeType(), NodeType.PARAGRAPH);
// Once we have a paragraph, we can move the builder to do it and write our comment.
builder.moveTo(comment.getLastParagraph());
builder.write("My comment.");
Assert.assertEquals(comment.getStoryType(), StoryType.COMMENTS);
doc.save(getArtifactsDir() + "InlineStory.InsertInlineStoryNodes.docx");
getStoryType in class InlineStoryStoryType.COMMENTS. The returned value is one of StoryType constants.public int getId()
Remarks:
The comment identifier allows to anchor a comment to a region of text in the document. The region must be demarcated using the CommentRangeStart and CommentRangeEnd object sharing the same identifier value as the Comment object.
You would use this value when looking for the CommentRangeStart and CommentRangeEnd nodes that are linked to this comment.
Comment identifiers are supposed to be unique across a document and Aspose.Words automatically maintains comment identifiers when loading, saving and combining documents.
Examples:
Shows how print the contents of all comments and their comment ranges using a document visitor.
public void createCommentsAndPrintAllInfo() throws Exception {
Document doc = new Document();
Comment newComment = new Comment(doc);
{
newComment.setAuthor("VDeryushev");
newComment.setInitial("VD");
newComment.setDateTime(new Date());
}
newComment.setText("Comment regarding text.");
// Add text to the document, warp it in a comment range, and then add your comment.
Paragraph para = doc.getFirstSection().getBody().getFirstParagraph();
para.appendChild(new CommentRangeStart(doc, newComment.getId()));
para.appendChild(new Run(doc, "Commented text."));
para.appendChild(new CommentRangeEnd(doc, newComment.getId()));
para.appendChild(newComment);
// Add two replies to the comment.
newComment.addReply("John Doe", "JD", new Date(), "New reply.");
newComment.addReply("John Doe", "JD", new Date(), "Another reply.");
printAllCommentInfo(doc.getChildNodes(NodeType.COMMENT, true));
}
/// <summary>
/// Iterates over every top-level comment and prints its comment range, contents, and replies.
/// </summary>
private static void printAllCommentInfo(NodeCollection comments) throws Exception {
CommentInfoPrinter commentVisitor = new CommentInfoPrinter();
// Iterate over all top-level comments. Unlike reply-type comments, top-level comments have no ancestor.
for (Comment comment : (Iterable<Comment>) comments) {
if (comment.getAncestor() == null) {
// First, visit the start of the comment range.
CommentRangeStart commentRangeStart = (CommentRangeStart) comment.getPreviousSibling().getPreviousSibling().getPreviousSibling();
commentRangeStart.accept(commentVisitor);
// Then, visit the comment, and any replies that it may have.
comment.accept(commentVisitor);
for (Comment reply : comment.getReplies())
reply.accept(commentVisitor);
// Finally, visit the end of the comment range, and then print the visitor's text contents.
CommentRangeEnd commentRangeEnd = (CommentRangeEnd) comment.getPreviousSibling();
commentRangeEnd.accept(commentVisitor);
System.out.println(commentVisitor.getText());
}
}
}
/// <summary>
/// Prints information and contents of all comments and comment ranges encountered in the document.
/// </summary>
public static class CommentInfoPrinter extends DocumentVisitor {
public CommentInfoPrinter() {
mBuilder = new StringBuilder();
mVisitorIsInsideComment = false;
}
/// <summary>
/// Gets the plain text of the document that was accumulated by the visitor.
/// </summary>
public String getText() {
return mBuilder.toString();
}
/// <summary>
/// Called when a Run node is encountered in the document.
/// </summary>
public int visitRun(Run run) {
if (mVisitorIsInsideComment) indentAndAppendLine("[Run] \"" + run.getText() + "\"");
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a CommentRangeStart node is encountered in the document.
/// </summary>
public int visitCommentRangeStart(CommentRangeStart commentRangeStart) {
indentAndAppendLine("[Comment range start] ID: " + commentRangeStart.getId());
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a CommentRangeEnd node is encountered in the document.
/// </summary>
public int visitCommentRangeEnd(CommentRangeEnd commentRangeEnd) {
mDocTraversalDepth--;
indentAndAppendLine("[Comment range end] ID: " + commentRangeEnd.getId() + "\n");
mVisitorIsInsideComment = false;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a Comment node is encountered in the document.
/// </summary>
public int visitCommentStart(Comment comment) {
indentAndAppendLine(MessageFormat.format("[Comment start] For comment range ID {0}, By {1} on {2}", comment.getId(),
comment.getAuthor(), comment.getDateTime()));
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when the visiting of a Comment node is ended in the document.
/// </summary>
public int visitCommentEnd(Comment comment) {
mDocTraversalDepth--;
indentAndAppendLine("[Comment end]");
mVisitorIsInsideComment = false;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Append a line to the StringBuilder and indent it depending on how deep the visitor is into the document tree.
/// </summary>
/// <param name="text"></param>
private void indentAndAppendLine(String text) {
for (int i = 0; i < mDocTraversalDepth; i++) {
mBuilder.append("| ");
}
mBuilder.append(text + "\r\n");
}
private boolean mVisitorIsInsideComment;
private int mDocTraversalDepth;
private final StringBuilder mBuilder;
}
public void setId(int value)
Remarks:
The comment identifier allows to anchor a comment to a region of text in the document. The region must be demarcated using the CommentRangeStart and CommentRangeEnd object sharing the same identifier value as the Comment object.
You would use this value when looking for the CommentRangeStart and CommentRangeEnd nodes that are linked to this comment.
Comment identifiers are supposed to be unique across a document and Aspose.Words automatically maintains comment identifiers when loading, saving and combining documents.
Examples:
Shows how print the contents of all comments and their comment ranges using a document visitor.
public void createCommentsAndPrintAllInfo() throws Exception {
Document doc = new Document();
Comment newComment = new Comment(doc);
{
newComment.setAuthor("VDeryushev");
newComment.setInitial("VD");
newComment.setDateTime(new Date());
}
newComment.setText("Comment regarding text.");
// Add text to the document, warp it in a comment range, and then add your comment.
Paragraph para = doc.getFirstSection().getBody().getFirstParagraph();
para.appendChild(new CommentRangeStart(doc, newComment.getId()));
para.appendChild(new Run(doc, "Commented text."));
para.appendChild(new CommentRangeEnd(doc, newComment.getId()));
para.appendChild(newComment);
// Add two replies to the comment.
newComment.addReply("John Doe", "JD", new Date(), "New reply.");
newComment.addReply("John Doe", "JD", new Date(), "Another reply.");
printAllCommentInfo(doc.getChildNodes(NodeType.COMMENT, true));
}
/// <summary>
/// Iterates over every top-level comment and prints its comment range, contents, and replies.
/// </summary>
private static void printAllCommentInfo(NodeCollection comments) throws Exception {
CommentInfoPrinter commentVisitor = new CommentInfoPrinter();
// Iterate over all top-level comments. Unlike reply-type comments, top-level comments have no ancestor.
for (Comment comment : (Iterable<Comment>) comments) {
if (comment.getAncestor() == null) {
// First, visit the start of the comment range.
CommentRangeStart commentRangeStart = (CommentRangeStart) comment.getPreviousSibling().getPreviousSibling().getPreviousSibling();
commentRangeStart.accept(commentVisitor);
// Then, visit the comment, and any replies that it may have.
comment.accept(commentVisitor);
for (Comment reply : comment.getReplies())
reply.accept(commentVisitor);
// Finally, visit the end of the comment range, and then print the visitor's text contents.
CommentRangeEnd commentRangeEnd = (CommentRangeEnd) comment.getPreviousSibling();
commentRangeEnd.accept(commentVisitor);
System.out.println(commentVisitor.getText());
}
}
}
/// <summary>
/// Prints information and contents of all comments and comment ranges encountered in the document.
/// </summary>
public static class CommentInfoPrinter extends DocumentVisitor {
public CommentInfoPrinter() {
mBuilder = new StringBuilder();
mVisitorIsInsideComment = false;
}
/// <summary>
/// Gets the plain text of the document that was accumulated by the visitor.
/// </summary>
public String getText() {
return mBuilder.toString();
}
/// <summary>
/// Called when a Run node is encountered in the document.
/// </summary>
public int visitRun(Run run) {
if (mVisitorIsInsideComment) indentAndAppendLine("[Run] \"" + run.getText() + "\"");
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a CommentRangeStart node is encountered in the document.
/// </summary>
public int visitCommentRangeStart(CommentRangeStart commentRangeStart) {
indentAndAppendLine("[Comment range start] ID: " + commentRangeStart.getId());
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a CommentRangeEnd node is encountered in the document.
/// </summary>
public int visitCommentRangeEnd(CommentRangeEnd commentRangeEnd) {
mDocTraversalDepth--;
indentAndAppendLine("[Comment range end] ID: " + commentRangeEnd.getId() + "\n");
mVisitorIsInsideComment = false;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a Comment node is encountered in the document.
/// </summary>
public int visitCommentStart(Comment comment) {
indentAndAppendLine(MessageFormat.format("[Comment start] For comment range ID {0}, By {1} on {2}", comment.getId(),
comment.getAuthor(), comment.getDateTime()));
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when the visiting of a Comment node is ended in the document.
/// </summary>
public int visitCommentEnd(Comment comment) {
mDocTraversalDepth--;
indentAndAppendLine("[Comment end]");
mVisitorIsInsideComment = false;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Append a line to the StringBuilder and indent it depending on how deep the visitor is into the document tree.
/// </summary>
/// <param name="text"></param>
private void indentAndAppendLine(String text) {
for (int i = 0; i < mDocTraversalDepth; i++) {
mBuilder.append("| ");
}
mBuilder.append(text + "\r\n");
}
private boolean mVisitorIsInsideComment;
private int mDocTraversalDepth;
private final StringBuilder mBuilder;
}
value - The comment identifier.public int getIdInternal()
public void setIdInternal(int value)
public int getParentIdInternal()
public void setParentIdInternal(int value)
public java.lang.String getInitial()
Remarks:
Cannot be null.
Default is empty string.
Examples:
Shows how print the contents of all comments and their comment ranges using a document visitor.
public void createCommentsAndPrintAllInfo() throws Exception {
Document doc = new Document();
Comment newComment = new Comment(doc);
{
newComment.setAuthor("VDeryushev");
newComment.setInitial("VD");
newComment.setDateTime(new Date());
}
newComment.setText("Comment regarding text.");
// Add text to the document, warp it in a comment range, and then add your comment.
Paragraph para = doc.getFirstSection().getBody().getFirstParagraph();
para.appendChild(new CommentRangeStart(doc, newComment.getId()));
para.appendChild(new Run(doc, "Commented text."));
para.appendChild(new CommentRangeEnd(doc, newComment.getId()));
para.appendChild(newComment);
// Add two replies to the comment.
newComment.addReply("John Doe", "JD", new Date(), "New reply.");
newComment.addReply("John Doe", "JD", new Date(), "Another reply.");
printAllCommentInfo(doc.getChildNodes(NodeType.COMMENT, true));
}
/// <summary>
/// Iterates over every top-level comment and prints its comment range, contents, and replies.
/// </summary>
private static void printAllCommentInfo(NodeCollection comments) throws Exception {
CommentInfoPrinter commentVisitor = new CommentInfoPrinter();
// Iterate over all top-level comments. Unlike reply-type comments, top-level comments have no ancestor.
for (Comment comment : (Iterable<Comment>) comments) {
if (comment.getAncestor() == null) {
// First, visit the start of the comment range.
CommentRangeStart commentRangeStart = (CommentRangeStart) comment.getPreviousSibling().getPreviousSibling().getPreviousSibling();
commentRangeStart.accept(commentVisitor);
// Then, visit the comment, and any replies that it may have.
comment.accept(commentVisitor);
for (Comment reply : comment.getReplies())
reply.accept(commentVisitor);
// Finally, visit the end of the comment range, and then print the visitor's text contents.
CommentRangeEnd commentRangeEnd = (CommentRangeEnd) comment.getPreviousSibling();
commentRangeEnd.accept(commentVisitor);
System.out.println(commentVisitor.getText());
}
}
}
/// <summary>
/// Prints information and contents of all comments and comment ranges encountered in the document.
/// </summary>
public static class CommentInfoPrinter extends DocumentVisitor {
public CommentInfoPrinter() {
mBuilder = new StringBuilder();
mVisitorIsInsideComment = false;
}
/// <summary>
/// Gets the plain text of the document that was accumulated by the visitor.
/// </summary>
public String getText() {
return mBuilder.toString();
}
/// <summary>
/// Called when a Run node is encountered in the document.
/// </summary>
public int visitRun(Run run) {
if (mVisitorIsInsideComment) indentAndAppendLine("[Run] \"" + run.getText() + "\"");
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a CommentRangeStart node is encountered in the document.
/// </summary>
public int visitCommentRangeStart(CommentRangeStart commentRangeStart) {
indentAndAppendLine("[Comment range start] ID: " + commentRangeStart.getId());
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a CommentRangeEnd node is encountered in the document.
/// </summary>
public int visitCommentRangeEnd(CommentRangeEnd commentRangeEnd) {
mDocTraversalDepth--;
indentAndAppendLine("[Comment range end] ID: " + commentRangeEnd.getId() + "\n");
mVisitorIsInsideComment = false;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a Comment node is encountered in the document.
/// </summary>
public int visitCommentStart(Comment comment) {
indentAndAppendLine(MessageFormat.format("[Comment start] For comment range ID {0}, By {1} on {2}", comment.getId(),
comment.getAuthor(), comment.getDateTime()));
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when the visiting of a Comment node is ended in the document.
/// </summary>
public int visitCommentEnd(Comment comment) {
mDocTraversalDepth--;
indentAndAppendLine("[Comment end]");
mVisitorIsInsideComment = false;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Append a line to the StringBuilder and indent it depending on how deep the visitor is into the document tree.
/// </summary>
/// <param name="text"></param>
private void indentAndAppendLine(String text) {
for (int i = 0; i < mDocTraversalDepth; i++) {
mBuilder.append("| ");
}
mBuilder.append(text + "\r\n");
}
private boolean mVisitorIsInsideComment;
private int mDocTraversalDepth;
private final StringBuilder mBuilder;
}
public void setInitial(java.lang.String value)
Remarks:
Cannot be null.
Default is empty string.
Examples:
Shows how print the contents of all comments and their comment ranges using a document visitor.
public void createCommentsAndPrintAllInfo() throws Exception {
Document doc = new Document();
Comment newComment = new Comment(doc);
{
newComment.setAuthor("VDeryushev");
newComment.setInitial("VD");
newComment.setDateTime(new Date());
}
newComment.setText("Comment regarding text.");
// Add text to the document, warp it in a comment range, and then add your comment.
Paragraph para = doc.getFirstSection().getBody().getFirstParagraph();
para.appendChild(new CommentRangeStart(doc, newComment.getId()));
para.appendChild(new Run(doc, "Commented text."));
para.appendChild(new CommentRangeEnd(doc, newComment.getId()));
para.appendChild(newComment);
// Add two replies to the comment.
newComment.addReply("John Doe", "JD", new Date(), "New reply.");
newComment.addReply("John Doe", "JD", new Date(), "Another reply.");
printAllCommentInfo(doc.getChildNodes(NodeType.COMMENT, true));
}
/// <summary>
/// Iterates over every top-level comment and prints its comment range, contents, and replies.
/// </summary>
private static void printAllCommentInfo(NodeCollection comments) throws Exception {
CommentInfoPrinter commentVisitor = new CommentInfoPrinter();
// Iterate over all top-level comments. Unlike reply-type comments, top-level comments have no ancestor.
for (Comment comment : (Iterable<Comment>) comments) {
if (comment.getAncestor() == null) {
// First, visit the start of the comment range.
CommentRangeStart commentRangeStart = (CommentRangeStart) comment.getPreviousSibling().getPreviousSibling().getPreviousSibling();
commentRangeStart.accept(commentVisitor);
// Then, visit the comment, and any replies that it may have.
comment.accept(commentVisitor);
for (Comment reply : comment.getReplies())
reply.accept(commentVisitor);
// Finally, visit the end of the comment range, and then print the visitor's text contents.
CommentRangeEnd commentRangeEnd = (CommentRangeEnd) comment.getPreviousSibling();
commentRangeEnd.accept(commentVisitor);
System.out.println(commentVisitor.getText());
}
}
}
/// <summary>
/// Prints information and contents of all comments and comment ranges encountered in the document.
/// </summary>
public static class CommentInfoPrinter extends DocumentVisitor {
public CommentInfoPrinter() {
mBuilder = new StringBuilder();
mVisitorIsInsideComment = false;
}
/// <summary>
/// Gets the plain text of the document that was accumulated by the visitor.
/// </summary>
public String getText() {
return mBuilder.toString();
}
/// <summary>
/// Called when a Run node is encountered in the document.
/// </summary>
public int visitRun(Run run) {
if (mVisitorIsInsideComment) indentAndAppendLine("[Run] \"" + run.getText() + "\"");
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a CommentRangeStart node is encountered in the document.
/// </summary>
public int visitCommentRangeStart(CommentRangeStart commentRangeStart) {
indentAndAppendLine("[Comment range start] ID: " + commentRangeStart.getId());
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a CommentRangeEnd node is encountered in the document.
/// </summary>
public int visitCommentRangeEnd(CommentRangeEnd commentRangeEnd) {
mDocTraversalDepth--;
indentAndAppendLine("[Comment range end] ID: " + commentRangeEnd.getId() + "\n");
mVisitorIsInsideComment = false;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a Comment node is encountered in the document.
/// </summary>
public int visitCommentStart(Comment comment) {
indentAndAppendLine(MessageFormat.format("[Comment start] For comment range ID {0}, By {1} on {2}", comment.getId(),
comment.getAuthor(), comment.getDateTime()));
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when the visiting of a Comment node is ended in the document.
/// </summary>
public int visitCommentEnd(Comment comment) {
mDocTraversalDepth--;
indentAndAppendLine("[Comment end]");
mVisitorIsInsideComment = false;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Append a line to the StringBuilder and indent it depending on how deep the visitor is into the document tree.
/// </summary>
/// <param name="text"></param>
private void indentAndAppendLine(String text) {
for (int i = 0; i < mDocTraversalDepth; i++) {
mBuilder.append("| ");
}
mBuilder.append(text + "\r\n");
}
private boolean mVisitorIsInsideComment;
private int mDocTraversalDepth;
private final StringBuilder mBuilder;
}
value - The initials of the user associated with a specific comment.public java.util.Date getDateTime()
Remarks:
Default is 03.01.0001
Examples:
Shows how print the contents of all comments and their comment ranges using a document visitor.
public void createCommentsAndPrintAllInfo() throws Exception {
Document doc = new Document();
Comment newComment = new Comment(doc);
{
newComment.setAuthor("VDeryushev");
newComment.setInitial("VD");
newComment.setDateTime(new Date());
}
newComment.setText("Comment regarding text.");
// Add text to the document, warp it in a comment range, and then add your comment.
Paragraph para = doc.getFirstSection().getBody().getFirstParagraph();
para.appendChild(new CommentRangeStart(doc, newComment.getId()));
para.appendChild(new Run(doc, "Commented text."));
para.appendChild(new CommentRangeEnd(doc, newComment.getId()));
para.appendChild(newComment);
// Add two replies to the comment.
newComment.addReply("John Doe", "JD", new Date(), "New reply.");
newComment.addReply("John Doe", "JD", new Date(), "Another reply.");
printAllCommentInfo(doc.getChildNodes(NodeType.COMMENT, true));
}
/// <summary>
/// Iterates over every top-level comment and prints its comment range, contents, and replies.
/// </summary>
private static void printAllCommentInfo(NodeCollection comments) throws Exception {
CommentInfoPrinter commentVisitor = new CommentInfoPrinter();
// Iterate over all top-level comments. Unlike reply-type comments, top-level comments have no ancestor.
for (Comment comment : (Iterable<Comment>) comments) {
if (comment.getAncestor() == null) {
// First, visit the start of the comment range.
CommentRangeStart commentRangeStart = (CommentRangeStart) comment.getPreviousSibling().getPreviousSibling().getPreviousSibling();
commentRangeStart.accept(commentVisitor);
// Then, visit the comment, and any replies that it may have.
comment.accept(commentVisitor);
for (Comment reply : comment.getReplies())
reply.accept(commentVisitor);
// Finally, visit the end of the comment range, and then print the visitor's text contents.
CommentRangeEnd commentRangeEnd = (CommentRangeEnd) comment.getPreviousSibling();
commentRangeEnd.accept(commentVisitor);
System.out.println(commentVisitor.getText());
}
}
}
/// <summary>
/// Prints information and contents of all comments and comment ranges encountered in the document.
/// </summary>
public static class CommentInfoPrinter extends DocumentVisitor {
public CommentInfoPrinter() {
mBuilder = new StringBuilder();
mVisitorIsInsideComment = false;
}
/// <summary>
/// Gets the plain text of the document that was accumulated by the visitor.
/// </summary>
public String getText() {
return mBuilder.toString();
}
/// <summary>
/// Called when a Run node is encountered in the document.
/// </summary>
public int visitRun(Run run) {
if (mVisitorIsInsideComment) indentAndAppendLine("[Run] \"" + run.getText() + "\"");
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a CommentRangeStart node is encountered in the document.
/// </summary>
public int visitCommentRangeStart(CommentRangeStart commentRangeStart) {
indentAndAppendLine("[Comment range start] ID: " + commentRangeStart.getId());
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a CommentRangeEnd node is encountered in the document.
/// </summary>
public int visitCommentRangeEnd(CommentRangeEnd commentRangeEnd) {
mDocTraversalDepth--;
indentAndAppendLine("[Comment range end] ID: " + commentRangeEnd.getId() + "\n");
mVisitorIsInsideComment = false;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a Comment node is encountered in the document.
/// </summary>
public int visitCommentStart(Comment comment) {
indentAndAppendLine(MessageFormat.format("[Comment start] For comment range ID {0}, By {1} on {2}", comment.getId(),
comment.getAuthor(), comment.getDateTime()));
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when the visiting of a Comment node is ended in the document.
/// </summary>
public int visitCommentEnd(Comment comment) {
mDocTraversalDepth--;
indentAndAppendLine("[Comment end]");
mVisitorIsInsideComment = false;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Append a line to the StringBuilder and indent it depending on how deep the visitor is into the document tree.
/// </summary>
/// <param name="text"></param>
private void indentAndAppendLine(String text) {
for (int i = 0; i < mDocTraversalDepth; i++) {
mBuilder.append("| ");
}
mBuilder.append(text + "\r\n");
}
private boolean mVisitorIsInsideComment;
private int mDocTraversalDepth;
private final StringBuilder mBuilder;
}
public void setDateTime(java.util.Date value)
Remarks:
Default is 03.01.0001
Examples:
Shows how print the contents of all comments and their comment ranges using a document visitor.
public void createCommentsAndPrintAllInfo() throws Exception {
Document doc = new Document();
Comment newComment = new Comment(doc);
{
newComment.setAuthor("VDeryushev");
newComment.setInitial("VD");
newComment.setDateTime(new Date());
}
newComment.setText("Comment regarding text.");
// Add text to the document, warp it in a comment range, and then add your comment.
Paragraph para = doc.getFirstSection().getBody().getFirstParagraph();
para.appendChild(new CommentRangeStart(doc, newComment.getId()));
para.appendChild(new Run(doc, "Commented text."));
para.appendChild(new CommentRangeEnd(doc, newComment.getId()));
para.appendChild(newComment);
// Add two replies to the comment.
newComment.addReply("John Doe", "JD", new Date(), "New reply.");
newComment.addReply("John Doe", "JD", new Date(), "Another reply.");
printAllCommentInfo(doc.getChildNodes(NodeType.COMMENT, true));
}
/// <summary>
/// Iterates over every top-level comment and prints its comment range, contents, and replies.
/// </summary>
private static void printAllCommentInfo(NodeCollection comments) throws Exception {
CommentInfoPrinter commentVisitor = new CommentInfoPrinter();
// Iterate over all top-level comments. Unlike reply-type comments, top-level comments have no ancestor.
for (Comment comment : (Iterable<Comment>) comments) {
if (comment.getAncestor() == null) {
// First, visit the start of the comment range.
CommentRangeStart commentRangeStart = (CommentRangeStart) comment.getPreviousSibling().getPreviousSibling().getPreviousSibling();
commentRangeStart.accept(commentVisitor);
// Then, visit the comment, and any replies that it may have.
comment.accept(commentVisitor);
for (Comment reply : comment.getReplies())
reply.accept(commentVisitor);
// Finally, visit the end of the comment range, and then print the visitor's text contents.
CommentRangeEnd commentRangeEnd = (CommentRangeEnd) comment.getPreviousSibling();
commentRangeEnd.accept(commentVisitor);
System.out.println(commentVisitor.getText());
}
}
}
/// <summary>
/// Prints information and contents of all comments and comment ranges encountered in the document.
/// </summary>
public static class CommentInfoPrinter extends DocumentVisitor {
public CommentInfoPrinter() {
mBuilder = new StringBuilder();
mVisitorIsInsideComment = false;
}
/// <summary>
/// Gets the plain text of the document that was accumulated by the visitor.
/// </summary>
public String getText() {
return mBuilder.toString();
}
/// <summary>
/// Called when a Run node is encountered in the document.
/// </summary>
public int visitRun(Run run) {
if (mVisitorIsInsideComment) indentAndAppendLine("[Run] \"" + run.getText() + "\"");
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a CommentRangeStart node is encountered in the document.
/// </summary>
public int visitCommentRangeStart(CommentRangeStart commentRangeStart) {
indentAndAppendLine("[Comment range start] ID: " + commentRangeStart.getId());
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a CommentRangeEnd node is encountered in the document.
/// </summary>
public int visitCommentRangeEnd(CommentRangeEnd commentRangeEnd) {
mDocTraversalDepth--;
indentAndAppendLine("[Comment range end] ID: " + commentRangeEnd.getId() + "\n");
mVisitorIsInsideComment = false;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a Comment node is encountered in the document.
/// </summary>
public int visitCommentStart(Comment comment) {
indentAndAppendLine(MessageFormat.format("[Comment start] For comment range ID {0}, By {1} on {2}", comment.getId(),
comment.getAuthor(), comment.getDateTime()));
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when the visiting of a Comment node is ended in the document.
/// </summary>
public int visitCommentEnd(Comment comment) {
mDocTraversalDepth--;
indentAndAppendLine("[Comment end]");
mVisitorIsInsideComment = false;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Append a line to the StringBuilder and indent it depending on how deep the visitor is into the document tree.
/// </summary>
/// <param name="text"></param>
private void indentAndAppendLine(String text) {
for (int i = 0; i < mDocTraversalDepth; i++) {
mBuilder.append("| ");
}
mBuilder.append(text + "\r\n");
}
private boolean mVisitorIsInsideComment;
private int mDocTraversalDepth;
private final StringBuilder mBuilder;
}
value - The date and time that the comment was made.public java.util.Date getDateTimeUtc()
Remarks:
The default value is 03.01.0001
Examples:
Shows how to get UTC date and time.
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
Date dateTime = new Date();
Comment comment = new Comment(doc, "John Doe", "J.D.", dateTime);
comment.setText("My comment.");
builder.getCurrentParagraph().appendChild(comment);
doc.save(getArtifactsDir() + "Comment.UtcDateTime.docx");
doc = new Document(getArtifactsDir() + "Comment.UtcDateTime.docx");
comment = (Comment)doc.getChild(NodeType.COMMENT, 0, true);
// DateTimeUtc return data without milliseconds.
Assert.assertEquals(dateTime.toString(), comment.getDateTimeUtc().toString());
public java.lang.String getAuthor()
Remarks:
Cannot be null.
Default is empty string.
Examples:
Shows how to print all of a document's comments and their replies.
Document doc = new Document(getMyDir() + "Comments.docx");
NodeCollection comments = doc.getChildNodes(NodeType.COMMENT, true);
// If a comment has no ancestor, it is a "top-level" comment as opposed to a reply-type comment.
// Print all top-level comments along with any replies they may have.
for (Comment comment : (Iterable<Comment>) comments) {
if (comment.getAncestor() == null) {
System.out.println("Top-level comment:");
System.out.println("\t\"{comment.GetText().Trim()}\", by {comment.Author}");
System.out.println("Has {comment.Replies.Count} replies");
for (Comment commentReply : comment.getReplies()) {
System.out.println("\t\"{commentReply.GetText().Trim()}\", by {commentReply.Author}");
}
System.out.println();
}
}
public void setAuthor(java.lang.String value)
Remarks:
Cannot be null.
Default is empty string.
Examples:
Shows how to print all of a document's comments and their replies.
Document doc = new Document(getMyDir() + "Comments.docx");
NodeCollection comments = doc.getChildNodes(NodeType.COMMENT, true);
// If a comment has no ancestor, it is a "top-level" comment as opposed to a reply-type comment.
// Print all top-level comments along with any replies they may have.
for (Comment comment : (Iterable<Comment>) comments) {
if (comment.getAncestor() == null) {
System.out.println("Top-level comment:");
System.out.println("\t\"{comment.GetText().Trim()}\", by {comment.Author}");
System.out.println("Has {comment.Replies.Count} replies");
for (Comment commentReply : comment.getReplies()) {
System.out.println("\t\"{commentReply.GetText().Trim()}\", by {commentReply.Author}");
}
System.out.println();
}
}
value - The author name for a comment.public boolean accept(DocumentVisitor visitor) throws java.lang.Exception
Remarks:
Enumerates over this node and all of its children. Each node calls a corresponding method on DocumentVisitor.
For more info see the Visitor design pattern.
Calls DocumentVisitor.visitCommentStart(com.aspose.words.Comment), then calls Node.accept(com.aspose.words.DocumentVisitor) for all child nodes of the comment and calls DocumentVisitor.visitCommentEnd(com.aspose.words.Comment) at the end.
Examples:
Shows how print the contents of all comments and their comment ranges using a document visitor.
public void createCommentsAndPrintAllInfo() throws Exception {
Document doc = new Document();
Comment newComment = new Comment(doc);
{
newComment.setAuthor("VDeryushev");
newComment.setInitial("VD");
newComment.setDateTime(new Date());
}
newComment.setText("Comment regarding text.");
// Add text to the document, warp it in a comment range, and then add your comment.
Paragraph para = doc.getFirstSection().getBody().getFirstParagraph();
para.appendChild(new CommentRangeStart(doc, newComment.getId()));
para.appendChild(new Run(doc, "Commented text."));
para.appendChild(new CommentRangeEnd(doc, newComment.getId()));
para.appendChild(newComment);
// Add two replies to the comment.
newComment.addReply("John Doe", "JD", new Date(), "New reply.");
newComment.addReply("John Doe", "JD", new Date(), "Another reply.");
printAllCommentInfo(doc.getChildNodes(NodeType.COMMENT, true));
}
/// <summary>
/// Iterates over every top-level comment and prints its comment range, contents, and replies.
/// </summary>
private static void printAllCommentInfo(NodeCollection comments) throws Exception {
CommentInfoPrinter commentVisitor = new CommentInfoPrinter();
// Iterate over all top-level comments. Unlike reply-type comments, top-level comments have no ancestor.
for (Comment comment : (Iterable<Comment>) comments) {
if (comment.getAncestor() == null) {
// First, visit the start of the comment range.
CommentRangeStart commentRangeStart = (CommentRangeStart) comment.getPreviousSibling().getPreviousSibling().getPreviousSibling();
commentRangeStart.accept(commentVisitor);
// Then, visit the comment, and any replies that it may have.
comment.accept(commentVisitor);
for (Comment reply : comment.getReplies())
reply.accept(commentVisitor);
// Finally, visit the end of the comment range, and then print the visitor's text contents.
CommentRangeEnd commentRangeEnd = (CommentRangeEnd) comment.getPreviousSibling();
commentRangeEnd.accept(commentVisitor);
System.out.println(commentVisitor.getText());
}
}
}
/// <summary>
/// Prints information and contents of all comments and comment ranges encountered in the document.
/// </summary>
public static class CommentInfoPrinter extends DocumentVisitor {
public CommentInfoPrinter() {
mBuilder = new StringBuilder();
mVisitorIsInsideComment = false;
}
/// <summary>
/// Gets the plain text of the document that was accumulated by the visitor.
/// </summary>
public String getText() {
return mBuilder.toString();
}
/// <summary>
/// Called when a Run node is encountered in the document.
/// </summary>
public int visitRun(Run run) {
if (mVisitorIsInsideComment) indentAndAppendLine("[Run] \"" + run.getText() + "\"");
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a CommentRangeStart node is encountered in the document.
/// </summary>
public int visitCommentRangeStart(CommentRangeStart commentRangeStart) {
indentAndAppendLine("[Comment range start] ID: " + commentRangeStart.getId());
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a CommentRangeEnd node is encountered in the document.
/// </summary>
public int visitCommentRangeEnd(CommentRangeEnd commentRangeEnd) {
mDocTraversalDepth--;
indentAndAppendLine("[Comment range end] ID: " + commentRangeEnd.getId() + "\n");
mVisitorIsInsideComment = false;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a Comment node is encountered in the document.
/// </summary>
public int visitCommentStart(Comment comment) {
indentAndAppendLine(MessageFormat.format("[Comment start] For comment range ID {0}, By {1} on {2}", comment.getId(),
comment.getAuthor(), comment.getDateTime()));
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when the visiting of a Comment node is ended in the document.
/// </summary>
public int visitCommentEnd(Comment comment) {
mDocTraversalDepth--;
indentAndAppendLine("[Comment end]");
mVisitorIsInsideComment = false;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Append a line to the StringBuilder and indent it depending on how deep the visitor is into the document tree.
/// </summary>
/// <param name="text"></param>
private void indentAndAppendLine(String text) {
for (int i = 0; i < mDocTraversalDepth; i++) {
mBuilder.append("| ");
}
mBuilder.append(text + "\r\n");
}
private boolean mVisitorIsInsideComment;
private int mDocTraversalDepth;
private final StringBuilder mBuilder;
}
accept in class Nodevisitor - The visitor that will visit the nodes.DocumentVisitor stopped the operation before visiting all nodes.java.lang.Exceptionpublic Comment addReply(java.lang.String author, java.lang.String initial, java.util.Date dateTime, java.lang.String text) throws java.lang.Exception
author - The author name for the reply.initial - The author initials for the reply.dateTime - The date and time for the reply.text - The reply text.Comment node for the reply.java.lang.IllegalStateException - Throws if this method is called on the existing Reply comment.
Remarks:
Due to the existing MS Office limitations only 1 level of replies is allowed in the document.
Examples:
Shows how to add a comment to a document, and then reply to it.
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
Comment comment = new Comment(doc, "John Doe", "J.D.", new Date());
comment.setText("My comment.");
// Place the comment at a node in the document's body.
// This comment will show up at the location of its paragraph,
// outside the right-side margin of the page, and with a dotted line connecting it to its paragraph.
builder.getCurrentParagraph().appendChild(comment);
// Add a reply, which will show up under its parent comment.
comment.addReply("Joe Bloggs", "J.B.", new Date(), "New reply");
// Comments and replies are both Comment nodes.
Assert.assertEquals(2, doc.getChildNodes(NodeType.COMMENT, true).getCount());
// Comments that do not reply to other comments are "top-level". They have no ancestor comments.
Assert.assertNull(comment.getAncestor());
// Replies have an ancestor top-level comment.
Assert.assertEquals(comment, comment.getReplies().get(0).getAncestor());
doc.save(getArtifactsDir() + "Comment.AddCommentWithReply.docx");
java.lang.Exceptionpublic void removeReply(Comment reply) throws java.lang.Exception
Remarks:
All constituent nodes of the reply will be deleted from the document.
Examples:
Shows how to remove comment replies.
Document doc = new Document();
Comment comment = new Comment(doc, "John Doe", "J.D.", new Date());
comment.setText("My comment.");
doc.getFirstSection().getBody().getFirstParagraph().appendChild(comment);
comment.addReply("Joe Bloggs", "J.B.", new Date(), "New reply");
comment.addReply("Joe Bloggs", "J.B.", new Date(), "Another reply");
Assert.assertEquals(2, comment.getReplies().getCount());
// Below are two ways of removing replies from a comment.
// 1 - Use the "RemoveReply" method to remove replies from a comment individually:
comment.removeReply(comment.getReplies().get(0));
Assert.assertEquals(1, comment.getReplies().getCount());
// 2 - Use the "RemoveAllReplies" method to remove all replies from a comment at once:
comment.removeAllReplies();
Assert.assertEquals(0, comment.getReplies().getCount());
reply - The comment node of the deleting reply.java.lang.Exceptionpublic void removeAllReplies()
throws java.lang.Exception
Remarks:
All constituent nodes of the replies will be deleted from the document.
Examples:
Shows how to remove comment replies.
Document doc = new Document();
Comment comment = new Comment(doc, "John Doe", "J.D.", new Date());
comment.setText("My comment.");
doc.getFirstSection().getBody().getFirstParagraph().appendChild(comment);
comment.addReply("Joe Bloggs", "J.B.", new Date(), "New reply");
comment.addReply("Joe Bloggs", "J.B.", new Date(), "Another reply");
Assert.assertEquals(2, comment.getReplies().getCount());
// Below are two ways of removing replies from a comment.
// 1 - Use the "RemoveReply" method to remove replies from a comment individually:
comment.removeReply(comment.getReplies().get(0));
Assert.assertEquals(1, comment.getReplies().getCount());
// 2 - Use the "RemoveAllReplies" method to remove all replies from a comment at once:
comment.removeAllReplies();
Assert.assertEquals(0, comment.getReplies().getCount());
java.lang.Exceptionpublic int acceptStart(DocumentVisitor visitor) throws java.lang.Exception
Examples:
Shows how print the contents of all comments and their comment ranges using a document visitor.
public void createCommentsAndPrintAllInfo() throws Exception {
Document doc = new Document();
Comment newComment = new Comment(doc);
{
newComment.setAuthor("VDeryushev");
newComment.setInitial("VD");
newComment.setDateTime(new Date());
}
newComment.setText("Comment regarding text.");
// Add text to the document, warp it in a comment range, and then add your comment.
Paragraph para = doc.getFirstSection().getBody().getFirstParagraph();
para.appendChild(new CommentRangeStart(doc, newComment.getId()));
para.appendChild(new Run(doc, "Commented text."));
para.appendChild(new CommentRangeEnd(doc, newComment.getId()));
para.appendChild(newComment);
// Add two replies to the comment.
newComment.addReply("John Doe", "JD", new Date(), "New reply.");
newComment.addReply("John Doe", "JD", new Date(), "Another reply.");
printAllCommentInfo(doc.getChildNodes(NodeType.COMMENT, true));
}
/// <summary>
/// Iterates over every top-level comment and prints its comment range, contents, and replies.
/// </summary>
private static void printAllCommentInfo(NodeCollection comments) throws Exception {
CommentInfoPrinter commentVisitor = new CommentInfoPrinter();
// Iterate over all top-level comments. Unlike reply-type comments, top-level comments have no ancestor.
for (Comment comment : (Iterable<Comment>) comments) {
if (comment.getAncestor() == null) {
// First, visit the start of the comment range.
CommentRangeStart commentRangeStart = (CommentRangeStart) comment.getPreviousSibling().getPreviousSibling().getPreviousSibling();
commentRangeStart.accept(commentVisitor);
// Then, visit the comment, and any replies that it may have.
comment.accept(commentVisitor);
for (Comment reply : comment.getReplies())
reply.accept(commentVisitor);
// Finally, visit the end of the comment range, and then print the visitor's text contents.
CommentRangeEnd commentRangeEnd = (CommentRangeEnd) comment.getPreviousSibling();
commentRangeEnd.accept(commentVisitor);
System.out.println(commentVisitor.getText());
}
}
}
/// <summary>
/// Prints information and contents of all comments and comment ranges encountered in the document.
/// </summary>
public static class CommentInfoPrinter extends DocumentVisitor {
public CommentInfoPrinter() {
mBuilder = new StringBuilder();
mVisitorIsInsideComment = false;
}
/// <summary>
/// Gets the plain text of the document that was accumulated by the visitor.
/// </summary>
public String getText() {
return mBuilder.toString();
}
/// <summary>
/// Called when a Run node is encountered in the document.
/// </summary>
public int visitRun(Run run) {
if (mVisitorIsInsideComment) indentAndAppendLine("[Run] \"" + run.getText() + "\"");
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a CommentRangeStart node is encountered in the document.
/// </summary>
public int visitCommentRangeStart(CommentRangeStart commentRangeStart) {
indentAndAppendLine("[Comment range start] ID: " + commentRangeStart.getId());
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a CommentRangeEnd node is encountered in the document.
/// </summary>
public int visitCommentRangeEnd(CommentRangeEnd commentRangeEnd) {
mDocTraversalDepth--;
indentAndAppendLine("[Comment range end] ID: " + commentRangeEnd.getId() + "\n");
mVisitorIsInsideComment = false;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a Comment node is encountered in the document.
/// </summary>
public int visitCommentStart(Comment comment) {
indentAndAppendLine(MessageFormat.format("[Comment start] For comment range ID {0}, By {1} on {2}", comment.getId(),
comment.getAuthor(), comment.getDateTime()));
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when the visiting of a Comment node is ended in the document.
/// </summary>
public int visitCommentEnd(Comment comment) {
mDocTraversalDepth--;
indentAndAppendLine("[Comment end]");
mVisitorIsInsideComment = false;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Append a line to the StringBuilder and indent it depending on how deep the visitor is into the document tree.
/// </summary>
/// <param name="text"></param>
private void indentAndAppendLine(String text) {
for (int i = 0; i < mDocTraversalDepth; i++) {
mBuilder.append("| ");
}
mBuilder.append(text + "\r\n");
}
private boolean mVisitorIsInsideComment;
private int mDocTraversalDepth;
private final StringBuilder mBuilder;
}
acceptStart in class CompositeNodevisitor - The document visitor.VisitorAction constants.java.lang.Exceptionpublic int acceptEnd(DocumentVisitor visitor) throws java.lang.Exception
Examples:
Shows how print the contents of all comments and their comment ranges using a document visitor.
public void createCommentsAndPrintAllInfo() throws Exception {
Document doc = new Document();
Comment newComment = new Comment(doc);
{
newComment.setAuthor("VDeryushev");
newComment.setInitial("VD");
newComment.setDateTime(new Date());
}
newComment.setText("Comment regarding text.");
// Add text to the document, warp it in a comment range, and then add your comment.
Paragraph para = doc.getFirstSection().getBody().getFirstParagraph();
para.appendChild(new CommentRangeStart(doc, newComment.getId()));
para.appendChild(new Run(doc, "Commented text."));
para.appendChild(new CommentRangeEnd(doc, newComment.getId()));
para.appendChild(newComment);
// Add two replies to the comment.
newComment.addReply("John Doe", "JD", new Date(), "New reply.");
newComment.addReply("John Doe", "JD", new Date(), "Another reply.");
printAllCommentInfo(doc.getChildNodes(NodeType.COMMENT, true));
}
/// <summary>
/// Iterates over every top-level comment and prints its comment range, contents, and replies.
/// </summary>
private static void printAllCommentInfo(NodeCollection comments) throws Exception {
CommentInfoPrinter commentVisitor = new CommentInfoPrinter();
// Iterate over all top-level comments. Unlike reply-type comments, top-level comments have no ancestor.
for (Comment comment : (Iterable<Comment>) comments) {
if (comment.getAncestor() == null) {
// First, visit the start of the comment range.
CommentRangeStart commentRangeStart = (CommentRangeStart) comment.getPreviousSibling().getPreviousSibling().getPreviousSibling();
commentRangeStart.accept(commentVisitor);
// Then, visit the comment, and any replies that it may have.
comment.accept(commentVisitor);
for (Comment reply : comment.getReplies())
reply.accept(commentVisitor);
// Finally, visit the end of the comment range, and then print the visitor's text contents.
CommentRangeEnd commentRangeEnd = (CommentRangeEnd) comment.getPreviousSibling();
commentRangeEnd.accept(commentVisitor);
System.out.println(commentVisitor.getText());
}
}
}
/// <summary>
/// Prints information and contents of all comments and comment ranges encountered in the document.
/// </summary>
public static class CommentInfoPrinter extends DocumentVisitor {
public CommentInfoPrinter() {
mBuilder = new StringBuilder();
mVisitorIsInsideComment = false;
}
/// <summary>
/// Gets the plain text of the document that was accumulated by the visitor.
/// </summary>
public String getText() {
return mBuilder.toString();
}
/// <summary>
/// Called when a Run node is encountered in the document.
/// </summary>
public int visitRun(Run run) {
if (mVisitorIsInsideComment) indentAndAppendLine("[Run] \"" + run.getText() + "\"");
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a CommentRangeStart node is encountered in the document.
/// </summary>
public int visitCommentRangeStart(CommentRangeStart commentRangeStart) {
indentAndAppendLine("[Comment range start] ID: " + commentRangeStart.getId());
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a CommentRangeEnd node is encountered in the document.
/// </summary>
public int visitCommentRangeEnd(CommentRangeEnd commentRangeEnd) {
mDocTraversalDepth--;
indentAndAppendLine("[Comment range end] ID: " + commentRangeEnd.getId() + "\n");
mVisitorIsInsideComment = false;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a Comment node is encountered in the document.
/// </summary>
public int visitCommentStart(Comment comment) {
indentAndAppendLine(MessageFormat.format("[Comment start] For comment range ID {0}, By {1} on {2}", comment.getId(),
comment.getAuthor(), comment.getDateTime()));
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when the visiting of a Comment node is ended in the document.
/// </summary>
public int visitCommentEnd(Comment comment) {
mDocTraversalDepth--;
indentAndAppendLine("[Comment end]");
mVisitorIsInsideComment = false;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Append a line to the StringBuilder and indent it depending on how deep the visitor is into the document tree.
/// </summary>
/// <param name="text"></param>
private void indentAndAppendLine(String text) {
for (int i = 0; i < mDocTraversalDepth; i++) {
mBuilder.append("| ");
}
mBuilder.append(text + "\r\n");
}
private boolean mVisitorIsInsideComment;
private int mDocTraversalDepth;
private final StringBuilder mBuilder;
}
acceptEnd in class CompositeNodevisitor - The document visitor.VisitorAction constants.java.lang.Exceptionpublic void setText(java.lang.String text)
Remarks:
This method allows to quickly set text of a comment from a string. The string can contain paragraph breaks, this will create paragraphs of text in the comment accordingly. If you want to insert more complex elements into the comment, for example bookmarks or tables or apply rich formatting, then you need to use the appropriate node classes to build up the comment text.
Examples:
Shows how to add a comment to a document, and then reply to it.
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
Comment comment = new Comment(doc, "John Doe", "J.D.", new Date());
comment.setText("My comment.");
// Place the comment at a node in the document's body.
// This comment will show up at the location of its paragraph,
// outside the right-side margin of the page, and with a dotted line connecting it to its paragraph.
builder.getCurrentParagraph().appendChild(comment);
// Add a reply, which will show up under its parent comment.
comment.addReply("Joe Bloggs", "J.B.", new Date(), "New reply");
// Comments and replies are both Comment nodes.
Assert.assertEquals(2, doc.getChildNodes(NodeType.COMMENT, true).getCount());
// Comments that do not reply to other comments are "top-level". They have no ancestor comments.
Assert.assertNull(comment.getAncestor());
// Replies have an ancestor top-level comment.
Assert.assertEquals(comment, comment.getReplies().get(0).getAncestor());
doc.save(getArtifactsDir() + "Comment.AddCommentWithReply.docx");
text - The new text of the comment.public Comment getAncestor()
Comment object. Returns null for top-level comments.
Examples:
Shows how to print all of a document's comments and their replies.
Document doc = new Document(getMyDir() + "Comments.docx");
NodeCollection comments = doc.getChildNodes(NodeType.COMMENT, true);
// If a comment has no ancestor, it is a "top-level" comment as opposed to a reply-type comment.
// Print all top-level comments along with any replies they may have.
for (Comment comment : (Iterable<Comment>) comments) {
if (comment.getAncestor() == null) {
System.out.println("Top-level comment:");
System.out.println("\t\"{comment.GetText().Trim()}\", by {comment.Author}");
System.out.println("Has {comment.Replies.Count} replies");
for (Comment commentReply : comment.getReplies()) {
System.out.println("\t\"{commentReply.GetText().Trim()}\", by {commentReply.Author}");
}
System.out.println();
}
}
Comment object.public CommentCollection getReplies()
Comment objects that are immediate children of the specified comment.
Examples:
Shows how to print all of a document's comments and their replies.
Document doc = new Document(getMyDir() + "Comments.docx");
NodeCollection comments = doc.getChildNodes(NodeType.COMMENT, true);
// If a comment has no ancestor, it is a "top-level" comment as opposed to a reply-type comment.
// Print all top-level comments along with any replies they may have.
for (Comment comment : (Iterable<Comment>) comments) {
if (comment.getAncestor() == null) {
System.out.println("Top-level comment:");
System.out.println("\t\"{comment.GetText().Trim()}\", by {comment.Author}");
System.out.println("Has {comment.Replies.Count} replies");
for (Comment commentReply : comment.getReplies()) {
System.out.println("\t\"{commentReply.GetText().Trim()}\", by {commentReply.Author}");
}
System.out.println();
}
}
Comment objects that are immediate children of the specified comment.public boolean getDone()
Examples:
Shows how to mark a comment as "done".
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
builder.writeln("Helo world!");
// Insert a comment to point out an error.
Comment comment = new Comment(doc, "John Doe", "J.D.", new Date());
comment.setText("Fix the spelling error!");
doc.getFirstSection().getBody().getFirstParagraph().appendChild(comment);
// Comments have a "Done" flag, which is set to "false" by default.
// If a comment suggests that we make a change within the document,
// we can apply the change, and then also set the "Done" flag afterwards to indicate the correction.
Assert.assertFalse(comment.getDone());
doc.getFirstSection().getBody().getFirstParagraph().getRuns().get(0).setText("Hello world!");
comment.setDone(true);
// Comments that are "done" will differentiate themselves
// from ones that are not "done" with a faded text color.
comment = new Comment(doc, "John Doe", "J.D.", new Date());
comment.setText("Add text to this paragraph.");
builder.getCurrentParagraph().appendChild(comment);
doc.save(getArtifactsDir() + "Comment.Done.docx");
Shows how print the contents of all comments and their comment ranges using a document visitor.
public void createCommentsAndPrintAllInfo() throws Exception {
Document doc = new Document();
Comment newComment = new Comment(doc);
{
newComment.setAuthor("VDeryushev");
newComment.setInitial("VD");
newComment.setDateTime(new Date());
}
newComment.setText("Comment regarding text.");
// Add text to the document, warp it in a comment range, and then add your comment.
Paragraph para = doc.getFirstSection().getBody().getFirstParagraph();
para.appendChild(new CommentRangeStart(doc, newComment.getId()));
para.appendChild(new Run(doc, "Commented text."));
para.appendChild(new CommentRangeEnd(doc, newComment.getId()));
para.appendChild(newComment);
// Add two replies to the comment.
newComment.addReply("John Doe", "JD", new Date(), "New reply.");
newComment.addReply("John Doe", "JD", new Date(), "Another reply.");
printAllCommentInfo(doc.getChildNodes(NodeType.COMMENT, true));
}
/// <summary>
/// Iterates over every top-level comment and prints its comment range, contents, and replies.
/// </summary>
private static void printAllCommentInfo(NodeCollection comments) throws Exception {
CommentInfoPrinter commentVisitor = new CommentInfoPrinter();
// Iterate over all top-level comments. Unlike reply-type comments, top-level comments have no ancestor.
for (Comment comment : (Iterable<Comment>) comments) {
if (comment.getAncestor() == null) {
// First, visit the start of the comment range.
CommentRangeStart commentRangeStart = (CommentRangeStart) comment.getPreviousSibling().getPreviousSibling().getPreviousSibling();
commentRangeStart.accept(commentVisitor);
// Then, visit the comment, and any replies that it may have.
comment.accept(commentVisitor);
for (Comment reply : comment.getReplies())
reply.accept(commentVisitor);
// Finally, visit the end of the comment range, and then print the visitor's text contents.
CommentRangeEnd commentRangeEnd = (CommentRangeEnd) comment.getPreviousSibling();
commentRangeEnd.accept(commentVisitor);
System.out.println(commentVisitor.getText());
}
}
}
/// <summary>
/// Prints information and contents of all comments and comment ranges encountered in the document.
/// </summary>
public static class CommentInfoPrinter extends DocumentVisitor {
public CommentInfoPrinter() {
mBuilder = new StringBuilder();
mVisitorIsInsideComment = false;
}
/// <summary>
/// Gets the plain text of the document that was accumulated by the visitor.
/// </summary>
public String getText() {
return mBuilder.toString();
}
/// <summary>
/// Called when a Run node is encountered in the document.
/// </summary>
public int visitRun(Run run) {
if (mVisitorIsInsideComment) indentAndAppendLine("[Run] \"" + run.getText() + "\"");
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a CommentRangeStart node is encountered in the document.
/// </summary>
public int visitCommentRangeStart(CommentRangeStart commentRangeStart) {
indentAndAppendLine("[Comment range start] ID: " + commentRangeStart.getId());
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a CommentRangeEnd node is encountered in the document.
/// </summary>
public int visitCommentRangeEnd(CommentRangeEnd commentRangeEnd) {
mDocTraversalDepth--;
indentAndAppendLine("[Comment range end] ID: " + commentRangeEnd.getId() + "\n");
mVisitorIsInsideComment = false;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a Comment node is encountered in the document.
/// </summary>
public int visitCommentStart(Comment comment) {
indentAndAppendLine(MessageFormat.format("[Comment start] For comment range ID {0}, By {1} on {2}", comment.getId(),
comment.getAuthor(), comment.getDateTime()));
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when the visiting of a Comment node is ended in the document.
/// </summary>
public int visitCommentEnd(Comment comment) {
mDocTraversalDepth--;
indentAndAppendLine("[Comment end]");
mVisitorIsInsideComment = false;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Append a line to the StringBuilder and indent it depending on how deep the visitor is into the document tree.
/// </summary>
/// <param name="text"></param>
private void indentAndAppendLine(String text) {
for (int i = 0; i < mDocTraversalDepth; i++) {
mBuilder.append("| ");
}
mBuilder.append(text + "\r\n");
}
private boolean mVisitorIsInsideComment;
private int mDocTraversalDepth;
private final StringBuilder mBuilder;
}
public void setDone(boolean value)
Examples:
Shows how to mark a comment as "done".
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
builder.writeln("Helo world!");
// Insert a comment to point out an error.
Comment comment = new Comment(doc, "John Doe", "J.D.", new Date());
comment.setText("Fix the spelling error!");
doc.getFirstSection().getBody().getFirstParagraph().appendChild(comment);
// Comments have a "Done" flag, which is set to "false" by default.
// If a comment suggests that we make a change within the document,
// we can apply the change, and then also set the "Done" flag afterwards to indicate the correction.
Assert.assertFalse(comment.getDone());
doc.getFirstSection().getBody().getFirstParagraph().getRuns().get(0).setText("Hello world!");
comment.setDone(true);
// Comments that are "done" will differentiate themselves
// from ones that are not "done" with a faded text color.
comment = new Comment(doc, "John Doe", "J.D.", new Date());
comment.setText("Add text to this paragraph.");
builder.getCurrentParagraph().appendChild(comment);
doc.save(getArtifactsDir() + "Comment.Done.docx");
Shows how print the contents of all comments and their comment ranges using a document visitor.
public void createCommentsAndPrintAllInfo() throws Exception {
Document doc = new Document();
Comment newComment = new Comment(doc);
{
newComment.setAuthor("VDeryushev");
newComment.setInitial("VD");
newComment.setDateTime(new Date());
}
newComment.setText("Comment regarding text.");
// Add text to the document, warp it in a comment range, and then add your comment.
Paragraph para = doc.getFirstSection().getBody().getFirstParagraph();
para.appendChild(new CommentRangeStart(doc, newComment.getId()));
para.appendChild(new Run(doc, "Commented text."));
para.appendChild(new CommentRangeEnd(doc, newComment.getId()));
para.appendChild(newComment);
// Add two replies to the comment.
newComment.addReply("John Doe", "JD", new Date(), "New reply.");
newComment.addReply("John Doe", "JD", new Date(), "Another reply.");
printAllCommentInfo(doc.getChildNodes(NodeType.COMMENT, true));
}
/// <summary>
/// Iterates over every top-level comment and prints its comment range, contents, and replies.
/// </summary>
private static void printAllCommentInfo(NodeCollection comments) throws Exception {
CommentInfoPrinter commentVisitor = new CommentInfoPrinter();
// Iterate over all top-level comments. Unlike reply-type comments, top-level comments have no ancestor.
for (Comment comment : (Iterable<Comment>) comments) {
if (comment.getAncestor() == null) {
// First, visit the start of the comment range.
CommentRangeStart commentRangeStart = (CommentRangeStart) comment.getPreviousSibling().getPreviousSibling().getPreviousSibling();
commentRangeStart.accept(commentVisitor);
// Then, visit the comment, and any replies that it may have.
comment.accept(commentVisitor);
for (Comment reply : comment.getReplies())
reply.accept(commentVisitor);
// Finally, visit the end of the comment range, and then print the visitor's text contents.
CommentRangeEnd commentRangeEnd = (CommentRangeEnd) comment.getPreviousSibling();
commentRangeEnd.accept(commentVisitor);
System.out.println(commentVisitor.getText());
}
}
}
/// <summary>
/// Prints information and contents of all comments and comment ranges encountered in the document.
/// </summary>
public static class CommentInfoPrinter extends DocumentVisitor {
public CommentInfoPrinter() {
mBuilder = new StringBuilder();
mVisitorIsInsideComment = false;
}
/// <summary>
/// Gets the plain text of the document that was accumulated by the visitor.
/// </summary>
public String getText() {
return mBuilder.toString();
}
/// <summary>
/// Called when a Run node is encountered in the document.
/// </summary>
public int visitRun(Run run) {
if (mVisitorIsInsideComment) indentAndAppendLine("[Run] \"" + run.getText() + "\"");
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a CommentRangeStart node is encountered in the document.
/// </summary>
public int visitCommentRangeStart(CommentRangeStart commentRangeStart) {
indentAndAppendLine("[Comment range start] ID: " + commentRangeStart.getId());
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a CommentRangeEnd node is encountered in the document.
/// </summary>
public int visitCommentRangeEnd(CommentRangeEnd commentRangeEnd) {
mDocTraversalDepth--;
indentAndAppendLine("[Comment range end] ID: " + commentRangeEnd.getId() + "\n");
mVisitorIsInsideComment = false;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a Comment node is encountered in the document.
/// </summary>
public int visitCommentStart(Comment comment) {
indentAndAppendLine(MessageFormat.format("[Comment start] For comment range ID {0}, By {1} on {2}", comment.getId(),
comment.getAuthor(), comment.getDateTime()));
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when the visiting of a Comment node is ended in the document.
/// </summary>
public int visitCommentEnd(Comment comment) {
mDocTraversalDepth--;
indentAndAppendLine("[Comment end]");
mVisitorIsInsideComment = false;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Append a line to the StringBuilder and indent it depending on how deep the visitor is into the document tree.
/// </summary>
/// <param name="text"></param>
private void indentAndAppendLine(String text) {
for (int i = 0; i < mDocTraversalDepth; i++) {
mBuilder.append("| ");
}
mBuilder.append(text + "\r\n");
}
private boolean mVisitorIsInsideComment;
private int mDocTraversalDepth;
private final StringBuilder mBuilder;
}
value - Flag indicating that the comment has been marked done.public int getParentId()
-1 means the comment has no parent.public void setParentId(int value)
-1 means the comment has no parent.value - The parent comment ID.public void removeMoveRevisions()