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

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

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

JFrameはJFC/Swingフレームワークのコンポーネントであり、トップレベルのコンテナです。

Java

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

Q&A

解決済

2回答

2014閲覧

JavaのTextareaの文章を自動更新する。

man_

総合スコア45

JFrame

JFrameはJFC/Swingフレームワークのコンポーネントであり、トップレベルのコンテナです。

Java

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

0グッド

0クリップ

投稿2020/04/11 13:24

編集2020/04/12 06:12

#実現したいこと
JavaでTextAreaに表示したテキストを文字列が追加されるたびに自動で更新したい。

#現在の課題
以下にTextAreaにテキストファイルの文章を表示する部分のコードを示します。
JFrameのTextAreaに無限ループを使用して文字列が追加されるたびに文字列を追記で表示したいのですが、現段階の課題として、無限ループを使用するとTextAreaに文字が表示されません。

有識者の方々ご協力お願いします

Java

1 package logViewer; 2 3import java.awt.BorderLayout; 4import java.awt.Dimension; 5import java.awt.event.ActionEvent; 6import java.awt.event.ActionListener; 7import java.io.BufferedReader; 8import java.io.File; 9import java.io.FileReader; 10import java.io.IOException; 11 12import javax.swing.JButton; 13import javax.swing.JFileChooser; 14import javax.swing.JOptionPane; 15import javax.swing.JPanel; 16import javax.swing.JScrollPane; 17import javax.swing.JTextArea; 18import javax.swing.JTextField; 19import javax.swing.border.TitledBorder; 20 21 22public class LogPanel2 extends JPanel implements ActionListener,Runnable{ 23 24 private JTextArea ta = new JTextArea(); //editer 25 private JTextField tf = null; //title 26 private JButton btn = null; //ボタン 27 28 private static int selected; 29 30 private static File selectedFile; 31 32 33 public LogPanel2() { //logAdd classでcheckBeforeReadfileを使用 34 35 } 36 37 public LogPanel2(String title) { 38 super(); 39 this.setLayout(new BorderLayout()); 40 41 tf=new JTextField(); 42 btn=new JButton("Open"); 43 44 //btn.addActionListener(this); 45 46 JPanel pnl=new JPanel(); 47 pnl.setLayout(new BorderLayout()); 48 pnl.add(tf,BorderLayout.CENTER); 49 pnl.add(btn,BorderLayout.EAST); 50 51 //ta = new JTextArea(); 52 JScrollPane sp = new JScrollPane(ta); 53 sp.setAutoscrolls(true); 54 55 this.add(pnl, BorderLayout.NORTH); 56 this.add(sp, BorderLayout.CENTER); 57 58 this.setBorder(new TitledBorder(title)); 59 this.setPreferredSize(new Dimension(400,200)); 60 61 btn.addActionListener(this); 62 63 } 64 65 66 /* ファイルを開く 67 */ 68 69 public void actionPerformed(ActionEvent e) { 70 JFileChooser filechooser = new JFileChooser(); 71 72 selected = filechooser.showOpenDialog(this); 73 74 if (JFileChooser.APPROVE_OPTION == selected) { 75 76 77 selectedFile = filechooser.getSelectedFile(); 78 79 tf.setText(""); 80 81 String strFileName = selectedFile.getName(); 82 tf.setText(strFileName); 83 84 Thread thread = new Thread(new LogPanel2()); 85 thread.start(); 86 } 87 88 89 } 90 91 92 public static boolean checkBeforeReadfile(File file) { 93 if(file.exists()) { 94 if(file.isFile() && file.canRead()) { 95 return true; 96 } 97 } 98 99 return false; 100 101 } 102 103 public void run() { 104 105 106 try { 107 if(checkBeforeReadfile(selectedFile)) { 108 109 String str; 110 111 BufferedReader br = new BufferedReader(new FileReader(selectedFile)); 112 113 //StringBuilder sb = new StringBuilder(); 114 115 ta.setText("AA"); 116 117 while((str = br.readLine()) != null) { 118 119 ta.append(str); 120 ta.append("\n"); 121 122 123 System.out.println(str); 124 125 } 126 System.out.println("null"); 127 128 //ta.setText(new String(sb)); 129 130 br.close(); 131 132 }else { 133 System.out.println("null"); 134 } 135 136 137 } catch(IOException err) { 138 139 JOptionPane.showMessageDialog(this,"IOException: ファイルを開くのに失敗しました。"); 140 } 141 142 143 } 144 145 146} 147

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

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

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

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

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

TN8001

2020/04/12 05:00

> 文字列が追加されるたびに自動で更新したい。 「文字列が追加される」っていうのは「対象のファイルが更新された」って意味ですか? だとするとファイル更新を監視するのが筋でしょうが、あまりにも今のコードとかけ離れます。 タイマーで何秒かおきに読み直すとかでしょうか。
man_

2020/04/12 05:46

TN8001さん回答ありがとうございます。 対象のファイルが更新されたという意味であっています。 現段階では、TextAreaに定期的に文字列を表示する部分を書いていました。 そこの部分が実装できていない状態です。 マルチスレッドを実装して、run()のメソッドでTextAreaに文字列を表示したいのですが、何も表示されない状態です。
guest

回答2

0

別スレッドからUIを触るとエラーになりますので(回避法もありますが)、タイマーでやった例です。

細かいテストはしていないです(読み書きがバッティングすると、表示が消えてしまうかもしれません)

Java

1import java.awt.BorderLayout; 2import java.awt.event.ActionEvent; 3import java.awt.event.ActionListener; 4import java.io.File; 5import java.io.IOException; 6import java.nio.file.Files; 7import java.util.stream.Collectors; 8import java.util.stream.Stream; 9import javax.swing.JButton; 10import javax.swing.JFileChooser; 11import javax.swing.JFrame; 12import javax.swing.JTextArea; 13import javax.swing.JTextField; 14import javax.swing.Timer; 15import javax.swing.filechooser.FileNameExtensionFilter; 16 17class Main extends JFrame implements ActionListener { 18 private JTextField textField; 19 private JTextArea textArea; 20 private File selectedFile; 21 private Timer timer; 22 23 public static void main(String[] args) { 24 Main frame = new Main(); 25 frame.setVisible(true); 26 } 27 28 Main() { 29 setSize(600, 400); 30 setLocationRelativeTo(null); 31 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 32 33 textField = new JTextField(); 34 add(textField, BorderLayout.NORTH); 35 36 textArea = new JTextArea(); 37 add(textArea, BorderLayout.CENTER); 38 39 JButton button = new JButton("ファイル選択..."); 40 button.addActionListener(this); 41 add(button, BorderLayout.SOUTH); 42 43 timer = new Timer(1000, e -> showFile()); 44 } 45 46 @Override public void actionPerformed(ActionEvent e) { 47 textField.setText(""); 48 textArea.setText(""); 49 timer.stop(); 50 51 JFileChooser fileChooser = new JFileChooser(); 52 fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("テキストファイル", "txt")); 53 fileChooser.setAcceptAllFileFilterUsed(false); 54 55 if (fileChooser.showOpenDialog(this) != JFileChooser.APPROVE_OPTION) return; 56 57 selectedFile = fileChooser.getSelectedFile(); 58 if (!checkBeforeReadfile(selectedFile)) return; 59 60 textField.setText(selectedFile.getName()); 61 showFile(); 62 timer.start(); 63 } 64 65 private void showFile() { 66 try { 67 try (Stream<String> lines = Files.lines(selectedFile.toPath())) { 68 textArea.setText(lines.collect(Collectors.joining("\n"))); 69 } 70 } catch (IOException e) { 71 textField.setText(""); 72 textArea.setText(""); 73 timer.stop(); 74// e.printStackTrace(); 75 } 76 } 77 78 private boolean checkBeforeReadfile(File file) { 79 return file.exists() && file.isFile() && file.canRead(); 80 } 81}

投稿2020/04/12 06:12

TN8001

総合スコア9862

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

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

man_

2020/04/12 06:20

TN8001さん回答ありがとうございます。 ご教示いただいたコードを参考にコーディングしていきます。 ありがとうございます。
guest

0

ベストアンサー

Swing はシングルスレッドです. ご提示のコードでは, actionPerformed が終わるまで, 再表示を含む Swing の全処理は停止しています.
読み込み及び文字列の設定を別スレッドで行うようにしてください.

投稿2020/04/11 13:50

jimbe

総合スコア13209

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

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

man_

2020/04/11 15:35

jimbeさん回答ありがとうございます。 別スレッドで実装してみましたが、TextAreaに表示されませんでした。 修正点等ご教示お願いします。
jimbe

2020/04/12 06:04

ta に TextArea が設定されている個所が見当たりませんが, ちゃんと設定されているのでしょうか.
jimbe

2020/04/12 06:09

いや, もしやこの actionPerformed が含まれているのが LogPanel2 ということでしょうか. (こういうことがあるので出来るだけ全体をご提示頂きたいのですが...) だとすれば Thread thread = new Thread(new LogPanel2()); で動くスレッドはこのオブジェクトではありませんので ta 等は設定されていないはずです. Thread thread = new Thread(this); としてください.
man_

2020/04/12 06:18

jimbeさん回答ありがとうございます。 コード全体を表示しました。 回答の通りThread thread = new Thread (this);とし、taの設定をグローバル変数部分で行ったところ表示されるようになりました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問