Accessing the Adobe Acrobat Reader Control from Java Swing

Accessing the Adobe Acrobat Reader Control from Java Swing

Java/J2EE COM Interoperability Products Page

This example demonstrates how to embed the Adobe Acrobat reader control in a Java Swing container. J-Integra® for COM is a Java interoperability component that bridges Java and Adobe Acrobat Reader. It provides bi-directional access of Java objects and COM components.

Contents

  1. Introduction

  2. Embedding the Adobe Acrobat Reader 7.0 Control in Swing

  3. Embedding the Adobe Acrobat Reader (6.x, 5.x, or 4.x) Control in Swing

Introduction

An ActiveX Control is a kind of COM component that generally requires hosting in a GUI container. ActiveX Controls typically have the extension '.ocx'.

J-Integra® lets you embed a COM ActiveX Control inside a Java GUI as though the ActiveX Control were a Java GUI component. It lets you access the control's methods and properties and subscribe to its events using the standard Java mechanisms.

Note that using a Java class generated by 'com2java' with the option to generate AWT classes from ActiveX Controls set, J-Integra® will run in native mode automatically.

This is the Java GUI which you will be building. There is a Java Frame, with Adobe Acrobat embedded inside it:

Accessing the Adobe Acrobat Reader Control from Java Swing: Adobe Acrobat embedded in Java Swing container

You will need to install Adobe Acrobat Reader, available from here http://www.adobe.com/products/acrobat/readstep.html. You will also need a Sun JDK which supports Swing, for this specific example (Swing is not a requirement for using J-Integra® to embed ActiveX Controls inside Java Applications -- the next example just uses AWT classes).

 

Embedding the Adobe Acrobat Reader 7.0 Control in Swing

  1. Generate the proxies used to access the Acrobat DLL
  2. Create and run the Java Application
  3. An extra example of using java.swing.JInternalFrame

Generate the proxies used to access the Acrobat DLL

J-Integra®'s com2java tool (in the J-Integra® 'bin' directory) analyzes a COM type library (which contains descriptions of COM classes and interfaces) and outputs corresponding Java classes and interfaces which can be used to access those COM classes.

  1. First, create the directory into which the proxies will be generated. This example assumes your working directory is d:\pure, and that the proxies will be generated into d:\pure\pdf. Create these two directories, or your own equivalents elsewhere.
  2. Start the J-Integra® 'com2java' tool, which will be in \jintegra\bin\com2java.exe. Click on the Select button to select Acropdf.dll as the type library, which by default is in \Program Files\Adobe\Acrobat 7.0\ActiveX\Acropdf.dll on the drive in which Acrobat Reader is installed.
  3. Next click on the Options button and check the Generate Java AWT Classes checkbox (don't forget to uncheck it later). Click on OK to leave the Options dialog and return to the main dialog. Do not check this option if your Java client does not embed an ActiveX Control.
  4. Finally enter pdf as the Java Package in the main dialog, and then click on the Generate Proxies ... button, and select the d:\pure\pdf directory you created above (or its equivalent) as the output directory.

The com2java tool will generate a AcroPDF.java java class which contains all of the methods and properties which the Pdf ActiveX Control contains. It derives ultimately from java.awt.Canvas, so it is a regular Java GUI class.

Create and run the Java Application

Use your favourite editor to create a file called d:\pure\JavaPDF.java, with the following contents:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class JavaPDF {
  static pdf.AcroPDF pdf;

  public static void main(String[] args) throws Exception {
    try {
      com.linar.jintegra.Log.logImmediately(3, "jintegra.log");
      System.setProperty("JINTEGRA_RELEASEALL_SHUTDOWN_HOOK", "");
      JFrame frame = new JFrame("Acrobat Reader inside a Java Frame");
      frame.setSize(new Dimension(410, 430));
      frame.addWindowListener(new WindowAdapter() {
        public void windowClosing(WindowEvent e) {
          try {
            // You must invoke pdf.setSrc("") before this Java Window closes,
            // otherwise you may get the error below after opening and closing
            // this Java Windows for about 20 times:
            // "The maximum number of files are already open.
            // No other files can be opened or printed until some are closed."
            pdf.setSrc("");

            com.linar.jintegra.Cleaner.releaseAll();
            pdf = null;
            System.gc();
          } catch (Exception ex) {
            ex.printStackTrace();
          } finally {
            System.exit(0);
          }
        }
      });

      // Create the PDF Control, set its size, and set its source document
      pdf = new pdf.AcroPDF();

      // Add the PDF control to the frame, and display the frame
      frame.getContentPane().add(pdf, BorderLayout.CENTER);

      // Invoke frame.validate() to make ActiveX Control appear instantly.
     // For example, you may create a button which adds an ActiveX Control
// to Java frame once the button is clicked. Then you must invoke
// validate() after the button is clicked.
    frame.validate();
frame.setVisible(true); pdf.setSize(400,400); pdf.setSrc("http://j-integra.intrinsyc.com/pdfs/brochure_interop.pdf"); } catch (Exception e) { e.printStackTrace(); } } }

You can the setSrc method above to ensure that it refers to a PDF document that exists.

Start a DOS box, and make sure your PATH includes the JDK \bin and \jre\bin directories and the J-Integra® \bin directory, and that your CLASSPATH includes the J-Integra® runtime (jintegra.jar), and the current directory (.). Compile the Java class you created and run it. If you get errors about classes not being found, then your CLASSPATH is not set correctly:
cd d:\pure
set path=C:\java\j2sdk1.4.2\bin;C:\java\j2sdk1.4.2\jre\bin;C:\jintegra\bin;%PATH%
set CLASSPATH=%CLASSPATH%;d:\jintegra\lib\jintegra.jar;.
javac JavaPDF.java
java JavaPDF

You should see the GUI shown above displayed. If you get an error, please check your CLASSPATH and PATH, and if all else fails, follow the steps at the end of the Trouble Shooter section of the J-Integra® documentation.

If you get a NullPointerException when programming your own Java GUI which embeds an ActiveX Control, please refer to J-Integra® Knowledge Base article 30945.

An extra example of using java.swing.JInternalFrame

The JInternalFramePDF.java below shows how to embed the Acrobat Reader in a java.swing.JInternalFrame:

Accessing the Adobe Acrobat Reader Control from Java Swing: Java source code

In this example, remember to put the PDF file and JInternalFramePDF.java in the same directory. Here is the source code of JInternalFramePDF.java:
import javax.swing.JInternalFrame;
import javax.swing.JDesktopPane;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JMenuBar;
import javax.swing.JFrame;

import java.awt.event.*;
import java.awt.*;

public class JInternalFramePDF extends JFrame {
  JDesktopPane desktop;
  pdf.AcroPDF pdf;

  public JInternalFramePDF() {
    super("Adobe Acrobat Reader Embedded in java.swing.JInternalFrame");

    // Make the big window be indented 50 pixels from each edge
    // of the screen.
    int inset = 50;
    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    setBounds(inset, inset,
    screenSize.width - inset*2,
    screenSize.height-inset*2);

    // Quit this app when the big window closes.
    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        try {
          // You must invoke pdf.setSrc("") before this Java Window closes,
          // otherwise you may get the error below after opening and closing
          // this Java Windows for about 20 times:
          // "The maximum number of files are already open.
          // No other files can be opened or printed until some are closed."
          pdf.setSrc("");

          com.linar.jintegra.Cleaner.releaseAll();
          pdf = null;
          System.gc();
        } catch (Exception ex) {
          ex.printStackTrace();
        } finally {
          System.exit(0);
        }
      }
    });

    // Set up the GUI
    desktop = new JDesktopPane(); //a specialized layered pane
    createFrame(); //Create first window
    setContentPane(desktop);

    //Make dragging faster
    desktop.putClientProperty("JDesktopPane.dragMode", "outline");
  }

  protected void createFrame() {
    MyInternalFrame frame = new MyInternalFrame();
    frame.setVisible(true); //necessary as of 1.3; OK to use before
    frame.setSize(450, 450);
    desktop.add(frame);
    try {
      frame.setSize(new Dimension(500, 500));

      // Create the PDF Control, set its size, and set its source document
      pdf = new pdf.AcroPDF();
      pdf.setSize(400,400);
      pdf.setSrc("http://j-integra.intrinsyc.com/pdfs/brochure_interop.pdf");

      // Add the PDF control to the frame, and display the frame
      frame.getContentPane().add(pdf, BorderLayout.CENTER);
      frame.setVisible(true);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public static void main(String[] args) {
    com.linar.jintegra.Log.logImmediately(3, "jintegra.log");
    System.out.println(com.linar.jintegra.Version.getVersion());
    JInternalFramePDF frame = new JInternalFramePDF();

    // Invoke frame.validate() to make ActiveX Control appear instantly.
    // For example, you may create a button which adds an ActiveX Control
// to Java frame once the button is clicked. Then you must invoke
// validate() after the button is clicked.
frame.validate(); frame.setVisible(true); } } class MyInternalFrame extends JInternalFrame { static int openFrameCount = 0; static final int xOffset = 30, yOffset = 30; public MyInternalFrame() { super( "Document #" + (++openFrameCount), true, // resizable true, // closable true, // maximizable true // inconifiable ); setSize(300,300); //Set the window's location setLocation(xOffset*openFrameCount, yOffset*openFrameCount); } }

Note: If you encounter errors running this example, refer to the following knowledge base article:
Common Errors When Embedding an ActiveX Control in a Java Frame

 

 

Embedding the Adobe Acrobat Reader (6.x, 5.x, or 4.x) Control in Swing

  1. Generate the proxies used to access the Acrobat OCX
  2. Create and run the Java Application
  3. An extra example of using java.swing.JInternalFrame

Generate the proxies used to access the Acrobat OCX

J-Integra®'s com2java tool (in the J-Integra® 'bin' directory) analyzes a COM type library (which contains descriptions of COM classes and interfaces) and outputs corresponding Java classes and interfaces which can be used to access those COM classes.

  1. First, create the directory into which the proxies will be generated. This example assumes your working directory is d:\pure, and that the proxies will be generated into d:\pure\pdfocx. Create these two directories, or your own equivalents elsewhere.

  2. Start the J-Integra® 'com2java' tool, which will be in \jintegra\bin\com2java.exe. Click on the Select button to select pdf.ocx as the type library, which by default is in \Program Files\Adobe\Acrobat 4.0\Reader\ActiveX\pdf.ocx on the drive in which Acrobat Reader is installed.
  3. Next click on the Options button and check the Generate Java AWT Classes checkbox (don't forget to uncheck it later). Click on OK to leave the Options dialog and return to the main dialog. Do not check this option if your Java client does not embed an ActiveX Control.
  4. Finally enter pdfocx as the Java Package in the main dialog, and then click on the Generate Proxies ... button, and select the d:\pure\pdfocx directory you created above (or its equivalent) as the output directory.

The com2java tool will generate a Pdf.java java class which contains all of the methods and properties which the Pdf ActiveX Control contains. It derives ultimately from java.awt.Canvas, so it is a regular Java GUI class.

Create and run the Java Application

Use your favourite editor to create a file called d:\pure\JavaPDF.java, with the following contents:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class JavaPDF {
  static pdfocx.Pdf pdf;

  public static void main(String[] args) throws Exception {
    try {
      com.linar.jintegra.Log.logImmediately(3, "jintegra.log");
      System.setProperty("JINTEGRA_RELEASEALL_SHUTDOWN_HOOK", "");
      JFrame frame = new JFrame("Acrobat Reader inside a Java Frame");
      frame.setSize(new Dimension(410, 430));
      frame.addWindowListener(new WindowAdapter() {
        public void windowClosing(WindowEvent e) {
          try {
            // You must invoke pdf.setSrc("") before this Java Window closes,
            // otherwise you may get the error below after opening and closing
            // this Java Windows for about 20 times:
            // "The maximum number of files are already open.
            // No other files can be opened or printed until some are closed."
            pdf.setSrc("");

            com.linar.jintegra.Cleaner.releaseAll();
            pdf = null;
            System.gc();
          } catch (Exception ex) {
            ex.printStackTrace();
          } finally {
            System.exit(0);
          }
        }
      });

      // Create the PDF Control, set its size, and set its source document
      pdf = new pdfocx.Pdf();

      // Add the PDF control to the frame, and display the frame
      frame.getContentPane().add(pdf, BorderLayout.CENTER);

      // Invoke frame.validate() to make ActiveX Control appear instantly.
      // For example, you may create a button which adds an ActiveX Control
      // to Java frame once the button is clicked. Then you must invoke
      // validate() after the button is clicked.
      frame.validate();

      frame.setVisible(true);

      pdf.setSize(400,400);
      pdf.setSrc("http://j-integra.intrinsyc.com/pdfs/brochure_interop.pdf");
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

You can the setSrc method above to ensure that it refers to a PDF document that exists.

Start a DOS box, and make sure your PATH includes the JDK \bin and \jre\bin directories and the J-Integra® \bin directory, and that your CLASSPATH includes the J-Integra® runtime (jintegra.jar), and the current directory (.). Compile the Java class you created and run it. If you get errors about classes not being found, then your CLASSPATH is not set correctly:
cd d:\pure
set path=C:\java\j2sdk1.4.2\bin;C:\java\j2sdk1.4.2\jre\bin;C:\jintegra\bin;%PATH%
set CLASSPATH=%CLASSPATH%;d:\jintegra\lib\jintegra.jar;.
javac JavaPDF.java
java JavaPDF

You should see the GUI shown above displayed. If you get an error, please check your CLASSPATH and PATH, and if all else fails, follow the steps at the end of the Trouble Shooter section of the J-Integra® documentation.

If you get a NullPointerException when programming your own Java GUI which embeds an ActiveX Control, please refer to J-Integra® Knowledge Base article 30945.

An extra example of using java.swing.JInternalFrame

The JInternalFramePDF.java below shows how to embed the Acrobat Reader in a java.swing.JInternalFrame:

Accessing the Adobe Acrobat Reader Control from Java Swing: Java source code

In this example, remember to put the PDF file and JInternalFramePDF.java in the same directory. Here is the source code of JInternalFramePDF.java:
import javax.swing.JInternalFrame;
import javax.swing.JDesktopPane;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JMenuBar;
import javax.swing.JFrame;

import java.awt.event.*;
import java.awt.*;

public class JInternalFramePDF extends JFrame {
  JDesktopPane desktop;
  pdfocx.Pdf pdf;

  public JInternalFramePDF() {
    super("Adobe Acrobat Reader Embedded in java.swing.JInternalFrame");

    // Make the big window be indented 50 pixels from each edge 
    // of the screen.
    int inset = 50;
    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    setBounds(inset, inset, 
    screenSize.width - inset*2, 
    screenSize.height-inset*2);

    // Quit this app when the big window closes.
    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        try {
          // You must invoke pdf.setSrc("") before this Java Window closes,
          // otherwise you may get the error below after opening and closing 
          // this Java Windows for about 20 times: 
          // "The maximum number of files are already open. 
          // No other files can be opened or printed until some are closed."
          pdf.setSrc("");

          com.linar.jintegra.Cleaner.releaseAll();
          pdf = null;
          System.gc(); 
        } catch (Exception ex) {
          ex.printStackTrace();
        } finally {
          System.exit(0);
        }
      }
    });

    // Set up the GUI
    desktop = new JDesktopPane(); //a specialized layered pane
    createFrame(); //Create first window
    setContentPane(desktop);

    //Make dragging faster
    desktop.putClientProperty("JDesktopPane.dragMode", "outline");
  }

  protected void createFrame() {
    MyInternalFrame frame = new MyInternalFrame();
    frame.setVisible(true); //necessary as of 1.3; OK to use before
    frame.setSize(450, 450);
    desktop.add(frame);
    try {
      frame.setSize(new Dimension(500, 500));

      // Create the PDF Control, set its size, and set its source document
      pdf = new pdfocx.Pdf();
      pdf.setSize(400,400);
      pdf.setSrc("http://j-integra.intrinsyc.com/pdfs/brochure_interop.pdf");

      // Add the PDF control to the frame, and display the frame
      frame.getContentPane().add(pdf, BorderLayout.CENTER);

      // Invoke frame.validate() to make ActiveX Control appear instantly.
      // For example, you may create a button which adds an ActiveX Control
// to Java frame once the button is clicked. Then you must invoke
// validate() after the button is clicked.
frame.validate(); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { com.linar.jintegra.Log.logImmediately(3, "jintegra.log"); System.out.println(com.linar.jintegra.Version.getVersion()); JInternalFramePDF frame = new JInternalFramePDF(); frame.setVisible(true); } } class MyInternalFrame extends JInternalFrame { static int openFrameCount = 0; static final int xOffset = 30, yOffset = 30; public MyInternalFrame() { super( "Document #" + (++openFrameCount), true, // resizable true, // closable true, // maximizable true // inconifiable ); setSize(300,300); //Set the window's location setLocation(xOffset*openFrameCount, yOffset*openFrameCount); } }

Note: If you encounter errors running this example, refer to the following knowledge base article:
Common Errors When Embedding an ActiveX Control in a Java Frame