使用 JavaFX 时一些奇怪的问题
继承自 Application 类的构造函数会被执行两次
先看代码:
// FXTestMain.java
import javafx.application.Application;
import javafx.stage.Stage;
public class FXTestMain extends Application {
public void main(String[] args) { launch(args); }
int counter = 0;
public FXTestMain() {
System.out.println(++counter);
}
@Override
public void start(Stage stage) {}
}
//FXtest.java
public class FXTest {
public static void main(String[] args) {
FXTestMain GUI = new FXTestMain();
GUI.main(args);
}
}
将会输出:
1
1
在 Line.9 打个断点,会发现这一句会被线程 main
与 JavaFX Application Thread
都执行一遍,然而把 GUI.main(args)
注释掉后就很正常。于是考虑看 launch
到底干了什么:(经过反编译后的代码)
// Application.class: Line.52
LauncherImpl.launchApplication(var12, var0);
// LauncherImpl.class: Line.82
launchApplication(var0, var2, var1);
// LauncherImpl.class: Line.98
launchApplication1(var0, var1, var2);
// LauncherImpl.class: Line.514-522
try {
Constructor var3 = var1.getConstructor();
var10.set((Preloader)var3.newInstance());
ParametersImpl.registerParameters((Application)var10.get(), new ParametersImpl(var2));
} catch (Throwable var4) {
System.err.println("Exception in Preloader constructor");
pConstructorError = var4;
error = true;
}
可见 launch
方法中通过 Constructor
的 newInstance()
创建和初始化一个新实例,会调用它的构造方法。
使用 SourceDataLine 播放音频错误重复循环一片段
个人猜测是因为多次播放,对 buffer
的抢占导致的。在 Doc4dev 文档 里可以看到具有非实时声音数据且可以预加载到内存时,应该使用使用Clip,尤其是它已经被加载进内存的情况下。
解决办法:使用 Clip
进行播放。但是也会导致相邻两子间隔太短而吞音,不整了。
Main 方法结束后,程序仍未退出
我创建了 IOThread
类,在读取存档时候会被调用,而常态在 wait
状态:
public void reStartRead() {
try {
synchronized (this) {
this.notify();
additionAction();
this.wait();
}
} catch (InterruptedException e) {
System.out.println("[ERROR] Cannot restart thread to start read saves.");
e.printStackTrace();
}
}
只要在退出时使用 this.interrupt();
就好了(不要使用已经废弃的 stop()
)。