私はここで何が起こっているのかを説明してくれることを願っています。
Dialog
は、基本的にサブクラス化するのに便利なクラスです。Shell
自体はサブクラス化されていないためです。必要に応じて、Dialog
を使わずにシェルを作成することもできます。この場合、MyDialog
クラスは、他の人が同じ種類のダイアログを繰り返し開くために使用できるクラスです。
コードのこの作品は、(シェル上の閉じるボタンをクリックすると、デフォルトでシェルを配置する)限り、シェルが開いているとSWTのイベントループを駆動する:
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) display.sleep();
}
あなたは維持するために定期的にDisplay.readAndDispatch
を呼び出す必要がありますあなたのSWTアプリケーションは「ロックアップ」しています。基本的には、オペレーティングシステムからのすべての着信イベント(キーボードとマウスイベント、再描画イベントなど)がアプリケーションによって正しく処理されます。 readAndDispatch
は基本的にアプリケーションのイベントキューからイベントを受け取り、正しいリスナを呼び出します。 Eclipse RCPアプリケーションでは、通常、ワークベンチはイベント・ループを「ポンピング」する責任があります。 「手動」は、この文脈において、イベントループポンプのHere's a little more info about the event loop.
目的は、シェルが配置されていないながら戻ることMyDialog.open
を防ぐが、それでも「ハング」からアプリケーションを保つことです。 MyDialog.open
メソッドがシェルの廃棄を待つが、イベントループをポンピングしなかった場合、アプリケーションはイベントループが実行されていなければシェルに通知されることはない処分されるべきです!
お客様このパターンを使用せずにシェルを作成してください。
public class Shells {
private static int numDisposals = 0;
public static void main(String[] args) {
Display d = Display.getDefault();
for (int i = 0; i < 5; i++) {
Shell s = new Shell(d);
s.open();
s.addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent arg0) {
numDisposals++;
}
});
}
while (numDisposals < 5) {
while (!d.readAndDispatch()) {
d.sleep();
}
}
}
}
:ここですべてを一度シェルのトンを開き、非常に単純なSWTアプリケーションの例だと限りそれらの少なくとも1つがまだ開いているとして稼働し続け(私はパッケージ宣言や輸入を省略しました)
各シェルにDisposeListener
を追加するので、シェルを閉じたときに何らかのアクションを取ることができます。IShellListener
を使用して、closeイベントをより直接聞くこともできますし、実際にはそれを防ぐことさえできます(シェルに保存されていない作業がある場合など)。ここでは5つのシェルを起動する最初のプログラムに迷惑修正だとランダムにそれらを閉じてからあなたを防ぐ:
public class Shells {
private static Random r = new Random();
private static int numDisposals = 0;
public static void main(String[] args) {
Display d = Display.getDefault();
for (int i = 0; i < 5; i++) {
Shell s = new Shell(d);
s.open();
s.addShellListener(new ShellAdapter() {
@Override
public void shellClosed(ShellEvent e) {
boolean close = r.nextBoolean();
if (close) {
System.out.println("Alright, shell closing.");
} else {
System.out.println("Try again.");
}
e.doit = close;
}
});
s.addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent arg0) {
numDisposals++;
}
});
}
while (numDisposals < 5) {
while (!d.readAndDispatch()) {
d.sleep();
}
}
}
}
がうまくいけば、これは物事をより明確に貢献してきました!
追加する編集:私はあなたのシェルのためのWindowsのタスクバーの項目を取得されない理由は全くわからないんだけど、私はそれはあなたがシェルの内を通過しているスタイルフラグとは何かを持っている疑いがありますコンストラクタ。私の例のシェルにはスタイルフラグはなく、すべてタスクバーのアイコンが表示されます。
この非常に有益な回答ありがとうございます。タスクバーアイコンについて:私はダイアログウィンドウの親として「メインウィンドウ」を設定しました。新しいシェルのコンストラクタの親として別のシェルを渡すと、新しいシェルはタスクバーアイコンを受け取らず、新しいシェルは常にその親の上に(無視されないように)置かれます。親として表示されているシェルのみがタスクバーに表示されます(Windows 7)。少なくとも、これは私のテストが提案したものです。 – Buttons840