text-io icon indicating copy to clipboard operation
text-io copied to clipboard

How to restart gracefully

Open mokun opened this issue 6 years ago • 4 comments

How do I restart a SwingTextTerminal gracefully without quitting the application ?

I have a main application running side-by-side with a SwingTextTerminal console in Windows.

e.g. I have a while loop that set up a menu for querying things.

		while (keepRunning) {
			     
		    BiConsumer<TextIO, RunnerData> menu = chooseMenu(textIO);
		    terminal.printf(System.lineSeparator());
	       
		    // Set up the prompt for the menu
		    menu.accept(textIO, null);
	        
		    // if the sim is being saved, enter this while loop
			while (masterClock.isSavingSimulation()) {
		    	delay(500L);
		    }
		}
	}
   /**
     * Presents choices in the console menu
     * 
     * @param textIO
     * @return {@link BiConsumer}
     */
    private static BiConsumer<TextIO, RunnerData> chooseMenu(TextIO textIO) {
        List<BiConsumer<TextIO, RunnerData>> apps = Arrays.asList(
        		chatMenu,
                new AutosaveMenu(),
                new SaveMenu(),
                new TimeRatioMenu(),
                new LogMenu(),
                new ExitMenu()
        );
       
        BiConsumer<TextIO, RunnerData> app = textIO.<BiConsumer<TextIO, RunnerData>>newGenericInputReader(null)
            .withNumberedPossibleValues(apps)
            .read(System.lineSeparator() 
            		+ "-------------------  C O N S O L E   M E N U  -------------------" 
            		+ System.lineSeparator());
        String propsFileName = app.getClass().getSimpleName() + ".properties";
        System.setProperty(AbstractTextTerminal.SYSPROP_PROPERTIES_FILE_LOCATION, propsFileName);
//        profile.term().moveToLineStart();	    
        return app;
    }

Previously, when I call terminal.dispose(null) to end the SwingTextTerminal instance, it would crash.

So I end up always calling system.exit(0) to end everything (the main application and the beryx terminal).

But what if I simply want to quit the existing terminal that has been corrupted and restart it since I want to keep the main application running ?

How do I do that ?

mokun avatar Oct 04 '19 21:10 mokun

How does terminal.dispose(null) crash? Can you post the stack trace?

siordache avatar Oct 05 '19 07:10 siordache

Sorry. not crashing. I meant the JFrame was disposed before I can save up some objects.

So I'm hoping not to dispose the JFrame.

But if I set the keepRunning to false, the beryx console would just halt and no longer work.

So my question is how can I make the console work again without disposing/rebuilding the whole JFrame ?

mokun avatar Oct 05 '19 22:10 mokun

I'm not sure if it helps, but try to replace this line with:

((MarsTerminal)InteractiveTerm.getTextIO().getTextTerminal()).getFrame().setVisible(false);

siordache avatar Oct 10 '19 19:10 siordache

My first objective is to find out how to exit the text-io properly.

In my case in a class called MarsTerminal that extends SwingTextTerminal, I attach a listener to the top-right corner exit button to ask for confirmation if I want to exit as follows :

  private void configureMainMenu() {
        frame = getFrame();
         
	frame.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent event) {
				// Save simulation and UI configuration when window is closed.
				int reply = JOptionPane.showConfirmDialog(null, "Are you sure you want to quit?", "Exit", JOptionPane.YES_NO_OPTION);
		        if (reply == JOptionPane.YES_OPTION) {
		            printf("Exiting the Simulation..." + System.lineSeparator());
		            Simulation sim = Simulation.instance();
		        	sim.endSimulation(); 
		    		sim.getSimExecutor().shutdownNow();
		    		if (sim.getMasterClock() != null)
		    			sim.getMasterClock().exitProgram();
		    		logger.info("Exiting the Simulation.");
		    		InteractiveTerm.setKeepRunning(false);
					System.exit(0);
					frame.setVisible(false);
			    	dispose(null);
		        }
			}
		});

When I choose the Yes button to quit, I have the following stacktrace :

java.lang.RuntimeException: read interrupted
	at org.beryx.textio.swing.SwingTextTerminal.read(SwingTextTerminal.java:378)
	at org.beryx.textio.InputReader.readWithPrompt(InputReader.java:437)
	at org.beryx.textio.InputReader.lambda$read$3(InputReader.java:382)
	at org.beryx.textio.TextTerminal.applyWithPropertiesConfigurator(TextTerminal.java:243)
	at org.beryx.textio.InputReader.executeWithTerminal(InputReader.java:461)
	at org.beryx.textio.InputReader.read(InputReader.java:380)
	at org.beryx.textio.InputReader.read(InputReader.java:368)
	at org.mars.sim.console.SwingHandler$Task.run(SwingHandler.java:188)
	at org.mars.sim.console.SwingHandler.executeOneTask(SwingHandler.java:345)
	at org.mars.sim.console.InteractiveTerm.selectMode(InteractiveTerm.java:165)
	at org.mars.sim.console.InteractiveTerm.startModeSelection(InteractiveTerm.java:136)
	at org.mars_sim.main.MarsProject.handleNewSimulation(MarsProject.java:418)
	at org.mars_sim.main.MarsProject.initializeSimulation(MarsProject.java:191)
	at org.mars_sim.main.MarsProject$SimulationTask.run(MarsProject.java:164)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.InterruptedException
	at java.base/java.lang.Object.wait(Native Method)
	at java.base/java.lang.Object.wait(Object.java:328)
	at org.beryx.textio.swing.SwingTextTerminal.read(SwingTextTerminal.java:355)
	... 18 more

mokun avatar Nov 13 '19 02:11 mokun