#35 fix demo
[fanfix.git] / src / jexer / backend / SwingTerminal.java
index 6a3b203dbff2d5f4d8ad59ed992cf62b549ff75c..134eceda63772cec5c776b9d0dedf323f4559bf3 100644 (file)
@@ -51,8 +51,8 @@ import java.awt.event.WindowListener;
 import java.awt.geom.Rectangle2D;
 import java.awt.image.BufferedImage;
 import java.io.InputStream;
+import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import javax.swing.JComponent;
@@ -98,7 +98,7 @@ public class SwingTerminal extends LogicalScreen
     /**
      * The terminus font resource filename.
      */
-    private static final String FONTFILE = "terminus-ttf-4.39/TerminusTTF-Bold-4.39.ttf";
+    public static final String FONTFILE = "terminus-ttf-4.39/TerminusTTF-Bold-4.39.ttf";
 
     /**
      * Cursor style to draw.
@@ -182,12 +182,12 @@ public class SwingTerminal extends LogicalScreen
     /**
      * Width of a character cell in pixels.
      */
-    private int textWidth = 1;
+    private int textWidth = 16;
 
     /**
      * Height of a character cell in pixels.
      */
-    private int textHeight = 1;
+    private int textHeight = 20;
 
     /**
      * Width of a character cell in pixels, as reported by font.
@@ -301,6 +301,13 @@ public class SwingTerminal extends LogicalScreen
     // Constructors -----------------------------------------------------------
     // ------------------------------------------------------------------------
 
+    /**
+     * Static constructor.
+     */
+    static {
+        setDOSColors();
+    }
+
     /**
      * Public constructor creates a new JFrame to render to.
      *
@@ -316,7 +323,6 @@ public class SwingTerminal extends LogicalScreen
 
         this.fontSize = fontSize;
 
-        setDOSColors();
         reloadOptions();
 
         try {
@@ -397,7 +403,7 @@ public class SwingTerminal extends LogicalScreen
                     SwingTerminal.this.setDimensions(sessionInfo.
                         getWindowWidth(), sessionInfo.getWindowHeight());
 
-                    SwingTerminal.this.resizeToScreen();
+                    SwingTerminal.this.resizeToScreen(true);
                     SwingTerminal.this.swing.setVisible(true);
                 }
             });
@@ -411,7 +417,7 @@ public class SwingTerminal extends LogicalScreen
         mouse1           = false;
         mouse2           = false;
         mouse3           = false;
-        eventQueue       = new LinkedList<TInputEvent>();
+        eventQueue       = new ArrayList<TInputEvent>();
 
         // Add listeners to Swing.
         swing.addKeyListener(this);
@@ -438,7 +444,6 @@ public class SwingTerminal extends LogicalScreen
 
         this.fontSize = fontSize;
 
-        setDOSColors();
         reloadOptions();
 
         try {
@@ -525,7 +530,7 @@ public class SwingTerminal extends LogicalScreen
         mouse1           = false;
         mouse2           = false;
         mouse3           = false;
-        eventQueue       = new LinkedList<TInputEvent>();
+        eventQueue       = new ArrayList<TInputEvent>();
 
         // Add listeners to Swing.
         swing.addKeyListener(this);
@@ -568,6 +573,7 @@ public class SwingTerminal extends LogicalScreen
         ) {
             do {
                 do {
+                    clearPhysical();
                     drawToSwing();
                 } while (swing.getBufferStrategy().contentsRestored());
 
@@ -714,6 +720,15 @@ public class SwingTerminal extends LogicalScreen
         return blinkMillis;
     }
 
+    /**
+     * Get the current status of the blink flag.
+     *
+     * @return true if the cursor and blinking text should be visible
+     */
+    public boolean getCursorBlinkVisible() {
+        return cursorBlinkVisible;
+    }
+
     /**
      * Get the font size in points.
      *
@@ -746,7 +761,7 @@ public class SwingTerminal extends LogicalScreen
             swing.setFont(font);
             glyphCacheBlink = new HashMap<Cell, BufferedImage>();
             glyphCache = new HashMap<Cell, BufferedImage>();
-            resizeToScreen();
+            resizeToScreen(true);
         }
     }
 
@@ -881,7 +896,7 @@ public class SwingTerminal extends LogicalScreen
      * @param attr the text attributes
      * @return the Swing Color
      */
-    private Color attrToForegroundColor(final CellAttributes attr) {
+    public static Color attrToForegroundColor(final CellAttributes attr) {
         int rgb = attr.getForeColorRGB();
         if (rgb >= 0) {
             int red     = (rgb >> 16) & 0xFF;
@@ -938,7 +953,7 @@ public class SwingTerminal extends LogicalScreen
      * @param attr the text attributes
      * @return the Swing Color
      */
-    private Color attrToBackgroundColor(final CellAttributes attr) {
+    public static Color attrToBackgroundColor(final CellAttributes attr) {
         int rgb = attr.getBackColorRGB();
         if (rgb >= 0) {
             int red     = (rgb >> 16) & 0xFF;
@@ -1096,10 +1111,23 @@ public class SwingTerminal extends LogicalScreen
     }
 
     /**
-     * Resize to font dimensions.
+     * Resize the physical screen to match the logical screen dimensions.
+     *
+     * @param resizeComponent if true, resize the Swing component
+     */
+    private void resizeToScreen(final boolean resizeComponent) {
+        if (resizeComponent) {
+            swing.setDimensions(textWidth * width, textHeight * height);
+        }
+        clearPhysical();
+    }
+
+    /**
+     * Resize the physical screen to match the logical screen dimensions.
      */
+    @Override
     public void resizeToScreen() {
-        swing.setDimensions(textWidth * (width + 1), textHeight * (height + 1));
+        resizeToScreen(false);
     }
 
     /**
@@ -1184,8 +1212,7 @@ public class SwingTerminal extends LogicalScreen
             gr2 = (Graphics2D) gr;
         }
 
-        Cell cellColor = new Cell();
-        cellColor.setTo(cell);
+        Cell cellColor = new Cell(cell);
 
         // Check for reverse
         if (cell.isReverse()) {
@@ -1217,8 +1244,7 @@ public class SwingTerminal extends LogicalScreen
 
             // We need a new key that will not be mutated by
             // invertCell().
-            Cell key = new Cell();
-            key.setTo(cell);
+            Cell key = new Cell(cell);
             if (cell.isBlink() && !cursorBlinkVisible) {
                 glyphCacheBlink.put(key, image);
             } else {
@@ -1251,18 +1277,31 @@ public class SwingTerminal extends LogicalScreen
             int xPixel = cursorX * textWidth + left;
             int yPixel = cursorY * textHeight + top;
             Cell lCell = logical[cursorX][cursorY];
+            int cursorWidth = textWidth;
+            switch (lCell.getWidth()) {
+            case SINGLE:
+                // NOP
+                break;
+            case LEFT:
+                cursorWidth *= 2;
+                break;
+            case RIGHT:
+                cursorWidth *= 2;
+                xPixel -= textWidth;
+                break;
+            }
             gr.setColor(attrToForegroundColor(lCell));
             switch (cursorStyle) {
             default:
                 // Fall through...
             case UNDERLINE:
-                gr.fillRect(xPixel, yPixel + textHeight - 2, textWidth, 2);
+                gr.fillRect(xPixel, yPixel + textHeight - 2, cursorWidth, 2);
                 break;
             case BLOCK:
-                gr.fillRect(xPixel, yPixel, textWidth, textHeight);
+                gr.fillRect(xPixel, yPixel, cursorWidth, textHeight);
                 break;
             case OUTLINE:
-                gr.drawRect(xPixel, yPixel, textWidth - 1, textHeight - 1);
+                gr.drawRect(xPixel, yPixel, cursorWidth - 1, textHeight - 1);
                 break;
             }
         }
@@ -1840,9 +1879,9 @@ public class SwingTerminal extends LogicalScreen
      * @param event window event received
      */
     public void windowClosing(final WindowEvent event) {
-        // Drop a cmAbort and walk away
+        // Drop a cmBackendDisconnect and walk away
         synchronized (eventQueue) {
-            eventQueue.add(new TCommandEvent(cmAbort));
+            eventQueue.add(new TCommandEvent(cmBackendDisconnect));
             resetBlinkTimer();
         }
         if (listener != null) {
@@ -1932,6 +1971,12 @@ public class SwingTerminal extends LogicalScreen
             return;
         }
 
+        if (sessionInfo == null) {
+            // This is the initial component resize in construction, bail
+            // out.
+            return;
+        }
+
         // Drop a new TResizeEvent into the queue
         sessionInfo.queryWindowSize();
         synchronized (eventQueue) {