To add more functionality to my app, I am wrapping it with a Swing launcher (Nifty was giving me too many troubles and I feel more comfortable with Swing). The user picks their settings, then presses a start button which executes the application:
SwingUtilities.invokeLater(() -> new Thread(liaison::start).start());
liaison
is an instance of a class that extends SimpleApplication, which in turn starts an AppState for the main program.
This has worked fine, except the jme3 window becomes un-resizable when launching for a second time (that is, not closing the entire program, but just the jme3 AWT window, and launching it again from the Swing GUI). This only seems to happen on Windows (at least not Ubuntu, I don’t have a Mac to find out).
I’ve made sure that I set it to resizable (SimpleApplication.start):
@Override
public void start() {
var settings = new AppSettings(true);
...
settings.setResizable(true);
...
setSettings(settings);
super.start();
}
I tried making the settings final static and calling setSettings(SETTINGS)
each time, instead of creating a new AppSettings each time.
Here’s a minimal, reproducable example. Launch the below program and press “Start!”, the game starts and the window is resizable. Press Esc or X and press “Start!” again. The window is now not resizable.
import com.jme3.app.LegacyApplication;
import com.jme3.app.SimpleApplication;
import com.jme3.app.state.AbstractAppState;
import com.jme3.app.state.AppStateManager;
import com.jme3.system.AppSettings;
import javax.swing.*;
import static javax.swing.WindowConstants.EXIT_ON_CLOSE;
public class SwingExample {
public static void main(String[] args) {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
JButton button = new JButton("Start!");
button.addActionListener(e -> startJme());
panel.add(button);
frame.setContentPane(panel);
frame.pack();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setVisible(true);
}
private static void startJme() {
SwingUtilities.invokeLater(() -> new Thread(new Application()::start).start());
}
}
class Application extends SimpleApplication {
@Override
public void start() {
AppSettings settings = new AppSettings(true);
settings.setResizable(true);
setSettings(settings);
setShowSettings(false);
super.start();
}
@Override
public void simpleInitApp() {
TheAppState appState = new TheAppState();
stateManager.attach(appState);
}
}
class TheAppState extends AbstractAppState {
@Override
public void initialize(AppStateManager stateManager, com.jme3.app.Application app) {
super.initialize(stateManager, app);
((Application) app).getFlyByCamera().setDragToRotate(true); // Don't lock cursor
}
}
Is my best bet to create a Swing window and place jme3 inside of that which could fix this? Or is there some other solution I’m missing?