Need to destroy JmeContext display mode

Hi there, so i have made a vehicle selector stage as a SimpleApplication game , when i enter the game after choosing my spaceship , everything goes normal & fine , then i exit the game & re-enter the vehicle selector stage (which is a JFrame having a canvas holding the stage) it opens its context on the last game configuration that i have already exited , keeping the display width & height configs of the stage :

Vehicle Selector Stage code :


package Store;

import com.jme3.app.Application;
import com.jme3.app.SimpleApplication;
import com.jme3.app.state.BaseAppState;
import com.jme3.bullet.BulletAppState;
import com.jme3.input.ChaseCamera;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.light.AmbientLight;
import com.jme3.light.DirectionalLight;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.post.FilterPostProcessor;
import com.jme3.post.filters.LightScatteringFilter;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;

/**
 *
 * @author twisted
 */
public class VehicleSelectorStage extends SimpleApplication {
    private BulletAppState bulletAppState;
    private Node vehicle;
    private String selectedSpaceShip;
    
    /**
     * create a new Instance of stage view
     * @param selectedSpaceShip default spaceship
     */
    public VehicleSelectorStage(String selectedSpaceShip){
        this.selectedSpaceShip=selectedSpaceShip;
    }
    
    
    /**
     * change the vehicle view on the stage
     * @param selectedSpaceShip vehicle directory
     */
    public void changeVehicle(String selectedSpaceShip) {
      try{
           Thread.sleep(150);
           vehicle=(Node) rootNode.getChild("Vehicle");
           vehicle.detachAllChildren();
           vehicle.attachChild(assetManager.loadModel(selectedSpaceShip).scale(1.5f));
           /**
            * add Light to the node
            */
            DirectionalLight metallicLight = new DirectionalLight();
            metallicLight.setDirection(rootNode.getChild("stage").getLocalTranslation().negate());
            metallicLight.setColor(ColorRGBA.Blue);
            vehicle.addLight(metallicLight); 
      }catch(InterruptedException e){
          System.err.println(e.getMessage());
      }
    }
    @Override
    public void simpleInitApp() {
        /**
         * Attach physcis state
         */
        bulletAppState=new BulletAppState();
        stateManager.attach(bulletAppState);
        bulletAppState.setDebugEnabled(false);
        /**
         * Light up the world
         */
        rootNode.addLight(new AmbientLight(ColorRGBA.White));  

        /**
         * load the stage scene & the stage Vehicles
         */
        rootNode.attachChild(assetManager.loadModel("Scenes/Vehicle Selector Stage/VehicleSelectorStage.j3o"));
        vehicle=(Node) rootNode.getChild("Vehicle");
        vehicle.detachAllChildren();
        vehicle.attachChild(assetManager.loadModel(selectedSpaceShip).scale(1.5f));
        /**
         * Setting up the camera
         */
        ChaseCamera vehicleStageCamera=new ChaseCamera(cam, vehicle);
        vehicleStageCamera.setDefaultDistance(-20);
        vehicleStageCamera.setChasingSensitivity(0.05f);
        vehicleStageCamera.setSmoothMotion(true);
        
        vehicleStageCamera.registerWithInput(inputManager);
        vehicleStageCamera.setToggleRotationTrigger(new MouseButtonTrigger(MouseInput.AXIS_X));        
        /**
         * Set-up Stage Effects(FIlter effect)
         */
      
        FilterPostProcessor stagefilter=new FilterPostProcessor(assetManager);
        LightScatteringFilter stagelight = new LightScatteringFilter(rootNode.getChild("stage").getLocalTranslation());
        stagelight.setLightDensity(10f);
        stagefilter.addFilter(stagelight);
        viewPort.addProcessor(stagefilter); 
        
        DirectionalLight stageDirectLight = new DirectionalLight();
        stageDirectLight.setDirection(rootNode.getChild("stage").getLocalTranslation().negate());
        stageDirectLight.setColor(ColorRGBA.Blue);
        rootNode.addLight(stageDirectLight); 

            
        DirectionalLight metallicLight = new DirectionalLight();
        metallicLight.setDirection(rootNode.getChild("stage").getLocalTranslation().negate());
        metallicLight.setColor(ColorRGBA.Blue);
        vehicle.addLight(metallicLight); 

    } 
    
}

how i call it inside a JFrame Swing:

/**
     * Load the canvas & the renderer with-in inside
     */
    private void loadVehicleSelectorCanvas() {
        
        spaceShips=new String[]{"Mars HoverTank/MarsHoverTankEdited.j3o","Universe Vehicles/starwarsShip.j3o","Universe Vehicles/spaceShip1.j3o"};
        availableVehicles=new JLabel[]{marsRover,starwars,ship1};
        availableVehicles[shipPage].setForeground(Color.YELLOW);
        
           jmeThread = new Thread(() -> {
            vehicleSelectorStage = new VehicleSelectorStage("Models/"+spaceShips[shipPage]);
            
            AppSettings stageConfig = new AppSettings(true);
            stageConfig.setFullscreen(false);
            stageConfig.setGammaCorrection(true);
            stageConfig.setFrameRate(60);
            
            stageConfig.setFrequency(60);
            stageConfig.setVSync(false);
            stageConfig.setDepthBits(24);
            stageConfig.setSamples(6);
            stageConfig.setResolution(stageHolder.getWidth(), stageHolder.getHeight());
            
            vehicleSelectorStage.setDisplayFps(false);
            vehicleSelectorStage.setDisplayStatView(false);
            vehicleSelectorStage.setShowSettings(false);
            vehicleSelectorStage.setSettings(stageConfig);
            vehicleSelectorStage.setPauseOnLostFocus(false);
            
            vehicleSelectorStage.createCanvas();
            vehicleSelectorStage.startCanvas(true);
            
            JmeCanvasContext stageContext = (JmeCanvasContext)    vehicleSelectorStage.getContext();
            stageContext.restart();
            Canvas stageRenderer = stageContext.getCanvas();
            stageRenderer.invalidate();
            stageRenderer.repaint();
            stageRenderer.setSize(stageConfig.getWidth(), stageConfig.getHeight());
            stageHolder.add(stageRenderer);
        });
        jmeThread.start();
    }

& this is how i exit this stage & start my Game after it passing the vehicle selected as an argument after loading data from sql(options config) :

                        vehicleSelectorStage.stop(false);
                        LOAD_DATA();
                        map = new UniverseMap(devmode,activateEffects,"Models/"+spaceShips[shipPage]);
                        startGame();
/*
this starts the game straight forward & shuts off the vehicle selector stage JFrame
 private void startGame(){
         AppSettings config = new AppSettings(true);
            config.setFrameRate(refreshrate); // set to less than or equal screen refresh rate
            config.setVSync(vsync);   // prevents page tearing
            config.setFrequency(60); // set to screen refresh rate
            config.setResolution(r1, r2);
            config.setDepthBits(colorDepth);
            config.setFullscreen(fullscreen);
            config.setGammaCorrection(gammacorrection);
            config.setSamples(antialiasingValue);    // anti-aliasing
            config.setTitle("J-Pluto Mars Map"); // branding: window name
            try {
                // Branding: window icon
                config.setIcons(new BufferedImage[]{ImageIO.read(new File("assets/Interface/rocket-launch-run-icon.png"))});
            } catch (IOException ex) {
                System.err.println(ex.getMessage());
            }
            // branding: load splashscreen from assets
            //                        cfg.setSettingsDialogImage("Interface/MySplashscreen.png");
            map.setShowSettings(false); // or don't display splashscreen
            map.setSettings(config);
            map.start();
           vehicleSelectorStage.enqueue(()->{
              vehicleSelectorStage.stop();
        });
           dispose();
    }
*/

this image of stage renders when its my first time entering the application :

& this image of stage after i started my Game then i exited it & renter the vehicle store to choose vehicle & start once again , seems that the previous game context didnot shut down properly so its assigned back to JmeContext as the stage uses some of the configs that are settled for the game only ! or maybe that because i am using dispose() on a JFrame !

& of course the canvas the empty in the 2nd time because it starts in the context of the Previous SimpleApplication without creating a new context !

its minimized there : image the J-Pluto item in the panel

1 Like

I think this design is not what you should be doing. If you want a menu or a vehicle selector screen for a game, make it in the game rather than a separate swing frame before you start the game.

3 Likes

Indeed. You are basically asking for trouble.

Also, you should use AppStates rather than exiting and reentering the Game.

1 Like

@Pesegato yes its the best approach concerning code logic , but the same problem exists , so the best solution was to transform my gui to ingame gui , so i will give it another try if i succeeded i will post the code otherwise i will use in-game Lemur GUI