質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

1回答

1618閲覧

TextAreaを初期化したい。

TA-KEY

総合スコア21

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2018/01/30 02:02

編集2018/01/30 04:39

TextAreaにAと記入

setText("");で初期化。

同じ場所にBと記入。

という、流れにしたいのですが、初期化した後、なぜかABと記入されてしまいます。

用意されている文章を順番に出力したいだけなので、記載したコードだけで完結しています。

java

1public class Frame4 extends JFrame implements MouseListener { 2 int count = 0; 3 JTextArea mainArea; 4 Scanner input = new Scanner(System.in); 5 6 ByteArrayOutputStream bytes = new ByteArrayOutputStream() { 7 public synchronized void flush() throws IOException { 8 mainArea.setText(toString()); 9 } 10 }; 11 12 PrintStream out = new PrintStream(bytes, true); 13 14 Frame4(String title){ 15 this.setTitle(title); 16 this.setSize(624, 580); 17 this.setLocationRelativeTo(null); 18 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 19 this.addMouseListener(this); 20 21 JPanel pane1 = new JPanel(); 22 23 mainArea = new JTextArea(""); 24 mainArea.setPreferredSize(new Dimension(580, 150)); 25 mainArea.setEditable(false); 26 mainArea.setLineWrap(true); 27 mainArea.setBorder(new EtchedBorder(EtchedBorder.LOWERED)); 28 29 pane1.add(mainArea); 30 31 Container con = this.getContentPane(); 32 con.add(pane1); 33 } 34 35 @Override 36 public void mouseClicked(MouseEvent e) { 37 System.setErr(out); 38 System.setOut(out); 39 switch(count){ 40 case 0: 41 System.out.println("テスト1"); 42 break; 43 case 1: 44 System.out.println("テスト2"); 45 break; 46 case 2: 47 mainArea.setText(""); 48 break; 49 case 3: 50 System.out.println("テスト3"); 51 break; 52 } 53 count ++; 54 } 55}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KSwordOfHaste

2018/01/30 03:11 編集

コード上でmainAreaは編集不可になっており、setTextで""以外を設定する箇所はSystem.outのコンソールの出力によっているようですが、再現手順がよくわかりません。また一部コードを省略しておられますが、肝心な部分が抜けているということはないでしょうか?どうやったらABとなるのか再現手順を明確に記入してはいかがでしょうか?コンソールから実行しているか(そのコンソールはどのOSのどういうターミナルソフトか)またはIDEから実行しているならどのIDEのどのバージョンかも記入した方がよいかも知れません。
TA-KEY

2018/01/30 04:38

説明が足りなくて申し訳ないです。用意されている文章を順番に出力したいだけなので、記載したコードだけで完結しています。
guest

回答1

0

ベストアンサー

手順がはっきりとわからなかったので推測です。

ByteArrayOutputStreamに出力関数を通じて(または直接に) flush()が呼び出されたときにout(ByteArrayOutputStream)にそれまで出力された内容を

mainArea.setText(toString());

で出力するというからくりだと思います。

つまり「Aと記入。」の意味はコンソールから

A + ENTER

をタイプし、それをなんらかの方法でoutへ出力したということでしょう。

Aと表示された後にJFrame上でマウスを3回クリックすると一旦mainAreaがクリア(setText(""))されますが、その後にBをoutへ出力し、flushすると、「outへこれまで出力した全ての文字列」がByteArrayOutputStream#toString()の結果に含まれることになります。

それゆえ期待が「後から入力したBのみmainAreaへ表示」だったのに対し「実際にはAもBもmainAreaに表示された」・・・ということではないでしょうか?


System.inからの入力をどのようにして出力しているかや、そもそもこのアプリケーションがどういうものを狙ったものかにより対処法は変わるような気がします。場合によっては仕組みを変えた方がよいということがあるかも知れません。そのため「どうしたらよい」かはっきり意見をいいにくいです。

少なくとも期待しておられる振る舞いをさせるためにはByteArrayOutputStreamの機能がマッチしていないような気はします。


追記:

より適したやり方

(1) ByteArrayOutputStreamよりはCharArrayWriter

文字の入出力をする際には、バイナリーストリームを使うよりは文字ストリームを使う方が自然だと思います。ByteArrayOutputStreamに似たjava.io.CharArrayWriterというクラスがあります。こちらのクラスではbyteではなく文字を扱えます。

(2) CharArrayWriterとPipiedWriter

CharArrayWriterは出力した内容がどんどん内部バッファーにたまっていきます。このクラスは「随時出力した文字列を最後に一回だけ全部取り出す」という目的で使うのが普通だと思います。出力側で何かを随時出力しながらそれを入力側で「追記された部分のみ取り出す」方が柔軟な気がします。
質問者さんはJTextArea#setTextを用いておられるので「表示すべき全体のテキストを毎回求めて設定する」という方法論なわけですが、JTextArea#appendを用いると「現在のテキストの末尾へ指定した文字列を追記する」ということもできます。それと併用するならCharArrayWriterよりはPipiedWriter/PipiedReaderの組み合わせのようなものがよいと思います。

(3) java.io.xxxよりは・・・

本来的(?)にはjava.ioにあるストリームの内容をGUIのJTextAreaなどへ「随時反映する」という機能は別スレッドで行った方がよい気がします。GUIのスレッド(swingではEDTスレッドと呼びます)で呼び出し元スレッドがブロックしてしまうようなread/write系の機能を使うのは下手をするとGUIの機能を損ないかねません。例えば出力側がまだ文字列を書き込んでいないタイミングでストリームからreadしようとするとGUI全体がハングなんて事態が起こりかねません。

ご質問のコードで言えば、マウスイベントでoutへprintlnで出力してますが、そうせずに単にmainAreaへappendする方がより自然な方法だと思います。

投稿2018/01/30 03:32

編集2018/01/30 06:16
KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TA-KEY

2018/01/30 04:42

解答ありがとうございます。 ByteArrayOutputStream#toString()の結果を空にするにはどうしたらいいんでしょうか。 また、実はあまりよく分からず、調べながらByteArrayOutputStreamを使っています。もしよろしければ、より適したやり方を教えていただけないでしょうか。
KSwordOfHaste

2018/01/30 05:58

> ByteArrayOutputStream#toString()の結果を空にする とりあえずはByteArrayOutputStream#resetを呼び出せばよいと思います。 > より適したやり方 回答へ追記します。
TA-KEY

2018/01/30 07:48

ByteArrayOutputStream#resetで一旦解決はできました。 KSwordOfHaste様に教えてもらった他のやり方も試してみようと思います。勉強不足でした。本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問