@Override
 public void mousePressed(MouseEvent me) {
   x = me.getX();
   y = me.getY();
   altDown = me.isAltDown() || me.isAltGraphDown();
   undo = (me.getButton() == MouseEvent.BUTTON3) || altDown;
   ctrlDown = me.isControlDown() || me.isMetaDown();
   shiftDown = me.isShiftDown();
   first = true;
   if (!oneShot) {
     if (timer == null) {
       timer =
           new Timer(
               delay,
               e -> {
                 Point worldCoords = view.viewToWorld((int) x, (int) y);
                 tick(worldCoords.x, worldCoords.y, undo, first, 1.0f);
                 view.updateStatusBar(worldCoords.x, worldCoords.y);
                 first = false;
               });
       timer.setInitialDelay(0);
       timer.start();
       //                start = System.currentTimeMillis();
     }
   } else {
     Point worldCoords = view.viewToWorld((int) x, (int) y);
     tick(worldCoords.x, worldCoords.y, undo, true, 1.0f);
     view.updateStatusBar(worldCoords.x, worldCoords.y);
     Dimension dimension = getDimension();
     if (dimension != null) {
       dimension.armSavePoint();
     }
     logOperation(undo ? statisticsKeyUndo : statisticsKey);
   }
 }
 @Override
 public void mouseReleased(MouseEvent me) {
   if (!oneShot) {
     if (timer != null) {
       logOperation(undo ? statisticsKeyUndo : statisticsKey);
       timer.stop();
       timer = null;
     }
     finished();
     Dimension dimension = getDimension();
     if (dimension != null) {
       dimension.armSavePoint();
     }
   }
 }
 @Override
 public void penButtonEvent(PButtonEvent pbe) {
   PKind.Type penKindType = pbe.pen.getKind().getType();
   final boolean stylus = penKindType == PKind.Type.STYLUS;
   final boolean eraser = penKindType == PKind.Type.ERASER;
   if ((!stylus) && (!eraser) && (penKindType != PKind.Type.CURSOR)) {
     // We don't want events from keyboards, etc.
     return;
   }
   final PButton.Type buttonType = pbe.button.getType();
   switch (buttonType) {
     case ALT:
       altDown = pbe.button.value;
       break;
     case CONTROL:
       ctrlDown = pbe.button.value;
       break;
     case SHIFT:
       shiftDown = pbe.button.value;
       break;
     case LEFT:
     case RIGHT:
       if (pbe.button.value) {
         // Button pressed
         first = true;
         undo = eraser || (buttonType == PButton.Type.RIGHT) || altDown;
         if (!oneShot) {
           if (timer == null) {
             timer =
                 new Timer(
                     delay,
                     e -> {
                       Point worldCoords = view.viewToWorld((int) x, (int) y);
                       tick(
                           worldCoords.x,
                           worldCoords.y,
                           undo,
                           first,
                           (stylus || eraser) ? dynamicLevel : 1.0f);
                       view.updateStatusBar(worldCoords.x, worldCoords.y);
                       first = false;
                     });
             timer.setInitialDelay(0);
             timer.start();
             //                    start = System.currentTimeMillis();
           }
         } else {
           Point worldCoords = view.viewToWorld((int) x, (int) y);
           SwingUtilities.invokeLater(
               () -> {
                 tick(worldCoords.x, worldCoords.y, undo, true, 1.0f);
                 view.updateStatusBar(worldCoords.x, worldCoords.y);
                 Dimension dimension = getDimension();
                 if (dimension != null) {
                   dimension.armSavePoint();
                 }
                 logOperation(undo ? statisticsKeyUndo : statisticsKey);
               });
         }
       } else {
         // Button released
         if (!oneShot) {
           SwingUtilities.invokeLater(
               () -> {
                 if (timer != null) {
                   logOperation(undo ? statisticsKeyUndo : statisticsKey);
                   timer.stop();
                   timer = null;
                 }
                 finished();
                 Dimension dimension = getDimension();
                 if (dimension != null) {
                   dimension.armSavePoint();
                 }
               });
         }
       }
       break;
   }
 }