- PR -

JTextAreaについて

1
投稿者投稿内容
およよ
会議室デビュー日: 2003/12/29
投稿数: 16
投稿日時: 2003-12-29 23:44
皆様宜しくお願い致します。
現在、Swingを使用して、単なるテキストエディタではなく、ターミナルのようなアプリケーションを作ろうと考えています。
その際にメッセージのやり取りを行う画面にJTextAreaを使用して、その中のみでメッセージのやり取りを行えるようにしようと考えているのですが、ある方にお聞きしたところ、表示するテキストエリアは編集不可能にし、KeyEventによって、入力した文字または他から受け取った文字をテキストエリアに表示するようにするやり方もあると聞きました。
そのようにJTextAreaをsetEditableによって編集不可にした場合、Caretを表示することは出来るのでしょうか?
またターミナルのようなアプリケーションをSwingで作る場合、他に良い方法などあるのでしょうか?
宜しくお願い致します。
さくらば
大ベテラン
会議室デビュー日: 2002/11/12
投稿数: 145
投稿日時: 2003-12-30 04:10
こんにちは、さくらばです。

引用:

およよさんの書き込み (2003-12-29 23:44) より:
JTextAreaをsetEditableによって編集不可にした場合、Caretを表示することは出来るのでしょうか?



setEditable(false) されるとキャレットは setVisible(false) されるだけなので、
setVisible(true) にすれば表示されます。

ただし、内部的に JTextArea に文字をアペンドなどしてもキャレット位置は
更新されないので、自力で更新する必要があります。

とりあえず、サンプルつけてみたので、試してみてください。

コード:
import java.lang.reflect.InvocationTargetException;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

public class CaretTest {
    private JTextArea area;

    public CaretTest() {
        JFrame frame = new JFrame("Test");
        frame.setBounds(100, 100, 400, 400);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        area = new JTextArea();
        area.setEditable(false);

        // キャレットを表示する
        area.getCaret().setVisible(true);

        frame.setContentPane(new JScrollPane(area));
        frame.setVisible(true);

        try {
            Thread.sleep(1000L);
        } catch (Exception e) {}

        // 試しに文字を表示してみる
        for (int i = 0; i < 50; i++) {
            for (int j = 0; j < 20; j++) {
                area.append(j + " ");
                updateCaret();

                try {
                    Thread.sleep(50L);
                } catch (Exception e) {}
            }
            area.append("\n");
            updateCaret();
        }
    }

    // キャレット位置の更新
    private void updateCaret() {
        try {
            // キャレット位置が更新されるまで待つ
            SwingUtilities.invokeAndWait(new Runnable() {
                public void run() {
                    area.setCaretPosition(area.getText().length());
                }
            });
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        } catch (InvocationTargetException ex) {
            ex.printStackTrace();
        }
    }

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


およよ
会議室デビュー日: 2003/12/29
投稿数: 16
投稿日時: 2003-12-30 12:11
さくらば様
大変ありがとうございます。
頂いたサンプルを参考にして、さっそくチャレンジしてみます。
またご報告致します。

およよ
会議室デビュー日: 2003/12/29
投稿数: 16
投稿日時: 2003-12-31 02:31
さくらば様
サンプルコード、大変参考になりました。
意図していたものが出来ました。
ありがとうございました。
およよ
会議室デビュー日: 2003/12/29
投稿数: 16
投稿日時: 2003-12-31 03:08
皆様宜しくお願い致します。
このスレッドで頂いたお返事でJTextAreaについて一つ解決したのですが、
setEditable(false)としたJTextArea上で、1文字削除の場合にBACK_SPACEキーを叩くとビープ音が鳴ります。この音を鳴らさないように(通常のテキストエディタでの1文字削除)出来ないものかと悩んでおります。
以下に現時点でのコードを記しておきます。
宜しくお願い致します。

コード:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class TerminalTest {
JFrame frame;
Container cnt;
JTextArea area;

public TerminalTest(String title) {
frame = new JFrame("Terminal");
frame.setBounds(100, 100, 600, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cnt = frame.getContentPane();
cnt.setLayout(new BorderLayout());

area = new JTextArea();
area.setEditable(false);
area.setLineWrap(true);
area.setBackground(Color.BLACK);
area.setForeground(Color.WHITE);
area.setCaretColor(Color.WHITE);
area.addFocusListener(new FocusAdapter() {
public void focusGained(FocusEvent e) {
area.getCaret().setVisible(true);
}
});

//キーイベント設定
area.addKeyListener(new KeyAdapter() {
StringBuffer fixText = new StringBuffer();
StringBuffer addText = new StringBuffer();
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
fixText.append(addText + "\n");
addText.delete(0, addText.length());
area.setText(fixText.toString());
} else if (e.getKeyCode() == KeyEvent.VK_BACK_SPACE) {
if (addText.length() == 0) {
System.out.println("VK_BACK_SPACE");
return;
}
addText.delete(addText.length() - 1, addText.length());
area.setText(fixText.toString() + addText);
} else {
addText.append(e.getKeyChar());
area.setText(fixText.toString() + addText);
}
System.out.println(e.getKeyCode());
}
});

JScrollPane myScroll = new JScrollPane(area);

cnt.add(myScroll, BorderLayout.CENTER);

frame.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_TAB) {
area.requestFocus();
area.getCaret().setVisible(true);
}
}
});

frame.setVisible(true);
}

public static void main(String args[]) {
new TerminalTest("Terminal");
}
}



[ メッセージ編集済み 編集者: およよ 編集日時 2003-12-31 03:10 ]

[ メッセージ編集済み 編集者: およよ 編集日時 2003-12-31 03:11 ]
さくらば
大ベテラン
会議室デビュー日: 2002/11/12
投稿数: 145
投稿日時: 2003-12-31 05:26
こんにちは、さくらばです。

お互い、すごい時間に書き込みしてますね

引用:

およよさんの書き込み (2003-12-31 03:08) より:
setEditable(false)としたJTextArea上で、1文字削除の場合にBACK_SPACEキーを叩くとビープ音が鳴ります。この音を鳴らさないように(通常のテキストエディタでの1文字削除)出来ないものかと悩んでおります。



キーが押されたときになにをするかということは keymap に書かれているの
ですが、これを編集することで音を出さないようにすることができます。

およよさんのコードの中で適当なところに次の 3 行を入れてみてください。

コード:
    Keymap keymap = area.getKeymap();
    keymap.addActionForKeyStroke(KeyStroke.getKeyStroke("typed \010"),
                            new DefaultEditorKit.DefaultKeyTypedAction());



Kemap クラスと DefaultEditorKit クラスは共に javax.swing.text パッケージ
なので、import 文も加えておいてください。

# たぶん、この後 ctrl-C や ctrl-X でコピペをしてみたいくなると思いますが、
# 同じような方法で実現できます。
およよ
会議室デビュー日: 2003/12/29
投稿数: 16
投稿日時: 2003-12-31 17:04
さくらば様
またまたありがとうございます。
本当に明確なお答えを頂いて、本当に助かります。
ちょっと遅くなってしまいましたが、これからまた頂いたお返事を
参考に取り組んでみます。
では、さくらば様も良いお年をお迎えください!
1

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