Undo/Redo PDF Edits - Java Sample Code

The Apryse SDK has a low-level facility for undo and redo operations. It is a API that applies to any edits made to a particular document (not just annotations). This sample code (provided in Python, C++, C#, Java, Node.js, PHP, Ruby, Go and VB) shows how to use Apryse SDK to walk back and forth on a fully general, bit-exact list of document states. Saving changes in a mode that is not 'incremental' will wipe out the undo-redo state list; the API will not be able to access old snapshots anymore. See the undoing and redoing guide for more information. Learn more about our Server SDK.

1//---------------------------------------------------------------------------------------
2// Copyright (c) 2001-2024 by Apryse Software Inc. All Rights Reserved.
3// Consult legal.txt regarding legal and license information.
4//---------------------------------------------------------------------------------------
5
6import com.pdftron.pdf.*;
7import com.pdftron.sdf.Obj;
8import com.pdftron.common.Matrix2D;
9import com.pdftron.common.PDFNetException;
10import com.pdftron.sdf.UndoManager;
11import com.pdftron.sdf.ResultSnapshot;
12import com.pdftron.sdf.DocSnapshot;
13import com.pdftron.sdf.SDFDoc;
14
15import java.io.File;
16import java.io.IOException;
17import java.io.FileNotFoundException;
18
19//---------------------------------------------------------------------------------------
20// The following sample illustrates how to use the UndoRedo API.
21//---------------------------------------------------------------------------------------
22public class UndoRedoTest
23{
24 public static void main(String[] args)
25 {
26 try
27 {
28 // The first step in every application using PDFNet is to initialize the
29 // library and set the path to common PDF resources. The library is usually
30 // initialized only once, but calling Initialize() multiple times is also fine.
31 PDFNet.initialize(PDFTronLicense.Key());
32
33 // Relative path to the folder containing test files.
34 String input_path = "../../TestFiles/";
35 String output_path = "../../TestFiles/Output/";
36
37 // Open the PDF document.
38 try (PDFDoc doc = new PDFDoc(input_path + "newsletter.pdf")) {
39
40 UndoManager undo_manager = doc.getUndoManager();
41
42 // Take a snapshot to which we can undo after making changes.
43 ResultSnapshot snap0 = undo_manager.takeSnapshot();
44
45 DocSnapshot snap0_state = snap0.currentState();
46
47 Page page = doc.pageCreate(); // Start a new page
48
49 ElementBuilder bld = new ElementBuilder(); // Used to build new Element objects
50 ElementWriter writer = new ElementWriter(); // Used to write Elements to the page
51 writer.begin(page); // Begin writing to this page
52
53 // ----------------------------------------------------------
54 // Add JPEG image to the file
55 Image img = Image.create(doc, input_path + "peppers.jpg");
56 Element element = bld.createImage(img, new Matrix2D(200, 0, 0, 250, 50, 500));
57 writer.writePlacedElement(element);
58
59 writer.end(); // Finish writing to the page
60 doc.pagePushFront(page);
61
62 // Take a snapshot after making changes, so that we can redo later (after undoing first).
63 ResultSnapshot snap1 = undo_manager.takeSnapshot();
64
65 if (snap1.previousState().equals(snap0_state))
66 {
67 System.out.println("snap1 previous state equals snap0_state; previous state is correct");
68 }
69
70 DocSnapshot snap1_state = snap1.currentState();
71
72 doc.save(output_path + "addimage.pdf", SDFDoc.SaveMode.INCREMENTAL, null);
73
74 if (undo_manager.canUndo())
75 {
76 ResultSnapshot undo_snap;
77 undo_snap = undo_manager.undo();
78
79 doc.save(output_path + "addimage_undone.pdf", SDFDoc.SaveMode.INCREMENTAL, null);
80
81 DocSnapshot undo_snap_state = undo_snap.currentState();
82
83 if (undo_snap_state.equals(snap0_state))
84 {
85 System.out.println("undo_snap_state equals snap0_state; undo was successful");
86 }
87
88 if (undo_manager.canRedo())
89 {
90 ResultSnapshot redo_snap = undo_manager.redo();
91
92 doc.save(output_path + "addimage_redone.pdf", SDFDoc.SaveMode.INCREMENTAL, null);
93
94 if (redo_snap.previousState().equals(undo_snap_state))
95 {
96 System.out.println("redo_snap previous state equals undo_snap_state; previous state is correct");
97 }
98
99 DocSnapshot redo_snap_state = redo_snap.currentState();
100
101 if (redo_snap_state.equals(snap1_state))
102 {
103 System.out.println("Snap1 and redo_snap are equal; redo was successful");
104 }
105 }
106 else
107 {
108 System.out.println("Problem encountered - cannot redo.");
109 }
110 }
111 else
112 {
113 System.out.println("Problem encountered - cannot undo.");
114 }
115 }
116
117 // Calling Terminate when PDFNet is no longer in use is a good practice, but
118 // is not required.
119 PDFNet.terminate();
120 }
121 catch (Exception e)
122 {
123 e.printStackTrace();
124 }
125 }
126}

Did you find this helpful?

Trial setup questions?

Ask experts on Discord

Need other help?

Contact Support

Pricing or product questions?

Contact Sales