Package org.jpedal.examples.simpleviewer.gui.popups

Source Code of org.jpedal.examples.simpleviewer.gui.popups.SignWizardModel$CommonPanel

/**
* ===========================================
* Java Pdf Extraction Decoding Access Library
* ===========================================
*
* Project Info:  http://www.jpedal.org
* (C) Copyright 1997-2008, IDRsolutions and Contributors.
*
*   This file is part of JPedal
*
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


*
* ---------------------
* SignWizardModel.java
* ---------------------
*/

package org.jpedal.examples.simpleviewer.gui.popups;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import java.awt.image.BufferedImage;
import java.io.File;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JRadioButton;
import javax.swing.JSeparator;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;
import javax.swing.border.EtchedBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import org.jpedal.PdfDecoder;
import org.jpedal.examples.simpleviewer.objects.SignData;
import org.jpedal.examples.simpleviewer.utils.FileFilterer;
import org.jpedal.examples.simpleviewer.utils.ItextFunctions;
import org.jpedal.exception.PdfException;
import org.jpedal.objects.PdfPageData;
import org.jpedal.objects.acroforms.rendering.AcroRenderer;
import org.jpedal.utils.Messages;

/**This class implements the WizardPanelModel and in this
* case contains the JPanels to be drawn as inner classes.
* The methods in SignWizardModel are mainly concerned with
* controlling what panels are next and whether they can be
* currently reached.
*/
public class SignWizardModel implements WizardPanelModel
  //Each panel must have a unique String identifier
  private static final String MODE_SELECT = "0";
  private static final String PFX_PANEL = "1";
  private static final String KEYSTORE_PANEL = "3";
  private static final String COMMON_PANEL = "4";
  private static final String ENCRYPTION_PANEL = "5";
  private static final String VISIBLE_SIGNATURE_PANEL = "6";
 
  public static final String NO_FILE_SELECTED = Messages.getMessage("PdfSigner.NoFileSelected");
 
  private static final int MAXIMUM_PANELS = 5;
   
  private SignData signData;
  private PdfDecoder pdfDecoder;
  private String rootDir;
 
  /*The JPanels in this wizard */
  private ModeSelect modeSelect;
  private PFXPanel pFXPanel;
  private KeystorePanel keystorePanel;
  private CommonPanel commonPanel;
  private EncryptionPanel encryptionPanel;
  private SignaturePanel signaturePanel;
 
  /*Maps the JPanels' ID to the panel*/
  private Map panels;
 
  /* The ID of the currently displayed panel*/
  private String currentPanel;
 
  /**
   * @param signData Will contain all the information acquired from the user for signing a Pdf
   * @param pdfFile The path to the Pdf document to be signed.
   */
  public SignWizardModel(SignData signData, String pdfFile, String rootDir)
  {
    this.signData = signData;
    this.rootDir = rootDir;
   
    pdfDecoder = new PdfDecoder();
    try {
      pdfDecoder.openPdfFile(pdfFile);
    }
    catch (Exception e) {
            e.printStackTrace();
    }
   
    if(pdfDecoder.isEncrypted()) {
      String password =System.getProperty("org.jpedal.password");
      if(password != null) {
        try {
          pdfDecoder.setEncryptionPassword(password);
        } catch (PdfException e) {
          e.printStackTrace();
        }
      }
    }
    /*JPanel contents vary depending on whether the Pdf has bee previously signed.*/
    testForSignedPDF();
   
    panels = new HashMap();
      modeSelect = new ModeSelect();
      pFXPanel = new PFXPanel();
      keystorePanel = new KeystorePanel();
      commonPanel = new CommonPanel();     
      encryptionPanel = new EncryptionPanel();
      signaturePanel = new SignaturePanel();
     
      panels.put(MODE_SELECT, modeSelect);
      panels.put(PFX_PANEL, pFXPanel);
      panels.put(KEYSTORE_PANEL, keystorePanel);
      panels.put(COMMON_PANEL, commonPanel);
      panels.put(ENCRYPTION_PANEL, encryptionPanel);
      panels.put(VISIBLE_SIGNATURE_PANEL, signaturePanel);
     
      currentPanel = MODE_SELECT;
  }
 
  /**
   * A map of the JPanels the Wizard Dialog should contain.
   *
   * @return The ID strings mapped to their corresponding JPanels
   */
  public Map getJPanels()
  {
    return panels;
  }

  /**
   * Advance to the next JPanel.
   *
   * @return Unique identifier for the now current JPanel
   */
  public String next()
  {
    updateSignData();
   
    if(currentPanel.equals(MODE_SELECT)) {
      if(!signData.isKeystoreSign()) {
        return currentPanel = PFX_PANEL;
      }
      else {
        return currentPanel = KEYSTORE_PANEL;
     
    }
    else if(currentPanel.equals(PFX_PANEL)) {
      return currentPanel = VISIBLE_SIGNATURE_PANEL;
    }
    else if(currentPanel.equals(KEYSTORE_PANEL)) {
      return currentPanel = VISIBLE_SIGNATURE_PANEL;
    }     
    else if(currentPanel.equals(VISIBLE_SIGNATURE_PANEL)) {
      return currentPanel = ENCRYPTION_PANEL;
    }
    else if(currentPanel.equals(ENCRYPTION_PANEL)) {
      return currentPanel = COMMON_PANEL;
    }
    /* The following exception should never be thrown and is here to alerted me
     * should I create a trail of panels that is incorrect */
    throw new NullPointerException("Whoops! Tried to move to a nextID where there is no nextID to be had");
  }

  /**
   * Set the current JPanel to the previous JPanel.
   *
   * @return Unique identifier for the now current JPanel
   */
  public String previous()
  {
    updateSignData();
    if(currentPanel.equals(PFX_PANEL) || currentPanel.equals(KEYSTORE_PANEL)) {
      return currentPanel = MODE_SELECT;
    }
    else if(currentPanel.equals(ENCRYPTION_PANEL)) {
      return currentPanel = VISIBLE_SIGNATURE_PANEL;
    }
    else if(currentPanel.equals(VISIBLE_SIGNATURE_PANEL)) {
      if(signData.isKeystoreSign()) {
          return currentPanel = KEYSTORE_PANEL;
      }
      else {
        return currentPanel = PFX_PANEL;
        }
    }
    else if(currentPanel.equals(COMMON_PANEL)){
            return currentPanel = ENCRYPTION_PANEL;
    }

    throw new NullPointerException("Tried to move to get a previousID where there is no previous");
  }

  public boolean hasPrevious()
  {
    return !currentPanel.equals(MODE_SELECT);
  }

  public String getStartPanelID()
  {
    return MODE_SELECT;
  }
 
  public boolean isFinishPanel()
  {
    return currentPanel==COMMON_PANEL;
  }
 
  /**
   * Indicates whether the next or finish button can be enabled.
   *
   * @return true if the current panel can be advanced in its current state
   */
  public boolean canAdvance()
  {
    if(currentPanel.equals(COMMON_PANEL)) {
      return commonPanel.canFinish();
    }
    else if(currentPanel.equals(PFX_PANEL)){
        return pFXPanel.canAdvance();
    }
    else if(currentPanel.equals(KEYSTORE_PANEL)){
      return keystorePanel.canAdvance();
    }
    else if(currentPanel.equals(ENCRYPTION_PANEL)) {
      return encryptionPanel.canAdvance();
    }
    else {
      return true;
    }
  }
 
  /**
   * Harvest user data from the currently displayed panel
   */
  public void updateSignData()
  {
    if(currentPanel.equals(PFX_PANEL)) {
      pFXPanel.collectData();
    }
    else if(currentPanel.equals(KEYSTORE_PANEL)) {
      keystorePanel.collectData();
    }
    else if(currentPanel.equals(COMMON_PANEL)) {
      commonPanel.collectData();
    }
    else if(currentPanel.equals(ENCRYPTION_PANEL)) {
      encryptionPanel.collectData();
    }
    else if(currentPanel.equals(MODE_SELECT)) {
      modeSelect.collectData();
   
    else if(currentPanel.equals(VISIBLE_SIGNATURE_PANEL)) {
      signaturePanel.collectData();
    }
     else {
       /*Should never be throw, here to indicate if I've made a mistake in the flow of the JPanels */
      throw new NullPointerException("Tried to update a panel which doesnt exist");
    }
  }
 
  /**
   * When an event is triggered with one of the registered panels
   * the wizard will call back this class and check if the panel can be advanced.
   *
   * @param wizard Listeners to enable/disable advance button
   */
  public void registerNextChangeListeners(ChangeListener wizard)
  {
    commonPanel.registerChange(wizard);
    pFXPanel.registerChange(wizard);
    keystorePanel.registerChange(wizard);
    encryptionPanel.registerChange(wizard);
  }
 
  /**
   * Same as the previous method but listens for key changes instead.
   *
    @param wizard Listeners to enable/disable advance button
   */
  public void registerNextKeyListeners(KeyListener wizard)
  {
    pFXPanel.registerListener(wizard);
    keystorePanel.registerNextKeyListeners(wizard);
    encryptionPanel.registerNextKeyListeners(wizard);
  }
 
  /**
   * To avoid memory leaks I want to close the decoder I opened in this
   * class when ever the dialog is closed.  Also collects any last
   * data.
   */
  public void close()
  {
    updateSignData();
    pdfDecoder.closePdfFile();
  }
 
  /**
   * Don't want to corrupt any Pdf files so a check is performed
   * to find whether a signature should be appended to the document
   * or created fresh.
   */
  private void testForSignedPDF()
  {
    signData.setAppend(false);
   
    for(int page = 1; page<=pdfDecoder.getPageCount(); page++) {
        try {
        pdfDecoder.decodePage(page);
        pdfDecoder.waitForDecodingToFinish();
            AcroRenderer currentFormRenderer = pdfDecoder.getFormRenderer();
            Iterator signatureObjects = currentFormRenderer.getSignatureObjects();
            if(signatureObjects!=null) {
              signData.setAppend(true);
              break;
            }
      } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
  }
 
  private boolean isPdfSigned()
  {
        return signData.isAppendMode();
  }
 
  /**
   * The individual JPanels that I want to show in the Wizard
   */
  private class PFXPanel extends JPanel
  {
    private JLabel keyFileLabel = new JLabel();
    private JButton browseKeyButton = new JButton();
    private JLabel currentKeyFilePath = new JLabel(NO_FILE_SELECTED);
    private JCheckBox visiblePassCheck = new JCheckBox();

    private JLabel passwordLabel = new JLabel();
    private JPasswordField passwordField = new JPasswordField();
   
    private volatile boolean keyNext = false;
    private volatile boolean passNext = false;
   
    private int y = 0;

    public PFXPanel()
    {
      try
      {
        init();
      }
      catch( Exception e )
      {
        e.printStackTrace();
      }
    }
   
    private void init() throws Exception
    {
      setLayout(new BorderLayout());
          add(new TitlePanel(Messages.getMessage("PdfSigner.PfxSignMode")), BorderLayout.NORTH);
     
      JPanel inputPanel = new JPanel(new GridBagLayout());
      inputPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
      GridBagConstraints c = new GridBagConstraints();
           
      //Key
      keyFileLabel.setText(Messages.getMessage("PdfSigner.KeyFile")); //@TODO Internalise signing messages  Messages.getMessage()
      keyFileLabel.setFont( new java.awt.Font( "Dialog", Font.BOLD, 14 ) );
      c.anchor = GridBagConstraints.FIRST_LINE_START; //Has no effect
      c.fill = GridBagConstraints.HORIZONTAL;
      c.gridx = c.gridy = 0;
      c.insets = new Insets(0,10,10,0);
      inputPanel.add(keyFileLabel, c);

      c = new GridBagConstraints();
      c.fill = GridBagConstraints.HORIZONTAL;
      c.gridx = 0;
      c.gridy = ++y;
      c.gridwidth = 3;
      currentKeyFilePath.setPreferredSize(new Dimension(250,20));
      c.insets = new Insets(10,10,10,10);
      inputPanel.add(currentKeyFilePath, c);
      browseKeyButton.setText(Messages.getMessage("PdfViewerOption.Browse")); //Messages.getMessage("PdfViewerOption.Browse"));
      browseKeyButton.addActionListener( new ActionListener() {
        public void actionPerformed( ActionEvent e ){
          JFileChooser chooser = new JFileChooser(rootDir);
          String[] pfx = new String[] { "pfx" };
          chooser.addChoosableFileFilter(new FileFilterer(pfx, "Key (pfx)"));
          int state = chooser.showOpenDialog(null);

          File file = chooser.getSelectedFile();

          if (file != null && state == JFileChooser.APPROVE_OPTION) {
            currentKeyFilePath.setText(file.getAbsolutePath());
            keyNext = true;
          }
        }
      } );
      c = new GridBagConstraints();
      c.fill = GridBagConstraints.HORIZONTAL;
      c.gridx = 2;
      c.gridy = 0;
      c.insets = new Insets(0,25,0,10);
      inputPanel.add(browseKeyButton, c);

//      c = new GridBagConstraints();
//      c.gridx = 0;
//      c.gridy = ++y;
//      c.gridwidth = 3;
//      c.fill = GridBagConstraints.HORIZONTAL;
//      inputPanel.add(new JSeparator(SwingConstants.HORIZONTAL), c);
     
      //Key password
      passwordLabel.setText(Messages.getMessage("PdfSigner.Password")); //Messages.getMessage("PdfViewerPassword.message"));
      passwordLabel.setFont(new java.awt.Font( "Dialog", Font.BOLD, 14 ));
      c.fill = GridBagConstraints.HORIZONTAL;
      c.gridx = 0;
      c.gridy = ++y;
      c.insets = new Insets(20,10,10,10);
      inputPanel.add(passwordLabel, c);

      passwordField.addKeyListener( new KeyListener() {     
          public void keyReleased(KeyEvent e) {

          }
         
          public void keyPressed(KeyEvent e) {
            passNext = true;           
          }
         
          public void keyTyped(KeyEvent e) {

          } 
      });
     
      c = new GridBagConstraints();
      c.fill = GridBagConstraints.HORIZONTAL;
      c.gridx = 1;
      c.gridy = y;
      c.gridwidth = 1;
      c.insets = new Insets(20,10,0,10);
      passwordField.setPreferredSize(new Dimension(100,20));
      inputPanel.add(passwordField, c);
     
      c = new GridBagConstraints();
      c.fill = GridBagConstraints.HORIZONTAL;
      c.gridx = 2;
      c.gridy = y;
      c.insets = new Insets(20,0,0,0);
      visiblePassCheck.setToolTipText(Messages.getMessage("PdfSigner.ShowPassword"));
      visiblePassCheck.addActionListener(new ActionListener() {
        private char defaultChar;
       
        public void actionPerformed(ActionEvent e) {
          if(visiblePassCheck.isSelected()) {
            defaultChar = passwordField.getEchoChar();
            passwordField.setEchoChar((char) 0);
          }
          else {
            passwordField.setEchoChar(defaultChar);
          }
        }
      });
      inputPanel.add(visiblePassCheck, c);
     
      add(inputPanel, BorderLayout.CENTER);
     
      add(new ProgressPanel(2), BorderLayout.SOUTH);
    }
   
    public void registerChange(ChangeListener e)
    {
      browseKeyButton.addChangeListener(e);
    }
   
    public void registerListener(KeyListener e)
    {
      passwordField.addKeyListener(e);
    }
   
    public boolean canAdvance()
    {
      return passNext && keyNext;
    }
   
    public void collectData()
    {
      signData.setKeyFilePassword(passwordField.getPassword());
      signData.setKeyFilePath(currentKeyFilePath.getText());
    }
  }
   
    private class ModeSelect extends JPanel
  {
    private String selfString = Messages.getMessage("PdfSigner.HaveKeystore");
    private String otherString = Messages.getMessage("PdfSigner.HavePfx");
    private int y = 0;
   
    private JRadioButton selfButton = new JRadioButton(selfString);
    private String[] certifyOptions = {Messages.getMessage("PdfSigner.NotCertified"), Messages.getMessage("PdfSigner.NoChangesAllowed"), Messages.getMessage("PdfSigner.FormFilling"), Messages.getMessage("PdfSigner.FormFillingAndAnnotations")}
    private JComboBox certifyCombo = new JComboBox(certifyOptions);
    private int certifyMode = ItextFunctions.NOT_CERTIFIED;
   
    public ModeSelect()
    {
      if(!signData.isAppendMode()) {
        certifyCombo = new JComboBox(certifyOptions);
      }
      else {
        String[] s = {"Not Allowed..."};
        certifyCombo = new JComboBox(s);
      }
      setLayout(new BorderLayout());
          add(new TitlePanel(Messages.getMessage("PdfSigner.SelectSigningMode")), BorderLayout.NORTH);
           
      JPanel optionPanel = new JPanel();   
      optionPanel.setLayout(new GridBagLayout());
      //buttons.setAlignmentX(Component.CENTER_ALIGNMENT);
      GridBagConstraints c = new GridBagConstraints();
     
     
        selfButton.setActionCommand(selfString);
        //selfButton.setAlignmentX(Component.LEFT_ALIGNMENT);
        c.gridx = 0;
        c.gridy = y;
      c.anchor = GridBagConstraints.FIRST_LINE_START; //Has no effect
      c.fill = GridBagConstraints.HORIZONTAL;
        c.insets = new Insets(10,0,20,0);
        selfButton.setFont(new Font("Dialog", Font.BOLD, 12));
        optionPanel.add(selfButton,c);

        JRadioButton otherButton = new JRadioButton(otherString);
        otherButton.setActionCommand(otherString);
        //otherButton.setAlignmentX(Component.LEFT_ALIGNMENT);
        otherButton.setSelected(true);
        signData.setSignMode(false);
        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = ++y;
        c.fill = GridBagConstraints.HORIZONTAL;
        otherButton.setFont(new Font("Dialog", Font.BOLD, 12));
        optionPanel.add(otherButton, c);
       
        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = ++y;
        c.fill = GridBagConstraints.HORIZONTAL;
        c.insets = new Insets(30,0,30,0);
        optionPanel.add(new JSeparator(SwingConstants.HORIZONTAL), c);
             
        JLabel certifyLabel = new JLabel(Messages.getMessage("PdfSigner.CertificationAuthor"));
        certifyLabel.setFont(new Font("Dialog", Font.BOLD, 12));
        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = ++y;
        c.fill = GridBagConstraints.CENTER;
        optionPanel.add(certifyLabel, c);
       
        c = new GridBagConstraints();
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 0;
        c.gridy = ++y;
        c.insets = new Insets(10,0,0,0);
      c.anchor = GridBagConstraints.PAGE_END; 
      certifyCombo.setEnabled(!isPdfSigned());
      certifyCombo.setSelectedIndex(0);
      certifyCombo.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          String mode = (String) certifyCombo.getSelectedItem();
          if(mode.equals(Messages.getMessage("PdfSigner.NotCertified"))) {
            certifyMode = ItextFunctions.NOT_CERTIFIED;
          }
          else if(mode.equals(Messages.getMessage("PdfSigner.NoChangesAllowed"))) {
            certifyMode = ItextFunctions.CERTIFIED_NO_CHANGES_ALLOWED;
          }
          else if(mode.equals(Messages.getMessage("PdfSigner.FormFilling"))) {
            certifyMode = ItextFunctions.CERTIFIED_FORM_FILLING;
          }
          else if(mode.equals(Messages.getMessage("PdfSigner.FormFillingAndAnnotations"))) {
            certifyMode = ItextFunctions.CERTIFIED_FORM_FILLING_AND_ANNOTATIONS;
          }
          else {
            throw new NullPointerException("The certifyCombo box is sending a string that is not recognised.");
          }
        }
      });
        optionPanel.add(certifyCombo, c);
       
        if(isPdfSigned()) {
          certifyCombo.setToolTipText(Messages.getMessage("PdfSigner.NotPermittedOnSigned"));
        }
       
        add(optionPanel,BorderLayout.CENTER);
       
        ButtonGroup group = new ButtonGroup();
        group.add(selfButton);
        group.add(otherButton);
               
        add(new ProgressPanel(1), BorderLayout.SOUTH);
    }
   
    public void collectData()
    {
      signData.setSignMode(selfButton.isSelected());
      signData.setCertifyMode(certifyMode);
    }
  }
   
  private class KeystorePanel extends JPanel
  {   
    private JLabel keyStoreLabel = new JLabel();
    private JLabel currentKeyStorePath = new JLabel(NO_FILE_SELECTED);
    private JButton browseKeyStoreButton = new JButton();
   
    private JLabel passwordKeyStoreLabel = new JLabel();
    private JPasswordField passwordKeyStoreField = new JPasswordField();
    private JCheckBox visiblePassKeyCheck = new JCheckBox();
   
    private JLabel aliasNameLabel = new JLabel();
    private JTextField aliasNameField = new JTextField();
    private JLabel aliasPasswordLabel = new JLabel();
    private JPasswordField aliasPasswordField = new JPasswordField()
    private JCheckBox visiblePassAliasCheck = new JCheckBox();
   
    private volatile boolean storeAdvance, storePassAdvance, aliasAdvance, aliasPassAdvance = false;
     
    public KeystorePanel()
    {
      try  {
        init();
      }
      catch( Exception e ) {
        e.printStackTrace();
      }
    }
   
    private void init()
    {
      setLayout(new BorderLayout());
          add(new TitlePanel(Messages.getMessage("PdfSigner.KeyStoreMode")), BorderLayout.NORTH);
     
      JPanel inputPanel = new JPanel(new GridBagLayout());
      inputPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
      GridBagConstraints c = new GridBagConstraints();
     
      //Keystore file
      keyStoreLabel.setText(Messages.getMessage("PdfSigner.SelectKeyStore"));
      keyStoreLabel.setFont( new java.awt.Font( "Dialog", Font.BOLD, 14 ) );
      c.anchor = GridBagConstraints.FIRST_LINE_START;
      c.fill = GridBagConstraints.HORIZONTAL;
      c.gridx = c.gridy = 0;
      c.insets = new Insets(0,10,10,0);
      inputPanel.add(keyStoreLabel, c);
     
      c = new GridBagConstraints();
      c.fill = GridBagConstraints.HORIZONTAL;
      c.gridx = 0;
      c.gridy = 1;
      c.gridwidth = 3;
      c.insets = new Insets(0,20,0,10);
      currentKeyStorePath.setPreferredSize(new Dimension(250,20));
      inputPanel.add(currentKeyStorePath, c);

      browseKeyStoreButton.setText(Messages.getMessage("PdfViewerOption.Browse"));
      browseKeyStoreButton.addActionListener( new ActionListener() {
        public void actionPerformed( ActionEvent e ){
          JFileChooser chooser = new JFileChooser(rootDir);
          chooser.setFileHidingEnabled(false);
//          String[] keystore = new String[] { "keystore" };
//          chooser.addChoosableFileFilter(new FileFilterer(keystore, "*.*"));
          int state = chooser.showOpenDialog(null);

          File file = chooser.getSelectedFile();

          if (file != null && state == JFileChooser.APPROVE_OPTION) {
            currentKeyStorePath.setText(file.getAbsolutePath());
            storeAdvance = true;
          }
        }
      } );
      c = new GridBagConstraints();
      c.fill = GridBagConstraints.HORIZONTAL;
      c.gridx = 1;
      c.gridy = 0;
      c.insets = new Insets(0,30,0,0);
      inputPanel.add(browseKeyStoreButton, c);

      //KeyStore password
      passwordKeyStoreLabel.setText(Messages.getMessage("PdfSigner.Password")); //Messages.getMessage("PdfViewerPassword.message"));
      passwordKeyStoreLabel.setFont(new java.awt.Font( "Dialog", Font.BOLD, 14 ));
      c = new GridBagConstraints();
      c.fill = GridBagConstraints.HORIZONTAL;
      c.gridx = 0;
      c.gridy = 2;
      c.insets = new Insets(30,10,0,10);
      inputPanel.add(passwordKeyStoreLabel, c);

      passwordKeyStoreField.addKeyListener(new KeyListener() {
        public void keyReleased(KeyEvent e) {
         
        }
       
        public void keyPressed(KeyEvent e) {
         
        }
       
        public void keyTyped(KeyEvent e) {
          storePassAdvance = true;
        }
      });
     
      c = new GridBagConstraints();
      c.fill = GridBagConstraints.HORIZONTAL;
      c.gridx = 1;
      c.gridy = 2;
      c.gridwidth = 1;
      c.insets = new Insets(30,10,0,10);
      //passwordKeyStoreField.setPreferredSize(new Dimension(200,20));
      inputPanel.add(passwordKeyStoreField, c);
     
      c = new GridBagConstraints();
      c.fill = GridBagConstraints.HORIZONTAL;
      c.gridx = 2;
      c.gridy = 2;
      c.insets = new Insets(30,0,0,0);
      visiblePassKeyCheck.setToolTipText(Messages.getMessage("PdfSigner.ShowPassword"));
      visiblePassKeyCheck.addActionListener(new ActionListener() {
        private char defaultChar;
       
        public void actionPerformed(ActionEvent e) {
          if(visiblePassKeyCheck.isSelected()) {
            defaultChar = passwordKeyStoreField.getEchoChar();
            passwordKeyStoreField.setEchoChar((char) 0);
          }
          else {
            passwordKeyStoreField.setEchoChar(defaultChar);
          }
        }
      });
      inputPanel.add(visiblePassKeyCheck, c);
     
     
      c = new GridBagConstraints();
      c.fill = GridBagConstraints.HORIZONTAL;
      c.gridx = 0;
      c.gridy = 4;
      c.gridwidth = 4;
      c.insets = new Insets(10,0,10,0);
      inputPanel.add(new JSeparator(SwingConstants.HORIZONTAL), c);
     
//      //Alias
      aliasNameLabel.setText(Messages.getMessage("PdfSigner.AliasName"));
      aliasNameLabel.setFont( new java.awt.Font( "Dialog", Font.BOLD, 14 ) );
      c = new GridBagConstraints();
      c.fill = GridBagConstraints.HORIZONTAL;
      c.gridx = 0;
      c.gridy = 5;
      c.insets = new Insets(0,10,10,0);
      inputPanel.add(aliasNameLabel,c);
      aliasNameField.addKeyListener(new KeyListener () {
        public void keyReleased(KeyEvent e) {
         
        }
       
        public void keyPressed(KeyEvent e) {
         
        }
       
        public void keyTyped(KeyEvent e) {
          aliasAdvance = true;
       
      });
      c = new GridBagConstraints();
      c.fill = GridBagConstraints.HORIZONTAL;
      c.gridx = 1;
      c.gridy = 5;
      c.gridwidth = 2;
      c.insets = new Insets(0,10,0,10);
      aliasNameField.setPreferredSize(new Dimension(150,20));
      inputPanel.add(aliasNameField,c);
     
      aliasPasswordLabel.setText(Messages.getMessage("PdfSigner.AliasPassword"));
      aliasPasswordLabel.setFont( new java.awt.Font( "Dialog", Font.BOLD, 14 ) );
      c = new GridBagConstraints();
      c.fill = GridBagConstraints.HORIZONTAL;
      c.gridx = 0;
      c.gridy = 7;
      c.insets = new Insets(10,10,0,10);
      inputPanel.add(aliasPasswordLabel,c);
      aliasPasswordField.addKeyListener(new KeyListener () {
        public void keyReleased(KeyEvent e) {
                   
        }
       
        public void keyPressed(KeyEvent e) {
         
        }
       
        public void keyTyped(KeyEvent e) {
          aliasPassAdvance = true;
        }
      });
      c = new GridBagConstraints();
      c.fill = GridBagConstraints.HORIZONTAL;
      c.gridx = 1;
      c.gridy = 7;
      //c.gridwidth = 2;
      c.insets = new Insets(0,10,0,10);
      c.anchor = GridBagConstraints.PAGE_END;
      aliasPasswordField.setPreferredSize(new Dimension(100,20));
      inputPanel.add(aliasPasswordField, c);
     
      c = new GridBagConstraints();
      c.fill = GridBagConstraints.HORIZONTAL;
      c.gridx = 2;
      c.gridy = 7;
      c.insets = new Insets(10,0,0,0);
      visiblePassAliasCheck.setToolTipText(Messages.getMessage("PdfSigner.ShowPassword"));
      visiblePassAliasCheck.addActionListener(new ActionListener() {
        private char defaultChar;
       
        public void actionPerformed(ActionEvent e) {
          if(visiblePassAliasCheck.isSelected()) {
            defaultChar = aliasPasswordField.getEchoChar();
            aliasPasswordField.setEchoChar((char) 0);
          }
          else {
            aliasPasswordField.setEchoChar(defaultChar);
          }
        }
      });
      inputPanel.add(visiblePassAliasCheck, c);
     
      add(inputPanel, BorderLayout.CENTER);
     
      add(new ProgressPanel(2), BorderLayout.SOUTH);
    }
   
    public void registerChange(ChangeListener e)
    {
      browseKeyStoreButton.addChangeListener(e);
    }
   
    public void registerNextKeyListeners(KeyListener e)
    {
      passwordKeyStoreField.addKeyListener(e);
      aliasNameField.addKeyListener(e);
      aliasPasswordField.addKeyListener(e);
    }
   
    public boolean canAdvance()
    {
      return storeAdvance && storePassAdvance && aliasAdvance && aliasPassAdvance;
   
   
    public void collectData()
    {
            signData.setKeyStorePath(currentKeyStorePath.getText());
            signData.setKeystorePassword(passwordKeyStoreField.getPassword());
            signData.setAlias(aliasNameField.getText());
            signData.setAliasPassword(aliasPasswordField.getPassword());
    }
  }
 
    private class CommonPanel extends JPanel
  {
    private JLabel reasonLabel = new JLabel();
    private JTextField signerReasonArea =new JTextField();

    private JLabel locationLabel = new JLabel();
    private JTextField signerLocationField =new JTextField();

    private JLabel outputFileLabel = new JLabel();
    private JLabel currentOutputFilePath = new JLabel();
    private JButton browseOutputButton = new JButton();

    private volatile boolean canAdvance = false;

    public CommonPanel()
    {
      try  {
        init();
      }
      catch(Exception e) {
        e.printStackTrace();
      }
    }

    private void init()
    {
      setLayout(new BorderLayout());
      add(new TitlePanel(Messages.getMessage("PdfSigner.ReasonAndLocation")), BorderLayout.NORTH);

      JPanel inputPanel = new JPanel(new GridBagLayout());
      inputPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));   
      GridBagConstraints c = new GridBagConstraints();

      //Reason
      reasonLabel.setText(Messages.getMessage("PdfSigner.Reason") + ':');
      reasonLabel.setFont(new java.awt.Font( "Dialog", Font.BOLD, 14 ));
      c.anchor = GridBagConstraints.FIRST_LINE_START; //Has no effect
      c.fill = GridBagConstraints.HORIZONTAL;
      c.gridx = c.gridy = 0;
      c.insets = new Insets(10,0,0,0);
      inputPanel.add(reasonLabel, c);

      c = new GridBagConstraints();
      c.fill = GridBagConstraints.HORIZONTAL;
      c.gridx = 0;
      c.gridy = 1;
      c.gridwidth = 3;
      c.insets = new Insets(10,0,10,0);
      signerReasonArea.setPreferredSize(new Dimension(200,20));
      inputPanel.add(signerReasonArea, c);

      //Location
      locationLabel.setText(Messages.getMessage("PdfSigner.Location")+ ':');
      locationLabel.setFont(new java.awt.Font( "Dialog", Font.BOLD, 14 ));
      c = new GridBagConstraints();
      c.fill = GridBagConstraints.HORIZONTAL;
      c.gridx = 0;
      c.gridy = 2;
      inputPanel.add(locationLabel, c);

      c = new GridBagConstraints();
      c.fill = GridBagConstraints.HORIZONTAL;
      c.gridx = 0;
      c.gridy = 3;
      c.insets = new Insets(10,0,0,0);
      c.gridwidth = 3;
      signerLocationField.setPreferredSize(new Dimension(200,20));
      inputPanel.add(signerLocationField, c);

      c = new GridBagConstraints();
      c.fill = GridBagConstraints.HORIZONTAL;
      c.gridx = 0;
      c.gridy = 4;
      c.gridwidth = 3;
      c.insets = new Insets(10,0,0,0);
      inputPanel.add(new JSeparator(SwingConstants.HORIZONTAL), c);

      //OutputFile
      outputFileLabel.setText(Messages.getMessage("PdfSigner.OutputFile"));
      outputFileLabel.setFont(new java.awt.Font( "Dialog", Font.BOLD, 14 ));
      c = new GridBagConstraints();
      c.fill = GridBagConstraints.HORIZONTAL;
      c.gridx = 0;
      c.gridy = 5;
      c.insets = new Insets(5,10,0,0);
      inputPanel.add(outputFileLabel, c);

      currentOutputFilePath.setText(NO_FILE_SELECTED);
      c = new GridBagConstraints();
      c.fill = GridBagConstraints.HORIZONTAL;
      c.gridx = 0;
      c.gridy = 6;
      c.insets = new Insets(10,0,0,0);
      c.gridwidth = 3;
      currentOutputFilePath.setPreferredSize(new Dimension(100, 20));
      inputPanel.add(currentOutputFilePath, c);

      browseOutputButton.setText(Messages.getMessage("PdfViewerOption.Browse"));
      browseOutputButton.addActionListener( new ActionListener() {
        public void actionPerformed( ActionEvent e ){
          JFileChooser chooser = new JFileChooser(rootDir);
          int state = chooser.showSaveDialog(null);

          File file = chooser.getSelectedFile();

          if (file != null && state == JFileChooser.APPROVE_OPTION) {
            if(file.exists()) {
              JOptionPane.showMessageDialog(null,
                  Messages.getMessage("PdfSigner.PleaseChooseAnotherFile"),
                  Messages.getMessage("PdfViewerGeneralError.message"),
                  JOptionPane.ERROR_MESSAGE);
              canAdvance = false;
              currentOutputFilePath.setText(NO_FILE_SELECTED);
              signData.setOutputFilePath(null);
            }
            else if(file.isDirectory()) {
              JOptionPane.showMessageDialog(null,
                  Messages.getMessage("PdfSigner.NoFileSelected"),
                  Messages.getMessage("PdfViewerGeneralError.message"),
                  JOptionPane.ERROR_MESSAGE);     
              canAdvance = false;
              currentOutputFilePath.setText(NO_FILE_SELECTED);
            }
            else {
              currentOutputFilePath.setText(file.getAbsolutePath());
              canAdvance = true;
            }
          }
        }
      } );
      c = new GridBagConstraints();
      c.fill = GridBagConstraints.HORIZONTAL;
      c.gridx = 2;
      c.gridy = 5;
      c.insets = new Insets(5,25,0,25);
      c.anchor = GridBagConstraints.LAST_LINE_END;
      inputPanel.add(browseOutputButton, c);     

      add(inputPanel, BorderLayout.CENTER);
     
      add(new ProgressPanel(5), BorderLayout.SOUTH);
    }

    public boolean canFinish()
    {
      return canAdvance;
   

    public void registerChange(ChangeListener e)
    {
      browseOutputButton.addChangeListener(e);
    }
   
    public void collectData()
    {
      signData.setReason(signerReasonArea.getText());
      signData.setLocation(signerLocationField.getText());
      signData.setOutputFilePath(currentOutputFilePath.getText());
    }
  }
 
  private class EncryptionPanel extends JPanel
 
    private JCheckBox encryptionCheck = new JCheckBox("Encrypt");
    private JCheckBox allowPrinting = new JCheckBox("Allow Printing");
    private JCheckBox allowModifyContent = new JCheckBox("Allow Content Modification");
    private JCheckBox allowCopy = new JCheckBox("Allow Copy");
    private JCheckBox allowModifyAnnotation = new JCheckBox("Allow Annotation Modification");
    private JCheckBox allowFillIn = new JCheckBox("Allow Fill In");
    private JCheckBox allowScreenReader = new JCheckBox("Allow Screen Reader");
    private JCheckBox allowAssembly = new JCheckBox("Allow Assembly");
    private JCheckBox allowDegradedPrinting = new JCheckBox("Allow Degraded Printing");
    private JPasswordField userPassword = new JPasswordField();
    private JPasswordField ownerPassword = new JPasswordField();
    private JCheckBox flatten = new JCheckBox("Flatten PDF")
   
    private JCheckBox visiblePassUserCheck = new JCheckBox();
    private JCheckBox visiblePassOwnerCheck = new JCheckBox();
    private boolean ownerAdvance = false;
    private volatile boolean canAdvance = true;
   
    public EncryptionPanel()
    {
      int y = 0;
      setLayout(new BorderLayout());
      add(new TitlePanel(Messages.getMessage("PdfSigner.EncryptionOptions")), BorderLayout.NORTH);

      JPanel optionPanel = new JPanel();   
      optionPanel.setLayout(new GridBagLayout());

      GridBagConstraints c = new GridBagConstraints();
      c.gridx = 0;
      c.gridy = y;
      c.fill = GridBagConstraints.HORIZONTAL;
      c.anchor = GridBagConstraints.PAGE_START;
      //encryptionCheck.setFont(new Font("Dialog", Font.BOLD, 12));
      encryptionCheck.setEnabled(!isPdfSigned());
      encryptionCheck.addActionListener(new ActionListener () {
        public void actionPerformed(ActionEvent e) {
          canAdvance = !encryptionCheck.isSelected() || ownerAdvance;
        }
      });

      optionPanel.add(encryptionCheck, c);
      encryptionCheck.setSelected(false);

      c = new GridBagConstraints();
      c.gridx = 2;
      c.gridy = y;
      c.fill = GridBagConstraints.HORIZONTAL;
      c.anchor = GridBagConstraints.FIRST_LINE_END;
      flatten.setEnabled(!isPdfSigned());
      optionPanel.add(flatten, c);
     
      c = new GridBagConstraints();
      c.gridx = 0;
      c.gridy = ++y;
      c.gridwidth = 3;
      c.fill = GridBagConstraints.HORIZONTAL;
      optionPanel.add(new JSeparator(SwingConstants.HORIZONTAL), c);

          //Encryption Options.     
      allowPrinting.setEnabled(false);
      c = new GridBagConstraints();
      c.gridx = 0;
      c.gridy = ++y;
      c.fill = GridBagConstraints.HORIZONTAL;
      optionPanel.add(allowPrinting, c);
      allowModifyContent.setEnabled(false);
      c = new GridBagConstraints();
      c.gridx = 1;
      c.gridy = y;
      c.fill = GridBagConstraints.HORIZONTAL;
      c.gridwidth = 2;
      optionPanel.add(allowModifyContent, c);
     
      allowCopy.setEnabled(false);
      c = new GridBagConstraints();
      c.gridx = 0;
      c.gridy = ++y;
      c.fill = GridBagConstraints.HORIZONTAL;
      optionPanel.add(allowCopy, c);
      allowModifyAnnotation.setEnabled(false);
      c = new GridBagConstraints();
      c.gridx = 1;
      c.gridy = y;
      c.fill = GridBagConstraints.HORIZONTAL;
      c.gridwidth = 2;
      optionPanel.add(allowModifyAnnotation, c);
     
      allowFillIn.setEnabled(false);
      c = new GridBagConstraints();
      c.gridx = 0;
      c.gridy = ++y;
      c.fill = GridBagConstraints.HORIZONTAL;
      optionPanel.add(allowFillIn, c);
      allowScreenReader.setEnabled(false);
      c = new GridBagConstraints();
      c.gridx = 1;
      c.gridy = y;
      c.fill = GridBagConstraints.HORIZONTAL;
      c.gridwidth = 2;
      optionPanel.add(allowScreenReader, c);
     
      allowAssembly.setEnabled(false);
      c = new GridBagConstraints();
      c.gridx = 0;
      c.gridy = ++y;
      c.fill = GridBagConstraints.HORIZONTAL;
      optionPanel.add(allowAssembly, c);
      allowDegradedPrinting.setEnabled(false);
      c = new GridBagConstraints();
      c.gridx = 1;
      c.gridy = y;
      c.fill = GridBagConstraints.HORIZONTAL;
      c.gridwidth = 2;
      optionPanel.add(allowDegradedPrinting, c);
     
      c = new GridBagConstraints();
      c.gridx = 0;
      c.gridy = ++y;
      c.gridwidth = 3;
      c.fill = GridBagConstraints.HORIZONTAL;
      optionPanel.add(new JSeparator(SwingConstants.HORIZONTAL), c);
     
      c = new GridBagConstraints();
      c.gridx = 0;
      c.gridy = ++y;
      c.fill = GridBagConstraints.HORIZONTAL;
      c.insets= new Insets(5,0,0,0);
      optionPanel.add(new JLabel(Messages.getMessage("PdfSigner.UserPassword")), c);
      c = new GridBagConstraints();
      c.gridx = 1;
      c.gridy = y;
      c.fill = GridBagConstraints.HORIZONTAL;
      c.insets= new Insets(5,0,0,0);
      userPassword.setEnabled(false);
      userPassword.setPreferredSize(new Dimension(100,20));
      userPassword.addKeyListener(new KeyListener () {
        public void keyReleased(KeyEvent e) {
                   
        }
       
        public void keyPressed(KeyEvent e) {
         
        }
       
        public void keyTyped(KeyEvent e) {
          ownerAdvance = true;
          canAdvance = true;
        }
      });
      optionPanel.add(userPassword, c);
     
      c = new GridBagConstraints();
      c.fill = GridBagConstraints.HORIZONTAL;
      c.gridx = 2;
      c.gridy = y;
      c.insets = new Insets(0,0,0,0);
      visiblePassUserCheck.setToolTipText(Messages.getMessage("PdfSigner.ShowPassword"));
      visiblePassUserCheck.addActionListener(new ActionListener() {
        private char defaultChar;
       
        public void actionPerformed(ActionEvent e) {
          if(visiblePassUserCheck.isSelected()) {
            defaultChar = userPassword.getEchoChar();
            userPassword.setEchoChar((char) 0);
          }
          else {
            userPassword.setEchoChar(defaultChar);
          }
        }
      });
      visiblePassUserCheck.setEnabled(false);
      optionPanel.add(visiblePassUserCheck, c);
     
      c = new GridBagConstraints();
      c.gridx = 0;
      c.gridy = ++y;
      c.fill = GridBagConstraints.HORIZONTAL;
      c.insets= new Insets(5,0,0,0);
      optionPanel.add(new JLabel(Messages.getMessage("PdfSigner.OwnerPassword")), c);
      c = new GridBagConstraints();
      c.gridx = 1;
      c.gridy = y;
      c.fill = GridBagConstraints.HORIZONTAL;
      c.insets= new Insets(5,0,0,0);
      ownerPassword.setEnabled(false);
      ownerPassword.setPreferredSize(new Dimension(100,20));
      optionPanel.add(ownerPassword, c);
     
      c = new GridBagConstraints();
      c.fill = GridBagConstraints.HORIZONTAL;
      c.gridx = 2;
      c.gridy = y;
      c.insets = new Insets(0,0,0,0);
      visiblePassOwnerCheck.setToolTipText(Messages.getMessage("PdfSigner.ShowPassword"));
      visiblePassOwnerCheck.addActionListener(new ActionListener() {
        private char defaultChar;
       
        public void actionPerformed(ActionEvent e) {
          if(visiblePassOwnerCheck.isSelected()) {
            defaultChar = ownerPassword.getEchoChar();
            ownerPassword.setEchoChar((char) 0);
          }
          else {
            ownerPassword.setEchoChar(defaultChar);
          }
        }
      });
      visiblePassOwnerCheck.setEnabled(false);
      optionPanel.add(visiblePassOwnerCheck, c);
           
      if(isPdfSigned()) {
        c = new GridBagConstraints();
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 0;
        c.gridy = ++y;
        c.gridwidth = 3;
        c.insets = new Insets(25,0,0,0);
        JLabel notAvailable = new JLabel(Messages.getMessage("PdfSigner.DisabledSigned"), JLabel.CENTER);
        notAvailable.setForeground(Color.red);
        optionPanel.add(notAvailable, c);
      }
     
      encryptionCheck.addItemListener(new ItemListener() {
        public void itemStateChanged(ItemEvent e) {
          boolean enable = e.getStateChange()== ItemEvent.SELECTED;
          allowPrinting.setEnabled(enable);
          allowModifyContent.setEnabled(enable);
          allowCopy.setEnabled(enable);
          allowModifyAnnotation.setEnabled(enable);
          allowFillIn.setEnabled(enable);
          allowScreenReader.setEnabled(enable);
          allowAssembly.setEnabled(enable);
          allowDegradedPrinting.setEnabled(enable);
          userPassword.setEnabled(enable);
          ownerPassword.setEnabled(enable);  
          visiblePassUserCheck.setEnabled(enable);
          visiblePassOwnerCheck.setEnabled(enable)
        }
      });
     
      add(optionPanel, BorderLayout.CENTER);
      add(new ProgressPanel(4), BorderLayout.SOUTH);
    }
         
    public void registerChange(ChangeListener wizard) {
      encryptionCheck.addChangeListener(wizard);
    }

    public void registerNextKeyListeners(KeyListener wizard) {
      userPassword.addKeyListener(wizard);
    }
   
    public boolean canAdvance()
    {
      return canAdvance;
    }

    public void collectData()
    {
      signData.setFlatten(flatten.isSelected());
      signData.setEncrypt(encryptionCheck.isSelected());
      if(encryptionCheck.isSelected()) {
        signData.setEncryptUserPass(userPassword.getPassword());
        signData.setEncryptOwnerPass(ownerPassword.getPassword());
       
        int result = 0;
       
        if(allowPrinting.isSelected()) result |= ItextFunctions.ALLOW_PRINTING;
        if(allowModifyContent.isSelected()) result |= ItextFunctions.ALLOW_MODIFY_CONTENTS;
        if(allowCopy.isSelected()) result |= ItextFunctions.ALLOW_COPY;
        if(allowModifyAnnotation.isSelected()) result |= ItextFunctions.ALLOW_MODIFY_ANNOTATIONS;
        if(allowFillIn.isSelected()) result |= ItextFunctions.ALLOW_FILL_IN;
        if(allowScreenReader.isSelected()) result |= ItextFunctions.ALLOW_SCREENREADERS;
        if(allowAssembly.isSelected()) result |= ItextFunctions.ALLOW_ASSEMBLY;
        if(allowDegradedPrinting.isSelected()) result |= ItextFunctions.ALLOW_DEGRADED_PRINTING;
       
        signData.setEncryptPermissions(result);
      }
    }
  }
 
    private class SignaturePanel extends JPanel
  {
    private JCheckBox visibleCheck = new JCheckBox(Messages.getMessage("PdfSigner.VisibleSignature"));
    private JComponent sigPreviewComp;
    private JSlider pageSlider;
    private JLabel pageNumberLabel;
    private int currentPage = 1;
    private Point signRectOrigin;
    private Point signRectEnd;
    private int offsetX, offsetY;
   
    private float scale;
    private int previewWidth, previewHeight;
    private volatile boolean drawRect = false;
    private boolean signAreaUndefined = true;
   
    private BufferedImage previewImage;
   
    public SignaturePanel()
    {       
     
      try {
        previewImage = pdfDecoder.getPageAsImage(currentPage);
      }
      catch (Exception e) {
       
      }
     
      int y = 0;
      setLayout(new BorderLayout());
      add(new TitlePanel(Messages.getMessage("PdfSigner.VisibleSignature") + ' ' + Messages.getMessage("PdfViewerMenu.options")), BorderLayout.NORTH);

      JPanel optionPanel = new JPanel();   
      optionPanel.setLayout(new GridBagLayout());

      GridBagConstraints c = new GridBagConstraints();
      c.gridx = 0;
      c.gridy = y;
      c.insets = new Insets(5,0,0,0);
      c.fill = GridBagConstraints.HORIZONTAL;
      c.anchor = GridBagConstraints.PAGE_START;
      visibleCheck.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          sigPreviewComp.repaint();
          if (pdfDecoder.getPageCount()>1)
              pageSlider.setEnabled(visibleCheck.isSelected());
        }
       
      });
      optionPanel.add(visibleCheck, c);
     
      c = new GridBagConstraints();
      c.gridx = 0;
      c.gridy = ++y;
      c.fill = GridBagConstraints.HORIZONTAL;
      c.insets = new Insets(10,0,10,0);
      optionPanel.add(new JSeparator(SwingConstants.HORIZONTAL), c);
     
      c = new GridBagConstraints();
      c.gridx = 0;
      c.gridy = ++y;
      c.fill = GridBagConstraints.HORIZONTAL;
      optionPanel.add(previewPanel(), c);
       
      add(optionPanel, BorderLayout.CENTER);
     
      add(new ProgressPanel(3), BorderLayout.SOUTH);
     
    }
   
    public void collectData() {
      signData.setVisibleSignature(visibleCheck.isSelected());
      if(visibleCheck.isSelected()) {
        int height = previewImage.getHeight();
                int x1 = (int) ((signRectOrigin.getX() - offsetX) / scale);
                int y1 = (int) ( height - ((signRectOrigin.getY() - offsetY) / scale));
        int x2 = (int) ((signRectEnd.getX() - offsetX) / scale);
        int y2 = (int) (height - ((signRectEnd.getY() - offsetY) / scale));
       
        PdfPageData pageData = pdfDecoder.getPdfPageData();
        int cropX = pageData.getCropBoxX(currentPage);
        int cropY = pageData.getCropBoxY(currentPage);
        x1 += cropX;
        y1 += cropY;
        x2 += cropX;
        y2 += cropY;
       
        signData.setRectangle(x1,y1,x2,y2);
        signData.setSignPage(currentPage);
      }
    }
 
    private JPanel previewPanel()
    {
      JPanel result = new JPanel(new BorderLayout());
                     
      sigPreviewComp = new JComponent() {     
              public void paintComponent(Graphics g){
                  sigPreview(g);
              }
          };
      sigPreviewComp.setPreferredSize(new Dimension(200,200));
      sigPreviewComp.setToolTipText(Messages.getMessage("PdfSigner.ClickAndDrag"));
          sigPreviewComp.addMouseListener(new MouseListener() {

        public void mouseClicked(MouseEvent e) {
        }

        public void mouseEntered(MouseEvent e) {
        }

        public void mouseExited(MouseEvent e) {
        }

        public void mousePressed(MouseEvent e) {
          if(visibleCheck.isSelected()) {
            signRectOrigin.setLocation(e.getX(), e.getY());
            drawRect = true;
           
            Thread rect = new Thread(signAreaThread());
            rect.start();
          }
        }

        public void mouseReleased(MouseEvent e) {
          if(visibleCheck.isSelected()) {
              drawRect = false;
              sigPreviewComp.repaint();
          }
        }
        
      });
     
      result.add(sigPreviewComp, BorderLayout.CENTER);
     
      //Add a slider if there is more than one page
      if(pdfDecoder.getPageCount()>1) {
        pageNumberLabel = new JLabel (Messages.getMessage("PdfSigner.PageNumber") + ' ' + currentPage);
        pageNumberLabel.setHorizontalAlignment(SwingConstants.CENTER);
        result.add(pageNumberLabel, BorderLayout.NORTH);
       
        pageSlider = new JSlider(JSlider.HORIZONTAL, 1, pdfDecoder.getPageCount(), currentPage);
        pageSlider.setMajorTickSpacing(pdfDecoder.getPageCount() - 1);
        pageSlider.setPaintLabels(true);

        pageSlider.addChangeListener(new ChangeListener() {
          public void stateChanged(ChangeEvent e)
          {
                        if(pageSlider.getValueIsAdjusting()) {
                          currentPage = pageSlider.getValue();
                      try {
                        previewImage = pdfDecoder.getPageAsImage(currentPage);
                        sigPreviewComp.repaint();
                        pageNumberLabel.setText(Messages.getMessage("PdfSigner.PageNumber") + ' ' + currentPage);
                      }
                      catch (Exception ex) {
                       
                      }
                        }
          }
        });
        result.add(pageSlider, BorderLayout.SOUTH);   
        pageSlider.setEnabled(false);
      }

     
      return result;
    }
   
    private void sigPreview(Graphics g)
    {
      int panelWidth = sigPreviewComp.getWidth();
      int panelHeight = sigPreviewComp.getHeight();
      previewWidth = previewImage.getWidth();
      previewHeight = previewImage.getHeight();

      scale = (previewWidth>previewHeight) ? (float) panelWidth / previewWidth : (float) panelHeight / previewHeight;

      previewWidth *= scale;
      previewHeight *= scale;
      offsetX = (panelWidth - previewWidth) / 2;
      offsetY =  (panelHeight - previewHeight) / 2;


      g.drawImage(previewImage, offsetX , offsetY, previewWidth, previewHeight, null);  

      if(visibleCheck.isSelected()) {
        g.clipRect(offsetX, offsetY, previewWidth, previewHeight);
        drawSignBox(g);
      }
    }
   
    private void drawSignBox(Graphics g)
    {
      if(signAreaUndefined) {
        PdfPageData pageData = pdfDecoder.getPdfPageData();
        signRectOrigin = new Point(offsetX,offsetY);
        signRectEnd = new Point((int) (pageData.getCropBoxWidth(currentPage) * scale) - 1 + offsetX,
                            (int) (pageData.getCropBoxHeight(currentPage) * scale) - 1 + offsetY);
        signAreaUndefined = false;
      }
      int xO = (int) signRectOrigin.getX();
      int yO = (int) signRectOrigin.getY();
      int xE = (int) signRectEnd.getX();  
      int yE = (int) signRectEnd.getY();
        if(xO>xE) {
          int temp = xE;
          xE = xO;
          xO = temp;
        }
        if(yO>yE) {
          int temp = yO;
          yO = yE;
          yE = temp;
        }
     
      g.drawRect(xO, yO, xE - xO, yE - yO);
      g.drawLine(xO, yO, xE, yE);
      g.drawLine(xO, yE, xE, yO);
    }
   
    private Runnable signAreaThread() {
      return new Runnable() {
        public void run()
        {
          Point origin = sigPreviewComp.getLocationOnScreen();
         
            while(drawRect) {
              try {
                  Thread.sleep(100);
              }
              catch (Exception e) {
               
              }             
              double x = MouseInfo.getPointerInfo().getLocation().getX() - origin.getX();
              double y = MouseInfo.getPointerInfo().getLocation().getY() - origin.getY();
                           
              signRectEnd.setLocation(x, y);             
              sigPreviewComp.repaint();
            }
        }
      };
    }
  }
   
    private static class ProgressPanel extends JPanel
  {
    public ProgressPanel(int current)
    {
      setBorder(new EtchedBorder());
      JLabel progressLabel = new JLabel("Step " + current + " of " + MAXIMUM_PANELS);
      progressLabel.setAlignmentX(RIGHT_ALIGNMENT);
        add(progressLabel);
      }
  }
 
  private static class TitlePanel extends JPanel
 
    public TitlePanel(String title)
    {
          setBackground(Color.gray);
          setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED));
         
          JLabel textLabel = new JLabel();
          textLabel.setBackground(Color.gray);
          textLabel.setFont(new Font("Dialog", Font.BOLD, 14));
          textLabel.setText(title);
          textLabel.setBorder(new EmptyBorder(new Insets(10, 10, 10, 10)));
          textLabel.setOpaque(true);
          add(textLabel);
    }
  }
  /**
   * This is an empty panel I used for a template. 
   * It is never instanced or shown in the actual dialog.
   */
  private static class PanelTemplate extends JPanel
  {
    public PanelTemplate()
    {
      int y = 0;
      setLayout(new BorderLayout());
      add(new TitlePanel("Template"), BorderLayout.NORTH);

      JPanel optionPanel = new JPanel();   
      optionPanel.setLayout(new GridBagLayout());

//      GridBagConstraints c = new GridBagConstraints();
//      c.gridx = 0;
//      c.gridy = y;
//      c.fill = GridBagConstraints.HORIZONTAL;
//      c.anchor = GridBagConstraints.PAGE_START;
     
      add(new ProgressPanel(3), BorderLayout.SOUTH);
    }
  } 
}

TOP

Related Classes of org.jpedal.examples.simpleviewer.gui.popups.SignWizardModel$CommonPanel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.