gt:     protected void cancelSendAfterEvent() {
context: /*
   * GRBL Control layer, coordinates all aspects of control.
   */
  /*
      Copywrite 2013 Will Winder
  
      This file is part of Universal Gcode Sender (UGS).
  
      UGS is free software: you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published by
      the Free Software Foundation, either version 3 of the License, or
      (at your option) any later version.
  
      UGS is distributed in the hope that it will be useful,
      but WITHOUT ANY WARRANTY; without even the implied warranty of
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      GNU General Public License for more details.
  
      You should have received a copy of the GNU General Public License
      along with UGS.  If not, see <http://www.gnu.org/licenses/>.
   */
  package com.willwinder.universalgcodesender;
  
  import com.willwinder.universalgcodesender.gcode.GcodeCommandCreator;
  import com.willwinder.universalgcodesender.i18n.Localization;
  import com.willwinder.universalgcodesender.listeners.GrblSettingsListener;
  import com.willwinder.universalgcodesender.types.GcodeCommand;
  import java.awt.event.ActionEvent;
  import java.awt.event.ActionListener;
  import java.io.*;
  import java.util.*;
  import java.util.logging.Level;
  import java.util.logging.Logger;
  import javax.swing.Timer;
  import javax.vecmath.Point3d;
  
  /**
   *
   * @author wwinder
   */
  public class GrblController extends AbstractController {
      // Grbl state
      private double grblVersion = 0.0;        // The 0.8 in 'Grbl 0.8c'
      private String grblVersionLetter = null; // The c in 'Grbl 0.8c'
      private Boolean isReady = false;         // Not ready until version is received.
      private GrblSettingsListener settings;
  
      // Grbl status members.
      private GrblUtils.Capabilities positionMode = null;
      private Boolean realTimeCapable = false;
      private String grblState;
      private Point3d machineLocation;
      private Point3d workLocation;
      private double maxZLocation;
      
      // Polling state
      private int outstandingPolls = 0;
      private Timer positionPollTimer = null;  
      
      protected GrblController(AbstractCommunicator comm) {
          super(comm);
          
          this.commandCreator = new GcodeCommandCreator();
          this.positionPollTimer = createPositionPollTimer();
          this.maxZLocation = -1;
          this.settings = new GrblSettingsListener(this);
      }
      
      public GrblController() {
          this(new GrblCommunicator()); //f4grx: connection created at opencomm() time
      }
  
      @Override
      public long getJobLengthEstimate(Collection<String> jobLines) {
          // Pending update to support cross-platform and multiple GRBL versions.
          return 0;
          //GrblSimulator simulator = new GrblSimulator(settings.getSettings());
          //return simulator.estimateRunLength(jobLines);
      }
  
      /***********************
       * API Implementation.
       ***********************
       */
      
      @Override
      protected void rawResponseHandler(String response) {
          /*
          // Check if was 'ok' or 'error'.
          if (GcodeCommand.isOkErrorResponse(response)) {
              
              // All Ok/Error messages go to console
              this.sendMessageToConsoleListener(response + "\n");
  
              // Pop the front of the active list.
              GcodeCommand command = this.activeCommandList.pop();
  
              command.setResponse(response);
  
              ListenerUtils.dispatchListenerEvents(ListenerUtils.COMMAND_COMPLETE, 
                      this.commandCompleteListeners, command);
  
              if (this.sendPaused == false) {
                  this.streamCommands();
              }
          }
          */
          
          if (GcodeCommand.isOkErrorResponse(response)) {            
              try {
                  this.commandComplete(response);
              } catch (Exception e) {
                  this.errorMessageForConsole(Localization.getString("controller.error.response")
                          + " <" + response + ">: " + e.getMessage());
              }
              
              this.messageForConsole(response + "\n");
          }
          
          else if (GrblUtils.isGrblVersionString(response)) {
              // Version string goes to console
              this.messageForConsole(response + "\n");
              
              this.grblVersion = GrblUtils.getVersionDouble(response);
              this.grblVersionLetter = GrblUtils.getVersionLetter(response);
              this.isReady = true;
              
              this.realTimeCapable = GrblUtils.isRealTimeCapable(this.grblVersion);
              
              this.positionMode = GrblUtils.getGrblStatusCapabilities(this.grblVersion, this.grblVersionLetter);
              this.beginPollingPosition();
              
              Logger.getLogger(GrblController.class.getName()).log(Level.CONFIG, 
                      "{0} = {1}{2}", new Object[]{Localization.getString("controller.log.version"), this.grblVersion, this.grblVersionLetter});
              Logger.getLogger(GrblController.class.getName()).log(Level.CONFIG, 
                      "{0} = {1}", new Object[]{Localization.getString("controller.log.realtime"), this.realTimeCapable});
          }
          
          else if (GrblUtils.isGrblStatusString(response)) {
              // Only 1 poll is sent at a time so don't decrement, reset to zero.
              this.outstandingPolls = 0;
  
              // Status string goes to verbose console
              verboseMessageForConsole(response + "\n");
              
              this.handlePositionString(response);
          }
          
          else {
              // Display any unhandled messages
              this.messageForConsole(response + "\n");
          }
      }
      @Override
      protected void pauseStreamingEvent() throws IOException {
          if (this.realTimeCapable) {
              this.comm.sendByteImmediately(GrblUtils.GRBL_PAUSE_COMMAND);
          }
      }
      
      @Override
      protected void resumeStreamingEvent() throws IOException {
          if (this.realTimeCapable) {
              this.comm.sendByteImmediately(GrblUtils.GRBL_RESUME_COMMAND);
          }
      }
      
      @Override
      protected void closeCommBeforeEvent() {
          this.stopPollingPosition();
      }
      
      @Override
      protected void closeCommAfterEvent() {
          this.grblVersion = 0.0;
          this.grblVersionLetter = null;
      }
      
      @Override
      protected void openCommAfterEvent() throws IOException {
          this.comm.sendByteImmediately(GrblUtils.GRBL_RESET_COMMAND);
      }
  
      @Override
      protected void isReadyToStreamFileEvent() throws Exception {
          if (this.isReady == false) {
              throw new Exception(Localization.getString("controller.exception.booting"));
          }
      }
      
      @Override
      protected void cancelSendBeforeEvent() {
          // Check if we can get fancy with a soft reset.
          if (this.realTimeCapable == true) {
              // This doesn't seem to work.
              /*
              try {
                  if (!this.paused) {
                      this.pauseStreaming();
                  }
                  this.issueSoftReset();
                  this.awaitingResponseQueue.clear();
              } catch (IOException e) {
                  // Oh well, was worth a shot.
                  System.out.println("Exception while trying to issue a soft reset: " + e.getMessage());
              }
              */
          }
      }
      
      @Override
  