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

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

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

Javaアプレットは、Webページに組み込まれて実行されるJavaアプリケーションの形式です。Java SE 11で廃止となりました。

Q&A

解決済

1回答

1039閲覧

repaint()を即時実行したい

Mats_k

総合スコア11

Javaアプレット

Javaアプレットは、Webページに組み込まれて実行されるJavaアプリケーションの形式です。Java SE 11で廃止となりました。

0グッド

0クリップ

投稿2019/05/05 03:02

前提・実現したいこと

Java初心者です。初めての質問のため、質問の仕方、調べ方なども含めアドバイスをいただけると幸いです。

今回、Javaアプレットでコマンド入力した長方形データを即時アプレット表示するプログラムを作っています。
run()メソッドが呼び出される度に「Applet表示」の出力がされているものの、repaint()が操作の終了後にしか実行されませんでした。

少し調べてみたところ、repaint()は再描画を要求しているだけに過ぎず、repaint()と書いた場所で即時に再描画されるわけではないということはわかりました。

そこで、具体的にすぐ再描画してほしい場合はどうすればいいのでしょうか?
稚拙な質問で申し訳ございません。よろしくお願いします。

該当のソースコード

Java

1import java.applet.Applet; 2import java.awt.*; 3 4public class RectangleEditor extends Applet { 5 Command command = new Command(); 6 //コマンド入力操作を行うクラスへ受け渡し 7 public void init(){ 8 command.choseCommand(); 9 } 10 11  //他クラスから呼び出しされるメソッド 12 public void run(){ 13 System.out.println("Applet表示"); 14 repaint(); 15 } 16 17 18 //長方形のデータを受け取り、描画する 19 public void paint(Graphics g) { 20 Board board = new Board();  //長方形データを格納しているクラス 21 int[] x = board.xList(); 22 int[] y = board.yList(); 23 int[] w = board.wList(); 24 int[] h = board.hList(); 25 String[] color = board.cList(); 26 27 for(int rectNumber = 0; rectNumber < board.isList(); rectNumber ++){ 28 if(color[rectNumber].equals("red")){ 29 g.setColor(Color.red); 30 }else if(color[rectNumber].equals("blue")){ 31 g.setColor(Color.blue); 32 }else if(color[rectNumber].equals("yellow")){ 33 g.setColor(Color.yellow); 34 }else if(color[rectNumber].equals("gray")){ 35 g.setColor(Color.gray); 36 } 37 38 g.fillRect(x[rectNumber],y[rectNumber],w[rectNumber],h[rectNumber]); 39 } 40 } 41}

試したこと

repaint();の後に、Thread.sleep(10000);を追加して時間の間隔を開けましたが、
結果は変わりませんでした。

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

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

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

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

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

guest

回答1

0

ベストアンサー

まず最初にプログラミングの大前提について提案したいことがあります。アプレットによるGUIはやめることをお勧めします。質問者さんの目的にもよりますが

・JavaによるスタンドアロンのGUIアプリケーションを作ってみる
=> swingないしはJavaFXを学ぶことをお勧めします。
・Webブラウザー上でGUIアプリケーション的なものを作ってみる
=> HTMLとJavaScriptを学ぶことをお勧めします。
・Java(的な言語)を用いて簡単にGUIアプリケーションを作ってみる
=> Processingをお勧めします。

さて、Applet(のサンプルとしてよくあるプログラムコード)に最も近いのはswingライブラリーによるスタンドアロンアプリケーションですのでそれを用いた例で本件についてコメントしてみますと・・・

swingのアプリケーションはイベントディスパッチ方式という仕組みで動いています。

swing内部 | <---- ユーザーの操作により発生するイベント | ----> そのイベントの処理をするハンドラーメソッド <---- | <---- 時間経過により発生するイベント ----> そのイベントの処理をするハンドラーメソッド <---- | ...

こんなふうにプログラムの主制御はswing内部のあるメソッドが司っており、これをアプリケーションに書いたどこかのメソッドで以下のようなことをしようとしても

例1:

swing内部 -----> どこかのメソッド | ----> repain的な何か(A1) ----> repain的な何か(A2) <---- + | (B) -> 再描画される(paintが呼ばれる) ...

(B)の時点までは実際の描画は行われません。(A1),(A2)では「次にswing内部に戻った時に再描画が必要であるということを覚えておくこと」しかできないのです。

なるべく即座にそれが反映されるようにするためにはswingを暇な状態にしてやらねばなりません。暇な状態というのは前述したevent-dispatch-loopに「戻る」ことを意味します。つまり(A1)で指示したrepaintの効果(再描画)を速やかに得たいなら(A1)をした後即座にswingへ戻らねばなりません。

例2:

swing内部 -----> どこかのメソッド | ----> repain的な何か(A1) <----- + (B) -> 再描画される(paintが呼ばれる) | ------> どこかのメソッド ----> repain的な何か(A2) <---- + (B) -> 再描画される(paintが呼ばれる) ...

例2のようにするには「どこかのメソッド」がしかるべきタイミングでswing内部から「呼び出してもらう」ことが必要です。典型的には「どこかのメソッド」はあるイベントにより起動されるハンドラーメソッドとして作る必要があります。ごく短い時間に連続してイベントを発生するにはjavax.swing.Timerなどのクラスを用いるとよいでしょう。

ただ、あなたがスレッドプログラミングを学ぶと例1に近い感覚でプログラミングすることもできます。でもそれを例2のようなswingのevent-dispatch-loop方式でのプログラミングをよく把握しないままやっても正しいプログラミングは難しいと思います。まずは例2の制御方式を学ぶことをお勧めします。


ご質問のコードは一部の抜粋なのでどういう制御をしようとしているかがはっきりわかりません。それがもう少し(充分短いコードで)提示されれば具体的な制御案のアドバイスが得られると思います。

投稿2019/05/05 03:56

KSwordOfHaste

総合スコア18394

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

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

Mats_k

2019/05/05 04:51

たくさんのアドバイスと丁寧な回答をありがとうございます。 大学で教わったことがなかったので、とても助かりました。 Boardクラス(長方形の格納クラス) ,,, import java.util.LinkedList; import java.util.List; public class Board{ static private int newListNumber = 0; //格納されている長方形の個数 static RectangleEditor re = new RectangleEditor(); static Command command = new Command(); Rectangle[] rect = new Rectangle[1]; //入力された長方形を一時格納する配列 static List<String> list = new LinkedList<String>(); static List<Integer> w = new LinkedList<Integer>(); static List<Integer> h = new LinkedList<Integer>(); static List<Integer> x = new LinkedList<Integer>(); static List<Integer> y = new LinkedList<Integer>(); static List<String> c = new LinkedList<String>(); //リストに長方形を追加する static public void add(ColorRectangle[] rect){ list.add(rect[0].toString()); w.add(rect[0].width()); h.add(rect[0].height()); x.add(rect[0].x()); y.add(rect[0].y()); c.add(rect[0].c()); newListNumber++; System.out.println("長方形を新たに追加できました"); command.displayBoard(); re.run(); command.choseCommand(); } //リストの長方形を削除する static public void delate(int numberRect){ //格納番号以外の数値を入力した場合のエラー処理 if(newListNumber <= numberRect || numberRect < 0){ System.out.println("指定された番号に長方形は存在しません。番号をもう一度確認してください。"); command.delate(); }else{ //該当の長方形の各データの削除 list.remove(numberRect); x.remove(numberRect); y.remove(numberRect); w.remove(numberRect); h.remove(numberRect); c.remove(numberRect); newListNumber--; System.out.println("指定の長方形を削除できました"); command.displayBoard(); re.run(); command.choseCommand(); } } .....(略) ,,, Commandクラス(コマンド入力の指示) ,,, public class Command{ Input input = new Input(); ColorRectangle[] rect = new ColorRectangle[1]; Board board = new Board(); //コマンドの入力 public void choseCommand(){ this.displayCommand(); int command = input.inputInteger("上記の操作のいずれかを入力してください"); //入力されたコマンドの条件分岐 switch(command){ case 1: this.displayBoard(); this.choseCommand(); break; case 2: this.exit(); break; case 3: this.create(); break; case 4: this.delate(); break; case 5: this.move(); break; case 6: this.expand_shrink(); break; case 7: this.delateAll(); break; default: System.out.println("指定外の整数を入力しています。番号を確認した上で、再度入力をお願いします。"); this.choseCommand(); } } //長方形の作成(create) public void create(){ Board board = new Board(); int dataNumber = 4; int[] data = new int[dataNumber]; //幅、高さ、左上隅座標の入力を要求する System.out.println(); System.out.println("幅(data[0])、高さ(data[1])、左上隅座標(x座標(data[2])、y座標(data[3]))を順に入力してください"); Input input = new Input(); for(int i = 0; i < dataNumber; i++){ data[i] = input.inputInteger("data[" + i + "]:"); } String color = choseColor(); while(color.equals("")){ color = this.choseColor(); } //Rectangleクラスにデータの読み込み this.rect[0] = new ColorRectangle(data[0],data[1],data[2],data[3],color); System.out.println("入力値: " + this.rect[0]); //エラー処理 String error = this.isError(this.rect); if(error.equals("false")){ //Boardに長方形を入力 board.add(this.rect); }else{ this.choseCommand(); } } //長方形を削除する(delate()) public void delate(){ //長方形が格納されているか確認する if(board.isList() == 0){ System.out.println("リスト内に長方形が存在しません。4以外のコマンドを選択してください。"); this.choseCommand(); }else{ //削除する長方形を選択し、Boardクラスのdelate()へ処理を渡す System.out.println(); board.showRect(); int listNumber = input.inputInteger("上記のリストの中で削除したい長方形の番号を半角数字で答えてください"); board.delate(listNumber); } } ...(略) ,,, 一部抜粋していますが、こちらがRectangleEditorクラスに直接関わりのあるクラスになります。 見づらいプログラムで申し訳ございません。 ぜひおすすめしていただいたswingのevent-dispatch-loop方式でのプログラミングを作成したいのですが具体的にどのように制御すればよいのか、どのように調べればよいのかアドバイスいただけたら幸いです。
KSwordOfHaste

2019/05/05 11:03 編集

えーと・・・本サイトのような場で質問するには長すぎるコードです。またコードをコメント欄に書くのは避けましょう。字下げもされずみづらいことこの上なしです。「字下げのないコードは見る気がしない」というプログラマーは多いです。質問の仕方をアドバイスしますと「余計な処理をそぎ落とし最低限の問題が再現する小さなコードをまず作り、それを省略せずに質問本文に提示すること」です。目安は100行ぐらい。本質問の要点が何かをよく考え必要最小限のコードにしてみることをまずお勧めします。
Mats_k

2019/05/05 14:43

本当に常識知らずすぎて申し訳ないです… 丁寧に教えてくださり、本当にありがとうございます。 また別途コードの書き方に気をつけて質問させていただきます。
KSwordOfHaste

2019/05/05 15:13

コメント欄でインデントを気にせず長いコードを書いてしまうといったことは割とよくあることです。自分ははっきりと指摘した方が伝わり易いと考えたのですが、表現がちょっと紳士的でなかったと思います。その点は失礼しました。指摘自体は本サイトの多くの閲覧者に賛同していただける内容と思いますのでくみ取っていただければ幸いです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問