10 May 2015

(Java) Swingのテキスト表示ダイアログ作成法

Swingでテキストを表示するダイアログを実装する方法メモ

JTextArea コンテナを使う (最も単純で簡単な方法)

JTextAreaは、単純にプレーンテキストを表示するコンテナ。一部分を着色したり、スタイルを変更したりする場合はJTextPaneを用いる。

20150510-swing-jtextarea.jpg

public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setTitle("テキストファイルの表示");
    frame.setSize(450, 350);
    // 親コンテナ(この中に、子コンテナとしてpanel2つを上下配置する)
    Container container = frame.getContentPane();
    container.setLayout(new BorderLayout());
    frame.setContentPane(container);
    // ダイアログ上部のテキスト表示エリアの定義
    JTextArea text = new JTextArea();
    text.setLineWrap(true);
    JScrollPane scroll = new JScrollPane();
    scroll.getViewport().setView(text);
    container.add(scroll, BorderLayout.CENTER);
    // ダイアログ下部のボタン エリアの定義
    JPanel panel_2 = new JPanel();
    panel_2.setLayout(new FlowLayout(FlowLayout.RIGHT, 10, 5));
    JButton buttonFileOpen = new JButton("ファイルを開く");
    panel_2.add(buttonFileOpen);
    JButton buttonClose = new JButton("終了");
    panel_2.add(buttonClose);
    container.add(panel_2, BorderLayout.PAGE_END);
    // 「終了」ボタンの処理
    buttonClose.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            frame.setVisible(false);
            frame.dispose();
        }
    });
    // 「ファイルを開く」ボタンの処理
    buttonFileOpen.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            JFileChooser dialog = new JFileChooser();
            dialog.setFileFilter(new FileNameExtensionFilter(
                    "HTMLファイル (*.html)", "html", "htm"));
            dialog.setFileFilter(new FileNameExtensionFilter(
                    "テキストファイル (*.txt)", "txt"));
            // dialog.setAcceptAllFileFilterUsed(false);    // 「全てのファイル」のフィルタを除去
            if (dialog.showOpenDialog(frame) == JFileChooser.APPROVE_OPTION) {
                ReadFromTextFile(text, dialog.getSelectedFile().getPath());
            }
        }
    });
    
    // 実行環境OSにあったUIを適用する
    try {
        // UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        // SwingUtilities.updateComponentTreeUI(panel);
        SwingUtilities.updateComponentTreeUI(frame);
    } catch (Exception e) {
    }
    // メイン ダイアログの表示
    frame.setVisible(true);
}
    
private static void ReadFromTextFile(JTextArea t, String filename) {
    try {
        File file = new File(filename);
        BufferedReader br = new BufferedReader(new FileReader(file));
        // ファイル末端まで、各行をstrに読み込んでからJTextAreaコンテナに追加していく
        String str = br.readLine();
        t.setText("");
        while (str != null) {
            t.append(str + "\n");
            str = br.readLine();
        }
        br.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

テキストエリア全てのテキスト色や、太字、斜体などの指定、フォントサイズを変更するには

 〜 略 〜
// ダイアログ上部のテキスト表示エリアの定義
JTextArea text = new JTextArea();
text.setLineWrap(true);
Font font = new Font(Font.SANS_SERIF, Font.BOLD|Font.ITALIC, 16);
text.setFont(font);
text.setForeground(Color.BLUE);
 
 〜 略 〜

JTextPaneコンテナを使う

20150510-swing-jtextpane.jpg

public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setTitle("テキストファイルの表示");
    frame.setSize(450, 350);
    // 親コンテナ(この中に、子コンテナとしてpanel2つを上下配置する)
    Container container = frame.getContentPane();
    container.setLayout(new BorderLayout());
    frame.setContentPane(container);
    // ダイアログ上部のテキスト表示エリアの定義
    JTextPane text = new JTextPane();
    JScrollPane scroll = new JScrollPane();
    scroll.getViewport().setView(text);
    container.add(scroll, BorderLayout.CENTER);
    // ダイアログ下部のボタン エリアの定義
    JPanel panel_2 = new JPanel();
    panel_2.setLayout(new FlowLayout(FlowLayout.RIGHT, 10, 5));
    JButton buttonFileOpen = new JButton("ファイルを開く");
    panel_2.add(buttonFileOpen);
    JButton buttonClose = new JButton("終了");
    panel_2.add(buttonClose);
    container.add(panel_2, BorderLayout.PAGE_END);
    // 「終了」ボタンの処理
    buttonClose.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            frame.setVisible(false);
            frame.dispose();
        }
    });
    // 「ファイルを開く」ボタンの処理
    buttonFileOpen.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            JFileChooser dialog = new JFileChooser();
            dialog.setFileFilter(new FileNameExtensionFilter(
                    "HTMLファイル (*.html)", "html", "htm"));
            dialog.setFileFilter(new FileNameExtensionFilter(
                    "テキストファイル (*.txt)", "txt"));
            // dialog.setAcceptAllFileFilterUsed(false);    // 「全てのファイル」のフィルタを除去
            if (dialog.showOpenDialog(frame) == JFileChooser.APPROVE_OPTION) {
                ReadFromTextFile(text, dialog.getSelectedFile()
                        .getPath());
            }
        }
    });
    
private static void ReadFromTextFile(JTextPane t, String filename) {
    StyleContext sc = new StyleContext();
    DefaultStyledDocument doc = new DefaultStyledDocument(sc);
    t.setDocument(doc);
    try {
        File file = new File(filename);
        BufferedReader br = new BufferedReader(new FileReader(file));
        // ファイル末端まで、各行をstrに読み込んでからdocコンテナに追加していく
        String str = br.readLine();
        doc.insertString(0, "", sc.getStyle(StyleContext.DEFAULT_STYLE));
        while (str != null) {
            doc.insertString(doc.getLength(), str + "\n",
                    sc.getStyle(StyleContext.DEFAULT_STYLE));
            str = br.readLine();
        }
        br.close();
    } catch (IOException | BadLocationException e) {
        e.printStackTrace();
    }
    // 特定の文字に色を付けてみる
    String strFind = "ダキア";
    SimpleAttributeSet attr = new SimpleAttributeSet();
    StyleConstants.setForeground(attr, new Color(0xff0000));
    StyleConstants.setBold(attr, true);
    StyleConstants.setItalic(attr, true);
    int startAt = t.getText().indexOf(strFind);
    while (startAt > 0) {
        doc.setCharacterAttributes(startAt, strFind.length(), attr, true);
        startAt = t.getText().indexOf(strFind, startAt + 1);
    }
}

たとえば、テキスト全てに着色する場合は、insertStringメソッドを使うときに次のようにすればよい

doc.insertString(doc.getLength(), str + "\n", attr);