• 締切済み

SwingUtilities.invokeLater(new Runnable()はなんですか?

noname#94983の回答

noname#94983
noname#94983
回答No.1

おそらくJFrameのインスタンスを作って画面に表示するとかいった処理を行っていると思う。Swingで、コンテナやコンポーネントを作成したりするような処理は、SwingUtilities.invokeLaterを使って実行することが推奨されている。 このSwingUtilities.invokeLaterは、イベントキューに処理を登録し、実行する働きを持つ。これにより、その他の何らかの(早急に実行すべき)処理があった場合にはそれらが終わった後にイベントキューに従って処理が実行される。こうすることにより、非同期にかつ安全に処理を実行させることができる。 実はSwingというのはシングルすれどで設計されている。だから、何かの処理を実行すると、その間、他の処理がとまってしまう。そこで、直接メインスレッド内で実行させるのでなく、SwingUtilities.invokeLaterを使ってイベントキューに登録し、安全に実行させるほうがよい、というわけ。 が、まぁ実際問題として、コンポーネント類の初期化などでSwingUtilities.invokeLaterせずメインスレッドから実行したためにトラブルが起こるというようなことは(コード自体がバグってない限り)まずないと思っていいので、たいていの人はSwingUtilities.invokeLaterを使わず直接mainに処理を書いていると思う。「本当はこうしたほうがいいが、まぁしなくても問題が起こることはまずないだろう」ということ。

rescue99
質問者

お礼

わかりやすい解説をありがとうございます!!

関連するQ&A

  • SwingUtilities.invokeLater(new Runn

    SwingUtilities.invokeLater(new Runnable() {}について 以前質問でgooで教えて頂いた際、以下のようなコードがありました。 どのような効果があるのか教えてください。 APIを見ても理解できませんでした。 また、APIを理解するコツのようなものはあるでしょうか。 ご存知の方がおられましたら教えてください。 ・試してみたこと  重いプログラムを起動させ、実行速度を比べた。------ほとんど同じでした。   public static void main(String a[]) { SwingUtilities.invokeLater(new Runnable() { public void run() { new test(); } }); }

    • ベストアンサー
    • Java
  • Runnableのインスタンス化について

    下記のコードについてです。 Runnableがインスタンス化されていますが、 どうしてそれが可能なのかが分かりません。 分からない点は 1.Runnableはインタフェースであるから、本来、直接インスタンス化は不可能であるはず。 2.しかし、Runnableはクラスライブラリjava.langパッケージに含まれている。 だからインスタンス化は可能なのかもしれない。 3.あるいは、下記のコードではメソッド内の無名クラスであるから、「new Runnable(){」の 部分でスーパークラスとしてのRunnableを継承したサブクラスを生成しているのかもしれない。 アドバイスをよろしくお願い致します。 public class Main{ public static void main(String[]args){ Runnable task = new Runnable(){ public void run(){ System.out.println("run"); } }; Thread thread = new Thread(task){ public synchronized void start(){ System.out.println("start"); } }; thread.start(); } }

    • ベストアンサー
    • Java
  • SwingでSwingUtilities.invokeLater()の利用

    はじめまして。Javaビギナーです。 今Swingを利用したチャットアプリを作成しようと色々調べているところなのですが、よくmain()メソッド内にて public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { // 初期処理 } }); } というのを見かけます。 これは、Swingでアプリを実行する場合に上記のように作成することが一般的なのでしょうか? それとも、マルチスレッドを利用する必要のない場合などは上記のようなコーディングは行われないのでしょうか? 後々の機能拡張などを考えれば、上記のようにコーディングした方が良いのだと思いますが、一般的な利用方法を教えていただければと思います。宜しくお願いします。

  • コンパイルエラー(Threadオブジェクト化)

    Runnableを継承したNormalClassをThreadとしてオブジェクト化しようとしているのですが、コンパイルエラーが出現して困っています。どうすればいいでしょうか? 下記エラー参照 Main.java:1: NormalClass は abstract でなく、java.lang.Runnable 内の abstract メソッド run() をオーバーライドしません。 下記ソース class NormalClass implements Runnable{ } class Main extends Thread{ public static void main(String args[]){ test = new Thread(new NormalClass()); } }

    • ベストアンサー
    • Java
  • java8でテキストのレンダリングが不正になる

    先日java8をインストールしたのですが、JMenu/JButton/JLabelなどの文字やボーダーが一部欠けたように表示されるようになりました(画像を添付しました)。 java7では再現しないことから色々探してみると下記サイトで同件と思われるレポートを見つけました。 http://stackoverflow.com/questions/22737535/swing-rendering-appears-broken-in-jdk-1-8-correct-in-jdk-1-7 しかし「NVIDIAのカードの設定を変えたら動くようになった」というコメント以外に対応策らしきものがなく、それを自分も試してみたものの解決せずでした。 もしjava8の問題ならしばらくはjava7を使い続けるしかないとは思うのですが、同件と思われる問題が上記サイト以外に見つけられなかったことからjava8問題だというのは早計かとも思い、諦めてしまう前に「同じ現象になったよ」「こうしたら動いた」「コードに問題がある」などの情報がないかと思い質問を上げさせていただきました。コメントいただけたらありがたいです。 再現コード: package jp.po.test1; import java.awt.Font; import javax.swing.*; public class Test1 extends JFrame { public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new Test1().setVisible(true); } }); } Test1() { super("title"); JLabel label = new JLabel("BOO FOO WOO"); label.setFont(new Font(Font.DIALOG, Font.PLAIN, 30)); getContentPane().add(label); setDefaultCloseOperation(EXIT_ON_CLOSE); pack(); } }

    • ベストアンサー
    • Java
  • SwingとEDT(イベントディスパッチスレッド)

    多くのサイトを見て、色々考えているのですが、イマイチ理解が及びません。以下のような風に思っていていいのでしょうか。 ・Swingではメインとなるmainスレッド(表現は正しくないかもしれない)と、描画関係のイベントを実行するイベントディスパッチスレッドで出来てる。 ・描画関係のイベント(正確にはコンポーネントの可視化及び可視化したコンポーネントの描画)はイベントディスパッチスレッド上で実行しなければならない。 ・SwingUtilities.invokeLaterを使うことによってその中身のプログラムをイベントディスパッチスレッドで実行してくれる...? →setVisible(true)やsetText("")など全てSwingUtilities.invokeLaterを使って記述しなければならない.....???(面倒すぎじゃないでしょうか) ・Swingでのマルチスレッドを行うにはSwingWorkerを使う(ことは見つけているのですが、まずEDTについて理解しないと先に進めないと思い、まだあまりこれの内容は調べていません) ・描画系の命令を実行しないのならば、別スレッドを作成して使用しても良い....? こんなところでしょうか。 しかし、このとおりだとすると今までの自分の書いてきたプログラムは間違いだらけ(特に「全ての描画系命令をSwingUtilities.invokeLaterを使いEDTで実行する」点)になってしまいます。 ちゃんとした理解をしておきたいので、わかりやすい説明でも、上記の間違っている点でもご教示願います。

  • DocumentListenerについて

    DocumentListenerについて JTextPaneのDocumentにDocumentListenerを設定しました。 例えば public void insertUpdate(DocumentEvent e){ e.getDocument().insertString(e.getOffset(), "追加します", null); } こうすると何か文字を入力するとランタイムエラーになります。 [Attempt to mutate in notification] DocumentListenerが動いてるときはDocumentを改変してはならないようです。 よって public void insertUpdate(DocumentEvent e){ SwingUtilities.invokeLater( new InsertInvoker(e) ); } class InsertInvoker implements Runnable{ public void run{ [Document編集処理](文字の色を変える、UndoManagerにイベントを追加する処理です。) } } こうしたのですが今度は ペーストを連続で行った場合や、 文字を選択した上で入力した場合(removeUpdateとinsertUpdateがほぼ同時に起きる) にInsertInvokerやRemoveInvokerの処理がまとめて最後に行われるという 事態になってしまいました。 offsetの位置がずれてしまい、ぐちゃぐちゃになります。 insertUpdateが終わった瞬間にInsertInvokerが処理を行い、 その間他の処理を受け付けないようにしたいのですが どうしたらいいでしょうか?

    • ベストアンサー
    • Java
  • Appletを利用したマルチスレッドプログラミング

    現在JavaのAppletを利用したマルチスレッドのプログラミングを行っているのですが、なかなか思うように行きません。 やりたいのは同じクラスを持つインスタンスをそれぞれスレッドで動かし、それぞれ個別に操作を与えたいのです。 例えばこのサイトのページではボール1、ボール2をそれぞれ作成していますが、もう少し汎用化したいのです。 http://www.mm2d.net/applet-howto/howto-07.shtml 例えばAppletで動かすSampleBallクラスのインスタンスを複数作成し、 それぞれスレッドで動かすにはどうすれば良いでしょうか。 別クラス(ファイル)として作成したいです。 イメージとしてはこのような感じなのですが、Main.javaを起動するとAppletが起動しません。 またそれぞれスレッドで動かすということで、任意にAppletにSampleBallクラスのインスタンスを 追加したり、削除したり、操作したりするにはどうすればよいでしょうか。 ・Main.java static void main(String args[]) {   SampleBall ball1 = new SampleBall(・・・);   SampleBall ball2 = new SampleBall(・・・);   SampleBall ball3 = new SampleBall(・・・);   … } ・SampleBall.java public class SampleBall extends Applet implements Runnable{ public SampleBall(…){ ・・・ }    public void changeColor(Color col){・・・}    … } 参考になるページ等も教えて頂ければ助かります。 どうぞよろしくお願いします

  • Java言語のインタフェースについて

    Java言語を学習している者です。 インターフェースについて理解できずに困っております。 ここでは、Runnableインターフェースを例にとります。 (1)正しいコード public class ThreadTest implements Runnable { public static void main (String args[]) { ThreadTest ins = new ThreadTest(); Thread th = new Thread(ins); th.start(); for(int i = 0; i < 10; i++) { System.out.println("main : " + i); } } public void run() { for(int i = 0; i < 10; i++) { System.out.println("run : " + i); } } } (1)のコードは正常に動きます。 (2)間違ったコード (implements Runnableを記述しなかった場合) public class ThreadTest{ public static void main (String args[]) { ThreadTest ins = new ThreadTest(); Thread th = new Thread(ins); th.start(); for(int i = 0; i < 10; i++) { System.out.println("main : " + i); } } public void run() { for(int i = 0; i < 10; i++) { System.out.println("run : " + i); } } } (2)のコードでは、 Thread th = new Thread(ins); で、 コンストラクタ―Thread(ThreadTest)は未定義です。 とエラーが出てしまいます。 確かに未定義なのですが、(1)でも定義していないように思えます。 Runnableインターフェースの働きのお陰だと言うことはわかるのですが、どういった働きによるものなのかがわかりません。 インターフェースのについて、 ・インターフェースのフィールドは必ず定数。 ・インターフェースのメソッドは必ず抽象メソッド。 ・インターフェースはインスタンスを作ることが出来ない。 ・抽象メソッドは必ず実装しなければならない。 は理解しているつもりです。 今回の質問をするに当たって、 RunnableのAPI http://java.sun.com/javase/ja/6/docs/ja/api/java/lang/Runnable.html を見たのですが、それでも理由が分からないので質問致します。 もし宜しかったら、APIの見方についてもコメントして頂けるとありがたいです。 宜しくお願いします。

    • ベストアンサー
    • Java
  • newについて

    newを使った場合、3バイト分確保したつもりでしたが、7バイト?になります。どうしてでしょうか? newした場合はdeleteをしないといけませんが、deleteした後にNULLで初期化する意味はあるのでしょうか? CとC++が混在?(newはC++かな?)しているソースなのですが、 現場(クリティカルな開発)ではこういう書き方はNGでしょうか? 組み込み系のお仕事をされている方の意見も聞きたいです。 #include <string.h> void main(void){ char *cstr = new char [3]; printf("%d\n", strlen(cstr)); // 3を期待していたのですが、7になります。 if (cstr != NULL){ delete cstr; cstr = NULL; } }