-1

I am able to load/save JTextArea unicode (devanagari) contents to file fine. I wanted to print the contents to pdf file so I am using iTextPDF api. My snippet is as below which prints empty file instead of with contents.

package i18n;

import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;
import java.util.ResourceBundle;

import javax.swing.Box;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

import com.itextpdf.awt.PdfGraphics2D;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfWriter;



public class MyNumbers extends JFrame {
    private ResourceBundle rb;
    private Font devanagariFont;

    public MyNumbers (String language, String fontFile) {
        loadResourceBundle(language);
        loadFont(fontFile);
        display();
    }

    TextArea txtArea;

    private void display() {
        String unicode = null;

        JPanel labels = new JPanel(new GridLayout(0,2));
        JLabel uni = null;
        for(int i=0; i<=10; i++) {
            unicode = rb.getString("" +i);
            labels.add(new JLabel("" + i));
            labels.add(uni = new JLabel(unicode));
            //uni.setFont(devanagariFont);
        }
        labels.add(new JLabel("Time"));
        labels.add(new ClockLabel());
        getContentPane().setLayout(new FlowLayout());
        Box b = Box.createVerticalBox();
        b.add(labels);
        b.add(txtArea = new TextArea(10, 40));
        getContentPane().add(b);
        addWindowListener(new WindowAdapter() {

            @Override
            public void windowOpened(WindowEvent e) {
                // TODO Auto-generated method stub
                try {
                    getInputContext().selectInputMethod(new Locale("hi", "IN"));
                    read();
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
            }

            @Override
            public void windowClosing(WindowEvent e) {
                // TODO Auto-generated method stub
                try {
                    System.out.println(getInputContext().getLocale());
                    save();
                    print();
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                System.exit(0);

            }


        });
        //setDefaultCloseOperation(EXIT_ON_CLOSE);
        pack();
        setVisible(true);



    }


    String fileName = "MyNumbers.txt";
    private void save() throws IOException {
        File f = new File(fileName);
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f), "UTF-16"));
        String txt = txtArea.getText();
        writer.write(txt);
        writer.flush();
        writer.close();
    }

    private void read() throws IOException {
        File f = new File(fileName);
        if(f.exists() == false) return;
        BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(f), "UTF-16"));
        String line = null;
        while((line = reader.readLine()) != null) {
            txtArea.append(line + "\n");
        }
        reader.close();
    }

    private void loadFont(String fontFile) {
        try {
            InputStream input = getClass().getResourceAsStream(fontFile);
            Font b = Font.createFont(Font.TRUETYPE_FONT, input);
            devanagariFont = b.deriveFont(Font.PLAIN, 11);

        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    private void loadResourceBundle(String language) {
        String base = getClass().getName() + "rb";
        rb = ResourceBundle.getBundle(base, new Locale(language));

    }

    static class ClockLabel extends JLabel implements ActionListener {


        private ClockLabel() {
            new Timer(1000, this).start();
        }



        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");

        public void actionPerformed(ActionEvent e) {
            Calendar cal = Calendar.getInstance();
            setText(sdf.format(cal.getTime()));

        }
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new MyNumbers("hi", "Devnew.ttf");      
            }
        });

    }

    String pdfFileName = "MyNumbers.pdf";
    private void print() {
        System.out.println("Printing PDF file ..");
        try { 
            Document document = new Document(PageSize.A4);  
            PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(pdfFileName));
            document.open();
            PdfContentByte cb = writer.getDirectContent( );
            PdfGraphics2D g2d = new PdfGraphics2D(cb, PageSize.A4.getWidth(), PageSize.A4.getHeight());
            System.out.println(txtArea.getSize());
            txtArea.print(g2d);
            g2d.dispose();
            document.close ();
        }
        catch(DocumentException de) {
            System.err.println(de.getMessage());
        }
        catch(IOException ioe) {
            System.err.println(ioe.getMessage());
        }
    }

}

Output to console:

hi_IN
Printing PDF file ..
java.awt.Dimension[width=300,height=170]

Please let me know know the fix. I am not setting any font for graphics assuming that the swing JTextArea should be able to handle it. The unicode support is added with indicim.jar Input Method framework. As per output above the Dimension shows that text area is not of zero size.

In order to test above you need 2 files:

indicim.jar and place it in jre/lib/ext

MyNumbers.txt - unicode content file in devanagari as below which as such you can type it yourself in text area and program saves/loads on shutdown/startup. You save it in the project dir of eclipse.

अम२ जवान
अम२ जवान
अम२ जवान
अम२ जवान
अम२ जवान
अम२ जवान
अम२ जवान
अम२ जवान
अम२ जवान
ऊँ 

A pdf file will get created in eclipse project dir but for now its empty.

Miten
  • 356
  • 7
  • 23
  • Try to post an [SSCCE](http://sscce.org). Is your textarea properly sized (a size of 0x0 would result in an empty page)? How is it initiated? Impossible to help you more without more input from you. – Guillaume Polet Sep 25 '12 at 12:47
  • @GuillaumePolet I left it snippet based to avoid having to get into details of gui construction but to make it easy for any one to test and fix I am now providing all details. – Miten Sep 26 '12 at 05:03

1 Answers1

4

The problem is that you don't call:

writer.close()

on your PdfWriter. Adding that line at the end of your print() method should do the trick.

EDIT:

Here is an SSCCE (well you still need to add iText lib, version 4.2.0, to your dependencies) that works for me:

import java.awt.Desktop;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;

import javax.swing.Box;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.PageSize;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfWriter;

public class MyNumbers extends JFrame {
    private Font devanagariFont;

    public MyNumbers(String language, String fontFile) {
        loadResourceBundle(language);
        loadFont(fontFile);
        display();
    }

    TextArea txtArea;

    private void display() {
        String unicode = null;

        JPanel labels = new JPanel(new GridLayout(0, 2));
        JLabel uni = null;
        for (int i = 0; i <= 10; i++) {
            unicode = String.valueOf(i);
            labels.add(new JLabel("" + i));
            labels.add(uni = new JLabel(unicode));
            // uni.setFont(devanagariFont);
        }
        labels.add(new JLabel("Time"));
        labels.add(new ClockLabel());
        getContentPane().setLayout(new FlowLayout());
        Box b = Box.createVerticalBox();
        b.add(labels);
        b.add(txtArea = new TextArea(10, 40));
        getContentPane().add(b);
        addWindowListener(new WindowAdapter() {

            @Override
            public void windowOpened(WindowEvent e) {
                // TODO Auto-generated method stub
                try {
                    getInputContext().selectInputMethod(new Locale("hi", "IN"));
                    read();
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
            }

            @Override
            public void windowClosing(WindowEvent e) {
                // TODO Auto-generated method stub
                try {
                    System.out.println(getInputContext().getLocale());
                    save();
                    print();
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                System.exit(0);

            }

        });
        // setDefaultCloseOperation(EXIT_ON_CLOSE);
        pack();
        setVisible(true);

    }

    String fileName = "MyNumbers.txt";

    private void save() throws IOException {
        File f = new File(fileName);
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f), "UTF-16"));
        String txt = txtArea.getText();
        writer.write(txt);
        writer.flush();
        writer.close();
    }

    private void read() throws IOException {
        File f = new File(fileName);
        if (f.exists() == false) {
            return;
        }
        BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(f), "UTF-16"));
        String line = null;
        while ((line = reader.readLine()) != null) {
            txtArea.append(line + "\n");
        }
        reader.close();
    }

    private void loadFont(String fontFile) {
        try {
            InputStream input = getClass().getResourceAsStream(fontFile);
            Font b = Font.createFont(Font.TRUETYPE_FONT, input);
            devanagariFont = b.deriveFont(Font.PLAIN, 11);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void loadResourceBundle(String language) {
        String base = getClass().getName() + "rb";

    }

    static class ClockLabel extends JLabel implements ActionListener {

        private ClockLabel() {
            new Timer(1000, this).start();
        }

        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");

        @Override
        public void actionPerformed(ActionEvent e) {
            Calendar cal = Calendar.getInstance();
            setText(sdf.format(cal.getTime()));

        }
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new MyNumbers("hi", "Devnew.ttf");
            }
        });

    }

    String pdfFileName = "MyNumbers.pdf";

    private void print() {
        System.out.println("Printing PDF file ..");
        try {
            File pdf = new File(pdfFileName);
            Document document = new Document(PageSize.A4);
            PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(pdf));
            document.open();
            PdfContentByte cb = writer.getDirectContent();
            Graphics2D g2d = cb.createGraphics(PageSize.A4.getWidth(), PageSize.A4.getHeight());
            System.out.println(txtArea.getSize());
            txtArea.printAll(g2d);
            g2d.dispose();
            document.close();
            writer.flush();
            writer.close();
            Desktop.getDesktop().open(pdf);
        } catch (DocumentException de) {
            System.err.println(de.getMessage());
        } catch (IOException ioe) {
            System.err.println(ioe.getMessage());
        }
    }

}
Guillaume Polet
  • 47,259
  • 4
  • 83
  • 117
  • 1
    @Miten I posted the code I used to make this work. I used iText 4.2.0. Next time you post some code, try to trim everything that is not necessary to reproduce the issue and try to make self-contained, ie, independent of external files etc... – Guillaume Polet Sep 26 '12 at 13:14
  • @Guillaume Polet `Xxx.close()` in the finally block please – mKorbel Sep 26 '12 at 13:37
  • @mKorbel if that was the only thing to fix in that code... ;-) But you are right indeed, this should be embedded in a finally block. – Guillaume Polet Sep 26 '12 at 13:40
  • @GuillaumePolet Thanks for solution. I changed txtArea.print to txtArea.printAll and it worked. I though do not see complete contents of the txtArea. – Miten Sep 27 '12 at 04:57
  • @GuillaumePolet if the txtArea has text with paragraphs and white space how can I get it to show up in pdf document. I mean how to get good pagination done on the pdf. Currently all that gets printed is visible text that too with component. what I like to get it just styled text. I tried LineBreakMeasurer and TextLayout but they ignore the embedded new lines in text while printing to graphics. – Miten Sep 27 '12 at 12:46
  • @Miten Post an new question on SO instead of extending this one in comments. Cheers ;-) – Guillaume Polet Sep 27 '12 at 13:00