You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by ti...@apache.org on 2015/05/31 09:45:23 UTC

svn commit: r1682687 - in /pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools: PDFDebugger.java pdfdebugger/treestatus/TreeStatusPane.java pdfdebugger/ui/ pdfdebugger/ui/Tree.java util/FileOpenSaveDialog.java

Author: tilman
Date: Sun May 31 07:45:23 2015
New Revision: 1682687

URL: http://svn.apache.org/r1682687
Log:
PDFBOX-2530: save streams from context + tree focus, as done by Khyrul Bashar in GSoC2015

Added:
    pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/pdfdebugger/ui/
    pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/pdfdebugger/ui/Tree.java   (with props)
    pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/util/FileOpenSaveDialog.java   (with props)
Modified:
    pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/PDFDebugger.java
    pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/pdfdebugger/treestatus/TreeStatusPane.java

Modified: pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/PDFDebugger.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/PDFDebugger.java?rev=1682687&r1=1682686&r2=1682687&view=diff
==============================================================================
--- pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/PDFDebugger.java (original)
+++ pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/PDFDebugger.java Sun May 31 07:45:23 2015
@@ -19,23 +19,27 @@ package org.apache.pdfbox.tools;
 import java.awt.BorderLayout;
 import java.awt.Dimension;
 import java.awt.event.ActionEvent;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
 import java.util.List;
 import javax.swing.AbstractAction;
 import javax.swing.Action;
 import javax.swing.JComponent;
-import javax.swing.JFileChooser;
 import javax.swing.JMenu;
 import javax.swing.JMenuItem;
 import javax.swing.JPanel;
 import javax.swing.JScrollPane;
 import javax.swing.UIManager;
 import javax.swing.border.BevelBorder;
-import javax.swing.tree.TreeModel;
-import javax.swing.tree.TreePath;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
+import org.apache.pdfbox.tools.gui.PDFTreeModel;
+import org.apache.pdfbox.tools.gui.PDFTreeCellRenderer;
+import org.apache.pdfbox.tools.gui.ArrayEntry;
+import org.apache.pdfbox.tools.gui.MapEntry;
+
+import org.apache.pdfbox.pdmodel.PDDocument;
+
 import org.apache.pdfbox.cos.COSBoolean;
 import org.apache.pdfbox.cos.COSFloat;
 import org.apache.pdfbox.cos.COSInteger;
@@ -43,11 +47,16 @@ import org.apache.pdfbox.cos.COSName;
 import org.apache.pdfbox.cos.COSNull;
 import org.apache.pdfbox.cos.COSStream;
 import org.apache.pdfbox.cos.COSString;
-import org.apache.pdfbox.pdmodel.PDDocument;
-import org.apache.pdfbox.tools.gui.ArrayEntry;
-import org.apache.pdfbox.tools.gui.MapEntry;
-import org.apache.pdfbox.tools.gui.PDFTreeCellRenderer;
-import org.apache.pdfbox.tools.gui.PDFTreeModel;
+
+import javax.swing.tree.TreeModel;
+import javax.swing.tree.TreePath;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.InputStream;
+import java.io.IOException;
+import org.apache.pdfbox.tools.util.FileOpenSaveDialog;
+import org.apache.pdfbox.tools.pdfdebugger.ui.Tree;
 import org.apache.pdfbox.tools.pdfdebugger.treestatus.TreeStatus;
 import org.apache.pdfbox.tools.pdfdebugger.treestatus.TreeStatusPane;
 import org.apache.pdfbox.tools.util.RecentFiles;
@@ -61,7 +70,6 @@ public class PDFDebugger extends javax.s
 {
     private TreeStatusPane statusPane;
 
-    private File currentDir=new File(".");
     private PDDocument document = null;
     private String currentFilePath = null;
 
@@ -87,7 +95,7 @@ public class PDFDebugger extends javax.s
     {
         jSplitPane1 = new javax.swing.JSplitPane();
         jScrollPane1 = new JScrollPane();
-        jTree1 = new javax.swing.JTree();
+        tree = new Tree(this);
         jScrollPane2 = new JScrollPane();
         jTextPane1 = new javax.swing.JTextPane();
         menuBar = new javax.swing.JMenuBar();
@@ -106,36 +114,47 @@ public class PDFDebugger extends javax.s
         contentsMenuItem = new JMenuItem();
         aboutMenuItem = new JMenuItem();
 
-        jTree1.setCellRenderer( new PDFTreeCellRenderer() );
-        jTree1.setModel( null );
+        tree.setCellRenderer( new PDFTreeCellRenderer() );
+        tree.setModel( null );
 
         setTitle("PDFBox - PDF Debugger");
+
+        addWindowFocusListener(new WindowAdapter()
+        {
+            @Override
+            public void windowGainedFocus(WindowEvent e)
+            {
+                jScrollPane1.requestFocusInWindow();
+                super.windowGainedFocus(e);
+            }
+        });
+
         addWindowListener(new java.awt.event.WindowAdapter()
         {
             @Override
-            public void windowClosing(java.awt.event.WindowEvent evt)
+            public void windowClosing(WindowEvent evt)
             {
                 exitForm(evt);
             }
         });
 
 
-        jScrollPane1.setBorder(new javax.swing.border.BevelBorder(javax.swing.border.BevelBorder.RAISED));
-        jScrollPane1.setPreferredSize(new java.awt.Dimension(300, 500));
-        jTree1.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener()
+        jScrollPane1.setBorder(new BevelBorder(BevelBorder.RAISED));
+        jScrollPane1.setPreferredSize(new Dimension(300, 500));
+        tree.addTreeSelectionListener(new TreeSelectionListener()
         {
             @Override
-            public void valueChanged(javax.swing.event.TreeSelectionEvent evt)
+            public void valueChanged(TreeSelectionEvent evt)
             {
                 jTree1ValueChanged(evt);
             }
         });
 
-        jScrollPane1.setViewportView(jTree1);
+        jScrollPane1.setViewportView(tree);
 
         jSplitPane1.setRightComponent(jScrollPane2);
 
-        jScrollPane2.setPreferredSize(new java.awt.Dimension(300, 500));
+        jScrollPane2.setPreferredSize(new Dimension(300, 500));
         jScrollPane2.setViewportView(jTextPane1);
 
         jSplitPane1.setLeftComponent(jScrollPane1);
@@ -143,12 +162,12 @@ public class PDFDebugger extends javax.s
         JScrollPane documentScroller = new JScrollPane();
         documentScroller.setViewportView( documentPanel );
 
-        statusPane = new TreeStatusPane(jTree1);
+        statusPane = new TreeStatusPane(tree);
         statusPane.getPanel().setBorder(new BevelBorder(BevelBorder.RAISED));
         statusPane.getPanel().setPreferredSize(new Dimension(300, 25));
         getContentPane().add(statusPane.getPanel(), BorderLayout.PAGE_START);
 
-        getContentPane().add( jSplitPane1, java.awt.BorderLayout.CENTER );
+        getContentPane().add( jSplitPane1, BorderLayout.CENTER );
 
         fileMenu.setText("File");
         openMenuItem.setText("Open");
@@ -218,46 +237,38 @@ public class PDFDebugger extends javax.s
 
         setJMenuBar(menuBar);
 
-
-        java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
+        Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
         setBounds((screenSize.width-700)/2, (screenSize.height-600)/2, 700, 600);
     }//GEN-END:initComponents
 
     private void openMenuItemActionPerformed(ActionEvent evt)
     {
-        JFileChooser chooser = new JFileChooser();
-        chooser.setCurrentDirectory(currentDir);
-
         ExtensionFileFilter pdfFilter = new ExtensionFileFilter(new String[] {"pdf", "PDF"}, "PDF Files");
-        chooser.setFileFilter(pdfFilter);
-        int result = chooser.showOpenDialog(PDFDebugger.this);
-        if (result == JFileChooser.APPROVE_OPTION)
+        FileOpenSaveDialog openDialog = new FileOpenSaveDialog(this, pdfFilter);
+        try
         {
-            String name = chooser.getSelectedFile().getPath();
-            currentDir = new File(name).getParentFile();
-            try
+            File file = openDialog.openFile();
+            if (file != null)
             {
+                String name = file.getPath();
                 readPDFFile(name, "");
             }
-            catch (Exception e)
-            {
-                throw new RuntimeException(e);
-            }
+        }
+        catch (Exception e)
+        {
+            throw new RuntimeException(e);
         }
     }//GEN-LAST:event_openMenuItemActionPerformed
 
-    private void jTree1ValueChanged(javax.swing.event.TreeSelectionEvent evt)
+    private void jTree1ValueChanged(TreeSelectionEvent evt)
     {
-        TreePath path = jTree1.getSelectionPath();
+        TreePath path = tree.getSelectionPath();
         if (path != null)
         {
             try
             {
                 Object selectedNode = path.getLastPathComponent();
                 String data=convertToString(selectedNode);
-
-
-
                 if (data != null)
                 {
                     jTextPane1.setText(data);
@@ -339,6 +350,8 @@ public class PDFDebugger extends javax.s
             try
             {
                 document.close();
+                recentFiles.addFile(currentFilePath);
+                recentFiles.close();
             }
             catch( IOException e )
             {
@@ -418,8 +431,8 @@ public class PDFDebugger extends javax.s
         TreeStatus treeStatus = new TreeStatus(document.getDocument().getTrailer());
         statusPane.updateTreeStatus(treeStatus);
         TreeModel model=new PDFTreeModel(document);
-        jTree1.setModel(model);
-        jTree1.setSelectionPath(treeStatus.getPathForString("Root"));
+        tree.setModel(model);
+        tree.setSelectionPath(treeStatus.getPathForString("Root"));
         setTitle("PDFBox - " + file.getAbsolutePath());
         addRecentFileItems();
     }
@@ -428,7 +441,7 @@ public class PDFDebugger extends javax.s
      *
      * @param file The file addressing the document.
      *
-     * @throws java.io.IOException If there is an error parsing the document.
+     * @throws IOException If there is an error parsing the document.
      */
     private void parseDocument( File file, String password )throws IOException
     {
@@ -499,7 +512,7 @@ public class PDFDebugger extends javax.s
     private JScrollPane jScrollPane2;
     private javax.swing.JSplitPane jSplitPane1;
     private javax.swing.JTextPane jTextPane1;
-    private javax.swing.JTree jTree1;
+    private Tree tree;
     private javax.swing.JMenuBar menuBar;
     private JMenuItem openMenuItem;
     private JMenuItem pasteMenuItem;

Modified: pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/pdfdebugger/treestatus/TreeStatusPane.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/pdfdebugger/treestatus/TreeStatusPane.java?rev=1682687&r1=1682686&r2=1682687&view=diff
==============================================================================
--- pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/pdfdebugger/treestatus/TreeStatusPane.java (original)
+++ pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/pdfdebugger/treestatus/TreeStatusPane.java Sun May 31 07:45:23 2015
@@ -52,6 +52,7 @@ public class TreeStatusPane implements T
             if (path != null)
             {
                 tree.setSelectionPath(path);
+                tree.requestFocusInWindow();
             }
             else
             {

Added: pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/pdfdebugger/ui/Tree.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/pdfdebugger/ui/Tree.java?rev=1682687&view=auto
==============================================================================
--- pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/pdfdebugger/ui/Tree.java (added)
+++ pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/pdfdebugger/ui/Tree.java Sun May 31 07:45:23 2015
@@ -0,0 +1,271 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.pdfbox.tools.pdfdebugger.ui;
+
+import java.awt.Point;
+import java.awt.Toolkit;
+import java.awt.datatransfer.Clipboard;
+import java.awt.datatransfer.StringSelection;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseEvent;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import javax.swing.JMenuItem;
+import javax.swing.JPopupMenu;
+import javax.swing.JTree;
+import javax.swing.tree.TreePath;
+import org.apache.pdfbox.cos.COSArray;
+import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.cos.COSStream;
+import org.apache.pdfbox.io.IOUtils;
+import org.apache.pdfbox.pdmodel.common.PDStream;
+import org.apache.pdfbox.tools.PDFDebugger;
+import org.apache.pdfbox.tools.gui.ArrayEntry;
+import org.apache.pdfbox.tools.gui.MapEntry;
+import org.apache.pdfbox.tools.pdfdebugger.treestatus.TreeStatus;
+import org.apache.pdfbox.tools.util.FileOpenSaveDialog;
+
+/**
+ * @author Khyrul Bashar
+ *
+ * A customized tree for PDFDebugger.
+ */
+public class Tree extends JTree
+{
+    private final JPopupMenu treePopupMenu;
+    private final PDFDebugger parent;
+    private final Object rootNode;
+
+    /**
+     * Constructor.
+     * @param parentComponent the main UI where the Tree resides.
+     */
+    public Tree(PDFDebugger parentComponent)
+    {
+        super();
+        treePopupMenu = new JPopupMenu();
+        setComponentPopupMenu(treePopupMenu);
+        parent = parentComponent;
+        rootNode = this.getModel().getRoot();
+    }
+
+    @Override
+    public Point getPopupLocation(MouseEvent event)
+    {
+        if (event != null)
+        {
+            TreePath path = getClosestPathForLocation(event.getX(), event.getY());
+            setSelectionPath(path);
+            treePopupMenu.removeAll();
+            for (JMenuItem menuItem : getPopupMenuItems(path))
+            {
+                treePopupMenu.add(menuItem);
+            }
+            return event.getPoint();
+        }
+        return null;
+    }
+
+    /**
+     * Produce the popup menu items depending on the node of a certain TreePath.
+     * @param nodePath is instance of TreePath of the specified Node.
+     * @return the JMenuItem list for the node
+     */
+    private ArrayList<JMenuItem> getPopupMenuItems(TreePath nodePath)
+    {
+        Object obj = nodePath.getLastPathComponent();
+        ArrayList<JMenuItem> menuItems = new ArrayList<JMenuItem>();
+
+        if (obj instanceof MapEntry)
+        {
+            obj = ((MapEntry) obj).getValue();
+        }
+        else if (obj instanceof ArrayEntry)
+        {
+            obj = ((ArrayEntry) obj).getValue();
+        }
+
+        if (obj instanceof COSStream)
+        {
+            COSStream stream = (COSStream) obj;
+            menuItems.add(getUnFilteredStreamSaveMenu(stream));
+            if (stream.getFilters() != null)
+            {
+                if (stream.getFilters() instanceof COSArray && ((COSArray) stream.getFilters()).size() >= 2)
+                {
+                    for (JMenuItem menuItem : getPartiallyFilteredStreamSaveMenu(stream))
+                    {
+                        menuItems.add(menuItem);
+                    }
+                }
+                menuItems.add(getFilteredStreamSaveMenu(stream));
+            }
+        }
+
+        menuItems.add(getTreePathMenuItem(nodePath));
+        return menuItems;
+    }
+
+    /**
+     * Produce the JMenuItem that gives way to copy tree path string to clipboard
+     * @param path the TreePath instance
+     * @return Menu Item
+     */
+    private JMenuItem getTreePathMenuItem(final TreePath path)
+    {
+        JMenuItem copyPathMenuItem = new JMenuItem("Copy tree path");
+        copyPathMenuItem.addActionListener(new ActionListener()
+        {
+            @Override
+            public void actionPerformed(ActionEvent actionEvent)
+            {
+                Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
+                clipboard.setContents(new StringSelection(new TreeStatus(rootNode).getStringForPath(path)), null);
+            }
+        });
+        return copyPathMenuItem;
+    }
+
+    /**
+     * Produce JMenuItem that saves filtered stream
+     * @param cosStream stream to save
+     * @return JMenuItem for saving filtered stream
+     */
+    private JMenuItem getFilteredStreamSaveMenu(final COSStream cosStream)
+    {
+        JMenuItem saveMenuItem = new JMenuItem("Save filtered stream ...");
+        saveMenuItem.addActionListener(new ActionListener()
+        {
+            @Override
+            public void actionPerformed(ActionEvent actionEvent)
+            {
+                try
+                {
+                    byte[] bytes = IOUtils.toByteArray(cosStream.getFilteredStream());
+                    saveStream(bytes);
+                }
+                catch (IOException e)
+                {
+                    e.printStackTrace();
+                }
+            }
+        });
+        return saveMenuItem;
+    }
+
+
+    /**
+     * Produce JMenuItem that saves unfiltered stream
+     * @param cosStream stream to save
+     * @return JMenuItem for saving unfiltered stream
+     */
+    private JMenuItem getUnFilteredStreamSaveMenu(final COSStream cosStream)
+    {
+        JMenuItem saveMenuItem = new JMenuItem("Save unfiltered stream ...");
+        saveMenuItem.addActionListener(new ActionListener()
+        {
+            @Override
+            public void actionPerformed(ActionEvent actionEvent)
+            {
+                try
+                {
+                    byte[] bytes = IOUtils.toByteArray(cosStream.getUnfilteredStream());
+                    saveStream(bytes);
+                }
+                catch (IOException e)
+                {
+                    e.printStackTrace();
+                }
+            }
+        });
+        return saveMenuItem;
+    }
+
+    /**
+     * produce possible partially filtered stream saving menu items
+     * @param cosStream stream to save
+     * @return JMenuItems for saving partially filtered streams
+     */
+    private List<JMenuItem> getPartiallyFilteredStreamSaveMenu(final COSStream cosStream)
+    {
+        List<JMenuItem> menuItems = new ArrayList<JMenuItem>();
+        PDStream stream = new PDStream(cosStream);
+
+        List<COSName> filters = stream.getFilters();
+
+        for (int i = filters.size() - 1; i >= 1; i--)
+        {
+            menuItems.add(getPartialStreamSavingMenuItem(i, stream));
+        }
+        return menuItems;
+    }
+
+    private JMenuItem getPartialStreamSavingMenuItem(final int indexOfStopFilter, final PDStream stream)
+    {
+        List<COSName> filters = stream.getFilters();
+
+        final List<String> stopFilters = new ArrayList<String>(1);
+        stopFilters.add(filters.get(indexOfStopFilter).getName());
+
+        StringBuilder nameListBuilder = new StringBuilder();
+        for (int i = indexOfStopFilter; i < filters.size(); i++)
+        {
+            nameListBuilder.append(filters.get(i).getName()).append(" & ");
+        }
+        nameListBuilder.delete(nameListBuilder.lastIndexOf("&"), nameListBuilder.length());
+        JMenuItem menuItem = new JMenuItem("Keep " + nameListBuilder.toString() + "...");
+
+        menuItem.addActionListener(new ActionListener()
+        {
+            @Override
+            public void actionPerformed(ActionEvent actionEvent)
+            {
+                try
+                {
+                    InputStream data = stream.getPartiallyFilteredStream(stopFilters);
+                    saveStream(IOUtils.toByteArray(data));
+                }
+                catch (IOException e)
+                {
+                    e.printStackTrace();
+                }
+            }
+        });
+        return menuItem;
+    }
+
+    /**
+     * save the stream
+     * @param bytes byte array of the stream
+     */
+    private void saveStream(byte[] bytes)
+    {
+        FileOpenSaveDialog saveDialog = new FileOpenSaveDialog(parent, null);
+        try
+        {
+            saveDialog.saveFile(bytes);
+        }
+        catch (IOException e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+}

Propchange: pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/pdfdebugger/ui/Tree.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/util/FileOpenSaveDialog.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/util/FileOpenSaveDialog.java?rev=1682687&view=auto
==============================================================================
--- pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/util/FileOpenSaveDialog.java (added)
+++ pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/util/FileOpenSaveDialog.java Sun May 31 07:45:23 2015
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.pdfbox.tools.util;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import javax.swing.JFileChooser;
+import javax.swing.JOptionPane;
+import org.apache.pdfbox.tools.ExtensionFileFilter;
+import org.apache.pdfbox.tools.PDFDebugger;
+
+/**
+ * @author Khyrul Bashar
+ *
+ * A Customized class that helps to open and save file. It uses JFileChooser to operate.
+ */
+public class FileOpenSaveDialog
+{
+    PDFDebugger mainUI;
+
+    private static final JFileChooser fileChooser = new JFileChooser() 
+    {
+        @Override
+        public void approveSelection()
+        {
+            File selectedFile = getSelectedFile();
+            if (selectedFile.exists() && getDialogType() == JFileChooser.SAVE_DIALOG)
+            {
+                int result = JOptionPane.showConfirmDialog(this,
+                        "Do you want to overwrite?",
+                        "File already exists",
+                        JOptionPane.YES_NO_OPTION);
+                if (result == JOptionPane.YES_OPTION)
+                {
+                    super.approveSelection();
+                }
+                else
+                {
+                    cancelSelection();
+                }
+            }
+            super.approveSelection();
+        }
+    };
+
+    /**
+     * Constructor.
+     * @param parentUI the main UI (JFrame) on top of which File open/save dialog should open.
+     * @param fileFilter file Filter, null is allowed when no filter is applicable.
+     */
+    public FileOpenSaveDialog(PDFDebugger parentUI, ExtensionFileFilter fileFilter)
+    {
+        mainUI = parentUI;
+        fileChooser.setFileFilter(fileFilter);
+    }
+
+    /**
+     * saves a file while user is prompted to chose the destination.
+     * @param bytes byte array of the saving file.
+     * @return true if file is saved successfully or false if failed.
+     * @throws IOException if there is error in creation of file.
+     */
+    public boolean saveFile(byte[] bytes) throws IOException
+    {
+        int result = fileChooser.showSaveDialog(mainUI);
+        if (result == JFileChooser.APPROVE_OPTION)
+        {
+            File selectedFile = fileChooser.getSelectedFile();
+            FileOutputStream outputStream = new FileOutputStream(selectedFile);
+            outputStream.write(bytes);
+            outputStream.close();
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * open a file prompting user to select the file.
+     * @return the file opened.
+     * @throws IOException if there is error in opening the file.
+     */
+    public File openFile() throws IOException
+    {
+        int result = fileChooser.showOpenDialog(mainUI);
+        if (result == JFileChooser.APPROVE_OPTION)
+        {
+            return fileChooser.getSelectedFile();
+        }
+        return null;
+    }
+}

Propchange: pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/util/FileOpenSaveDialog.java
------------------------------------------------------------------------------
    svn:eol-style = native