retrofit from gjexer
authorKevin Lamonte <kevin.lamonte@gmail.com>
Mon, 18 Feb 2019 15:55:02 +0000 (09:55 -0600)
committerKevin Lamonte <kevin.lamonte@gmail.com>
Mon, 18 Feb 2019 15:55:02 +0000 (09:55 -0600)
16 files changed:
src/jexer/TApplication.java
src/jexer/TButton.java
src/jexer/TImageWindow.java
src/jexer/TImageWindow.properties [new file with mode: 0644]
src/jexer/TKeypress.java
src/jexer/TTerminalWindow.java
src/jexer/TWindow.java
src/jexer/backend/ECMA48Terminal.java
src/jexer/backend/LogicalScreen.java
src/jexer/backend/MultiScreen.java
src/jexer/backend/SwingSessionInfo.java
src/jexer/backend/SwingTerminal.java
src/jexer/backend/TWindowBackend.java
src/jexer/demos/Demo6.java
src/jexer/demos/Demo6.properties [new file with mode: 0644]
src/jexer/tterminal/ECMA48.java

index 20406b1f8e82aa654efa86081c085d5f3883af03..4c317f304d6bb82c6fc39684ce17be4ffc8b53ea 100644 (file)
@@ -1508,6 +1508,18 @@ public class TApplication implements Runnable {
         }
     }
 
+    /**
+     * Check if application is still running.
+     *
+     * @return true if the application is running
+     */
+    public final boolean isRunning() {
+        if (quit == true) {
+            return false;
+        }
+        return true;
+    }
+
     // ------------------------------------------------------------------------
     // Screen refresh loop ----------------------------------------------------
     // ------------------------------------------------------------------------
@@ -1777,6 +1789,10 @@ public class TApplication implements Runnable {
 
         // Flush the screen contents
         if ((images.size() > 0) || getScreen().isDirty()) {
+            if (debugThreads) {
+                System.err.printf("%d %s backend.flushScreen()\n",
+                    System.currentTimeMillis(), Thread.currentThread());
+            }
             backend.flushScreen();
         }
 
@@ -1908,7 +1924,8 @@ public class TApplication implements Runnable {
 
         assert (!window.isActive());
         if (activeWindow != null) {
-            assert (activeWindow.getZ() == 0);
+            // TODO: see if this assertion is really necessary.
+            // assert (activeWindow.getZ() == 0);
 
             activeWindow.setActive(false);
 
@@ -2241,6 +2258,21 @@ public class TApplication implements Runnable {
         return false;
     }
 
+    /**
+     * Check if there is a window with overridden menu flag on top.
+     *
+     * @return true if the active window is overriding the menu
+     */
+    private boolean overrideMenuWindowActive() {
+        if (activeWindow != null) {
+            if (activeWindow.hasOverriddenMenu()) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
     /**
      * Close all open windows.
      */
@@ -2571,6 +2603,7 @@ public class TApplication implements Runnable {
         if ((mouse.getType() == TMouseEvent.Type.MOUSE_DOWN)
             && (mouse.isMouse1())
             && (!modalWindowActive())
+            && (!overrideMenuWindowActive())
             && (mouse.getAbsoluteY() == 0)
         ) {
 
index 9c0e98be0a799765a013f278f1575f5562389a35..83ff2d241f0c1c31dc27b45c65285c346f87b417 100644 (file)
@@ -253,7 +253,6 @@ public class TButton extends TWidget {
                 putCharXY(1 + mnemonic.getShortcutIdx(), 0,
                     mnemonic.getShortcut(), menuMnemonicColor);
             }
-
         }
     }
 
index d38cd253bcd80ec0cead90fea514924c32eb0324..a4a54a91d8c601ebd82c0311ddba7f2056ac9d8c 100644 (file)
@@ -31,6 +31,7 @@ package jexer;
 import java.awt.image.BufferedImage;
 import java.io.File;
 import java.io.IOException;
+import java.util.ResourceBundle;
 import javax.imageio.ImageIO;
 
 import jexer.event.TKeypressEvent;
@@ -43,6 +44,11 @@ import static jexer.TKeypress.*;
  */
 public class TImageWindow extends TScrollableWindow {
 
+    /**
+     * Translated strings.
+     */
+    private static final ResourceBundle i18n = ResourceBundle.getBundle(TImageWindow.class.getName());
+
     // ------------------------------------------------------------------------
     // Constants --------------------------------------------------------------
     // ------------------------------------------------------------------------
@@ -124,6 +130,8 @@ public class TImageWindow extends TScrollableWindow {
         setBottomValue(imageField.getRows() - imageField.getHeight());
         setLeftValue(0);
         setRightValue(imageField.getColumns() - imageField.getWidth());
+
+        statusBar = newStatusBar(i18n.getString("statusBar"));
     }
 
     // ------------------------------------------------------------------------
diff --git a/src/jexer/TImageWindow.properties b/src/jexer/TImageWindow.properties
new file mode 100644 (file)
index 0000000..c9494e3
--- /dev/null
@@ -0,0 +1 @@
+statusBar=Alt-\u2190\u2192: Rotate Left/Right   Alt-\u2191\u2193: Bigger/Smaller   \u2190\u2192\u2191\u2193: Pan
index 58085455eda4897a6ed3c1ee3f045fd11cf7f6c6..9cb493282d82adcfab4c1d14e308b40d9d32cc03 100644 (file)
@@ -487,6 +487,26 @@ public class TKeypress {
             0, 'y', true, false, false);
     public static final TKeypress kbAltZ = new TKeypress(false,
             0, 'z', true, false, false);
+    public static final TKeypress kbAlt0 = new TKeypress(false,
+            0, '0', true, false, false);
+    public static final TKeypress kbAlt1 = new TKeypress(false,
+            0, '1', true, false, false);
+    public static final TKeypress kbAlt2 = new TKeypress(false,
+            0, '2', true, false, false);
+    public static final TKeypress kbAlt3 = new TKeypress(false,
+            0, '3', true, false, false);
+    public static final TKeypress kbAlt4 = new TKeypress(false,
+            0, '4', true, false, false);
+    public static final TKeypress kbAlt5 = new TKeypress(false,
+            0, '5', true, false, false);
+    public static final TKeypress kbAlt6 = new TKeypress(false,
+            0, '6', true, false, false);
+    public static final TKeypress kbAlt7 = new TKeypress(false,
+            0, '7', true, false, false);
+    public static final TKeypress kbAlt8 = new TKeypress(false,
+            0, '8', true, false, false);
+    public static final TKeypress kbAlt9 = new TKeypress(false,
+            0, '9', true, false, false);
     public static final TKeypress kbCtrlA = new TKeypress(false,
             0, 'A', false, true, false);
     public static final TKeypress kbCtrlB = new TKeypress(false,
index b55e7b05bc1137600ea337cb71acc2ba29976b87..a243a43cb2743325f79e7b7e936c554fc7a00758 100644 (file)
@@ -789,7 +789,7 @@ public class TTerminalWindow extends TScrollableWindow
         // thread.
         synchronized (emulator) {
             setHiddenMouse(emulator.hasHiddenMousePointer());
-            
+
             setCursorX(emulator.getCursorX() + 1);
             setCursorY(emulator.getCursorY() + 1
                 + (getHeight() - 2 - emulator.getHeight())
index e50e16fd1c5a9eec4f6b45c4e836a5d31b6bbdec..16945496e1f792d526240f3982aca67fc0f8a6a9 100644 (file)
@@ -91,6 +91,11 @@ public class TWindow extends TWidget {
      */
     public static final int HIDEONCLOSE = 0x40;
 
+    /**
+     * Menus cannot be used when this window is active (default no).
+     */
+    public static final int OVERRIDEMENU        = 0x80;
+
     // ------------------------------------------------------------------------
     // Variables --------------------------------------------------------------
     // ------------------------------------------------------------------------
@@ -1251,6 +1256,20 @@ public class TWindow extends TWidget {
         return false;
     }
 
+    /**
+     * Returns true if this window does not want menus to work while it is
+     * visible.
+     *
+     * @return true if this window does not want menus to work while it is
+     * visible
+     */
+    public final boolean hasOverriddenMenu() {
+        if ((flags & OVERRIDEMENU) != 0) {
+            return true;
+        }
+        return false;
+    }
+
     /**
      * Retrieve the background color.
      *
index 7416819a3b73ed54f3da1518c1afbd68efcb12ce..0cbd4f0502f9ca96a73136b4f1d995efa219a682 100644 (file)
@@ -480,9 +480,9 @@ public class ECMA48Terminal extends LogicalScreen
                     int red, green, blue;
                     if (imageX < image.getWidth() - 1) {
                         int pXpY  = ditheredImage.getRGB(imageX + 1, imageY);
-                        red   = (int) ((pXpY >>> 16) & 0xFF) + (7 * redError);
-                        green = (int) ((pXpY >>>  8) & 0xFF) + (7 * greenError);
-                        blue  = (int) ( pXpY         & 0xFF) + (7 * blueError);
+                        red   = ((pXpY >>> 16) & 0xFF) + (7 * redError);
+                        green = ((pXpY >>>  8) & 0xFF) + (7 * greenError);
+                        blue  = ( pXpY         & 0xFF) + (7 * blueError);
                         red = clamp(red);
                         green = clamp(green);
                         blue = clamp(blue);
@@ -493,9 +493,9 @@ public class ECMA48Terminal extends LogicalScreen
                         if (imageY < image.getHeight() - 1) {
                             int pXpYp = ditheredImage.getRGB(imageX + 1,
                                 imageY + 1);
-                            red   = (int) ((pXpYp >>> 16) & 0xFF) + redError;
-                            green = (int) ((pXpYp >>>  8) & 0xFF) + greenError;
-                            blue  = (int) ( pXpYp         & 0xFF) + blueError;
+                            red   = ((pXpYp >>> 16) & 0xFF) + redError;
+                            green = ((pXpYp >>>  8) & 0xFF) + greenError;
+                            blue  = ( pXpYp         & 0xFF) + blueError;
                             red = clamp(red);
                             green = clamp(green);
                             blue = clamp(blue);
@@ -509,9 +509,9 @@ public class ECMA48Terminal extends LogicalScreen
                         int pXYp  = ditheredImage.getRGB(imageX,
                             imageY + 1);
 
-                        red   = (int) ((pXmYp >>> 16) & 0xFF) + (3 * redError);
-                        green = (int) ((pXmYp >>>  8) & 0xFF) + (3 * greenError);
-                        blue  = (int) ( pXmYp         & 0xFF) + (3 * blueError);
+                        red   = ((pXmYp >>> 16) & 0xFF) + (3 * redError);
+                        green = ((pXmYp >>>  8) & 0xFF) + (3 * greenError);
+                        blue  = ( pXmYp         & 0xFF) + (3 * blueError);
                         red = clamp(red);
                         green = clamp(green);
                         blue = clamp(blue);
@@ -519,9 +519,9 @@ public class ECMA48Terminal extends LogicalScreen
                         pXmYp |= ((green & 0xFF) << 8) | (blue & 0xFF);
                         ditheredImage.setRGB(imageX - 1, imageY + 1, pXmYp);
 
-                        red   = (int) ((pXYp >>> 16) & 0xFF) + (5 * redError);
-                        green = (int) ((pXYp >>>  8) & 0xFF) + (5 * greenError);
-                        blue  = (int) ( pXYp         & 0xFF) + (5 * blueError);
+                        red   = ((pXYp >>> 16) & 0xFF) + (5 * redError);
+                        green = ((pXYp >>>  8) & 0xFF) + (5 * greenError);
+                        blue  = ( pXYp         & 0xFF) + (5 * blueError);
                         red = clamp(red);
                         green = clamp(green);
                         blue = clamp(blue);
@@ -1238,6 +1238,19 @@ public class ECMA48Terminal extends LogicalScreen
         flush();
     }
 
+    /**
+     * Resize the physical screen to match the logical screen dimensions.
+     */
+    @Override
+    public void resizeToScreen() {
+        // Send dtterm/xterm sequences, which will probably not work because
+        // allowWindowOps is defaulted to false.
+        String resizeString = String.format("\033[8;%d;%dt", getHeight(),
+            getWidth());
+        this.output.write(resizeString);
+        this.output.flush();
+    }
+
     // ------------------------------------------------------------------------
     // TerminalReader ---------------------------------------------------------
     // ------------------------------------------------------------------------
@@ -2213,6 +2226,9 @@ public class ECMA48Terminal extends LogicalScreen
         // Check for new window size
         long windowSizeDelay = nowTime - windowSizeTime;
         if (windowSizeDelay > 1000) {
+            int oldTextWidth = getTextWidth();
+            int oldTextHeight = getTextHeight();
+
             sessionInfo.queryWindowSize();
             int newWidth = sessionInfo.getWindowWidth();
             int newHeight = sessionInfo.getWindowHeight();
@@ -2221,14 +2237,24 @@ public class ECMA48Terminal extends LogicalScreen
                 || (newHeight != windowResize.getHeight())
             ) {
 
+                // Request xterm report window dimensions in pixels again.
+                // Between now and then, ensure that the reported text cell
+                // size is the same by setting widthPixels and heightPixels
+                // to match the new dimensions.
+                widthPixels = oldTextWidth * newWidth;
+                heightPixels = oldTextHeight * newHeight;
+
                 if (debugToStderr) {
                     System.err.println("Screen size changed, old size " +
                         windowResize);
                     System.err.println("                     new size " +
                         newWidth + " x " + newHeight);
+                    System.err.println("                   old pixels " +
+                        oldTextWidth + " x " + oldTextHeight);
+                    System.err.println("                   new pixels " +
+                        getTextWidth() + " x " + getTextHeight());
                 }
 
-                // Request xterm report window dimensions in pixels again.
                 this.output.printf("%s", xtermReportWindowPixelDimensions());
                 this.output.flush();
 
@@ -2798,6 +2824,15 @@ public class ECMA48Terminal extends LogicalScreen
                 rgbArray = cells.get(i).getImage().getRGB(0, 0,
                     imageWidth, imageHeight, null, 0, imageWidth);
             }
+
+            /*
+            System.err.printf("calling image.setRGB(): %d %d %d %d %d\n",
+                i * imageWidth, 0, imageWidth, imageHeight,
+                0, imageWidth);
+            System.err.printf("   fullWidth %d fullHeight %d cells.size() %d textWidth %d\n",
+                fullWidth, fullHeight, cells.size(), getTextWidth());
+             */
+
             image.setRGB(i * imageWidth, 0, imageWidth, imageHeight,
                 rgbArray, 0, imageWidth);
             if (imageHeight < fullHeight) {
index b7648313d0d15513584dddf4659f42a841e8f47e..24ba4aff9f12afeec1b8b0609baf4e733d3a0524 100644 (file)
@@ -564,6 +564,14 @@ public class LogicalScreen implements Screen {
      */
     public final void setDimensions(final int width, final int height) {
         reallocate(width, height);
+        resizeToScreen();
+    }
+
+    /**
+     * Resize the physical screen to match the logical screen dimensions.
+     */
+    public void resizeToScreen() {
+        // Subclasses are expected to override this.
     }
 
     /**
@@ -889,6 +897,9 @@ public class LogicalScreen implements Screen {
      * @param y row coordinate.  0 is the top-most row.
      */
     public final void unsetImageRow(final int y) {
+        if ((y < 0) || (y >= height)) {
+            return;
+        }
         for (int x = 0; x < width; x++) {
             if (logical[x][y].isImage()) {
                 physical[x][y].unset();
index 02084100e900523033433ce205b5693fe749f2ad..880ee1888300d12ae936ed2106c927b311cdc5a0 100644 (file)
@@ -386,7 +386,20 @@ public class MultiScreen implements Screen {
      */
     public void setDimensions(final int width, final int height) {
         for (Screen screen: screens) {
-            screen.setDimensions(width, height);
+            // Do not blindly call setDimension() on every screen.  Instead
+            // call it only on those screens that do not already have the
+            // requested dimension.  With this very small check, we have the
+            // ability for ANY screen in the MultiBackend to resize ALL of
+            // the screens.
+            if ((screen.getWidth() != width)
+                || (screen.getHeight() != height)
+            ) {
+                screen.setDimensions(width, height);
+            } else {
+                // The screen that didn't change is probably the one that
+                // prompted the resize.  Force it to repaint.
+                screen.clearPhysical();
+            }
         }
     }
 
index 28668fd346d7012000a6887e54fac459bf1d04ea..2f74d7012130e0eeda1f44c4721396d645493b35 100644 (file)
@@ -179,6 +179,14 @@ public class SwingSessionInfo implements SessionInfo {
         Insets insets = swing.getInsets();
         int width = swing.getWidth() - insets.left - insets.right;
         int height = swing.getHeight() - insets.top - insets.bottom;
+        // In theory, if Java reported pixel-perfect dimensions, the
+        // expressions above would precisely line up with the requested
+        // window size from SwingComponent.setDimensions().  In practice,
+        // there appears to be a small difference.  Add half a text cell in
+        // both directions before the division to hopefully reach the same
+        // result as setDimensions() was supposed to give us.
+        width += (textWidth / 2);
+        height += (textHeight / 2);
         windowWidth = width / textWidth;
         windowHeight = height / textHeight;
 
index 6a3b203dbff2d5f4d8ad59ed992cf62b549ff75c..43c161f4d6091d16c1ed7ec4bc675d6e2a603c5a 100644 (file)
@@ -1096,10 +1096,11 @@ public class SwingTerminal extends LogicalScreen
     }
 
     /**
-     * Resize to font dimensions.
+     * Resize the physical screen to match the logical screen dimensions.
      */
+    @Override
     public void resizeToScreen() {
-        swing.setDimensions(textWidth * (width + 1), textHeight * (height + 1));
+        swing.setDimensions(textWidth * width, textHeight * height);
     }
 
     /**
index 10f95c666da3dc8c545dbf409d8778f683fb04c8..a34ba78bc23f173b1d43b4066539b74825955fc3 100644 (file)
@@ -35,6 +35,7 @@ import jexer.bits.CellAttributes;
 import jexer.event.TInputEvent;
 import jexer.event.TKeypressEvent;
 import jexer.event.TMouseEvent;
+import jexer.event.TResizeEvent;
 import jexer.TApplication;
 import jexer.TWindow;
 
@@ -69,15 +70,50 @@ public class TWindowBackend extends TWindow implements Backend {
     private List<TInputEvent> eventQueue;
 
     /**
-     * The screen to use.
+     * The screen this window is monitoring.
      */
     private Screen otherScreen;
 
+    /**
+     * The application associated with otherScreen.
+     */
+    private TApplication otherApplication;
+
     /**
      * The session information.
      */
     private SessionInfo sessionInfo;
 
+    /**
+     * OtherScreen provides a hook to notify TWindowBackend of screen size
+     * changes.
+     */
+    private class OtherScreen extends LogicalScreen {
+
+        /**
+         * The TWindowBackend to notify.
+         */
+        private TWindowBackend window;
+
+        /**
+         * Public constructor.
+         */
+        public OtherScreen(final TWindowBackend window) {
+            this.window = window;
+        }
+
+        /**
+         * Resize the physical screen to match the logical screen dimensions.
+         */
+        @Override
+        public void resizeToScreen() {
+            window.setWidth(getWidth() + 2);
+            window.setHeight(getHeight() + 2);
+        }
+
+    }
+
+
     // ------------------------------------------------------------------------
     // Constructors -----------------------------------------------------------
     // ------------------------------------------------------------------------
@@ -101,7 +137,7 @@ public class TWindowBackend extends TWindow implements Backend {
         this.listener = listener;
         eventQueue = new LinkedList<TInputEvent>();
         sessionInfo = new TSessionInfo(width, height);
-        otherScreen = new LogicalScreen();
+        otherScreen = new OtherScreen(this);
         otherScreen.setDimensions(width - 2, height - 2);
         drawLock = otherScreen;
         setHiddenMouse(true);
@@ -127,7 +163,7 @@ public class TWindowBackend extends TWindow implements Backend {
         this.listener = listener;
         eventQueue = new LinkedList<TInputEvent>();
         sessionInfo = new TSessionInfo(width, height);
-        otherScreen = new LogicalScreen();
+        otherScreen = new OtherScreen(this);
         otherScreen.setDimensions(width - 2, height - 2);
         drawLock = otherScreen;
         setHiddenMouse(true);
@@ -154,7 +190,7 @@ public class TWindowBackend extends TWindow implements Backend {
         this.listener = listener;
         eventQueue = new LinkedList<TInputEvent>();
         sessionInfo = new TSessionInfo(width, height);
-        otherScreen = new LogicalScreen();
+        otherScreen = new OtherScreen(this);
         otherScreen.setDimensions(width - 2, height - 2);
         drawLock = otherScreen;
         setHiddenMouse(true);
@@ -183,7 +219,7 @@ public class TWindowBackend extends TWindow implements Backend {
         this.listener = listener;
         eventQueue = new LinkedList<TInputEvent>();
         sessionInfo = new TSessionInfo(width, height);
-        otherScreen = new LogicalScreen();
+        otherScreen = new OtherScreen(this);
         otherScreen.setDimensions(width - 2, height - 2);
         drawLock = otherScreen;
         setHiddenMouse(true);
@@ -193,6 +229,35 @@ public class TWindowBackend extends TWindow implements Backend {
     // Event handlers ---------------------------------------------------------
     // ------------------------------------------------------------------------
 
+    /**
+     * Handle window/screen resize events.
+     *
+     * @param event resize event
+     */
+    @Override
+    public void onResize(final TResizeEvent event) {
+        if (event.getType() == TResizeEvent.Type.WIDGET) {
+            int newWidth = event.getWidth() - 2;
+            int newHeight = event.getHeight() - 2;
+            if ((newWidth != otherScreen.getWidth())
+                || (newHeight != otherScreen.getHeight())
+            ) {
+                // I was resized, notify the screen I am watching to match my
+                // new size.
+                synchronized (eventQueue) {
+                    eventQueue.add(new TResizeEvent(TResizeEvent.Type.SCREEN,
+                            newWidth, newHeight));
+                }
+                synchronized (listener) {
+                    listener.notifyAll();
+                }
+            }
+            return;
+        } else {
+            super.onResize(event);
+        }
+    }
+
     /**
      * Returns true if the mouse is currently in the otherScreen window.
      *
@@ -327,6 +392,15 @@ public class TWindowBackend extends TWindow implements Backend {
                 setCursorVisible(false);
             }
         }
+
+        // Check if the other application has died.  If so, unset hidden
+        // mouse.
+        if (otherApplication != null) {
+            if (otherApplication.isRunning() == false) {
+                setHiddenMouse(false);
+            }
+        }
+
     }
 
     /**
@@ -434,4 +508,13 @@ public class TWindowBackend extends TWindow implements Backend {
         return otherScreen;
     }
 
+    /**
+     * Set the other screen's application.
+     *
+     * @param application the application driving the other screen
+     */
+    public void setOtherApplication(final TApplication application) {
+        this.otherApplication = application;
+    }
+
 }
index 236e7a276733410d95d80224be04ccb792adc889..4af7c875a7df56526718bccee7aa27d2cc283703 100644 (file)
@@ -28,6 +28,8 @@
  */
 package jexer.demos;
 
+import java.util.ResourceBundle;
+
 import jexer.TApplication;
 import jexer.backend.*;
 import jexer.demos.DemoApplication;
@@ -37,6 +39,15 @@ import jexer.demos.DemoApplication;
  */
 public class Demo6 {
 
+    /**
+     * Translated strings.
+     */
+    private static final ResourceBundle i18n = ResourceBundle.getBundle(Demo6.class.getName());
+
+    // ------------------------------------------------------------------------
+    // Demo6 ------------------------------------------------------------------
+    // ------------------------------------------------------------------------
+
     /**
      * Main entry point.
      *
@@ -117,8 +128,10 @@ public class Demo6 {
              * eliminate) screen tearing/artifacts.
              */
             TWindowBackend windowBackend = new TWindowBackend(demoApp,
-                monitor, "Monitor Window", width + 2, height + 2);
+                monitor, i18n.getString("monitorWindow"),
+                width + 2, height + 2);
             windowBackend.setDrawLock(multiScreen);
+            windowBackend.setOtherApplication(demoApp);
             multiBackend.addBackend(windowBackend);
 
             /*
diff --git a/src/jexer/demos/Demo6.properties b/src/jexer/demos/Demo6.properties
new file mode 100644 (file)
index 0000000..450829a
--- /dev/null
@@ -0,0 +1 @@
+monitorWindow=Monitor Window
index ce3570b43cdb0b60718171d3b2f797abfcb967e4..00aa05bcf379d524f59b332fffc96b0717e46411 100644 (file)
@@ -1114,7 +1114,7 @@ public class ECMA48 implements Runnable {
     private void resetTabStops() {
         tabStops.clear();
         for (int i = 0; (i * 8) <= rightMargin; i++) {
-            tabStops.add(new Integer(i * 8));
+            tabStops.add(Integer.valueOf(i * 8));
         }
     }
 
@@ -1629,6 +1629,7 @@ public class ECMA48 implements Runnable {
      * @param keypress keypress received from the local user
      * @return string to transmit to the remote side
      */
+    @SuppressWarnings("fallthrough")
     private String keypressToString(final TKeypress keypress) {
 
         if ((fullDuplex == false) && (!keypress.isFnKey())) {
@@ -2367,13 +2368,13 @@ public class ECMA48 implements Runnable {
             switch (currentState.glLockshift) {
 
             case G1_GR:
-                assert (false);
+                throw new IllegalArgumentException("programming bug");
 
             case G2_GR:
-                assert (false);
+                throw new IllegalArgumentException("programming bug");
 
             case G3_GR:
-                assert (false);
+                throw new IllegalArgumentException("programming bug");
 
             case G2_GL:
                 // LS2
@@ -2394,10 +2395,10 @@ public class ECMA48 implements Runnable {
             switch (currentState.grLockshift) {
 
             case G2_GL:
-                assert (false);
+                throw new IllegalArgumentException("programming bug");
 
             case G3_GL:
-                assert (false);
+                throw new IllegalArgumentException("programming bug");
 
             case G1_GR:
                 // LS1R
@@ -2652,7 +2653,7 @@ public class ECMA48 implements Runnable {
      */
     private void param(final byte ch) {
         if (csiParams.size() == 0) {
-            csiParams.add(new Integer(0));
+            csiParams.add(Integer.valueOf(0));
         }
         Integer x = csiParams.get(csiParams.size() - 1);
         if ((ch >= '0') && (ch <= '9')) {
@@ -2662,7 +2663,7 @@ public class ECMA48 implements Runnable {
         }
 
         if (ch == ';') {
-            csiParams.add(new Integer(0));
+            csiParams.add(Integer.valueOf(0));
         }
     }