Ciao ragazzi....utilizzando JfreeChart e JCommon mi sono disegnato un diagramma di Gantt prelevando dati da un DB. A questo punto il risultato dovrei salvarlo in PDF utilizzando quindi la libreria apposita iText, ma ottengo il seguente errore:

java.io.FileNotFoundException: C:\Users\Public\Desktop\prova.pdf (Accesso negato)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(FileOutputStream.j ava:179)
at java.io.FileOutputStream.<init>(FileOutputStream.j ava:131)
at tirocinioServlet.GanttDiagram.saveChartAsPDF(Gantt Diagram.java:197)
at tirocinioServlet.GanttDiagram.<init>(GanttDiagram. java:75)
at tirocinioServlet.GanttDiagram.main(GanttDiagram.ja va:228)

Il codice che ho fatto è il seguente:
codice:
import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.DefaultFontMapper;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfTemplate;
import com.lowagie.text.pdf.PdfWriter;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletException;
import javax.swing.JOptionPane;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.data.category.IntervalCategoryDataset;
import org.jfree.data.gantt.Task;
import org.jfree.data.gantt.TaskSeries;
import org.jfree.data.gantt.TaskSeriesCollection;
import org.jfree.data.time.SimpleTimePeriod;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;

/**
 * Classe JAVA per creare un diagramma GANTT partendo dai dati inseriti nel
 * database. Viene richiamata nella pagina Web di riepilogo se si vuole, e da la
 * possibilità di salvare il tutto in .pdf.
 * @author Daniele Bertelli
 * @version DB 1.1
 */
public class GanttDiagram extends ApplicationFrame {

    private static Database db;
    private static String NomePreventivo = "";

    /**
     * Costruttore che crea un nuovo Diagramma di Gantt
     * @param Titolo del diagramma (nome del preventivo)
     */
    public GanttDiagram(final String title) {

        super(title);
        String nomeAsseY = "";
        Object[] obj = {"Attività", "Manodopera"};
        IntervalCategoryDataset dataset = null;
        int answer = javax.swing.JOptionPane.showOptionDialog(getRootPane(),
                "Scegli quale dei due diagrammi di Gantt vuoi creare\n", "Domanda",
                JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, obj, obj[0]);
        if (answer == JOptionPane.YES_OPTION) {
            dataset = createDatasetAttivita();
            nomeAsseY = "Attivita";
        } else {
            dataset = createDatasetManodopera();
            nomeAsseY = "Manodopera";
        }
        final JFreeChart chart = createChart(dataset, nomeAsseY);
        // Aggiungo il Chart al pannello...
        final ChartPanel chartPanel = new ChartPanel(chart);
        chartPanel.setPreferredSize(new java.awt.Dimension(500, 270));
        setContentPane(chartPanel);
        File fileName = new File("C:/Users/Public/Desktop/" + NomePreventivo + ".pdf");
        try {
            saveChartAsPDF(fileName, chart, 400, 300, new DefaultFontMapper());
        } catch (IOException ex) {
            Logger.getLogger(GanttDiagram.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    /**
     * Metodo per la creazione del DataSet per il diagramma Gantt sulle attività 
     * con le relative interrogazioni al Database per reperire i dati.
     */
    private static IntervalCategoryDataset createDatasetAttivita() {
        Vector v = new Vector(), Vtemp = new Vector();
        String[] res = null;
        GregorianCalendar gc = null;
        db = new Database("nome", "utente", "password");
        try {
            db.connetti();
        } catch (ServletException ex) {
        }
        v = db.eseguiQuery("SELECT IDpreventivo, Nome, DataInizio FROM preventivo");
        res = (String[]) v.elementAt(v.size() - 1);
        int ID = Integer.parseInt(res[0]);
        NomePreventivo = res[1];
        String[] split = res[2].split("-");
        String Iday = split[2];
        String Imonth = split[1];
        String Iyear = split[0];
        v = db.eseguiQuery("SELECT * FROM attivitapreventivo WHERE IDpreventivo=" + ID + ";");
        int i = 0;
        final TaskSeries s1 = new TaskSeries("Preventivato");
        while (i < v.size()) {
            res = (String[]) v.elementAt(i);
            int IDatt = Integer.parseInt(res[0]);
            Vtemp = db.eseguiQuery("SELECT Nome FROM attivita WHERE IDattivita=" + IDatt + ";");
            String[] n = (String[]) Vtemp.elementAt(0);
            String nomeAttivita = n[0];
            /* Controllo se c'è uno shift Temporale nella data d'inizio */
            gc = new GregorianCalendar(Integer.parseInt(Iyear),
                    Integer.parseInt(Imonth) - 1, Integer.parseInt(Iday));
            if (res[3] != null) {
                gc.add(Calendar.DAY_OF_MONTH, Integer.parseInt(res[3]));
            }
            Date inizio = gc.getTime();
            gc.add(Calendar.HOUR_OF_DAY, Integer.parseInt(res[2]));
            Date fine = gc.getTime();
            s1.add(new Task(nomeAttivita, new SimpleTimePeriod(inizio, fine)));
            i++;
        }
        final TaskSeriesCollection collection = new TaskSeriesCollection();
        collection.add(s1);

        return collection;
    }

    /**
     * Metodo per la creazione del DataSet per il diagramma Gantt sulla
     * manodopera con le relative interrogazioni al Database per reperire i dati.
     */
    private static IntervalCategoryDataset createDatasetManodopera() {
        Vector v = new Vector(), Vtemp = new Vector();
        String[] res = null;
        GregorianCalendar gc = null;
        db = new Database("nome", "utente", "password");
        try {
            db.connetti();
        } catch (ServletException ex) {
        }
        v = db.eseguiQuery("SELECT IDpreventivo, Nome, DataInizio FROM preventivo");
        res = (String[]) v.elementAt(v.size() - 1);
        int ID = Integer.parseInt(res[0]);
        NomePreventivo = res[1];
        String[] split = res[2].split("-");
        String Iday = split[2];
        String Imonth = split[1];
        String Iyear = split[0];
        v = db.eseguiQuery("SELECT * FROM preventivoqualifica WHERE IDpreventivo=" + ID + ";");
        int i = 0;
        final TaskSeries s1 = new TaskSeries("Preventivato");
        while (i < v.size()) {
            res = (String[]) v.elementAt(i);
            int IDqual = Integer.parseInt(res[0]);
            Vtemp = db.eseguiQuery("SELECT Descrizione FROM qualifica WHERE IDqualifica=" + IDqual + ";");
            String[] n = (String[]) Vtemp.elementAt(0);
            String nomeAttivita = n[0];
            /* Controllo se c'è uno shift Temporale nella data d'inizio */
            gc = new GregorianCalendar(Integer.parseInt(Iyear),
                    Integer.parseInt(Imonth) - 1, Integer.parseInt(Iday));
            if (res[3] != null) {
                gc.add(Calendar.DAY_OF_MONTH, Integer.parseInt(res[3]));
            }
            Date inizio = gc.getTime();
            gc.add(Calendar.HOUR_OF_DAY, Integer.parseInt(res[2]));
            Date fine = gc.getTime();
            s1.add(new Task(nomeAttivita, new SimpleTimePeriod(inizio, fine)));
            i++;
        }
        final TaskSeriesCollection collection = new TaskSeriesCollection();
        collection.add(s1);

        return collection;
    }

    /**
     * Metodo per la creazione del diagramma
     * @param dataset il dataset per il diagramma.
     */
    private JFreeChart createChart(final IntervalCategoryDataset dataset, String titolo) {
        final JFreeChart chart = ChartFactory.createGanttChart(
                "Preventivo " + NomePreventivo, // chart title
                titolo, // domain axis label
                "Tempo", // range axis label
                dataset, // data
                true, // include legend
                true, // tooltips
                false // urls
                );
        return chart;
    }

    private void saveChartAsPDF(File fileName, JFreeChart chart, int width, int height, DefaultFontMapper mapper)
            throws IOException {
        OutputStream out = new BufferedOutputStream(new FileOutputStream(fileName));
        writeChartAsPDF(out, chart, width, height, mapper);
        out.close();
    }

    private void writeChartAsPDF(OutputStream out, JFreeChart chart, int width, int height, DefaultFontMapper mapper) {
        Rectangle pagesize = new Rectangle(width, height);
        Document document = new Document(pagesize, 50, 50, 50, 50);
        try {
            PdfWriter writer = PdfWriter.getInstance(document, out);
            document.addAuthor("West Systems");
            document.addSubject("Preventivo");
            document.open();
            PdfContentByte cb = writer.getDirectContent();
            PdfTemplate tp = cb.createTemplate(width, height);
            Graphics2D g2 = tp.createGraphics(width, height, mapper);
            Rectangle2D r2D = new Rectangle2D.Double(0, 0, width, height);
            chart.draw(g2, r2D, null);
            g2.dispose();
            cb.addTemplate(tp, 0, 0);
        } catch (DocumentException de) {
            System.err.println(de.getMessage());
        }
        document.close();
    }

    /**
     * Metodo "main" per l'esecuzione dell'applicazione.
     * @param args NON UTILIZZATO.
     */
    public static void main(final String[] args) {
        final GanttDiagram demo = new GanttDiagram("Preventivo");
        demo.pack();
        RefineryUtilities.centerFrameOnScreen(demo);
        demo.setVisible(true);
    }
}
Qualcuno sa darmi una mano nel rintracciare cosa sbaglio??? Grazie mille!!!