LegacyApplication
class represents an instance of a
- * real-time 3D rendering jME application.
+ * The LegacyApplication
class represents an instance of a real-time 3D rendering jME
+ * application.
*
* An LegacyApplication
provides all the tools that are commonly used in jME3
* applications.
*
- * jME3 applications *SHOULD NOT EXTEND* this class but extend {@link com.jme3.app.SimpleApplication} instead.
+ * jME3 applications *SHOULD NOT EXTEND* this class but extend
+ * {@link com.jme3.app.SimpleApplication} instead.
*
*/
public class LegacyApplication implements Application, SystemListener {
- private static final Logger logger = Logger.getLogger(LegacyApplication.class.getName());
-
- protected AssetManager assetManager;
-
- protected AudioRenderer audioRenderer;
- protected Renderer renderer;
- protected RenderManager renderManager;
- protected ViewPort viewPort;
- protected ViewPort guiViewPort;
-
- protected JmeContext context;
- protected AppSettings settings;
- protected Timer timer = new NanoTimer();
- protected Camera cam;
- protected Listener listener;
-
- protected boolean inputEnabled = true;
- protected LostFocusBehavior lostFocusBehavior = LostFocusBehavior.ThrottleOnLostFocus;
- protected float speed = 1f;
- protected boolean paused = false;
- protected MouseInput mouseInput;
- protected KeyInput keyInput;
- protected JoyInput joyInput;
- protected TouchInput touchInput;
- protected InputManager inputManager;
- protected AppStateManager stateManager;
-
- protected AppProfiler prof;
-
- private final ConcurrentLinkedQueueLegacyApplication
.
- */
- public LegacyApplication() {
- this((AppState[]) null);
- }
-
- /**
- * Create a new instance of LegacyApplication
, preinitialized
- * with the specified set of app states.
- *
- * @param initialStates app states to pre-attach, or null for none
- */
- public LegacyApplication(AppState... initialStates) {
- initStateManager();
-
- if (initialStates != null) {
- for (AppState a : initialStates) {
- if (a != null) {
- stateManager.attach(a);
- }
- }
- }
- }
-
- /**
- * Determine the application's behavior when unfocused.
- *
- * @return The lost focus behavior of the application.
- */
- @Override
- public LostFocusBehavior getLostFocusBehavior() {
- return lostFocusBehavior;
- }
-
- /**
- * Changes the application's behavior when unfocused.
- *
- * By default, the application will
- * {@link LostFocusBehavior#ThrottleOnLostFocus throttle the update loop}
- * so as not to use 100% of the CPU when out of focus, e.g.
- * alt-tabbed, minimized, or hidden by another window.
- *
- * @param lostFocusBehavior The new lost focus behavior to use.
- *
- * @see LostFocusBehavior
- */
- @Override
- public void setLostFocusBehavior(LostFocusBehavior lostFocusBehavior) {
- this.lostFocusBehavior = lostFocusBehavior;
- }
-
- /**
- * Returns true if pause on lost focus is enabled, false otherwise.
- *
- * @return true if pause on lost focus is enabled
- *
- * @see #getLostFocusBehavior()
- */
- @Override
- public boolean isPauseOnLostFocus() {
- return getLostFocusBehavior() == LostFocusBehavior.PauseOnLostFocus;
- }
-
- /**
- * Enable or disable pause on lost focus.
- *
- * By default, pause on lost focus is enabled.
- * If enabled, the application will stop updating
- * when it loses focus or becomes inactive (e.g. alt-tab).
- * For online or real-time applications, this might be undesirable,
- * so this feature should be disabled. For other applications,
- * it is best to keep it enabled so the CPU is not used unnecessarily.
- *
- * @param pauseOnLostFocus True to enable pause on lost focus, false
- * otherwise.
- *
- * @see #setLostFocusBehavior(com.jme3.app.LostFocusBehavior)
- */
- @Override
- public void setPauseOnLostFocus(boolean pauseOnLostFocus) {
- if (pauseOnLostFocus) {
- setLostFocusBehavior(LostFocusBehavior.PauseOnLostFocus);
- } else {
- setLostFocusBehavior(LostFocusBehavior.Disabled);
+ private static final Logger logger = Logger.getLogger(LegacyApplication.class.getName());
+
+ protected AssetManager assetManager;
+
+ protected AudioRenderer audioRenderer;
+ protected Renderer renderer;
+ protected RenderManager renderManager;
+ protected ViewPort viewPort;
+ protected ViewPort guiViewPort;
+
+ protected JmeContext context;
+ protected AppSettings settings;
+ protected Timer timer = new NanoTimer();
+ protected Camera cam;
+ protected Listener listener;
+
+ protected boolean inputEnabled = true;
+ protected LostFocusBehavior lostFocusBehavior = LostFocusBehavior.ThrottleOnLostFocus;
+ protected float speed = 1f;
+ protected boolean paused = false;
+ protected MouseInput mouseInput;
+ protected KeyInput keyInput;
+ protected JoyInput joyInput;
+ protected TouchInput touchInput;
+ protected InputManager inputManager;
+ protected AppStateManager stateManager;
+
+ protected AppProfiler prof;
+
+ private final ConcurrentLinkedQueue
+ * By default, pause on lost focus is enabled. If enabled, the application will stop updating when
+ * it loses focus or becomes inactive (e.g. alt-tab). For online or real-time applications, this
+ * might be undesirable, so this feature should be disabled. For other applications, it is best to
+ * keep it enabled so the CPU is not used unnecessarily.
+ *
+ * @param pauseOnLostFocus True to enable pause on lost focus, false otherwise.
+ *
+ * @see #setLostFocusBehavior(com.jme3.app.LostFocusBehavior)
+ */
+ @Override
+ public void setPauseOnLostFocus(boolean pauseOnLostFocus) {
+ if (pauseOnLostFocus) {
+ setLostFocusBehavior(LostFocusBehavior.PauseOnLostFocus);
+ } else {
+ setLostFocusBehavior(LostFocusBehavior.Disabled);
+ }
+ }
+
+ @Deprecated
+ public void setAssetManager(AssetManager assetManager) {
+ if (this.assetManager != null)
+ throw new IllegalStateException("Can only set asset manager" + " before initialization.");
+
+ this.assetManager = assetManager;
+ }
+
+ private void initAssetManager() {
+ URL assetCfgUrl = null;
+
+ if (settings != null) {
+ String assetCfg = settings.getString("AssetConfigURL");
+ if (assetCfg != null) {
+ try {
+ assetCfgUrl = new URL(assetCfg);
+ } catch (MalformedURLException ex) {
}
if (assetCfgUrl == null) {
- assetCfgUrl = JmeSystem.getPlatformAssetConfigURL();
- }
- if (assetManager == null) {
- assetManager = JmeSystem.newAssetManager(assetCfgUrl);
- }
- }
-
- /**
- * Set the display settings to define the display created.
- *
- * Examples of display parameters include display pixel width and height,
- * color bit depth, z-buffer bits, anti-aliasing samples, and update frequency.
- * If this method is called while the application is already running, then
- * {@link #restart() } must be called to apply the settings to the display.
- *
- * @param settings The settings to set.
- */
- @Override
- public void setSettings(AppSettings settings) {
- this.settings = settings;
- if (context != null && settings.useInput() != inputEnabled) {
- // may need to create or destroy input based
- // on settings change
- inputEnabled = !inputEnabled;
- if (inputEnabled) {
- initInput();
- } else {
- destroyInput();
- }
- } else {
- inputEnabled = settings.useInput();
- }
- }
-
- /**
- * Sets the Timer implementation that will be used for calculating
- * frame times. By default, Application will use the Timer as returned
- * by the current JmeContext implementation.
- */
- @Override
- public void setTimer(Timer timer) {
- this.timer = timer;
-
- if (timer != null) {
- timer.reset();
- }
-
- if (renderManager != null) {
- renderManager.setTimer(timer);
- }
- }
-
- @Override
- public Timer getTimer() {
- return timer;
- }
-
- private void initDisplay() {
- // acquire important objects
- // from the context
- settings = context.getSettings();
-
- // Only reset the timer if a user has not already provided one
- if (timer == null) {
- timer = context.getTimer();
- }
-
- renderer = context.getRenderer();
- }
-
- private void initAudio() {
- if (settings.getAudioRenderer() != null && context.getType() != Type.Headless) {
- audioRenderer = JmeSystem.newAudioRenderer(settings);
- audioRenderer.initialize();
- AudioContext.setAudioRenderer(audioRenderer);
-
- listener = new Listener();
- audioRenderer.setListener(listener);
- }
- }
-
- /**
- * Creates the camera to use for rendering. Default values are perspective
- * projection with 45° field of view, with near and far values 1 and 1000
- * units respectively.
- */
- private void initCamera() {
- cam = new Camera(settings.getWidth(), settings.getHeight());
-
- cam.setFrustumPerspective(45f, (float) cam.getWidth() / cam.getHeight(), 1f, 1000f);
- cam.setLocation(new Vector3f(0f, 0f, 10f));
- cam.lookAt(new Vector3f(0f, 0f, 0f), Vector3f.UNIT_Y);
-
- renderManager = new RenderManager(renderer);
- //Remy - 09/14/2010 set the timer in the renderManager
- renderManager.setTimer(timer);
-
- if (prof != null) {
- renderManager.setAppProfiler(prof);
- }
-
- viewPort = renderManager.createMainView("Default", cam);
- viewPort.setClearFlags(true, true, true);
-
- // Create a new cam for the gui
- Camera guiCam = new Camera(settings.getWidth(), settings.getHeight());
- guiViewPort = renderManager.createPostView("Gui Default", guiCam);
- guiViewPort.setClearFlags(false, false, false);
- }
-
- /**
- * Initializes mouse and keyboard input. Also
- * initializes joystick input if joysticks are enabled in the
- * AppSettings.
- */
- private void initInput() {
- mouseInput = context.getMouseInput();
- if (mouseInput != null)
- mouseInput.initialize();
-
- keyInput = context.getKeyInput();
- if (keyInput != null)
- keyInput.initialize();
-
- touchInput = context.getTouchInput();
- if (touchInput != null)
- touchInput.initialize();
-
- if (settings.useJoysticks()) {
- joyInput = context.getJoyInput();
- if (joyInput != null)
- joyInput.initialize();
- }
-
- inputManager = new InputManager(mouseInput, keyInput, joyInput, touchInput);
- }
-
- private void initStateManager() {
- stateManager = new AppStateManager(this);
-
- // Always register a ResetStatsState to make sure
- // that the stats are cleared every frame
- stateManager.attach(new ResetStatsState());
- }
-
- /**
- * @return The {@link AssetManager asset manager} for this application.
- */
- @Override
- public AssetManager getAssetManager() {
- return assetManager;
- }
-
- /**
- * @return the {@link InputManager input manager}.
- */
- @Override
- public InputManager getInputManager() {
- return inputManager;
- }
-
- /**
- * @return the {@link AppStateManager app state manager}
- */
- @Override
- public AppStateManager getStateManager() {
- return stateManager;
- }
-
- /**
- * @return the {@link RenderManager render manager}
- */
- @Override
- public RenderManager getRenderManager() {
- return renderManager;
- }
-
- /**
- * @return The {@link Renderer renderer} for the application
- */
- @Override
- public Renderer getRenderer() {
- return renderer;
- }
-
- /**
- * @return The {@link AudioRenderer audio renderer} for the application
- */
- @Override
- public AudioRenderer getAudioRenderer() {
- return audioRenderer;
- }
-
- /**
- * @return The {@link Listener listener} object for audio
- */
- @Override
- public Listener getListener() {
- return listener;
- }
-
- /**
- * @return The {@link JmeContext display context} for the application
- */
- @Override
- public JmeContext getContext() {
- return context;
- }
-
- /**
- * @return The {@link Camera camera} for the application
- */
- @Override
- public Camera getCamera() {
- return cam;
- }
-
- /**
- * Starts the application in {@link Type#Display display} mode.
- *
- * @see #start(com.jme3.system.JmeContext.Type)
- */
- @Override
- public void start() {
- start(JmeContext.Type.Display, false);
- }
-
- /**
- * Starts the application in {@link Type#Display display} mode.
- *
- * @param waitFor true→wait for the context to be initialized,
- * false→don't wait
- * @see #start(com.jme3.system.JmeContext.Type)
- */
- @Override
- public void start(boolean waitFor) {
- start(JmeContext.Type.Display, waitFor);
- }
-
- /**
- * Starts the application.
- * Creating a rendering context and executing
- * the main loop in a separate thread.
- *
- * @param contextType the type of context to create
- */
- public void start(JmeContext.Type contextType) {
- start(contextType, false);
- }
-
- /**
- * Starts the application.
- * Creating a rendering context and executing
- * the main loop in a separate thread.
- *
- * @param contextType the type of context to create
- * @param waitFor true→wait for the context to be initialized,
- * false→don't wait
- */
- public void start(JmeContext.Type contextType, boolean waitFor) {
- if (context != null && context.isCreated()) {
- logger.warning("start() called when application already created!");
+ assetCfgUrl = LegacyApplication.class.getClassLoader().getResource(assetCfg);
+ if (assetCfgUrl == null) {
+ logger.log(Level.SEVERE, "Unable to access AssetConfigURL in asset config:{0}",
+ assetCfg);
return;
+ }
}
-
- if (settings == null) {
- settings = new AppSettings(true);
- }
-
- logger.log(Level.FINE, "Starting application: {0}", getClass().getName());
- context = JmeSystem.newContext(settings, contextType);
- context.setSystemListener(this);
- context.create(waitFor);
- }
-
- /**
- * Sets an AppProfiler hook that will be called back for
- * specific steps within a single update frame. Value defaults
- * to null.
- *
- * @param prof the profiler to use (alias created) or null for none
- */
- @Override
- public void setAppProfiler(AppProfiler prof) {
- this.prof = prof;
- if (renderManager != null) {
- renderManager.setAppProfiler(prof);
- }
- }
-
- /**
- * Returns the current AppProfiler hook, or null if none is set.
- */
- @Override
- public AppProfiler getAppProfiler() {
- return prof;
- }
-
- /**
- * Initializes the application's canvas for use.
- *
- * After calling this method, cast the {@link #getContext()} context to
- * JmeCanvasContext,
- * then acquire the canvas with JmeCanvasContext.getCanvas()
- * and attach it to an AWT/Swing Frame.
- * The rendering thread will start when the canvas becomes visible on
- * screen, however if you wish to start the context immediately you
- * may call {@link #startCanvas() } to force the rendering thread
- * to start.
- *
- * @see Type#Canvas
- */
- public void createCanvas() {
- if (context != null && context.isCreated()) {
- logger.warning("createCanvas() called when application already created!");
- return;
- }
-
- if (settings == null) {
- settings = new AppSettings(true);
- }
-
- if (logger.isLoggable(Level.FINE)) {
- logger.log(Level.FINE, "Starting application: {0}", getClass().getName());
- }
- context = JmeSystem.newContext(settings, JmeContext.Type.Canvas);
- context.setSystemListener(this);
- }
-
- /**
- * Starts the rendering thread after createCanvas() has been called.
- *
- * Same as calling startCanvas(false)
- *
- * @see #startCanvas(boolean)
- */
- public void startCanvas() {
- startCanvas(false);
- }
-
- /**
- * Starts the rendering thread after createCanvas() has been called.
- *
- * Calling this method is optional, the canvas will start automatically
- * when it becomes visible.
- *
- * @param waitFor If true, the current thread will block until the
- * rendering thread is running
- */
- public void startCanvas(boolean waitFor) {
- context.create(waitFor);
- }
-
- /**
- * Internal use only.
- */
- @Override
- public void reshape(int w, int h) {
- if (renderManager != null) {
- renderManager.notifyReshape(w, h);
- }
- }
-
-
- @Override
- public void rescale(float x, float y){
- if (renderManager != null) {
- renderManager.notifyRescale(x, y);
- }
- }
-
- /**
- * Restarts the context, applying any changed settings.
- *
- * Changes to the {@link AppSettings} of this Application are not
- * applied immediately; calling this method forces the context
- * to restart, applying the new settings.
- */
- @Override
- public void restart() {
- context.setSettings(settings);
- context.restart();
- }
-
- /**
- * Requests the context to close, shutting down the main loop
- * and making necessary cleanup operations.
- *
- * Same as calling stop(false)
- *
- * @see #stop(boolean)
- */
- @Override
- public void stop() {
- stop(false);
- }
-
- /**
- * Requests the context to close, shutting down the main loop
- * and making necessary cleanup operations.
- * After the application has stopped, it cannot be used anymore.
- *
- * @param waitFor true→wait for the context to be fully destroyed,
- * true→don't wait
- */
- @Override
- public void stop(boolean waitFor) {
- logger.log(Level.FINE, "Closing application: {0}", getClass().getName());
- context.destroy(waitFor);
- }
-
- /**
- * Do not call manually.
- * Callback from ContextListener.
- *
- * Initializes the
- * Callables are executed right at the beginning of the main loop.
- * They are executed even if the application is currently paused
- * or out of focus.
- *
- * @param
- * Runnables are executed right at the beginning of the main loop.
- * They are executed even if the application is currently paused
- * or out of focus.
- *
- * @param runnable The runnable to run in the main jME3 thread
- */
- @Override
- @SuppressWarnings("unchecked")
- public void enqueue(Runnable runnable) {
- enqueue(new RunnableWrapper(runnable));
- }
-
- /**
- * Runs tasks enqueued via {@link #enqueue(Callable)}
- */
- protected void runQueuedTasks() {
- AppTask> task;
- while ((task = taskQueue.poll()) != null) {
- if (!task.isCancelled()) {
- task.invoke();
- }
- }
- }
-
- /**
- * Do not call manually.
- * Callback from ContextListener.
- */
- @Override
- public void update() {
- // Make sure the audio renderer is available to callables
- AudioContext.setAudioRenderer(audioRenderer);
-
- if (prof != null)
- prof.appStep(AppStep.QueuedTasks);
- runQueuedTasks();
-
- if (speed == 0 || paused)
- return;
-
- timer.update();
-
- if (inputEnabled) {
- if (prof != null)
- prof.appStep(AppStep.ProcessInput);
- inputManager.update(timer.getTimePerFrame());
- }
-
- if (audioRenderer != null) {
- if (prof != null)
- prof.appStep(AppStep.ProcessAudio);
- audioRenderer.update(timer.getTimePerFrame());
- }
-
- // user code here
- }
-
- protected void destroyInput() {
- if (mouseInput != null)
- mouseInput.destroy();
-
- if (keyInput != null)
- keyInput.destroy();
-
- if (joyInput != null)
- joyInput.destroy();
-
- if (touchInput != null)
- touchInput.destroy();
-
- inputManager = null;
- }
-
- /**
- * Do not call manually.
- * Callback from ContextListener.
- */
- @Override
- public void destroy() {
- stateManager.cleanup();
-
+ }
+ }
+ if (assetCfgUrl == null) {
+ assetCfgUrl = JmeSystem.getPlatformAssetConfigURL();
+ }
+ if (assetManager == null) {
+ assetManager = JmeSystem.newAssetManager(assetCfgUrl);
+ }
+ }
+
+ /**
+ * Set the display settings to define the display created.
+ *
+ * Examples of display parameters include display pixel width and height, color bit depth,
+ * z-buffer bits, anti-aliasing samples, and update frequency. If this method is called while the
+ * application is already running, then {@link #restart() } must be called to apply the settings
+ * to the display.
+ *
+ * @param settings The settings to set.
+ */
+ @Override
+ public void setSettings(AppSettings settings) {
+ this.settings = settings;
+ if (context != null && settings.useInput() != inputEnabled) {
+ // may need to create or destroy input based
+ // on settings change
+ inputEnabled = !inputEnabled;
+ if (inputEnabled) {
+ initInput();
+ } else {
destroyInput();
- if (audioRenderer != null)
- audioRenderer.cleanup();
-
- timer.reset();
+ }
+ } else {
+ inputEnabled = settings.useInput();
}
+ }
- /**
- * @return The GUI viewport. Which is used for the on screen
- * statistics and FPS.
- */
- @Override
- public ViewPort getGuiViewPort() {
- return guiViewPort;
- }
+ /**
+ * Sets the Timer implementation that will be used for calculating frame times. By default,
+ * Application will use the Timer as returned by the current JmeContext implementation.
+ */
+ @Override
+ public void setTimer(Timer timer) {
+ this.timer = timer;
- @Override
- public ViewPort getViewPort() {
- return viewPort;
+ if (timer != null) {
+ timer.reset();
}
- private class RunnableWrapper implements Callable {
- private final Runnable runnable;
+ if (renderManager != null) {
+ renderManager.setTimer(timer);
+ }
+ }
- public RunnableWrapper(Runnable runnable) {
- this.runnable = runnable;
- }
+ @Override
+ public Timer getTimer() {
+ return timer;
+ }
+
+ private void initDisplay() {
+ // acquire important objects
+ // from the context
+ settings = context.getSettings();
+
+ // Only reset the timer if a user has not already provided one
+ if (timer == null) {
+ timer = context.getTimer();
+ }
+
+ renderer = context.getRenderer();
+ }
+
+ private void initAudio() {
+ if (settings.getAudioRenderer() != null && context.getType() != Type.Headless) {
+ audioRenderer = JmeSystem.newAudioRenderer(settings);
+ audioRenderer.initialize();
+ AudioContext.setAudioRenderer(audioRenderer);
+
+ listener = new Listener();
+ audioRenderer.setListener(listener);
+ }
+ }
+
+ /**
+ * Creates the camera to use for rendering. Default values are perspective projection with 45°
+ * field of view, with near and far values 1 and 1000 units respectively.
+ */
+ private void initCamera() {
+ cam = new Camera(settings.getWidth(), settings.getHeight());
+
+ cam.setFrustumPerspective(45f, (float) cam.getWidth() / cam.getHeight(), 1f, 1000f);
+ cam.setLocation(new Vector3f(0f, 0f, 10f));
+ cam.lookAt(new Vector3f(0f, 0f, 0f), Vector3f.UNIT_Y);
+
+ renderManager = new RenderManager(renderer);
+ // Remy - 09/14/2010 set the timer in the renderManager
+ renderManager.setTimer(timer);
+
+ if (prof != null) {
+ renderManager.setAppProfiler(prof);
+ }
+
+ viewPort = renderManager.createMainView("Default", cam);
+ viewPort.setClearFlags(true, true, true);
+
+ // Create a new cam for the gui
+ Camera guiCam = new Camera(settings.getWidth(), settings.getHeight());
+ guiViewPort = renderManager.createPostView("Gui Default", guiCam);
+ guiViewPort.setClearFlags(false, false, false);
+ }
+
+ /**
+ * Initializes mouse and keyboard input. Also initializes joystick input if joysticks are enabled
+ * in the AppSettings.
+ */
+ private void initInput() {
+ mouseInput = context.getMouseInput();
+ if (mouseInput != null)
+ mouseInput.initialize();
+
+ keyInput = context.getKeyInput();
+ if (keyInput != null)
+ keyInput.initialize();
+
+ touchInput = context.getTouchInput();
+ if (touchInput != null)
+ touchInput.initialize();
+
+ if (settings.useJoysticks()) {
+ joyInput = context.getJoyInput();
+ if (joyInput != null)
+ joyInput.initialize();
+ }
+
+ inputManager = new InputManager(mouseInput, keyInput, joyInput, touchInput);
+ }
+
+ private void initStateManager() {
+ stateManager = new AppStateManager(this);
+
+ // Always register a ResetStatsState to make sure
+ // that the stats are cleared every frame
+ stateManager.attach(new ResetStatsState());
+ }
+
+ /**
+ * @return The {@link AssetManager asset manager} for this application.
+ */
+ @Override
+ public AssetManager getAssetManager() {
+ return assetManager;
+ }
+
+ /**
+ * @return the {@link InputManager input manager}.
+ */
+ @Override
+ public InputManager getInputManager() {
+ return inputManager;
+ }
+
+ /**
+ * @return the {@link AppStateManager app state manager}
+ */
+ @Override
+ public AppStateManager getStateManager() {
+ return stateManager;
+ }
+
+ /**
+ * @return the {@link RenderManager render manager}
+ */
+ @Override
+ public RenderManager getRenderManager() {
+ return renderManager;
+ }
+
+ /**
+ * @return The {@link Renderer renderer} for the application
+ */
+ @Override
+ public Renderer getRenderer() {
+ return renderer;
+ }
+
+ /**
+ * @return The {@link AudioRenderer audio renderer} for the application
+ */
+ @Override
+ public AudioRenderer getAudioRenderer() {
+ return audioRenderer;
+ }
+
+ /**
+ * @return The {@link Listener listener} object for audio
+ */
+ @Override
+ public Listener getListener() {
+ return listener;
+ }
+
+ /**
+ * @return The {@link JmeContext display context} for the application
+ */
+ @Override
+ public JmeContext getContext() {
+ return context;
+ }
+
+ /**
+ * @return The {@link Camera camera} for the application
+ */
+ @Override
+ public Camera getCamera() {
+ return cam;
+ }
+
+ /**
+ * Starts the application in {@link Type#Display display} mode.
+ *
+ * @see #start(com.jme3.system.JmeContext.Type)
+ */
+ @Override
+ public void start() {
+ start(JmeContext.Type.Display, false);
+ }
+
+ /**
+ * Starts the application in {@link Type#Display display} mode.
+ *
+ * @param waitFor true→wait for the context to be initialized, false→don't wait
+ * @see #start(com.jme3.system.JmeContext.Type)
+ */
+ @Override
+ public void start(boolean waitFor) {
+ start(JmeContext.Type.Display, waitFor);
+ }
+
+ /**
+ * Starts the application. Creating a rendering context and executing the main loop in a separate
+ * thread.
+ *
+ * @param contextType the type of context to create
+ */
+ public void start(JmeContext.Type contextType) {
+ start(contextType, false);
+ }
+
+ /**
+ * Starts the application. Creating a rendering context and executing the main loop in a separate
+ * thread.
+ *
+ * @param contextType the type of context to create
+ * @param waitFor true→wait for the context to be initialized, false→don't wait
+ */
+ public void start(JmeContext.Type contextType, boolean waitFor) {
+ if (context != null && context.isCreated()) {
+ logger.warning("start() called when application already created!");
+ return;
+ }
+
+ if (settings == null) {
+ settings = new AppSettings(true);
+ }
+
+ logger.log(Level.FINE, "Starting application: {0}", getClass().getName());
+ context = JmeSystem.newContext(settings, contextType);
+ context.setSystemListener(this);
+ context.create(waitFor);
+ }
+
+ /**
+ * Sets an AppProfiler hook that will be called back for specific steps within a single update
+ * frame. Value defaults to null.
+ *
+ * @param prof the profiler to use (alias created) or null for none
+ */
+ @Override
+ public void setAppProfiler(AppProfiler prof) {
+ this.prof = prof;
+ if (renderManager != null) {
+ renderManager.setAppProfiler(prof);
+ }
+ }
+
+ /**
+ * Returns the current AppProfiler hook, or null if none is set.
+ */
+ @Override
+ public AppProfiler getAppProfiler() {
+ return prof;
+ }
+
+ /**
+ * Initializes the application's canvas for use.
+ *
+ * After calling this method, cast the {@link #getContext()} context to JmeCanvasContext, then
+ * acquire the canvas with JmeCanvasContext.getCanvas() and attach it to an AWT/Swing Frame. The
+ * rendering thread will start when the canvas becomes visible on screen, however if you wish to
+ * start the context immediately you may call {@link #startCanvas() } to force the rendering
+ * thread to start.
+ *
+ * @see Type#Canvas
+ */
+ public void createCanvas() {
+ if (context != null && context.isCreated()) {
+ logger.warning("createCanvas() called when application already created!");
+ return;
+ }
+
+ if (settings == null) {
+ settings = new AppSettings(true);
+ }
+
+ if (logger.isLoggable(Level.FINE)) {
+ logger.log(Level.FINE, "Starting application: {0}", getClass().getName());
+ }
+ context = JmeSystem.newContext(settings, JmeContext.Type.Canvas);
+ context.setSystemListener(this);
+ }
+
+ /**
+ * Starts the rendering thread after createCanvas() has been called.
+ *
+ * Same as calling startCanvas(false)
+ *
+ * @see #startCanvas(boolean)
+ */
+ public void startCanvas() {
+ startCanvas(false);
+ }
+
+ /**
+ * Starts the rendering thread after createCanvas() has been called.
+ *
+ * Calling this method is optional, the canvas will start automatically when it becomes visible.
+ *
+ * @param waitFor If true, the current thread will block until the rendering thread is running
+ */
+ public void startCanvas(boolean waitFor) {
+ context.create(waitFor);
+ }
+
+ /**
+ * Internal use only.
+ */
+ @Override
+ public void reshape(int w, int h) {
+ if (renderManager != null) {
+ renderManager.notifyReshape(w, h);
+ }
+ }
+
+
+ @Override
+ public void rescale(float x, float y) {
+ if (renderManager != null) {
+ renderManager.notifyRescale(x, y);
+ }
+ }
+
+ /**
+ * Restarts the context, applying any changed settings.
+ *
+ * Changes to the {@link AppSettings} of this Application are not applied immediately; calling
+ * this method forces the context to restart, applying the new settings.
+ */
+ @Override
+ public void restart() {
+ context.setSettings(settings);
+ context.restart();
+ }
+
+ /**
+ * Requests the context to close, shutting down the main loop and making necessary cleanup
+ * operations.
+ *
+ * Same as calling stop(false)
+ *
+ * @see #stop(boolean)
+ */
+ @Override
+ public void stop() {
+ stop(false);
+ }
+
+ /**
+ * Requests the context to close, shutting down the main loop and making necessary cleanup
+ * operations. After the application has stopped, it cannot be used anymore.
+ *
+ * @param waitFor true→wait for the context to be fully destroyed, true→don't wait
+ */
+ @Override
+ public void stop(boolean waitFor) {
+ logger.log(Level.FINE, "Closing application: {0}", getClass().getName());
+ context.destroy(waitFor);
+ }
+
+ /**
+ * Do not call manually. Callback from ContextListener.
+ *
+ * Initializes the
+ * Callables are executed right at the beginning of the main loop. They are executed even if the
+ * application is currently paused or out of focus.
+ *
+ * @param
+ * Runnables are executed right at the beginning of the main loop. They are executed even if the
+ * application is currently paused or out of focus.
+ *
+ * @param runnable The runnable to run in the main jME3 thread
+ */
+ @Override
+ @SuppressWarnings("unchecked")
+ public void enqueue(Runnable runnable) {
+ enqueue(new RunnableWrapper(runnable));
+ }
+
+ /**
+ * Runs tasks enqueued via {@link #enqueue(Callable)}
+ */
+ protected void runQueuedTasks() {
+ AppTask> task;
+ while ((task = taskQueue.poll()) != null) {
+ if (!task.isCancelled()) {
+ task.invoke();
+ }
+ }
+ }
+
+ /**
+ * Do not call manually. Callback from ContextListener.
+ */
+ @Override
+ public void update() {
+ // Make sure the audio renderer is available to callables
+ AudioContext.setAudioRenderer(audioRenderer);
+
+ if (prof != null)
+ prof.appStep(AppStep.QueuedTasks);
+ runQueuedTasks();
+
+ if (speed == 0 || paused)
+ return;
+
+ timer.update();
+
+ if (inputEnabled) {
+ if (prof != null)
+ prof.appStep(AppStep.ProcessInput);
+ inputManager.update(timer.getTimePerFrame());
+ }
+
+ if (audioRenderer != null) {
+ if (prof != null)
+ prof.appStep(AppStep.ProcessAudio);
+ audioRenderer.update(timer.getTimePerFrame());
+ }
+
+ // user code here
+ }
+
+ protected void destroyInput() {
+ if (mouseInput != null)
+ mouseInput.destroy();
+
+ if (keyInput != null)
+ keyInput.destroy();
+
+ if (joyInput != null)
+ joyInput.destroy();
+
+ if (touchInput != null)
+ touchInput.destroy();
+
+ inputManager = null;
+ }
+
+ /**
+ * Do not call manually. Callback from ContextListener.
+ */
+ @Override
+ public void destroy() {
+ stateManager.cleanup();
+
+ destroyInput();
+ if (audioRenderer != null)
+ audioRenderer.cleanup();
+
+ timer.reset();
+ }
+
+ /**
+ * @return The GUI viewport. Which is used for the on screen statistics and FPS.
+ */
+ @Override
+ public ViewPort getGuiViewPort() {
+ return guiViewPort;
+ }
+
+ @Override
+ public ViewPort getViewPort() {
+ return viewPort;
+ }
+
+ private class RunnableWrapper implements Callable {
+ private final Runnable runnable;
+
+ public RunnableWrapper(Runnable runnable) {
+ this.runnable = runnable;
+ }
+
+ @Override
+ public Object call() {
+ runnable.run();
+ return null;
+ }
+ }
+
+ /**
+ * This call will return a list of Monitors that glfwGetMonitors() returns and information about
+ * the monitor, like width, height, and refresh rate.
+ *
+ * @return returns a list of monitors and their information.
+ */
+ public Monitors getMonitors() {
+ return context.getMonitors();
+ }
- @Override
- public Object call() {
- runnable.run();
- return null;
- }
- }
-
- /**
- * This call will return a list of Monitors that glfwGetMonitors()
- * returns and information about the monitor, like width, height,
- * and refresh rate.
- *
- * @return returns a list of monitors and their information.
- */
- public Monitors getMonitors()
- {
- return context.getMonitors();
- }
-
- /**
- * Use this to get the positional number of the primary
- * monitor from the glfwGetMonitors() function call.
- *
- * @return the position of the value in the arraylist of
- * the primary monitor.
- */
- public int getPrimaryMonitor()
- {
- return context.getPrimaryMonitor();
- }
+ /**
+ * Use this to get the positional number of the primary monitor from the glfwGetMonitors()
+ * function call.
+ *
+ * @return the position of the value in the arraylist of the primary monitor.
+ */
+ public int getPrimaryMonitor() {
+ return context.getPrimaryMonitor();
+ }
}
diff --git a/jme3-core/src/main/java/com/jme3/system/AppSettings.java b/jme3-core/src/main/java/com/jme3/system/AppSettings.java
index c5509301ac..cfa98ec41e 100644
--- a/jme3-core/src/main/java/com/jme3/system/AppSettings.java
+++ b/jme3-core/src/main/java/com/jme3/system/AppSettings.java
@@ -1485,27 +1485,29 @@ public void setWindowYPosition(int pos) {
/**
* Gets the monitor number used when creating a window.
*
- * This setting is used only with LWJGL3, it defines which monitor
- * to use when creating a OpenGL window.
+ *
+ * This setting is used only with LWJGL3, it defines which monitor to use when creating a OpenGL
+ * window.
*
* @return the desired monitor used when creating a OpenGL window
* @see #setMonitor(long)
*/
public int getMonitor() {
- return getInteger("Monitor");
+ return getInteger("Monitor");
}
/**
- * Sets the monitor number used when creating a window. The position
- * number is the number in the list of monitors GlfwGetMonitors returns.
+ * Sets the monitor number used when creating a window. The position number is the number in the
+ * list of monitors GlfwGetMonitors returns.
*
- * This setting is used only with LWJGL3, it defines which monitor
- * to use when creating a OpenGL window. its default value is 0.
+ *
+ * This setting is used only with LWJGL3, it defines which monitor to use when creating a OpenGL
+ * window. its default value is 0.
*
* @param mon the desired monitor used when creating a OpenGL window
*
*/
public void setMonitor(int mon) {
- putInteger("Monitor", mon);
+ putInteger("Monitor", mon);
}
-}
+ }
diff --git a/jme3-core/src/main/java/com/jme3/system/JmeContext.java b/jme3-core/src/main/java/com/jme3/system/JmeContext.java
index 59d7cdbb05..258639634f 100644
--- a/jme3-core/src/main/java/com/jme3/system/JmeContext.java
+++ b/jme3-core/src/main/java/com/jme3/system/JmeContext.java
@@ -227,20 +227,18 @@ public enum Type {
public int getWindowYPosition();
/**
- * This call will return a list of Monitors that glfwGetMonitors()
- * returns and information about the monitor, like width, height,
- * and refresh rate.
+ * This call will return a list of Monitors that glfwGetMonitors() returns and information about
+ * the monitor, like width, height, and refresh rate.
*
* @return returns a list of monitors and their information.
*/
public Monitors getMonitors();
/**
- * Use this to get the positional number of the primary
- * monitor from the glfwGetMonitors() function call.
+ * Use this to get the positional number of the primary monitor from the glfwGetMonitors()
+ * function call.
*
- * @return the position of the value in the arraylist of
- * the primary monitor.
- */
+ * @return the position of the value in the arraylist of the primary monitor.
+ */
public int getPrimaryMonitor();
-}
+ }
diff --git a/jme3-core/src/main/java/com/jme3/system/MonitorInfo.java b/jme3-core/src/main/java/com/jme3/system/MonitorInfo.java
index 64864fb70e..a7791d37b2 100644
--- a/jme3-core/src/main/java/com/jme3/system/MonitorInfo.java
+++ b/jme3-core/src/main/java/com/jme3/system/MonitorInfo.java
@@ -1,73 +1,66 @@
/*
- * Copyright (c) 2009-2023 jMonkeyEngine
- * All rights reserved.
+ * Copyright (c) 2009-2023 jMonkeyEngine All rights reserved.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * Redistribution and use in source and binary forms, with or without modification, are permitted
+ * provided that the following conditions are met:
*
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * * Redistributions of source code must retain the above copyright notice, this list of conditions
+ * and the following disclaimer.
*
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
+ * * Redistributions in binary form must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other materials provided with
+ * the distribution.
*
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors may be used to endorse or
+ * promote products derived from this software without specific prior written permission.
*
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme3.system;
/**
- * This class holds information about the monitor that was
- * returned by glfwGetMonitors() calls in the context
- * class
+ * This class holds information about the monitor that was returned by glfwGetMonitors() calls in
+ * the context class
*
* @author Kevin Bales
*/
public class MonitorInfo {
-
- /**
- * monitorID - monitor id that was return from Lwjgl3.
- */
- public long monitorID = 0;
- /**
- * width - width that was return from Lwjgl3.
- */
- public int width = 1080;
+ /**
+ * monitorID - monitor id that was return from Lwjgl3.
+ */
+ public long monitorID = 0;
- /**
- * height - height that was return from Lwjgl3.
- */
- public int height = 1920;
+ /**
+ * width - width that was return from Lwjgl3.
+ */
+ public int width = 1080;
- /**
- * rate - refresh rate that was return from Lwjgl3.
- */
- public int rate = 60;
-
- /**
- * primary - indicates if the monitor is the primary monitor.
- */
- public boolean primary = false;
-
- /**
- * name - monitor name that was return from Lwjgl3.
- */
- public String name = "Generic Monitor";
+ /**
+ * height - height that was return from Lwjgl3.
+ */
+ public int height = 1920;
+
+ /**
+ * rate - refresh rate that was return from Lwjgl3.
+ */
+ public int rate = 60;
+
+ /**
+ * primary - indicates if the monitor is the primary monitor.
+ */
+ public boolean primary = false;
+
+ /**
+ * name - monitor name that was return from Lwjgl3.
+ */
+ public String name = "Generic Monitor";
}
diff --git a/jme3-core/src/main/java/com/jme3/system/Monitors.java b/jme3-core/src/main/java/com/jme3/system/Monitors.java
index 61a874d201..b834e518f8 100644
--- a/jme3-core/src/main/java/com/jme3/system/Monitors.java
+++ b/jme3-core/src/main/java/com/jme3/system/Monitors.java
@@ -1,119 +1,105 @@
/*
- * Copyright (c) 2009-2023 jMonkeyEngine
- * All rights reserved.
+ * Copyright (c) 2009-2023 jMonkeyEngine All rights reserved.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * Redistribution and use in source and binary forms, with or without modification, are permitted
+ * provided that the following conditions are met:
*
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * * Redistributions of source code must retain the above copyright notice, this list of conditions
+ * and the following disclaimer.
*
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
+ * * Redistributions in binary form must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other materials provided with
+ * the distribution.
*
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors may be used to endorse or
+ * promote products derived from this software without specific prior written permission.
*
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme3.system;
import java.util.ArrayList;
/**
- * This class holds all information about all monitors that where
- * return from the glfwGetMonitors() call. It stores them into
- * an LegacyApplication
.
+ */
+ public LegacyApplication() {
+ this((AppState[]) null);
+ }
+
+ /**
+ * Create a new instance of LegacyApplication
, preinitialized with the specified set
+ * of app states.
+ *
+ * @param initialStates app states to pre-attach, or null for none
+ */
+ public LegacyApplication(AppState... initialStates) {
+ initStateManager();
+
+ if (initialStates != null) {
+ for (AppState a : initialStates) {
+ if (a != null) {
+ stateManager.attach(a);
}
- }
-
- @Deprecated
- public void setAssetManager(AssetManager assetManager) {
- if (this.assetManager != null)
- throw new IllegalStateException("Can only set asset manager"
- + " before initialization.");
-
- this.assetManager = assetManager;
- }
-
- private void initAssetManager() {
- URL assetCfgUrl = null;
-
- if (settings != null) {
- String assetCfg = settings.getString("AssetConfigURL");
- if (assetCfg != null) {
- try {
- assetCfgUrl = new URL(assetCfg);
- } catch (MalformedURLException ex) {
- }
- if (assetCfgUrl == null) {
- assetCfgUrl = LegacyApplication.class.getClassLoader().getResource(assetCfg);
- if (assetCfgUrl == null) {
- logger.log(Level.SEVERE, "Unable to access AssetConfigURL in asset config:{0}", assetCfg);
- return;
- }
- }
- }
+ }
+ }
+ }
+
+ /**
+ * Determine the application's behavior when unfocused.
+ *
+ * @return The lost focus behavior of the application.
+ */
+ @Override
+ public LostFocusBehavior getLostFocusBehavior() {
+ return lostFocusBehavior;
+ }
+
+ /**
+ * Changes the application's behavior when unfocused.
+ *
+ * By default, the application will {@link LostFocusBehavior#ThrottleOnLostFocus throttle the
+ * update loop} so as not to use 100% of the CPU when out of focus, e.g. alt-tabbed, minimized, or
+ * hidden by another window.
+ *
+ * @param lostFocusBehavior The new lost focus behavior to use.
+ *
+ * @see LostFocusBehavior
+ */
+ @Override
+ public void setLostFocusBehavior(LostFocusBehavior lostFocusBehavior) {
+ this.lostFocusBehavior = lostFocusBehavior;
+ }
+
+ /**
+ * Returns true if pause on lost focus is enabled, false otherwise.
+ *
+ * @return true if pause on lost focus is enabled
+ *
+ * @see #getLostFocusBehavior()
+ */
+ @Override
+ public boolean isPauseOnLostFocus() {
+ return getLostFocusBehavior() == LostFocusBehavior.PauseOnLostFocus;
+ }
+
+ /**
+ * Enable or disable pause on lost focus.
+ * Application
, by creating a display and
- * default camera. If display settings are not specified, a default
- * 640x480 display is created. Default values are used for the camera;
- * perspective projection with 45° field of view, with near
- * and far values 1 and 1000 units respectively.
- */
- @Override
- public void initialize() {
- if (assetManager == null) {
- initAssetManager();
- }
-
- initDisplay();
- initCamera();
-
- if (inputEnabled) {
- initInput();
- }
- initAudio();
-
- // update timer so that the next delta is not too large
-// timer.update();
- timer.reset();
-
- // user code here
- }
-
- /**
- * Internal use only.
- */
- @Override
- public void handleError(String errMsg, Throwable t) {
- // Print error to log.
- logger.log(Level.SEVERE, errMsg, t);
- // Display error message on screen if not in headless mode
- if (context.getType() != JmeContext.Type.Headless) {
- if (t != null) {
- JmeSystem.handleErrorMessage(errMsg + "\n" + t.getClass().getSimpleName()
- + (t.getMessage() != null ? ": " + t.getMessage() : ""));
- } else {
- JmeSystem.handleErrorMessage(errMsg);
- }
- }
-
- stop(); // stop the application
- }
-
- /**
- * Internal use only.
- */
- @Override
- public void gainFocus() {
- if (lostFocusBehavior != LostFocusBehavior.Disabled) {
- if (lostFocusBehavior == LostFocusBehavior.PauseOnLostFocus) {
- paused = false;
- }
- context.setAutoFlushFrames(true);
- if (inputManager != null) {
- inputManager.reset();
- }
- }
- }
-
- /**
- * Internal use only.
- */
- @Override
- public void loseFocus() {
- if (lostFocusBehavior != LostFocusBehavior.Disabled) {
- if (lostFocusBehavior == LostFocusBehavior.PauseOnLostFocus) {
- paused = true;
- }
- context.setAutoFlushFrames(false);
- }
- }
-
- /**
- * Internal use only.
- */
- @Override
- public void requestClose(boolean esc) {
- context.destroy(false);
- }
-
- /**
- * Enqueues a task/callable object to execute in the jME3
- * rendering thread.
- * Application
, by creating a display and default camera. If display
+ * settings are not specified, a default 640x480 display is created. Default values are used for
+ * the camera; perspective projection with 45° field of view, with near and far values 1 and 1000
+ * units respectively.
+ */
+ @Override
+ public void initialize() {
+ if (assetManager == null) {
+ initAssetManager();
+ }
+
+ initDisplay();
+ initCamera();
+
+ if (inputEnabled) {
+ initInput();
+ }
+ initAudio();
+
+ // update timer so that the next delta is not too large
+ // timer.update();
+ timer.reset();
+
+ // user code here
+ }
+
+ /**
+ * Internal use only.
+ */
+ @Override
+ public void handleError(String errMsg, Throwable t) {
+ // Print error to log.
+ logger.log(Level.SEVERE, errMsg, t);
+ // Display error message on screen if not in headless mode
+ if (context.getType() != JmeContext.Type.Headless) {
+ if (t != null) {
+ JmeSystem.handleErrorMessage(errMsg + "\n" + t.getClass().getSimpleName()
+ + (t.getMessage() != null ? ": " + t.getMessage() : ""));
+ } else {
+ JmeSystem.handleErrorMessage(errMsg);
+ }
+ }
+
+ stop(); // stop the application
+ }
+
+ /**
+ * Internal use only.
+ */
+ @Override
+ public void gainFocus() {
+ if (lostFocusBehavior != LostFocusBehavior.Disabled) {
+ if (lostFocusBehavior == LostFocusBehavior.PauseOnLostFocus) {
+ paused = false;
+ }
+ context.setAutoFlushFrames(true);
+ if (inputManager != null) {
+ inputManager.reset();
+ }
+ }
+ }
+
+ /**
+ * Internal use only.
+ */
+ @Override
+ public void loseFocus() {
+ if (lostFocusBehavior != LostFocusBehavior.Disabled) {
+ if (lostFocusBehavior == LostFocusBehavior.PauseOnLostFocus) {
+ paused = true;
+ }
+ context.setAutoFlushFrames(false);
+ }
+ }
+
+ /**
+ * Internal use only.
+ */
+ @Override
+ public void requestClose(boolean esc) {
+ context.destroy(false);
+ }
+
+ /**
+ * Enqueues a task/callable object to execute in the jME3 rendering thread.
+ *