Я пытаюсь создать окно JFrame из приложения JavaFX.Я использую Oracle Java 8 и могу делать то, что мне нужно, в Linux, Windows, но не в Mac OS.Это похоже на проблему реализации JVM.Вот мои требования:
- Мне нужно вызвать метод библиотеки, который создает игровое окно (расширенный класс из JFrame).Мне нужно иметь возможность использовать клавиатуру в игре.
- Я могу получить доступ к исходному коду библиотеки, но не собираюсь менять исходный код библиотеки
- Мне нужнообрабатывать информацию об игре после ее завершения, поэтому мой основной поток должен ждать, пока игра не закончится
Я создал пример приложения ниже.Приложение прекрасно работает под Linux и Windows, но в Mac OS, когда я пытаюсь дождаться завершения потока приложения JFrame, зависание приложения и JFrame не отображаются.SwingUtilities.invokeLater не останавливается, но не ожидает завершения потока JFrame.Поскольку мне нужно дождаться потока JFrame, invokeLater для меня не вариант.
JFrameCreator.java
public class JFrameCreator implements Runnable {
@Override
public void run() {
System.out.println("Creating JFrame");
JFrame frame=new JFrame();
frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
frame.setSize(300,300);
frame.setVisible(true);
for (int i = 0; i < 100; i++) {
frame.getContentPane().getGraphics().drawOval(150-i/2,150-i/2,i,i);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
sample.fxml
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="100.0" prefWidth="200.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
<children>
<Button layoutX="51.0" layoutY="10.0" mnemonicParsing="false" onAction="#createJFrame" text="New JFrame" />
<RadioButton fx:id="cbThread" layoutX="10.0" layoutY="40.0" mnemonicParsing="false" selected="true" text="Thread">
<toggleGroup>
<ToggleGroup fx:id="tg" />
</toggleGroup>
</RadioButton>
<RadioButton fx:id="cbInvokeWait" layoutX="10.0" layoutY="60.0" mnemonicParsing="false" text="invokeAndWait" toggleGroup="$tg" />
<RadioButton fx:id="cbInvokeLater" layoutX="10.0" layoutY="80.0" mnemonicParsing="false" text="invokeLater" toggleGroup="$tg" />
</children>
</AnchorPane>
Controller.java
public class Controller {
@FXML RadioButton cbThread;
@FXML RadioButton cbInvokeWait;
@FXML RadioButton cbInvokeLater;
public void createJFrame(javafx.event.ActionEvent actionEvent) {
Runnable r=new JFrameCreator();
try {
if (cbThread.isSelected()) {
Thread t=new Thread(new JFrameCreator());
t.start();
t.join();
}
else if(cbInvokeWait.isSelected())
SwingUtilities.invokeAndWait(r);
else
SwingUtilities.invokeLater(r);
}
catch (InterruptedException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
Main.java
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("Swing in JavaFX");
primaryStage.setScene(new Scene(root, 200, 100));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Я также пробовал цикл while с методом Thread.isAlive (), но он также ведет себя как Thread.join ().Как я могу достичь своих требований?