Java は私の母国語ではなく、しばらくこの問題と戦ってきました。
基本的に、メソッド switchApplets() を init() から直接呼び出す場合と、init() によって生成された新しいスレッド内から呼び出す場合の動作の違いを見つけています。
新しいスレッド内から呼び出した結果、ユーザーがブラウザのサイズを変更または最小化するまで、またはしない限り、新しいアプレットはホワイトスクリーンになります。init() の最後に呼び出された場合、新しい UI はユーザーからの入力なしですぐにレンダリングされます。しかし、スレッドが準備作業を完了するのを待たないため、これはオプションではありません。
短縮されたコード:
public class PreLoader extends Applet implements AppletStub {
static JProgressBar pBar = null;
static JLabel message;
public void switchApplets() {
try {
Class main_class = Class.forName("MainClass");
Applet main_applet = (Applet)main_class.newInstance();
removeAll();
setSize(0,0);
setLayout(new GridLayout(1,0));
add(main_applet);
main_applet.init();
main_applet.start();
main_applet.setStub(this);
}
catch (Exception e) {
}
}
public void init() {
pBar = new JProgressBar(0, 100);
pBar.setValue(0);
pBar.setStringPainted(true);
message = new JLabel("Beginning work!");
add(message);
add(pBar);
FlowLayout flow = new FlowLayout();
setLayout(flow);
Thread t = new Thread ( new Runnable () {
public void run ()
{
longRunningFunction1();
longRunningFunction2();
message.setText("Work complete! Stand by..");
switchApplets(); //does NOT work as intended from here
return;
}
} );
t.start();
//switchApplets(); //works as intended if called HERE
}
public void longRunningFunction1() {
//perform some tasks, advance progress bar
}
public void longRunningFunction2() {
//perform some tasks, advance progress bar
}
public void start() {
return;
}
public void appletResize(int width, int height) {
return;
}
}
そこから switchApplets() を呼び出すことができるように init() をスレッドが終了するまで待機させようとしましたが、それは EDT をブロックするだけで、UI の更新を妨げました。また、SwingUtilities の invokeLater/invokeAndWait で遊んでみましたが、switchApplets() は EDT で実行されますが、init() から直接呼び出す必要があるようです (または、少なくとも init が実行されているスレッド)。 .
新しいスレッド内から switchApplets() を呼び出すと、わずかに異なる (そして望ましくない) UI 動作が発生するのはなぜですか?