/* * Gui.java * * * ==================================================== Professional Data Security (PDS) http://crypto.brettlee.com ==================================================== Copyright (c) 2009-2012, Brett Lee All rights reserved. Portions Copyright (C) 1995-2008, Sun Microsystems, Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the ORGANIZATION nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ============================================================================= */ package com.brettlee.crypto; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Cursor; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; import java.awt.FlowLayout; import java.awt.Font; import java.awt.Image; import java.awt.image.BufferedImage; import java.awt.Insets; import java.awt.Toolkit; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.Serializable; import java.util.HashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.BorderFactory; import javax.swing.event.CaretEvent; import javax.swing.event.CaretListener; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.event.UndoableEditEvent; import javax.swing.event.UndoableEditListener; import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JDesktopPane; import javax.swing.JEditorPane; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JInternalFrame; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JToolBar; import javax.swing.JViewport; import javax.swing.KeyStroke; import javax.swing.plaf.FontUIResource; import javax.swing.text.JTextComponent; import javax.swing.text.StyledEditorKit; import javax.swing.ToolTipManager; import javax.swing.UIManager; import javax.swing.undo.CannotRedoException; import javax.swing.undo.CannotUndoException; import javax.swing.undo.UndoManager; import javax.swing.WindowConstants; /** * @author Brett Lee * */ public class Gui { /** * Declarations (Well, I declare...) * */ // Gui final JFrame mainFrame = new JFrame(); // Content Pane private JMenuBar menuBar; private JToolBar toolBar; // File Menu private JMenu fileMenu; private JMenu newMenuItem; private JMenuItem newMenuItemFile; private JMenuItem newMenuItemKey; private JMenuItem newMenuItemKeyStore; private JMenu viewMenuItem; private JMenuItem viewMenuItemFile; // private JMenuItem viewMenuItemKey; // Not implemented private JMenuItem viewMenuItemKeyStore; private JMenu editMenuItem; private JMenuItem editMenuItemFile; private JMenuItem editMenuItemKey; private JMenuItem editMenuItemKeyStore; JMenuItem saveMenuItem; // used by CreateFileDialog JMenuItem saveAsMenuItem; // used by CreateFileDialog private JMenuItem printMenuItem; private JMenuItem deleteMenuItem; JMenuItem closeMenuItem; // used by CreateFileDialog private JMenu externalFileMenuItem; private JMenuItem externalFileMenuItemEncrypt; private JMenuItem externalFileMenuItemDecrypt; private JMenuItem externalFileMenuItemEncryptDir; private JMenuItem externalFileMenuItemDecryptDir; private JMenuItem externalFileMenuItemPubEncrypt; // Not implemented private JMenuItem externalFileMenuItemPubDecrypt; // Not implemented private JMenuItem exitMenuItem; // Edit Menu private JMenu editMenu; UndoAction undoAction = new UndoAction(); // subclass RedoAction redoAction = new RedoAction(); // subclass private CutAction cutAction = new CutAction(); private CopyAction copyAction = new CopyAction(); private PasteAction pasteAction = new PasteAction(); // Key Menu private JMenu keyMenu; private JMenuItem keyMenuItemNew; private JMenuItem keyMenuItemView; private JMenuItem keyMenuItemEdit; // KeyStore Menu private JMenu keyStoreMenu; private JMenuItem keyStoreMenuItemNew; private JMenuItem keyStoreMenuItemView; private JMenuItem keyStoreMenuItemEdit; private JMenuItem keyStoreMenuItemTransferKeys; // Encrypt Menu private JMenu encryptFileMenuItem; private JMenuItem encryptFileMenuItemEncrypt; private JMenuItem encryptFileMenuItemDecrypt; private JMenuItem encryptFileMenuItemEncryptDir; private JMenuItem encryptFileMenuItemDecryptDir; private JMenuItem encryptFileMenuItemPubEncrypt; // Not implemented private JMenuItem encryptFileMenuItemPubDecrypt; // Not implemented // Tools Menu private JMenu toolsMenu; private JMenuItem optionsMenuItem; // Help Menu private JMenu helpMenu; private JMenuItem contentsMenuItem; private JMenuItem aboutMenuItem; // Toolbar Buttons private JButton iconNewFile; private JButton iconViewFile; private JButton iconEditFile; JButton iconSave; // used by CreateFileDialog private JButton iconNewKey; private JButton iconEditKey; private JButton iconNewKeyStore; private JButton iconEditKeyStore; private JButton iconHelp; // Pane holding the Internal Frames JDesktopPane desktopPane; // used by CreateFileDialog, MyInternalFrame // Frequently used shortcuts String newline = System.getProperty("line.separator"); String fileSeparator = java.io.File.separator; // Runtime String runTimePath; // Save state between executions. StateObject stateObject; /////////////////////////////////////////////////////////////////////// /** * Gooey Gui * */ /////////////////////////////////////////////////////////////////////// public static void main(String args[]) { new Gui(1); } /** * Gui - Display the initialization Gui(1), or get a Gui() instance... * */ Gui(int go) { if ( go == 1 ) { // Schedule a job for the event-dispatching thread javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { initComponents(); } }); } } /////////////////////////////////////////////////////////////////////// /** * Static methods of the Gui class * */ /////////////////////////////////////////////////////////////////////// /** * Return an ImageIcon, or null if the path was invalid. * */ static ImageIcon createImageIcon(String path) { java.net.URL imgURL = Gui.class.getClassLoader().getResource( "com/brettlee/crypto/" + path ); if (imgURL != null) { return new ImageIcon(imgURL); } else { System.err.println("Couldn't find file: " + path); return null; } } static ImageIcon createImageIcon(String path, int size) { java.net.URL imgURL = Gui.class.getClassLoader().getResource( "com/brettlee/crypto/" + path ); // create an image from the path Image img = null; if (imgURL != null) { try { img = javax.imageio.ImageIO.read(imgURL); } catch (Exception ex) { System.out.println("Got an exception: " + ex); return null; } } // reduce the size BufferedImage bufImg = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB); java.awt.Graphics g = bufImg.createGraphics(); g.drawImage(img, 0, 0, size, size, null); g.dispose(); // return an image icon return new ImageIcon(bufImg); } static ImageIcon createImageIcon(String path, int size, int bgsize) { java.net.URL imgURL = Gui.class.getClassLoader().getResource( "com/brettlee/crypto/" + path ); // create an image from the path Image img = null; if (imgURL != null) { try { img = javax.imageio.ImageIO.read(imgURL); } catch (Exception ex) { System.out.println("Got an exception: " + ex); return null; } } // reduce the size BufferedImage bufImg = new BufferedImage(bgsize, bgsize, BufferedImage.TYPE_INT_ARGB); java.awt.Graphics g = bufImg.createGraphics(); g.drawImage(img, 0, 0, size, size, null); g.dispose(); // return an image icon return new ImageIcon(bufImg); } /** * Enter key can be used when JButton is in focus. * */ static void enterPressesWhenFocused(JButton button) { button.registerKeyboardAction( button.getActionForKeyStroke( KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, false)), KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, false), JComponent.WHEN_FOCUSED); button.registerKeyboardAction( button.getActionForKeyStroke( KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, true)), KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, true), JComponent.WHEN_FOCUSED); } /** * Set the default font * */ public static void setUIFont( javax.swing.plaf.FontUIResource font ) { java.util.Enumeration keys = UIManager.getDefaults().keys(); while ( keys.hasMoreElements() ) { Object key = keys.nextElement(); Object value = UIManager.get( key ); if (value instanceof javax.swing.plaf.FontUIResource) { UIManager.put( key, font ); } } } /////////////////////////////////////////////////////////////////////// /** * Private methods of the Gui class * */ /////////////////////////////////////////////////////////////////////// /** * closeApp - how to handle requests to close * */ private void closeApp() { // System.out.println("Application (mainFrame) Closing."); // OK, we've been told to close. // Check all the internal frames for unsaved changes. // How many frames are open // System.out.println("Open Frames: " + desktopPane.getAllFrames().length); // For each open frame... if ( desktopPane.getAllFrames().length > 0 ) { // System.out.println("Checking Internal Frames for Changes...."); JInternalFrame[] internalFrames = desktopPane.getAllFrames(); while ( desktopPane.getAllFrames().length > 0 ) { // System.out.println("Existing frames: " + desktopPane.getAllFrames().length ); // All Internal Frames are this type if ( internalFrames[ desktopPane.getAllFrames().length - 1 ] instanceof MyInternalFrame ) { MyInternalFrame mif = (MyInternalFrame) internalFrames[ desktopPane.getAllFrames().length - 1]; mif.toFront(); if ( ! closeInternalFrame( mif ) ) { return; } } } } System.exit(0); } /** * Methods to support Editing the JInternalFrame * */ HashMap actions = createActionTable( new JTextArea() ); private HashMap createActionTable(JTextComponent textComponent) { HashMap actions = new HashMap(); Action[] actionsArray = textComponent.getActions(); for (int i = 0; i < actionsArray.length; i++) { Action a = actionsArray[i]; actions.put(a.getValue(Action.NAME), a); } return actions; } private Action getActionByName(String name) { return actions.get(name); } /////////////////////////////////////////////////////////////////////// /** * (Not-so-private) methods of the Gui class * */ /////////////////////////////////////////////////////////////////////// /** * closeInternalFrame - how to handle requests to close Internal Frames * */ boolean closeInternalFrame( MyInternalFrame mif ) { // System.out.println("Closing the internal frame..."); // Get the CryptoFile and set the Document to the current text CryptoFileNative cryptoFile = (CryptoFileNative) mif.getCryptoFile(); // Get the EditorPane JScrollPane scrollPane = (JScrollPane) mif.getContentPane().getComponent(0); JViewport viewPort = (JViewport) scrollPane.getComponent(0); JEditorPane editorPane = (JEditorPane) viewPort.getComponent(0); // Are there unsaved changes? try { if ( ((MyDefaultStyledDocument) editorPane.getDocument()).getDocumentChanged() ) { int n; if (! editorPane.getDocument().getText(0, editorPane.getDocument().getLength()).equals( cryptoFile.getSavedDocument().getText(0, cryptoFile.getSavedDocument().getLength())) ) { // popup confirmation dialog - return or otherwise n = JOptionPane.showOptionDialog( mainFrame, "Do you want to save the changes made to " + cryptoFile.getFileName() + " ?", "Unsaved Changes Pending", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE, null, new String[] {"Yes", "No", "Cancel"}, "Cancel"); } else { n = JOptionPane.showOptionDialog( mainFrame, newline + "The text within this document, \"" + cryptoFile.getFileName() + "\", " + newline + "has NOT changed since it was last saved." + newline + newline + "However, changes to the document structure have been made." + newline + newline + "Should the changes be saved?" + newline + newline, "Document Changes Pending", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE, null, new String[] {"Yes", "No", "Cancel"}, "Cancel"); } // Cancel if ( n == 2 ) { return false; } // Don't bother saving the changes if ( n == 1 ) { mif.setVisible(false); mif.dispose(); } // Save the changes if ( n == 0 ) { // System.out.println("Saving Changes..."); mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); if ( new CryptoEngine().encrypt ( cryptoFile ) ) { mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); mif.setVisible(false); mif.dispose(); // notify on success JOptionPane.showMessageDialog( mainFrame, "File saved successfully:" + newline + cryptoFile.getFullyPathedFileName() + newline , "File saved successfully", JOptionPane.INFORMATION_MESSAGE, createImageIcon("images/PDS_Logo-32.png")); } else { mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); mif.setVisible(false); mif.dispose(); // notify if failure JOptionPane.showMessageDialog( mainFrame, "Error saving the file:" + newline + cryptoFile.getFullyPathedFileName() + newline + newline + "Please check the console for additional information." , "Error Saving File", JOptionPane.ERROR_MESSAGE); } } } // no changes exist, so close the internal frame mif.setVisible(false); mif.dispose(); } catch (Exception ex) { System.out.println("Got an exception: " + ex); } // Last frame? // System.out.println("Desktop Frames: " + desktopPane.getAllFrames().length); if ( desktopPane.getAllFrames().length < 1 ) { saveMenuItem.setEnabled(false); saveAsMenuItem.setEnabled(false); closeMenuItem.setEnabled(false); printMenuItem.setEnabled(false); iconSave.setEnabled(false); } return true; } /////////////////////////////////////////////////////////////////////// /** * Initialize Components - Called from the Gui() method * This is where the heavy lifting occurs. * */ /////////////////////////////////////////////////////////////////////// private void initComponents() { // Bring up our presence... stateObject = new StateObject(); /* Use an appropriate Look and Feel */ try { if ( StateObject.dosWindows ) { UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); //UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel"); } else { //UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel"); UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel"); } /* Turn off metal's use of bold fonts */ UIManager.put("swing.boldMetal", Boolean.FALSE); /* Try to make the default button follow the focus */ UIManager.put("Button.defaultButtonFollowsFocus", Boolean.TRUE); /* Define a default font */ setUIFont( new FontUIResource ("Verdana", Font.PLAIN, 12) ); } catch (Exception ex) { // ex.printStackTrace(); } // Display Intro Dialog on Initial Install // if ( stateObject.getInitialInit() ) { stateObject.setInitialInit( false ); stateObject.saveState(); int maxAESsize = 0; try { maxAESsize = javax.crypto.Cipher.getMaxAllowedKeyLength("AES"); } catch (Exception e) { } String jceInstalled; if (maxAESsize > 128) { jceInstalled = "The JCE within your JRE is \"Unlimited\""; } else { jceInstalled = "The JCE within your JRE is \"Strong\""; } JOptionPane.showMessageDialog( mainFrame, newline + "Professional Data Security (PDS)" + newline + "Version 2.0 beta 1" + newline + newline + "Copyright (C) 2009-2012, Brett Lee" + newline + "All rights reserved." + newline + newline + "Thank you for trying PDS !!!" + newline + "Details on the operation and functionality may be found at:" + newline + "http://crypto.brettlee.com" + newline + "An overview of PDS is available via Help->Introduction (F1)" + newline + newline + "PDS supports the following JCE ciphers:" + newline + "Strong: DES, 3DES & AES-128" + newline + "Unlimited: DES, 3DES & AES-128/192/256" + newline + newline + jceInstalled + newline + newline + "You may redefine your default directories. Currently they are..." + newline + "Encrypted files:" + newline + stateObject.getDefaultEncryptedFilePath() + newline + "Encryption keys:" + newline + stateObject.getDefaultKeyStoreDir() + newline + newline , "Welcome to PDS", JOptionPane.INFORMATION_MESSAGE, createImageIcon("images/PDS_Logo-32.png")); } /* * Control the Tool Tips * ------------------------------------------------------------ */ ToolTipManager ttm = ToolTipManager.sharedInstance(); ttm.setInitialDelay(1000); ttm.setDismissDelay(3000); ttm.setReshowDelay(0); /* * Build the Menu Bar (File, Edit...) * ------------------------------------------------------------ */ menuBar = new JMenuBar(); menuBar.setBorderPainted(false); /* * Build the File drop down (New, Open, Save, ...) * ------------------------------------------------------------ */ fileMenu = new JMenu(); fileMenu.setText("File"); fileMenu.setMnemonic(KeyEvent.VK_F); fileMenu.setToolTipText("Options for Files, Keys and KeyStores."); newMenuItem = new JMenu(); newMenuItem.setText("New"); newMenuItem.setMnemonic(KeyEvent.VK_N); // // newMenuItem is a JMenu with a submenu, so... // // items in the newMenuItem submenu newMenuItemFile = new JMenuItem("PDS File..."); newMenuItemFile.setMnemonic(KeyEvent.VK_P); newMenuItemFile.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F2,0)); newMenuItemFile.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { createFileActionPerformed(evt); } }); newMenuItem.add(newMenuItemFile); newMenuItemKey = new JMenuItem("Key..."); newMenuItemKey.setMnemonic(KeyEvent.VK_K); newMenuItemKey.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { createKeyActionPerformed(evt); } }); newMenuItem.add(newMenuItemKey); newMenuItemKeyStore = new JMenuItem("KeyStore..."); newMenuItemKeyStore.setMnemonic(KeyEvent.VK_S); newMenuItemKeyStore.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { createKeyStoreActionPerformed(evt); } }); newMenuItem.add(newMenuItemKeyStore); // end newMenuItem submenu fileMenu.add(newMenuItem); viewMenuItem = new JMenu(); viewMenuItem.setText("View"); viewMenuItem.setMnemonic(KeyEvent.VK_V); // // viewMenuItem is a JMenu with a submenu, so... // // items in the newMenuItem submenu viewMenuItemFile = new JMenuItem("PDS File..."); viewMenuItemFile.setMnemonic(KeyEvent.VK_P); viewMenuItemFile.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F3,0)); viewMenuItemFile.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { viewEncryptedFileActionPerformed(evt); } }); viewMenuItem.add(viewMenuItemFile); viewMenuItemKeyStore = new JMenuItem("KeyStore..."); viewMenuItemKeyStore.setMnemonic(KeyEvent.VK_S); viewMenuItemKeyStore.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { notImplementedActionPerformed(evt); } }); viewMenuItem.add(viewMenuItemKeyStore); viewMenuItemKeyStore.setEnabled(false); // end viewMenuItem submenu fileMenu.add(viewMenuItem); editMenuItem = new JMenu(); editMenuItem.setText("Edit"); editMenuItem.setMnemonic(KeyEvent.VK_E); // // editMenuItem is a JMenu with a submenu, so... // // items in the newMenuItem submenu editMenuItemFile = new JMenuItem("PDS File..."); editMenuItemFile.setMnemonic(KeyEvent.VK_P); editMenuItemFile.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F4,0)); editMenuItemFile.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { editEncryptedFileActionPerformed(evt); } }); editMenuItem.add(editMenuItemFile); editMenuItemKey = new JMenuItem("Key(s) in the KeyStore..."); editMenuItemKey.setMnemonic(KeyEvent.VK_K); editMenuItemKey.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { editMenuItemKeyActionPerformed(evt); } }); editMenuItem.add(editMenuItemKey); editMenuItemKeyStore = new JMenu(); editMenuItemKeyStore.setMnemonic(KeyEvent.VK_S); editMenuItemKeyStore.setText("KeyStore"); // // editMenuItemKeyStore is a JMenu with a submenu, so... // editMenuItemKeyStore = new JMenuItem("KeyStore Passphrase..."); editMenuItemKeyStore.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { editMenuItemKeyStoreChangePassActionPerformed(evt); } }); editMenuItem.add(editMenuItemKeyStore); // end editMenuItem submenu fileMenu.add(editMenuItem); // begin External Files Menu Item & Submenu externalFileMenuItem = new JMenu(); externalFileMenuItem.setText("Encrypt / Decrypt"); externalFileMenuItem.setMnemonic(KeyEvent.VK_R); // // encryptMenuItem is a JMenu with a submenu, so... // // items in the encryptMenuItem submenu externalFileMenuItemEncrypt = new JMenuItem("Encrypt a File..."); externalFileMenuItemEncrypt.setMnemonic(KeyEvent.VK_E); externalFileMenuItemEncrypt.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { encryptExternalFileActionPerformed(evt); } }); externalFileMenuItem.add (externalFileMenuItemEncrypt); externalFileMenuItemDecrypt = new JMenuItem("Decrypt a File..."); externalFileMenuItemDecrypt.setMnemonic(KeyEvent.VK_D); externalFileMenuItemDecrypt.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { decryptExternalFileActionPerformed(evt); } }); externalFileMenuItem.add (externalFileMenuItemDecrypt); externalFileMenuItem.addSeparator(); externalFileMenuItemEncryptDir = new JMenuItem("Encrypt a Directory..."); externalFileMenuItemEncryptDir.setMnemonic(KeyEvent.VK_N); externalFileMenuItemEncryptDir.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { encryptExternalDirActionPerformed(evt); } }); externalFileMenuItem.add (externalFileMenuItemEncryptDir); externalFileMenuItemDecryptDir = new JMenuItem("Decrypt a Directory..."); externalFileMenuItemDecryptDir.setMnemonic(KeyEvent.VK_C); externalFileMenuItemDecryptDir.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { decryptExternalDirActionPerformed(evt); } }); externalFileMenuItem.add (externalFileMenuItemDecryptDir); externalFileMenuItem.addSeparator(); // Not implemented // externalFileMenuItemPubEncrypt = new JMenuItem("Encrypt a File ( PKI )"); externalFileMenuItemPubEncrypt.setEnabled(false); externalFileMenuItem.add (externalFileMenuItemPubEncrypt); externalFileMenuItemPubDecrypt = new JMenuItem("Decrypt a File ( PKI )"); externalFileMenuItemPubDecrypt.setEnabled(false); externalFileMenuItem.add (externalFileMenuItemPubDecrypt); // end of externalFileMenuItem submenu. // add the externalFileMenuItem to the FileMenu. fileMenu.add(externalFileMenuItem); /* * Continue the File drop down (..., Save, Exit) * ------------------------------------------------------------ */ saveMenuItem = new JMenuItem(); saveMenuItem.setText("Save"); saveMenuItem.setMnemonic(KeyEvent.VK_S); saveMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F5,0)); saveMenuItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { saveEncryptedFileActionPerformed(evt); } }); saveMenuItem.setEnabled(false); fileMenu.add(saveMenuItem); saveAsMenuItem = new JMenuItem(); saveAsMenuItem.setText("Save As..."); saveAsMenuItem.setMnemonic(KeyEvent.VK_A); saveAsMenuItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { saveAsEncryptedFileActionPerformed(evt); } }); saveAsMenuItem.setEnabled(false); fileMenu.add(saveAsMenuItem); fileMenu.addSeparator(); printMenuItem = new JMenuItem(); printMenuItem.setText("Print..."); printMenuItem.setMnemonic(KeyEvent.VK_P); printMenuItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { notImplementedActionPerformed(evt); } }); printMenuItem.setEnabled(false); fileMenu.add(printMenuItem); fileMenu.addSeparator(); deleteMenuItem = new JMenuItem(); deleteMenuItem.setText("Delete..."); deleteMenuItem.setMnemonic(KeyEvent.VK_D); deleteMenuItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { deleteFileActionPerformed(evt); } }); fileMenu.add(deleteMenuItem); fileMenu.addSeparator(); closeMenuItem = new JMenuItem(); closeMenuItem.setText("Close"); closeMenuItem.setMnemonic(KeyEvent.VK_C); closeMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F7,0)); closeMenuItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { closeEncryptedFileActionPerformed(evt); } }); closeMenuItem.setEnabled(false); fileMenu.add(closeMenuItem); exitMenuItem = new JMenuItem("Exit"); exitMenuItem.setMnemonic(KeyEvent.VK_X); exitMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F12,0)); exitMenuItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { exitMenuItemActionPerformed(evt); } }); fileMenu.add(exitMenuItem); menuBar.add(fileMenu); /* * Build the Edit drop down (Undo, Redo, Cut, Copy, Paste, Find) * --------------------------------------------------------------- */ editMenu = new JMenu("Edit"); editMenu.setMnemonic(KeyEvent.VK_E); editMenu.setToolTipText("Useful editing shortcuts when editing PDS files."); editMenu.add(undoAction); editMenu.add(redoAction); editMenu.addSeparator(); editMenu.add(cutAction); editMenu.add(copyAction); editMenu.add(pasteAction); editMenu.addSeparator(); editMenu.add(getActionByName(StyledEditorKit.selectAllAction)); // add the menu bar menuBar.add(editMenu); /* * Build the Key drop down (New, View, Edit) * --------------------------------------------------------------- */ keyMenu = new JMenu("Key"); keyMenu.setMnemonic(KeyEvent.VK_K); keyMenu.setToolTipText("Work with Encryption Keys."); keyMenuItemNew = new JMenuItem(); keyMenuItemNew.setText("New Key"); keyMenuItemNew.setMnemonic(KeyEvent.VK_N); keyMenuItemNew.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { createKeyActionPerformed(evt); } }); keyMenu.add( keyMenuItemNew ); keyMenuItemView = new JMenuItem(); keyMenuItemView.setText("View Key"); keyMenuItemView.setMnemonic(KeyEvent.VK_V); keyMenuItemView.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { notImplementedActionPerformed(evt); } }); keyMenu.add( keyMenuItemView ); keyMenuItemView.setEnabled(false); keyMenuItemEdit = new JMenuItem(); keyMenuItemEdit.setText("Edit Key(s)"); keyMenuItemEdit.setMnemonic(KeyEvent.VK_E); keyMenuItemEdit.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { editMenuItemKeyActionPerformed(evt); } }); keyMenu.add( keyMenuItemEdit ); // add the new KeyMenu. menuBar.add(keyMenu); /* * Build the KeyStore drop down (New, View, Edit) * --------------------------------------------------------------- */ keyStoreMenu = new JMenu("KeyStore"); keyStoreMenu.setMnemonic(KeyEvent.VK_S); keyStoreMenu.setToolTipText("Work with a KeyStore."); keyStoreMenuItemNew = new JMenuItem(); keyStoreMenuItemNew.setText("New KeyStore"); keyStoreMenuItemNew.setMnemonic(KeyEvent.VK_N); keyStoreMenuItemNew.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { createKeyStoreActionPerformed(evt); } }); keyStoreMenu.add( keyStoreMenuItemNew ); keyStoreMenuItemView = new JMenuItem(); keyStoreMenuItemView.setText("View KeyStore"); keyStoreMenuItemView.setMnemonic(KeyEvent.VK_V); keyStoreMenuItemView.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { notImplementedActionPerformed(evt); } }); keyStoreMenu.add( keyStoreMenuItemView ); keyStoreMenuItemView.setEnabled(false); keyStoreMenuItemEdit = new JMenuItem(); keyStoreMenuItemEdit.setText("Edit KeyStore Passphrase"); keyStoreMenuItemEdit.setMnemonic(KeyEvent.VK_E); keyStoreMenuItemEdit.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { editMenuItemKeyStoreChangePassActionPerformed(evt); } }); keyStoreMenu.add( keyStoreMenuItemEdit ); keyStoreMenuItemTransferKeys = new JMenuItem("Transfer Keys between KeyStores..."); keyStoreMenuItemTransferKeys.setMnemonic(KeyEvent.VK_T); keyStoreMenuItemTransferKeys.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { notImplementedActionPerformed(evt); } }); keyStoreMenuItemTransferKeys.setEnabled(false); keyStoreMenu.add(keyStoreMenuItemTransferKeys); // add the new KeyStoreMenu. menuBar.add(keyStoreMenu); // begin Encrypt (External) Files Menu Item & Submenu encryptFileMenuItem = new JMenu("Encrypt"); encryptFileMenuItem.setMnemonic(KeyEvent.VK_R); // // encryptMenuItem is a JMenu with a submenu, so... // // items in the encryptMenuItem submenu encryptFileMenuItemEncrypt = new JMenuItem("Encrypt a File..."); encryptFileMenuItemEncrypt.setMnemonic(KeyEvent.VK_E); encryptFileMenuItemEncrypt.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { encryptExternalFileActionPerformed(evt); } }); encryptFileMenuItem.add (encryptFileMenuItemEncrypt); encryptFileMenuItemDecrypt = new JMenuItem("Decrypt a File..."); encryptFileMenuItemDecrypt.setMnemonic(KeyEvent.VK_D); encryptFileMenuItemDecrypt.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { decryptExternalFileActionPerformed(evt); } }); encryptFileMenuItem.add (encryptFileMenuItemDecrypt); encryptFileMenuItem.addSeparator(); encryptFileMenuItemEncryptDir = new JMenuItem("Encrypt a Directory..."); encryptFileMenuItemEncryptDir.setMnemonic(KeyEvent.VK_N); encryptFileMenuItemEncryptDir.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { encryptExternalDirActionPerformed(evt); } }); encryptFileMenuItem.add (encryptFileMenuItemEncryptDir); encryptFileMenuItemDecryptDir = new JMenuItem("Decrypt a Directory..."); encryptFileMenuItemDecryptDir.setMnemonic(KeyEvent.VK_C); encryptFileMenuItemDecryptDir.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { decryptExternalDirActionPerformed(evt); } }); encryptFileMenuItem.add (encryptFileMenuItemDecryptDir); encryptFileMenuItem.addSeparator(); // Not implemented // encryptFileMenuItemPubEncrypt = new JMenuItem("Encrypt a File ( PKI )"); encryptFileMenuItem.add (encryptFileMenuItemPubEncrypt); encryptFileMenuItemPubEncrypt.setEnabled(false); encryptFileMenuItemPubDecrypt = new JMenuItem("Decrypt a File ( PKI )"); encryptFileMenuItem.add (encryptFileMenuItemPubDecrypt); encryptFileMenuItemPubDecrypt.setEnabled(false); // end of externalFileMenuItem submenu. // add the new FileMenuItem. menuBar.add(encryptFileMenuItem); /* * Build the Tools drop down (Options) * ------------------------------------------------------------ */ toolsMenu = new JMenu(); toolsMenu.setText("Tools"); toolsMenu.setMnemonic(KeyEvent.VK_T); toolsMenu.setToolTipText("Utilities and application settings."); optionsMenuItem = new JMenuItem(); optionsMenuItem.setText("Options..."); optionsMenuItem.setMnemonic(KeyEvent.VK_O); optionsMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F8,0)); optionsMenuItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { optionsMenuItemActionPerformed(evt); } }); optionsMenuItem.setEnabled(true); toolsMenu.add(optionsMenuItem); menuBar.add(toolsMenu); /* * Build the Help drop down (Help, About) * ------------------------------------------------------------ */ helpMenu = new JMenu(); helpMenu.setText("Help"); helpMenu.setMnemonic(KeyEvent.VK_H); helpMenu.setToolTipText("Documentation about this application."); contentsMenuItem = new JMenuItem(); contentsMenuItem.setText("Introduction"); contentsMenuItem.setMnemonic(KeyEvent.VK_I); contentsMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F1,0)); contentsMenuItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { introductionMenuItemActionPerformed(evt); } }); helpMenu.add(contentsMenuItem); helpMenu.addSeparator(); aboutMenuItem = new JMenuItem(); aboutMenuItem.setText("About"); aboutMenuItem.setMnemonic(KeyEvent.VK_A); aboutMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F9,0)); aboutMenuItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { helpAboutMenuItemActionPerformed(evt); } }); helpMenu.add(aboutMenuItem); menuBar.add(helpMenu); /* * Build the Tool Bar - Icons * ------------------------------------------------------------ * */ toolBar = new JToolBar(); toolBar.setRollover(true); iconNewFile = new JButton( createImageIcon("images/fileNew.gif", 32)); iconNewFile.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { createFileActionPerformed(evt); } }); iconNewFile.setToolTipText("New PDS file"); iconNewFile.setMargin( new Insets(0, 0, 0, 0) ); iconNewFile.setBorderPainted(true); toolBar.add(iconNewFile); iconViewFile = new JButton( createImageIcon("images/fileView.gif", 32)); iconViewFile.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { viewEncryptedFileActionPerformed(evt); } }); iconViewFile.setToolTipText("View PDS file"); iconViewFile.setMargin( new Insets(0, 0, 0, 0) ); iconViewFile.setBorderPainted(true); toolBar.add(iconViewFile); iconEditFile = new JButton( createImageIcon("images/fileEdit.gif", 32)); iconEditFile.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { editEncryptedFileActionPerformed(evt); } }); iconEditFile.setToolTipText("Edit PDS file"); iconEditFile.setMargin( new Insets(0, 0, 0, 0) ); iconEditFile.setBorderPainted(true); toolBar.add(iconEditFile); toolBar.addSeparator(); // Override the ActionListener class saveActionListener implements ActionListener { public void actionPerformed ( ActionEvent evt ) { saveEncryptedFileActionPerformed(evt); } } iconSave = new JButton( createImageIcon("images/fileSave.gif", 32)); iconSave.addActionListener(new saveActionListener() { } ); iconSave.setToolTipText("Save PDS file"); iconSave.setMargin( new Insets(0, 0, 0, 0) ); iconSave.setBorderPainted(true); iconSave.setEnabled(false); toolBar.add(iconSave); toolBar.addSeparator(); iconNewKey = new JButton( createImageIcon("images/keyNew.gif", 32)); iconNewKey.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { createKeyActionPerformed(evt); } }); iconNewKey.setToolTipText("New Encryption Key"); iconNewKey.setMargin( new Insets(0, 0, 0, 0) ); iconNewKey.setBorderPainted(true); toolBar.add(iconNewKey); iconEditKey = new JButton( createImageIcon("images/keyEdit.gif", 32)); iconEditKey.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { editMenuItemKeyActionPerformed(evt); } }); iconEditKey.setToolTipText("Edit Encryption Key"); iconEditKey.setMargin( new Insets(0, 0, 0, 0) ); iconEditKey.setBorderPainted(true); toolBar.add(iconEditKey); toolBar.addSeparator(); iconNewKeyStore = new JButton( createImageIcon("images/keyStoreNew.gif", 32)); iconNewKeyStore.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { createKeyStoreActionPerformed(evt); } }); iconNewKeyStore.setToolTipText("New KeyStore"); iconNewKeyStore.setMargin( new Insets(0, 0, 0, 0) ); iconNewKeyStore.setBorderPainted(true); toolBar.add(iconNewKeyStore); iconEditKeyStore = new JButton( createImageIcon("images/keyStoreEdit.gif", 32)); iconEditKeyStore.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { editMenuItemKeyStoreChangePassActionPerformed(evt); } }); iconEditKeyStore.setToolTipText("Edit KeyStore"); iconEditKeyStore.setMargin( new Insets(0, 0, 0, 0) ); iconEditKeyStore.setBorderPainted(true); toolBar.add(iconEditKeyStore); toolBar.addSeparator(); iconHelp = new JButton( createImageIcon("images/toolsOptions.gif", 32)); iconHelp.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { optionsMenuItemActionPerformed(evt); } }); iconHelp.setToolTipText("Options"); iconHelp.setMargin( new Insets(0, 0, 0, 0) ); iconHelp.setBorderPainted(true); toolBar.add(iconHelp); iconHelp = new JButton( createImageIcon("images/helpIntro.gif", 32)); iconHelp.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { introductionMenuItemActionPerformed(evt); } }); iconHelp.setToolTipText("Introduction"); iconHelp.setMargin( new Insets(0, 0, 0, 0) ); iconHelp.setBorderPainted(true); toolBar.add(iconHelp); // Prevent JToolBar items from gaining focus in Windows // "Focus" seen in in Windows L&F and not on Metal L&F, // so stopping both seems to have the desired effect. if ( UIManager.getLookAndFeel().getName() == "Windows" ) { for (int i = toolBar.getComponentCount() - 1; i >= 0; --i) toolBar.getComponent(i).setFocusable(false); } /* * Build the Panel Structure for the menuBar & toolBar * ------------------------------------------------------------ * */ FlowLayout flowLayoutLeft = new FlowLayout(); flowLayoutLeft.setAlignment(FlowLayout.LEFT); JPanel menuBarPanel = new JPanel( flowLayoutLeft ); menuBarPanel.add( menuBar ); menuBarPanel.setBorder(BorderFactory.createEtchedBorder()); menuBarPanel.setAlignmentY(Component.TOP_ALIGNMENT); JPanel toolBarPanel = new JPanel( flowLayoutLeft ); toolBarPanel.add( toolBar ); toolBarPanel.setBorder(BorderFactory.createEtchedBorder()); mainFrame.setJMenuBar( menuBar ); mainFrame.getContentPane().add( toolBar, BorderLayout.NORTH); /* * Build the JDesktopPane for the Editor Pane * ------------------------------------------------------------ * */ // Outer frame to hold internal frames desktopPane = new JDesktopPane(); desktopPane.setBackground( new Color( 255,255,255 ) ); mainFrame.getContentPane().add( desktopPane ); Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); desktopPane.setPreferredSize( new Dimension ( ((int) (java.lang.Math.min(640, dim.getWidth()))), ((int) (java.lang.Math.min(480, dim.getHeight()))) )); desktopPane.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE); /* * Build the Footer * ------------------------------------------------------------ * */ JLabel label = new JLabel("Data Encryption - Security you can Trust", JLabel.CENTER); mainFrame.add(label, BorderLayout.PAGE_END); /* * Finish up initComponents() * ------------------------------------------------------------ * */ int maxAESsize = 0; try { maxAESsize = javax.crypto.Cipher.getMaxAllowedKeyLength("AES"); } catch (Exception e) { } String jceInstalled; if (maxAESsize > 128) { jceInstalled = " - JCE is Unlimited"; } else { jceInstalled = " - JCE is Strong"; } mainFrame.setTitle("Professional Data Security (PDS)" + jceInstalled); mainFrame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); mainFrame.addWindowListener(new java.awt.event.WindowAdapter() { public void windowClosing(java.awt.event.WindowEvent e) { // System.out.println("Application (mainFrame) Closing."); closeApp(); } }); mainFrame.pack(); mainFrame.setLocationRelativeTo(null); mainFrame.setVisible(true); /* Show the "About" dialog at startup */ // helpAboutMenuItemActionPerformed(null); } // End initComponents() /////////////////////////////////////////////////////////////////////// /** * Event Handlers: * Registered during initComponents() * */ /////////////////////////////////////////////////////////////////////// private void notImplementedActionPerformed(ActionEvent evt) { JOptionPane.showMessageDialog(mainFrame, "This functionality has not been implemented." , "Under Construction", JOptionPane.INFORMATION_MESSAGE, createImageIcon("images/PDS_Logo-32.png")); } // ========================================= // FILE Drop Down Menu // ========================================= // New File private void createFileActionPerformed(ActionEvent evt) { CryptoFile cryptoFile = new CryptoFileNative(); new CreateFileDialog( this, cryptoFile ); } // New Key private void createKeyActionPerformed(ActionEvent evt) { new CreateKeyDialog(this); } // New KeyStore private void createKeyStoreActionPerformed(ActionEvent evt) { new CreateKeyStoreDialog(this); } // View File private void viewEncryptedFileActionPerformed(ActionEvent evt) { CryptoFileNative viewCryptoFile = new CryptoFileNative(); final JFileChooser fileChooser; // Should ALWAYS be true if (stateObject.getDefaultEncryptedFilePath() instanceof String) { fileChooser = new JFileChooser ( stateObject.getDefaultEncryptedFilePath() ); } else { fileChooser = new JFileChooser ( runTimePath ); } fileChooser.setDialogTitle("Select File"); fileChooser.setApproveButtonText("Select"); FileNameExtensionFilter filterPDS = new FileNameExtensionFilter("Professional Data Security Files (PDS)", "PDS"); FileNameExtensionFilter filterJCEKS = new FileNameExtensionFilter("Java Cryptographic Extension (JCE) KeyStores (JCEKS)", "JCEKS"); FileNameExtensionFilter filterJKS = new FileNameExtensionFilter("Java KeyStores (JKS)", "JKS"); FileNameExtensionFilter filterKeyStores = new FileNameExtensionFilter("Java KeyStores (JCEKS, JKS)", "JCEKS", "JKS"); fileChooser.addChoosableFileFilter( filterJKS ); fileChooser.addChoosableFileFilter( filterJCEKS ); fileChooser.addChoosableFileFilter(filterKeyStores); fileChooser.addChoosableFileFilter( filterPDS ); int returnVal = fileChooser.showOpenDialog(mainFrame); if ( returnVal == 0 ) { viewCryptoFile.setFullyPathedFileName ( fileChooser.getSelectedFile().getPath() ); viewCryptoFile.setFileName( fileChooser.getSelectedFile().getName() ); // System.out.println("View File Name: " + viewCryptoFile.getFullyPathedFileName() ); } else { // System.out.println("File name not returned from the chooser. Cancel."); return; } // Have the filename. Need to verify this is a viewable (native) file, // and not an external file. boolean isNative = false; BufferedReader br = null; try { br = new BufferedReader( new FileReader( viewCryptoFile.getFullyPathedFileName() )); String currentLine; Pattern pattern = Pattern.compile("(.*?)#(.*)"); while ( ((currentLine = br.readLine()) != null) && (currentLine.getBytes().length != 0) ) { Matcher matcher = pattern.matcher(currentLine); if(matcher.matches()) { if ((matcher.group(1).equals("CryptoFile")) && (matcher.group(2).equals("NATIVE"))) { // System.out.println("File is a Native File"); isNative = true; } if ((matcher.group(1).equals("CryptoFileNativeFormat")) && (matcher.group(2).equals("DOCUMENT"))) { // System.out.println("File contains a StyledDocument"); viewCryptoFile.setIsStyledDocument( true ); } } } br.close(); } catch(Exception e) { System.out.println("Exception: " + e); try { br.close(); } catch ( Exception ex) { System.out.println("Exception: " + e); } finally { } } if (! isNative ) { // notify if failure JFrame frame = new JFrame(); JOptionPane.showMessageDialog( frame, "Unable to view this file:" + newline + viewCryptoFile.getFileName() + newline + "It is not recognized as a native PDS file." + newline + newline + "If this file should be Viewable, please backup the" + newline + "PDS file and add the following text to the" + newline + "metadata section at the top of the original file:" + newline + newline + "CryptoFile#NATIVE" + newline + newline + "Note that all native PDS files have a text header and" + newline + "the data is encoded Base64. For additional details," + newline + "please see the Release Notes - section 1.0 alpha 5." + newline + newline , "Unable to View File", JOptionPane.WARNING_MESSAGE); return; } // Need to verify the KeyStore location, as we may now be on // another computer, it might have moved, etc. mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); if (! new VerifyKeyStore(this).verifyLocation ( viewCryptoFile, 0 ) ) { mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); if ( StateObject.getFileChooserCancel() ) { StateObject.setFileChooserCancel( false ); } else { // notify if failure JFrame frame = new JFrame(); JOptionPane.showMessageDialog( frame, "Unable to proceed without a valid KeyStore." + newline + "Check the console for additional information." , "Unable to Verify the KeyStore", JOptionPane.WARNING_MESSAGE); } return; } mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); // System.out.println("KeyStore: " + viewCryptoFile.getKsName() ); // Have the KeyStore. Ready to decrypt the file. mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); if (! new CryptoFileNative().viewFile( viewCryptoFile ) ) { mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); // notify if failure JFrame frame = new JFrame(); JOptionPane.showMessageDialog( frame, "Error getting the file." + newline + "Retry using different credentials or" + newline + "check the console for additional information." , "Error Viewing File", JOptionPane.ERROR_MESSAGE); return; } mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); } // View KeyStore // not implemented yet // Edit PDS File private void editEncryptedFileActionPerformed(ActionEvent evt) { CryptoFileNative editCryptoFile = new CryptoFileNative(); final JFileChooser fileChooser; // Should ALWAYS be true - may want to modify/remove else? if (stateObject.getDefaultEncryptedFilePath() instanceof String) { fileChooser = new JFileChooser ( stateObject.getDefaultEncryptedFilePath() ); } else { fileChooser = new JFileChooser ( runTimePath ); } fileChooser.setDialogTitle("Select File"); fileChooser.setApproveButtonText("Select"); FileNameExtensionFilter filterPDS = new FileNameExtensionFilter("Professional Data Security Files (PDS)", "PDS"); FileNameExtensionFilter filterJCEKS = new FileNameExtensionFilter("Java Cryptographic Extension (JCE) KeyStores (JCEKS)", "JCEKS"); FileNameExtensionFilter filterJKS = new FileNameExtensionFilter("Java KeyStores (JKS)", "JKS"); FileNameExtensionFilter filterKeyStores = new FileNameExtensionFilter("Java KeyStores (JCEKS, JKS)", "JCEKS", "JKS"); fileChooser.addChoosableFileFilter( filterJKS ); fileChooser.addChoosableFileFilter( filterJCEKS ); fileChooser.addChoosableFileFilter(filterKeyStores); fileChooser.addChoosableFileFilter( filterPDS ); int returnVal = fileChooser.showOpenDialog(mainFrame); if ( returnVal == 0 ) { editCryptoFile.setFullyPathedFileName ( fileChooser.getSelectedFile().getPath() ); editCryptoFile.setFileName( fileChooser.getSelectedFile().getName() ); // System.out.println("File To Edit: " + editCryptoFile.getFullyPathedFileName() ); } else { // System.out.println("File name not returned from the chooser. Cancel."); return; } // Have the filename. Need to verify this is a viewable (native) file, // and not an external file. boolean isNative = false; BufferedReader br = null; try { br = new BufferedReader( new FileReader( editCryptoFile.getFullyPathedFileName() )); String currentLine; Pattern pattern = Pattern.compile("(.*?)#(.*)"); while ( ((currentLine = br.readLine()) != null) && (currentLine.getBytes().length != 0) ) { Matcher matcher = pattern.matcher(currentLine); if(matcher.matches()) { if ((matcher.group(1).equals("CryptoFile")) && (matcher.group(2).equals("NATIVE"))) { // System.out.println("File is a Native File"); isNative = true; } if ((matcher.group(1).equals("CryptoFileNativeFormat")) && (matcher.group(2).equals("DOCUMENT"))) { // System.out.println("File contains a StyledDocument"); editCryptoFile.setIsStyledDocument( true ); } } } br.close(); } catch(Exception e) { System.out.println("Exception: " + e); try { br.close(); } catch ( Exception ex) { System.out.println("Exception: " + e); } finally { } } if (! isNative ) { JFrame frame = new JFrame(); JOptionPane.showMessageDialog( frame, "Unable to edit this file:" + newline + editCryptoFile.getFileName() + newline + "It is not recognized as a native PDS file." + newline + newline + "If this file should be Editable, please backup the" + newline + "PDS file and add the following text to the" + newline + "metadata section at the top of the original file:" + newline + newline + "CryptoFile#NATIVE" + newline + newline + "Note that all native PDS files have a text header and" + newline + "the data is encoded Base64. For additional details," + newline + "please see the Release Notes - section 1.0 alpha 5." + newline + newline , "Unable to Edit File", JOptionPane.WARNING_MESSAGE); return; } // Need to verify the KeyStore location, as we may now be on // another computer, it might have moved, etc. mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); if (! new VerifyKeyStore(this).verifyLocation ( editCryptoFile, 0 ) ) { mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); // notify if failure JFrame frame = new JFrame(); JOptionPane.showMessageDialog( frame, "Error Verifying the KeyStore." + newline + "Check the console for additional information." , "Error Verifying the KeyStore", JOptionPane.ERROR_MESSAGE); return; } mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); // System.out.println("KeyStore: " + editCryptoFile.getKsName() ); // Have the KeyStore. Ready to decrypt the file. // mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); if (! new CryptoFileNative().editFile( editCryptoFile )) { mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); // Was the Auth Dialog action canceled - yes, we need a getAuthCancel() if ( StateObject.getFileChooserCancel() ) { StateObject.setFileChooserCancel(false); return; } // notify if failure JFrame frame = new JFrame(); JOptionPane.showMessageDialog( frame, "Error getting the file." + newline + "Retry using different credentials or" + newline + "check the console for additional information." , "Error Editing File", JOptionPane.ERROR_MESSAGE); return; } mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); // System.out.println("Internal frame count is: " + desktopPane.getAllFrames().length); JInternalFrame internalFrame = (JInternalFrame) new MyInternalFrame( this, editCryptoFile ); // System.out.println("Internal frame count is: " + desktopPane.getAllFrames().length); // Close it manually, allowing for the CANCEL option internalFrame.setDefaultCloseOperation(JInternalFrame.DO_NOTHING_ON_CLOSE); internalFrame.setSize(500, 300); internalFrame.setLocation( 20*desktopPane.getAllFrames().length, 30*desktopPane.getAllFrames().length ); desktopPane.add( internalFrame ); // Create the Editor final JEditorPane editorPane = new JEditorPane(); editorPane.putClientProperty("editor", editorPane); editorPane.setPreferredSize(new Dimension(450,250)); editorPane.setEditorKit( new StyledEditorKit() ); editorPane.setEditable(true); final UndoManager undo = new UndoManager(); // This listens for and reports caret movements. final class CaretListenerLabel extends JLabel implements CaretListener { public CaretListenerLabel(String label) { super(label); } // Might not be invoked from the event dispatch thread. public void caretUpdate(CaretEvent e) { } } // This one listens for edits that can be undone. final class MyUndoableEditListener implements UndoableEditListener { public void undoableEditHappened(UndoableEditEvent e) { // Remember the edit and update the menus. undo.addEdit(e.getEdit()); undoAction.updateUndoState(); redoAction.updateRedoState(); } } // And this one listens for any changes to the document. final class MyDocumentListener implements DocumentListener { public void insertUpdate(DocumentEvent e) { ((MyDefaultStyledDocument) editorPane.getDocument()).setDocumentChanged( true ); } public void removeUpdate(DocumentEvent e) { ((MyDefaultStyledDocument) editorPane.getDocument()).setDocumentChanged( true ); } public void changedUpdate(DocumentEvent e) { ((MyDefaultStyledDocument) editorPane.getDocument()).setDocumentChanged( true ); } } // Add the Document Text to the Editor // editorPane.setDocument( editCryptoFile.getActiveDocument() ); editorPane.setMargin( new Insets(10, 10, 10, 10) ); editorPane.setCaretPosition(0); editorPane.getDocument().addUndoableEditListener(new MyUndoableEditListener()); editorPane.addCaretListener(new CaretListenerLabel("")); editorPane.getDocument().addDocumentListener(new MyDocumentListener()); editorPane.putClientProperty("undo", undo); editorPane.addFocusListener(new FocusListener() { public void focusGained(FocusEvent e) { StateObject.setEditorInFocus(editorPane); undoAction.updateUndoState(); redoAction.updateRedoState(); } public void focusLost(FocusEvent e) { } }); // Add ScrollBars JScrollPane scrollPane = new JScrollPane(editorPane); // And Activate editorPane.addNotify(); scrollPane.addNotify(); // Add Editor to Internal Frame internalFrame.getContentPane().add( scrollPane, BorderLayout.CENTER ); // Add Footer JLabel footerLabel = new JLabel("Professional Data Security (PDS)", JLabel.CENTER); internalFrame.add(footerLabel, BorderLayout.PAGE_END); // And show... internalFrame.toFront(); internalFrame.setVisible(true); // Wake up the other functionalities saveMenuItem.setEnabled(true); saveAsMenuItem.setEnabled(true); closeMenuItem.setEnabled(true); iconSave.setEnabled(true); iconSave.repaint(); } // Edit PDS File Properties // not implemented yet // Edit Key private void editMenuItemKeyActionPerformed(ActionEvent evt) { new EditKeyDialog(this); } // Edit KeyStore Change Passphrase private void editMenuItemKeyStoreChangePassActionPerformed(ActionEvent evt) { new EditKeyStoreChangePassDialog(this); } // Save private void saveEncryptedFileActionPerformed(ActionEvent evt) { // System.out.println("CryptoFile File : " + editorCryptoFile.getFullyPathedFileName() ); // System.out.println("CryptoFile KeyStore Name : " + editorCryptoFile.getKsName() ); // System.out.print("KeyStore Passphrase: "); // for ( int i = 0; i < editorCryptoFile.getKsPass().length; i++ ) { // System.out.print( editorCryptoFile.getKsPass()[i] ); // } // System.out.println(); // System.out.println("CryptoFile Key Alias : " + editorCryptoFile.getKeyAlias() ); // System.out.print("Key Passphrase: "); // for ( int i = 0; i < editorCryptoFile.getKeyPass().length; i++ ) { // System.out.print( editorCryptoFile.getKeyPass()[i] ); // } // System.out.println(); // Get Selected Internal Frame if ( desktopPane.getSelectedFrame() instanceof MyInternalFrame ) { // All Internal Frames are this type MyInternalFrame mif = (MyInternalFrame) desktopPane.getSelectedFrame(); // Get the CryptoFile and set the Document to the current text CryptoFileNative cryptoFile = (CryptoFileNative) mif.getCryptoFile(); // Get the EditorPane // JScrollPane scrollPane = (JScrollPane) mif.getContentPane().getComponent(0); // JViewport viewPort = (JViewport) scrollPane.getComponent(0); // JEditorPane editorPane = (JEditorPane) viewPort.getComponent(0); mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); if ( new CryptoEngine().encrypt ( cryptoFile ) ) { mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); // notify on success JOptionPane.showMessageDialog( mainFrame, "File saved successfully." + newline + cryptoFile.getFullyPathedFileName() + newline , "File saved successfully", JOptionPane.INFORMATION_MESSAGE, createImageIcon("images/PDS_Logo-32.png")); } else { mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); // notify if failure JOptionPane.showMessageDialog( mainFrame, "Error saving the file:" + newline + cryptoFile.getFullyPathedFileName() + newline + newline + "Please check the console for additional information." , "Error Saving File", JOptionPane.ERROR_MESSAGE); } } } // Save As private void saveAsEncryptedFileActionPerformed(ActionEvent evt) { // System.out.println("CryptoFile File : " + editorCryptoFile.getFullyPathedFileName() ); // System.out.println("CryptoFile KeyStore Name : " + editorCryptoFile.getKsName() ); // System.out.print("KeyStore Passphrase: "); // for ( int i = 0; i < editorCryptoFile.getKsPass().length; i++ ) { // System.out.print( editorCryptoFile.getKsPass()[i] ); // } // System.out.println(); // System.out.println("CryptoFile Key Alias : " + editorCryptoFile.getKeyAlias() ); // System.out.print("Key Passphrase: "); // for ( int i = 0; i < editorCryptoFile.getKeyPass().length; i++ ) { // System.out.print( editorCryptoFile.getKeyPass()[i] ); // } // System.out.println(); // Get Selected Internal Frame if ( desktopPane.getSelectedFrame() instanceof MyInternalFrame ) { // All Internal Frames are this type MyInternalFrame mif = (MyInternalFrame) desktopPane.getSelectedFrame(); // Get the CryptoFile and set the Document to the current text CryptoFileNative cryptoFile = (CryptoFileNative) mif.getCryptoFile(); // Get the EditorPane // JScrollPane scrollPane = (JScrollPane) mif.getContentPane().getComponent(0); // JViewport viewPort = (JViewport) scrollPane.getComponent(0); // JEditorPane editorPane = (JEditorPane) viewPort.getComponent(0); final JFileChooser fileChooser = new JFileChooser ( stateObject.getDefaultEncryptedFilePath() ); fileChooser.setDialogTitle("Select Location"); fileChooser.setApproveButtonText("Save"); FileNameExtensionFilter filterPDS = new FileNameExtensionFilter("Professional Data Security Files (PDS)", "PDS"); FileNameExtensionFilter filterJCEKS = new FileNameExtensionFilter("Java Cryptographic Extension (JCE) KeyStores (JCEKS)", "JCEKS"); FileNameExtensionFilter filterJKS = new FileNameExtensionFilter("Java KeyStores (JKS)", "JKS"); FileNameExtensionFilter filterKeyStores = new FileNameExtensionFilter("Java KeyStores (JCEKS, JKS)", "JCEKS", "JKS"); fileChooser.addChoosableFileFilter( filterJKS ); fileChooser.addChoosableFileFilter( filterJCEKS ); fileChooser.addChoosableFileFilter(filterKeyStores); fileChooser.addChoosableFileFilter( filterPDS ); int returnVal = fileChooser.showOpenDialog(mainFrame); if ( returnVal == 0 ) { if ( ! ( cryptoFile.getFullyPathedFileName() ).equals ( fileChooser.getSelectedFile().getPath() )) { if ( new File (fileChooser.getSelectedFile().getPath()).exists() ) { JFrame frame = new JFrame(); int n = JOptionPane.showOptionDialog( frame, "A file with this name already exists. Overwrite?" + newline + fileChooser.getSelectedFile().getPath() + newline + newline , "Overwrite existing file?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, new String[] {"Yes", "No"}, "No"); if ( n != 0 ) { // System.out.println("No..."); return; } } } cryptoFile.setFullyPathedFileName ( fileChooser.getSelectedFile().getPath() ); cryptoFile.setFileName( fileChooser.getSelectedFile().getName() ); // Ensure ".PDS" extension exists Pattern pattern = Pattern.compile("(.*).PDS", Pattern.CASE_INSENSITIVE); Matcher matcher = pattern.matcher( cryptoFile.getFullyPathedFileName() ); if( ! matcher.matches()) { cryptoFile.setFullyPathedFileName( cryptoFile.getFullyPathedFileName() + ".PDS" ); cryptoFile.setFileName( fileChooser.getSelectedFile().getName() + ".PDS"); } // System.out.println("Crypto File Name: " + cryptoFile.getFullyPathedFileName() ); mif.setTitle(cryptoFile.getFileName() + " - " + cryptoFile.getFullyPathedFileName() ); } else { // System.out.println("Error returning the file name from the chooser..."); return; } mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); if ( new CryptoEngine().encrypt ( cryptoFile ) ) { mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); // notify on success JOptionPane.showMessageDialog( mainFrame, "File saved successfully." + newline + cryptoFile.getFullyPathedFileName() + newline , "File saved successfully", JOptionPane.INFORMATION_MESSAGE, createImageIcon("images/PDS_Logo-32.png")); } else { mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); // notify if failure JOptionPane.showMessageDialog( mainFrame, "Error saving the file:" + newline + cryptoFile.getFullyPathedFileName() + newline + newline + "Please check the console for additional information." , "Error Saving File", JOptionPane.ERROR_MESSAGE); } } } // Delete private void deleteFileActionPerformed(ActionEvent evt) { final JFileChooser fileChooser; // Should always be correct. May want to delete/modify the "else" clause. if (stateObject.getDefaultEncryptedFilePath() instanceof String) { fileChooser = new JFileChooser ( stateObject.getDefaultEncryptedFilePath() ); } else { fileChooser = new JFileChooser ( runTimePath ); } fileChooser.setDialogTitle("Delete Files Only"); fileChooser.setApproveButtonText("Delete"); FileNameExtensionFilter filterPDS = new FileNameExtensionFilter("Professional Data Security Files (PDS)", "PDS"); FileNameExtensionFilter filterJCEKS = new FileNameExtensionFilter("Java Cryptographic Extension (JCE) KeyStores (JCEKS)", "JCEKS"); FileNameExtensionFilter filterJKS = new FileNameExtensionFilter("Java KeyStores (JKS)", "JKS"); FileNameExtensionFilter filterKeyStores = new FileNameExtensionFilter("Java KeyStores (JCEKS, JKS)", "JCEKS", "JKS"); fileChooser.addChoosableFileFilter( filterJKS ); fileChooser.addChoosableFileFilter( filterJCEKS ); fileChooser.addChoosableFileFilter(filterKeyStores); fileChooser.addChoosableFileFilter( filterPDS ); int returnVal = fileChooser.showOpenDialog(mainFrame); if ( returnVal == 0 ) { String fileToDelete = fileChooser.getSelectedFile().getPath(); // System.out.println("File to delete: " + fileToDelete); JFrame frame = new JFrame(); int n = JOptionPane.showOptionDialog( frame, "About to delete this file: " + newline + fileToDelete + newline + newline + "Continue?", "Delete File", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, new String[] {"Yes", "No"}, "No"); if ( n != 0 ) { // System.out.println("Canceling..."); return; } // System.out.println("Deleting: " + fileToDelete); try { File f = new File( fileToDelete ); f.delete(); // notify on success JOptionPane.showMessageDialog( mainFrame, "File sucessfully deleted:" + newline + fileToDelete + newline , "File deleted.", JOptionPane.INFORMATION_MESSAGE, createImageIcon("images/PDS_Logo-32.png")); } catch (Exception e) { System.out.println("Unable to delete the file: " + fileToDelete); System.out.println("Exception: " + e); JOptionPane.showMessageDialog( mainFrame, "Unable to delete the file:" + newline + fileToDelete + newline + newline + "Please check the console for additional information." + newline , "Error deleting file", JOptionPane.ERROR_MESSAGE); } } else { // System.out.println("File name not returned from the chooser. Cancel."); return; } } // Close private void closeEncryptedFileActionPerformed(ActionEvent evt) { // Get Selected Internal Frame if ( desktopPane.getSelectedFrame() instanceof MyInternalFrame ) { // All Internal Frames are this type MyInternalFrame mif = (MyInternalFrame) desktopPane.getSelectedFrame(); mif.doDefaultCloseAction(); } } // Exit private void exitMenuItemActionPerformed(ActionEvent evt) { // System.out.println("Application (mainFrame) Closing."); closeApp(); } // ========================================= // EDIT Drop Down Menu // ========================================= // Undo // implemented below as an inner class // Redo // implemented below as an inner class // Find // Not implemented. For an example, see: // http://www.discoverteenergy.com/files/Editor.zip // Cut // implemented below as an inner class // Copy // implemented below as an inner class // Paste // implemented below as an inner class // ========================================= // TOOLS Drop Down Menu // ========================================= // ** External Files ** // Encrypt File using Symmetric Key public void encryptExternalFileActionPerformed(ActionEvent evt) { CryptoFileExternal cryptoFile = new CryptoFileExternal(); cryptoFile.setEncryptedOutputFormat( 1 ); cryptoFile.setDeviceType( 0 ); new CreateFileDialog( this, (CryptoFile) cryptoFile ); } // Decrypt File using Symmetric Key private void decryptExternalFileActionPerformed(ActionEvent evt) { CryptoFileExternal cryptoFile = new CryptoFileExternal(); cryptoFile.setDecryptionTypeRequested( 0 ); cryptoFile.setDeviceType( 0 ); new DecryptExternalFileDialog( this, cryptoFile, 0 ); } // Encrypt Directory using Symmetric Key private void encryptExternalDirActionPerformed(ActionEvent evt) { CryptoFileExternal cryptoFile = new CryptoFileExternal(); cryptoFile.setEncryptedOutputFormat( 2 ); cryptoFile.setDeviceType( 0 ); new CreateFileDialog( this, (CryptoFile) cryptoFile ); } // Decrypt Directory using Symmetric Key private void decryptExternalDirActionPerformed(ActionEvent evt) { CryptoFileExternal cryptoFile = new CryptoFileExternal(); cryptoFile.setDecryptionTypeRequested( 1 ); cryptoFile.setDeviceType( 0 ); new DecryptExternalFileDialog( this, cryptoFile , 1 ); } // Encrypt using Public Key // not implemented yet // Decrypt using Public Key // not implemented yet // Options Menu private void optionsMenuItemActionPerformed(ActionEvent evt) { new OptionsDialog(this); } // ========================================= // HELP Drop Down Menu // ========================================= private void introductionMenuItemActionPerformed(ActionEvent evt) { new IntroductionDialog(); } private void helpAboutMenuItemActionPerformed(ActionEvent evt) { int maxAESsize = 0; try { maxAESsize = javax.crypto.Cipher.getMaxAllowedKeyLength("AES"); } catch (Exception e) { } String jceInstalled; if (maxAESsize > 128) { jceInstalled = "The JCE within your JRE is \"Unlimited\""; } else { jceInstalled = "The JCE within your JRE is \"Strong\""; } JOptionPane.showMessageDialog( mainFrame, newline + "Professional Data Security (PDS)" + newline + "Version 2.0 beta 1" + newline + newline + "Copyright (C) 2009-2012, Brett Lee" + newline + "All rights reserved." + newline + newline + "Details on the operation and functionality may be found" + newline + "at: http://crypto.brettlee.com" + newline + "An overview of PDS is available via Help->Introduction (F1)" + newline + "Or, you may email me at: pds@brettlee.com." + newline + newline + "Contributors to PDS include:" + newline + "David Lee (dlee@calldei.com): Expert Advice ++" + newline + "Kim Lee (kim@thefrontoffice.biz): PDS Icons" + newline + "Karen Kroll (karen@katnapdesigns.com): PDS Logos" + newline + newline + "PDS supports the following JCE ciphers:" + newline + "Strong: DES, 3DES & AES-128" + newline + "Unlimited: DES, 3DES & AES-128/192/256" + newline + newline + jceInstalled + newline + newline , "About", JOptionPane.INFORMATION_MESSAGE, createImageIcon("images/PDS_Logo-32.png")); } // BUTTONS toolbar // ===================== // Handled in the Menu Bar /////////////////////////////////////////////////////////////////////// /** * Inner Classes * */ /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /** * Classes to support Editing (Undo/Redo) the Internal Frames * * Undo/RedoAction class from Java Swing Tutorials * http://java.sun.com/docs/books/tutorial/uiswing/examples/ * > /components/TextComponentDemoProject/src/components/TextComponentDemo.java * */ class UndoAction extends AbstractAction { UndoManager undo; private UndoAction() { super("Undo"); setEnabled(false); putValue( Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_U) ); putValue( Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_U, InputEvent.CTRL_MASK) ); } public void actionPerformed(ActionEvent e) { JEditorPane editorInFocus = StateObject.getEditorInFocus(); if ( editorInFocus.getClientProperty("undo") instanceof UndoManager ) { undo = (UndoManager) editorInFocus.getClientProperty("undo"); try { undo.undo(); } catch (CannotUndoException ex) { System.out.println("Unable to undo: " + ex); // ex.printStackTrace(); } updateUndoState(); redoAction.updateRedoState(); } else { System.out.println("No UndoManager - Undo"); } } void updateUndoState() { JEditorPane editorInFocus = StateObject.getEditorInFocus(); if ( editorInFocus.getClientProperty("undo") instanceof UndoManager ) { undo = (UndoManager) editorInFocus.getClientProperty("undo"); if (undo.canUndo()) { setEnabled(true); putValue(Action.NAME, undo.getUndoPresentationName()); } else { setEnabled(false); putValue(Action.NAME, "Undo"); } } else { System.out.println("No UndoManager - Undo"); } } } class RedoAction extends AbstractAction { UndoManager undo; private RedoAction() { super("Redo"); setEnabled(false); putValue( Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_R) ); putValue( Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_R, InputEvent.CTRL_MASK) ); } public void actionPerformed(ActionEvent e) { JEditorPane editorInFocus = StateObject.getEditorInFocus(); if ( editorInFocus.getClientProperty("undo") instanceof UndoManager ) { undo = (UndoManager) editorInFocus.getClientProperty("undo"); try { undo.redo(); } catch (CannotRedoException ex) { System.out.println("Unable to redo: " + ex); // ex.printStackTrace(); } updateRedoState(); undoAction.updateUndoState(); } else { System.out.println("No UndoManager - Redo"); } } void updateRedoState() { JEditorPane editorInFocus = StateObject.getEditorInFocus(); if ( editorInFocus.getClientProperty("undo") instanceof UndoManager ) { undo = (UndoManager) editorInFocus.getClientProperty("undo"); if (undo.canRedo()) { setEnabled(true); putValue(Action.NAME, undo.getRedoPresentationName()); } else { setEnabled(false); putValue(Action.NAME, "Redo"); } } else { System.out.println("No UndoManager - Redo"); } } } // The following classes are from Rob Camick (camikr) - Java / Swing Forum // See: http://www.discoverteenergy.com/files/Editor.zip // private class CutAction extends StyledEditorKit.CutAction { public CutAction() { putValue( Action.NAME, "Cut" ); putValue( Action.SHORT_DESCRIPTION, getValue(Action.NAME) ); putValue( Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_T) ); putValue( Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_X, InputEvent.CTRL_MASK) ); } } private class CopyAction extends StyledEditorKit.CopyAction { public CopyAction() { putValue( Action.NAME, "Copy" ); putValue( Action.SHORT_DESCRIPTION, getValue(Action.NAME) ); putValue( Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_C) ); putValue( Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_MASK) ); } } private class PasteAction extends StyledEditorKit.PasteAction { public PasteAction() { putValue( Action.NAME, "Paste" ); putValue( Action.SHORT_DESCRIPTION, getValue(Action.NAME) ); putValue( Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_P) ); putValue( Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_MASK) ); } } } // End of Gui (outer / main) class // ----------------------------------------------------------------------------