@IT会議室は、2009年4月15日に新システムに移行し、さらに2012年5月29日にITエンジニアに特化した
質問・回答コミュニティ「QA@IT」に生まれ変わりました。ぜひご利用くださいませ。
- PR -

処理を止める

1
投稿者投稿内容
あふち
会議室デビュー日: 2007/05/31
投稿数: 14
投稿日時: 2007-06-12 14:46
よろしくお願いいたします。

現在Jfreechartでチャート表示画面を表示するプログラム作成中です。
これは親画面があってそこにある釦を押下すると
JfreeChartによるチャート画面が表示されるようになっています。
チャートはChartFrameというもので表示しているのですが、
これをモードレス画面にしたいので親画面は操作可能のまま
処理を止めたいと思っています。
SWTで処理を止めるときに

while (!shell.isDisposed()){
if (!display.readAndDispatch()){
  display.sleep();
 }
}

といったような書き方で処理を止めていますが
AWTを使用した場合には上記と同様なことができますでしょうか?

nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2007-06-12 15:52
「処理を止める」とは?

Threadを一時停止させるならThread.sleep()ですし、
別スレッドからnotify()されるまで止めて置くならObject.wait()ですし、
中断して以後の処理をやめるという意味で「止める」ならThread.interrupt()です。

自分で作ったThreadを指定時間だけ停止したいのであればsleep()でよいでしょう。
もしその処理が動いているThreadがEDT(イベントディスパッチスレッド)ならばsleep()させてはいけません。
あふち
会議室デビュー日: 2007/05/31
投稿数: 14
投稿日時: 2007-06-12 16:03
nagiseさん、ありがとうございます。
私の書き方が舌足らずでしたね。

処理を止めたい、というのは
そこで処理を待っていて欲しいのです。
いつまでかというとチャート画面が消去されるまでです。
チャートを可視にしたあと、そこで消去されるまで
待つ方法があれば、という意味でした。
すみません。
ChartFrame.setDefaultCloseOperation()を使ったりするのか
実験中です。
子画面であるチャートが消去されたあとに、
処理を入れたいので、SWTのときと同様に
While文か何かで処理をその場で待つ方法はないでしょうか?
また舌足らずでしたらすみません・・・。
nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2007-06-12 18:32
具体的な実装方法はいろいろあると思いますが、状況によって使える/使えないというのがありますので、方針だけ端的に。

一番簡単なのは閉じる処理をしている直後にコードを挿入すること。
ただ、コードを自由に書きかえれる場合でないと無理です。

クラスによってはフックとなるメソッドが用意されている場合があります。
XXが終わった後に呼び出される〜といった類のメソッドですね。

またはイベント処理で対応している場合もあります。addXXXListenerの類。

上記のような手段が使えない場合で、該当クラス、メソッドがオーバーライド可能であれば、該当処理をしているクラスを継承したクラスを作り、該当処理をしてるメソッドで
コード:
  public void hoge() {
    super.hoge();
    // ここに独自処理を記述
  }


といった手法で既存処理のあとに独自処理を実行させることもできます。

また、実行しているThreadが明確かつ、寿命を持ったThreadである場合はThread.joinを利用することで該当のThreadの完了後に処理を行うことが出来ます。

本件がどの手法で可能かというのは該当クラスを調べて見ないと分からないですが、
Componentのイベント処理か、Thread.join()あたりで対処できそうな気もします。
あふち
会議室デビュー日: 2007/05/31
投稿数: 14
投稿日時: 2007-06-13 08:34
nagiseさん、ご丁寧にありがとうございました。
該当クラスは何かの派生クラス、というわけではなく、
JfreeChartを生成してChartFrameで表示する、というクラスです。
チャートを生成し、表示するメソッドで
ChartFrame.setVisible(true);
としてチャートを可視にしたあとで
そのメソッドを抜けずにとどまることができれば、というのが
一番の目的でした。
かつそのChartは親画面の釦を押下することで表示されるので
親画面の操作も可能としたいのです。
ただ、今回一番のネックは話がそれるのですが、
親画面のSWTで作られているということです。
なので今回のチャートもSWT_AWT.new_Frame()でshellとの
連携を試みたのですが、Windows上ではうまくいくのですが
Linux上でうまくいかなくて、はまっていました。
ご教示いただいた方法をいろいろ試してがんばってみますね。
ありがとうございました!

nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2007-06-13 13:31
若干補足を。
setVisible(true);
というのが結構曲者なんですよ。

http://www.jfree.org/jfreechart/api/javadoc/org/jfree/chart/ChartFrame.html
ドキュメントを見て分かるとおり、JFrameの派生クラスですからSwingの一般的な用法に則り、
ChartFrame.setVisible()はEDT(イベントディスパッチスレッド)から呼び出さなければなりません。
つまり、イベント処理中など、すでにEDTで実行されている場合を除くと
コード:
SwingUtilities.invokeLater(new Runnable() {
    public void run() {
        frame.setVisible(true);
    }
});


といった記述になるのですが、この場合、このRunnableはQueueに収められ
EDTで順次実行されるというわけです。

引用:

ChartFrame.setVisible(true);
としてチャートを可視にしたあとで
そのメソッドを抜けずにとどまることができれば


の「そのメソッド」が、setVisible()を指すにせよ、setVisible()を呼び出している
メソッドを指すにせよ、実際の描画は別スレッド(EDT)にて行われるのですから、
そこで止めても仕方がないのですね。

また、setVisible()を呼んでいる箇所がすでにEDTなのであれば、これは止めてはいけません。
EDTは速やかに処理を完了して抜けなくてはなりませんので。
EDTを止めるとその間、画面描画が更新されなくなってしまいます。

このように、処理の流れが複雑なので、どのスレッドがどのように動いているのか、
まずはそれを確認して見てください。
私はSWTについては無知なのでSWTでのイベント処理がどのようなスレッド構造で
行われているのかは知りませんが、SWT + Swingでの背後で動くスレッド郡を
正しく理解しないと、妙なバグにさいなまれることになるでしょう。お気をつけて。
あふち
会議室デビュー日: 2007/05/31
投稿数: 14
投稿日時: 2007-06-13 14:01
nagiseさん、いろいろと情報をありがとうございました。
本当に勉強になりました。
不勉強の中、いろいろ検討した結果、
http://cjasmin.fc2web.com/basic/thread.html
http://www.atmarkit.co.jp/fjava/rensai2/eclipse2_07/eclipse07_3.html
などのサイトを参考にして、
なんとか希望の動きを実現しました。

>SWT + Swingでの背後で動くスレッド郡を
>正しく理解しないと、妙なバグにさいなまれることになるでしょう。

まさにそのとおりですね。
これを機にもう少し動きを理解したいと思います。
本当にありがとうございました。
1

アイティメディアの提供サービス

ホワイトペーパー(TechTargetジャパン/閲覧には会員登録が必要です)

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