Window not resizable after subsequent launches from Swing

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?

Note: you don’t need to worry about Macs if you use Swing since apparently it doesn’t work anyway.

Note that if you are still interested in something “in game”, Lemur is way more like Swing than nifty is. I’ve been a hardcore Swing developer since 1998 or so and it heavily influenced the design of Lemur. I just streamlined a lot of the ancient boiler plate.

2 Likes