Fix Swing triple-buffering
[nikiroo-utils.git] / src / jexer / TApplication.java
index f4cf2d5cb7a54a800c421e21b854b8552247725a..e9a7a44c62ddb4c9cd53b17a3ca7eee35e8985b8 100644 (file)
@@ -31,6 +31,8 @@ package jexer;
 import java.io.InputStream;
 import java.io.IOException;
 import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.Reader;
 import java.io.UnsupportedEncodingException;
 import java.util.Collections;
 import java.util.Date;
@@ -544,6 +546,40 @@ public class TApplication implements Runnable {
         TApplicationImpl();
     }
 
+    /**
+     * Public constructor.  The backend type will be BackendType.ECMA48.
+     *
+     * @param input the InputStream underlying 'reader'.  Its available()
+     * method is used to determine if reader.read() will block or not.
+     * @param reader a Reader connected to the remote user.
+     * @param writer a PrintWriter connected to the remote user.
+     * @param setRawMode if true, set System.in into raw mode with stty.
+     * This should in general not be used.  It is here solely for Demo3,
+     * which uses System.in.
+     * @throws IllegalArgumentException if input, reader, or writer are null.
+     */
+    public TApplication(final InputStream input, final Reader reader,
+        final PrintWriter writer, final boolean setRawMode) {
+
+        backend = new ECMA48Backend(this, input, reader, writer, setRawMode);
+        TApplicationImpl();
+    }
+
+    /**
+     * Public constructor.  The backend type will be BackendType.ECMA48.
+     *
+     * @param input the InputStream underlying 'reader'.  Its available()
+     * method is used to determine if reader.read() will block or not.
+     * @param reader a Reader connected to the remote user.
+     * @param writer a PrintWriter connected to the remote user.
+     * @throws IllegalArgumentException if input, reader, or writer are null.
+     */
+    public TApplication(final InputStream input, final Reader reader,
+        final PrintWriter writer) {
+
+        this(input, reader, writer, false);
+    }
+
     /**
      * Public constructor.  This hook enables use with new non-Jexer
      * backends.
@@ -582,12 +618,13 @@ public class TApplication implements Runnable {
      * @param y row position
      */
     private void invertCell(final int x, final int y) {
-        synchronized (getScreen()) {
-            CellAttributes attr = getScreen().getAttrXY(x, y);
-            attr.setForeColor(attr.getForeColor().invert());
-            attr.setBackColor(attr.getBackColor().invert());
-            getScreen().putAttrXY(x, y, attr, false);
+        if (debugThreads) {
+            System.err.printf("invertCell() %d %d\n", x, y);
         }
+        CellAttributes attr = getScreen().getAttrXY(x, y);
+        attr.setForeColor(attr.getForeColor().invert());
+        attr.setBackColor(attr.getBackColor().invert());
+        getScreen().putAttrXY(x, y, attr, false);
     }
 
     /**
@@ -599,18 +636,23 @@ public class TApplication implements Runnable {
         }
 
         if (!repaint) {
-            if ((oldMouseX != mouseX) || (oldMouseY != mouseY)) {
-                // The only thing that has happened is the mouse moved.
-                // Clear the old position and draw the new position.
-                invertCell(oldMouseX, oldMouseY);
-                invertCell(mouseX, mouseY);
-                oldMouseX = mouseX;
-                oldMouseY = mouseY;
+            if (debugThreads) {
+                System.err.printf("drawAll() !repaint\n");
             }
-            if (getScreen().isDirty()) {
-                backend.flushScreen();
+            synchronized (getScreen()) {
+                if ((oldMouseX != mouseX) || (oldMouseY != mouseY)) {
+                    // The only thing that has happened is the mouse moved.
+                    // Clear the old position and draw the new position.
+                    invertCell(oldMouseX, oldMouseY);
+                    invertCell(mouseX, mouseY);
+                    oldMouseX = mouseX;
+                    oldMouseY = mouseY;
+                }
+                if (getScreen().isDirty()) {
+                    backend.flushScreen();
+                }
+                return;
             }
-            return;
         }
 
         if (debugThreads) {
@@ -676,6 +718,8 @@ public class TApplication implements Runnable {
 
         // Draw the mouse pointer
         invertCell(mouseX, mouseY);
+        oldMouseX = mouseX;
+        oldMouseY = mouseY;
 
         // Place the cursor if it is visible
         TWidget activeWidget = null;
@@ -694,7 +738,9 @@ public class TApplication implements Runnable {
         }
 
         // Flush the screen contents
-        backend.flushScreen();
+        if (getScreen().isDirty()) {
+            backend.flushScreen();
+        }
 
         repaint = false;
     }