- PR -

印刷プレビュー

1
投稿者投稿内容
sinh
ベテラン
会議室デビュー日: 2003/01/22
投稿数: 87
投稿日時: 2003-06-11 12:36
今、Javaでエディタを作成しています。その中で印刷プレビュー機能を作ろうとしていて、JDialogにJPanelを貼り付けてそれにテキストを書き込んでいるのですが、改行が入るとうまく動きません。
なにか、よい方法はありませんか?
さくらば
大ベテラン
会議室デビュー日: 2002/11/12
投稿数: 145
投稿日時: 2003-06-20 23:16
こんにちは、さくらばです。

引用:

sinさんの書き込み (2003-06-11 12:36) より:
今、Javaでエディタを作成しています。その中で印刷プレビュー機能を作ろうとしていて、JDialogにJPanelを貼り付けてそれにテキストを書き込んでいるのですが、改行が入るとうまく動きません。
なにか、よい方法はありませんか?



これだけだとよく分からないのですが、JPanel を派生させたクラスで
paint or paintComponent メソッドで直接描画を行うのか、JPanel に
テキスト処理を行えるコンポーネントをはって、それに描画させるのか
でずいぶん違うと思います。

後者の方が簡単です。JTextArea や JEditorPane を使えばできます。
前者の方はいろいろと面倒ですが、自分で細かい部分まで制御できます。
両方ともサンプルをのせておきます。後者の方は単に StringTokenizer
で行を分割しているので、\n がいくつあっても無視されてしまいますが...

sin さんが望んでいるのはどちらなのでしょうか?

コンポーネントを使用するサンプル
コード:
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;

public class DialogSample {

    private static String text = 
        "東海の小島の磯の白砂に\n" +
        "われ泣きぬれて\n" +
        "蟹とたはむる\n" +
        "Once upon a midnight dreary, while I pondered, weak and weary,\n" +
        "Over many a quaint and curious volume of forgotten lore,\n" +
        "While I nodded, nearly napping, suddenly there came a tapping,\n" +
        "As of some one gently rapping, rapping at my chamber door.\n" +
        "\"Tis some visiter,\" I muttered, \"tapping at my chamber door --" +
        "Only this, and nothing more.";

    public DialogSample () {
        JFrame frame = new JFrame("Dialog Sample");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setBounds(100, 100, 100, 100);
        frame.setVisible(true);

        JDialog dialog = new JDialog(frame, "Dialog Sample");

        JTextArea area = new JTextArea(text);
        area.setEditable(false);

        JPanel panel = new JPanel();
        panel.add(area);
        dialog.getContentPane().add(panel);
        dialog.pack();
        dialog.show();
    }

    public static void main(String[] args) throws Exception {
        new DialogSample();
    }
}



自前で文字描画を行うサンプル
コード:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.font.FontRenderContext;
import java.awt.font.LineBreakMeasurer;
import java.awt.font.TextAttribute;
import java.awt.font.TextLayout;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
import java.util.Hashtable;
import java.util.StringTokenizer;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class LineBreakSample extends JPanel {
    
    private Hashtable map = new Hashtable();
    private static String text = 
        "東海の小島の磯の白砂に\n" +
        "われ泣きぬれて\n" +
        "蟹とたはむる\n" +
        "Once upon a midnight dreary, while I pondered, weak and weary,\n" +
        "Over many a quaint and curious volume of forgotten lore,\n" +
        "While I nodded, nearly napping, suddenly there came a tapping,\n" +
        "As of some one gently rapping, rapping at my chamber door.\n" +
        "\"Tis some visiter,\" I muttered, \"tapping at my chamber door --" +
        "Only this, and nothing more.";
                                
    public LineBreakSample() {
        map.put(TextAttribute.SIZE, new Float(18.0));
    }  

    public void paintComponent(Graphics g) {
        Graphics2D graphics2D = (Graphics2D) g;
            
        Dimension size = getSize();
        float formatWidth = (float) size.width;
        float drawPosY = 0;
        
        StringTokenizer tok = new StringTokenizer(text, "\n");
        while (tok.hasMoreTokens()) {
            AttributedString attrStr = new AttributedString(tok.nextToken(), map);
            AttributedCharacterIterator line = attrStr.getIterator();
            int start = line.getBeginIndex();
            int end = line.getEndIndex();
            
            LineBreakMeasurer lineMeasurer = new LineBreakMeasurer(line,
                                                   new FontRenderContext(null, false, false));
            lineMeasurer.setPosition(start);

            while (lineMeasurer.getPosition() < end) {
                
                TextLayout layout = lineMeasurer.nextLayout(formatWidth);

                drawPosY += layout.getAscent();

                float drawPosX;
                if (layout.isLeftToRight()) {
                    drawPosX = 0;
                } else {
                    drawPosX = formatWidth - layout.getAdvance();
                }
                
                layout.draw(graphics2D, drawPosX, drawPosY);

                drawPosY += layout.getDescent() + layout.getLeading();
            }
        }
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("HitTestSample");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        LineBreakSample sample = new LineBreakSample();
        frame.getContentPane().add(sample);
        frame.setBounds(100, 100, 400, 500);
        frame.setVisible(true);
    }
}


sinh
ベテラン
会議室デビュー日: 2003/01/22
投稿数: 87
投稿日時: 2003-06-24 12:56
僕はCoreJavaという本に載っていたプログラムを参考にしてJPanelにpaintComponentを用いてプレビューを作成していました。
でも、さくらばさんの方法のJTextAreaを使う方法が簡単そうなので、そちらに変えようかと思います。ただ、JTextAreaを用いてプレビューを作成した場合、プレビュー画面と実際の印策されたものは、たとえば上のほうに日付やソース名を入れたい場合などは同じようにできるのでしょうか?
さくらば
大ベテラン
会議室デビュー日: 2002/11/12
投稿数: 145
投稿日時: 2003-06-24 22:42
こんにちは、さくらばです。

引用:

sinさんの書き込み (2003-06-24 12:56) より:
僕はCoreJavaという本に載っていたプログラムを参考にしてJPanelにpaintComponentを用いてプレビューを作成していました。
でも、さくらばさんの方法のJTextAreaを使う方法が簡単そうなので、そちらに変えようかと思います。ただ、JTextAreaを用いてプレビューを作成した場合、プレビュー画面と実際の印策されたものは、たとえば上のほうに日付やソース名を入れたい場合などは同じようにできるのでしょうか?



JTextArea の print メソッドは paint メソッドをコールしているので、
画面イメージとほぼ同じものになります。ただ、紙の大きさなどは無視するので、
一行の長さが印刷可能領域より長ければ欠けてしまいます。

ヘッダやフッタは JTextArea で書くのでしょうか。この場合プレビューにも
ヘッダやフッタが描画されますが、印刷とは同じになります。

もしくは JTextArea ではなく、別個にヘッダやフッタを独自に描画するので
しょうか。別個の場合は、JTextArea が描画を行うための原点をずらしてお
かないと重なってしまいます。

参考になるかもしれないので、前の DialogSample を最低限の印刷ができる
ように改造してみました。ヘッダとフッタはJTextArea とは別に描画してい
ます。

印刷するために Printable インタフェースを実装させ、print メソッドを
実装しています。その中で、ヘッダ、フッタを描画してから、JTextArea の
print メソッドをコールしています。

コード:
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.print.PageFormat;
import java.awt.print.PrinterJob;
import java.awt.print.Printable;
import java.util.Date;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class DialogSample implements Printable {

    private JTextArea area;

    private static String text = 
        "東海の小島の磯の白砂に\n" +
        "われ泣きぬれて\n" +
        "蟹とたはむる\n" +
        "Once upon a midnight dreary, while I pondered, weak and weary,\n" +
        "Over many a quaint and curious volume of forgotten lore,\n" +
        "While I nodded, nearly napping, suddenly there came a tapping,\n" +
        "As of some one gently rapping, rapping at my chamber door.\n" +
        "\"Tis some visiter,\" I muttered, \"tapping at my chamber door\n" +
        "-- Only this, and nothing more.";

    public DialogSample () {
        JFrame frame = new JFrame("Dialog Sample");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setBounds(100, 100, 100, 100);
        frame.setVisible(true);

        area = new JTextArea(text);
        area.setEditable(false);

        JPanel panel = new JPanel();
        panel.add(area);

        int result = JOptionPane.showOptionDialog(frame, panel, "Dialog Sample", 
                                                  JOptionPane.OK_CANCEL_OPTION,
                                                  JOptionPane.PLAIN_MESSAGE,
                                                  null, new String[]{"Print", "Cancel"},
                                                  "Print");
        if (result == 0) {
            printDoc();
        }
    }

    private void printDoc() {
        PrinterJob printerJob = PrinterJob.getPrinterJob();
        printerJob.setPrintable(this);
        boolean doPrint = printerJob.printDialog();
        if (doPrint) {
            try {
                printerJob.print();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }

    public int print(Graphics g, PageFormat format, int pageIndex) {
        if (pageIndex == 0) {
            Graphics2D g2D = (Graphics2D)g;
            g2D.translate(format.getImageableX(), format.getImageableY());
            g2D.drawString("Header: " + new Date(), 50, 20);
            g2D.drawString("Footer: 1/1", 50, (int)format.getImageableHeight());

            g2D.translate(0, 40);
            area.print(g2D);
            return Printable.PAGE_EXISTS;
        } else {
            return Printable.NO_SUCH_PAGE;
        }
    }

    public static void main(String[] args) throws Exception {
        new DialogSample();
    }
}

1

スキルアップ/キャリアアップ(JOB@IT)