我正在尝试使用 Java3D 的 Canvas3D 对象制作一个包含一些 3D 内容的 Swing GUI。问题是 Canvas3D 对象初始化需要一段时间,我希望 Swing GUI 立即出现。我对这个问题的解决方案是在单独的线程中初始化 Canvas3D,然后在初始化后将其添加到 JFrame。但是,当那个单独的线程将 Canvas3D 添加到 JFrame 时,窗口会暂时失去焦点,这是不可取的。我怎样才能防止这种情况发生?我已经包含了一个简单的示例来说明我正在尝试做的事情:
public class Main extends JFrame {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Main()::setup);
}
private void setup() {
setSize(600, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
Thread thread = new Thread() {
@Override
public void run() {
Canvas3D canvas = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
SwingUtilities.invokeLater(() -> {
Main.this.add(canvas); //the window loses focus for a moment here
Main.this.revalidate();
});
}
};
thread.start();
}
}
我正在使用 Java3D 1.7.1。
我已根据 R VISHAL 的评论修改了我的代码,但问题仍然存在。
public class Main extends JFrame {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Main()::setup);
}
private void setup() {
setSize(600, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
SwingWorker<Canvas3D, Object> worker = new SwingWorker<Canvas3D, Object>() {
@Override
public Canvas3D doInBackground() {
return new Canvas3D(SimpleUniverse.getPreferredConfiguration());
}
@Override
public void done() {
try {
Main.this.add(get());
} catch (InterruptedException|ExecutionException e) {
throw new RuntimeException();
}
Main.this.requestFocusInWindow();
Main.this.revalidate();
}
};
worker.execute();
}
}