X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fjexer%2Fbackend%2FSwingTerminal.java;h=f0ba3552fd52b812a91a06be0f97c9adb96604e7;hb=12b90437b5f22c2ae6e9b9b14c3b62b60f6143e5;hp=4cd6d07624010ae8facb31969042f118d59ce44b;hpb=9d990083da421ec7151d7462afa96305273af483;p=fanfix.git diff --git a/src/jexer/backend/SwingTerminal.java b/src/jexer/backend/SwingTerminal.java index 4cd6d07..f0ba355 100644 --- a/src/jexer/backend/SwingTerminal.java +++ b/src/jexer/backend/SwingTerminal.java @@ -117,7 +117,12 @@ public class SwingTerminal extends LogicalScreen /** * Use an outlined block for the cursor. */ - OUTLINE + OUTLINE, + + /** + * Use a vertical bar for the cursor. + */ + VERTICAL_BAR, } // ------------------------------------------------------------------------ @@ -182,12 +187,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. @@ -403,7 +408,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); } }); @@ -572,8 +577,8 @@ public class SwingTerminal extends LogicalScreen && (swing.getBufferStrategy() != null) ) { do { - clearPhysical(); do { + clearPhysical(); drawToSwing(); } while (swing.getBufferStrategy().contentsRestored()); @@ -648,6 +653,8 @@ public class SwingTerminal extends LogicalScreen cursorStyle = CursorStyle.OUTLINE; } else if (cursorStyleString.equals("block")) { cursorStyle = CursorStyle.BLOCK; + } else if (cursorStyleString.equals("verticalbar")) { + cursorStyle = CursorStyle.VERTICAL_BAR; } // Pull the system property for triple buffering. @@ -658,6 +665,9 @@ public class SwingTerminal extends LogicalScreen } else { SwingComponent.tripleBuffer = false; } + + // Set custom colors + setCustomSystemColors(); } // ------------------------------------------------------------------------ @@ -709,6 +719,62 @@ public class SwingTerminal extends LogicalScreen dosColors = true; } + /** + * Setup Swing colors to match those provided in system properties. + */ + private static void setCustomSystemColors() { + synchronized (SwingTerminal.class) { + MYBLACK = getCustomColor("jexer.Swing.color0", MYBLACK); + MYRED = getCustomColor("jexer.Swing.color1", MYRED); + MYGREEN = getCustomColor("jexer.Swing.color2", MYGREEN); + MYYELLOW = getCustomColor("jexer.Swing.color3", MYYELLOW); + MYBLUE = getCustomColor("jexer.Swing.color4", MYBLUE); + MYMAGENTA = getCustomColor("jexer.Swing.color5", MYMAGENTA); + MYCYAN = getCustomColor("jexer.Swing.color6", MYCYAN); + MYWHITE = getCustomColor("jexer.Swing.color7", MYWHITE); + MYBOLD_BLACK = getCustomColor("jexer.Swing.color8", MYBOLD_BLACK); + MYBOLD_RED = getCustomColor("jexer.Swing.color9", MYBOLD_RED); + MYBOLD_GREEN = getCustomColor("jexer.Swing.color10", MYBOLD_GREEN); + MYBOLD_YELLOW = getCustomColor("jexer.Swing.color11", MYBOLD_YELLOW); + MYBOLD_BLUE = getCustomColor("jexer.Swing.color12", MYBOLD_BLUE); + MYBOLD_MAGENTA = getCustomColor("jexer.Swing.color13", MYBOLD_MAGENTA); + MYBOLD_CYAN = getCustomColor("jexer.Swing.color14", MYBOLD_CYAN); + MYBOLD_WHITE = getCustomColor("jexer.Swing.color15", MYBOLD_WHITE); + } + } + + /** + * Setup one Swing color to match the RGB value provided in system + * properties. + * + * @param key the system property key + * @param defaultColor the default color to return if key is not set, or + * incorrect + * @return a color from the RGB string, or defaultColor + */ + private static Color getCustomColor(final String key, + final Color defaultColor) { + + String rgb = System.getProperty(key); + if (rgb == null) { + return defaultColor; + } + if (rgb.startsWith("#")) { + rgb = rgb.substring(1); + } + int rgbInt = 0; + try { + rgbInt = Integer.parseInt(rgb, 16); + } catch (NumberFormatException e) { + return defaultColor; + } + Color color = new Color((rgbInt & 0xFF0000) >>> 16, + (rgbInt & 0x00FF00) >>> 8, + (rgbInt & 0x0000FF)); + + return color; + } + /** * Get the number of millis to wait before switching the blink from * visible to invisible. @@ -755,13 +821,35 @@ public class SwingTerminal extends LogicalScreen * @param font the new font */ public void setFont(final Font font) { - synchronized (this) { - this.font = font; - getFontDimensions(); - swing.setFont(font); - glyphCacheBlink = new HashMap(); - glyphCache = new HashMap(); - resizeToScreen(); + if (!SwingUtilities.isEventDispatchThread()) { + // Not in the Swing thread: force this inside the Swing thread. + try { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + synchronized (this) { + SwingTerminal.this.font = font; + getFontDimensions(); + swing.setFont(font); + glyphCacheBlink = new HashMap(); + glyphCache = new HashMap(); + resizeToScreen(true); + } + } + }); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (java.lang.reflect.InvocationTargetException e) { + e.printStackTrace(); + } + } else { + synchronized (this) { + SwingTerminal.this.font = font; + getFontDimensions(); + swing.setFont(font); + glyphCacheBlink = new HashMap(); + glyphCache = new HashMap(); + resizeToScreen(true); + } } } @@ -1110,13 +1198,24 @@ public class SwingTerminal extends LogicalScreen gotFontDimensions = true; } + /** + * 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, textHeight * height); - clearPhysical(); + resizeToScreen(false); } /** @@ -1169,7 +1268,7 @@ public class SwingTerminal extends LogicalScreen /* System.err.println("drawGlyph(): " + xPixel + " " + yPixel + " " + cell); - */ + */ BufferedImage image = null; if (cell.isBlink() && !cursorBlinkVisible) { @@ -1201,8 +1300,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()) { @@ -1219,9 +1317,8 @@ public class SwingTerminal extends LogicalScreen || (cell.isBlink() && cursorBlinkVisible) ) { gr2.setColor(attrToForegroundColor(cellColor)); - char [] chars = new char[1]; - chars[0] = cell.getChar(); - gr2.drawChars(chars, 0, 1, gr2x + textAdjustX, + char [] chars = Character.toChars(cell.getChar()); + gr2.drawChars(chars, 0, chars.length, gr2x + textAdjustX, gr2y + textHeight - maxDescent + textAdjustY); if (cell.isUnderline()) { @@ -1234,8 +1331,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 { @@ -1268,18 +1364,34 @@ 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; + case VERTICAL_BAR: + gr.fillRect(xPixel, yPixel, 2, textHeight); break; } } @@ -1327,7 +1439,7 @@ public class SwingTerminal extends LogicalScreen if (bounds != null) { // Only update what is in the bounds xCellMin = textColumn(bounds.x); - xCellMax = textColumn(bounds.x + bounds.width); + xCellMax = textColumn(bounds.x + bounds.width) + 1; if (xCellMax > width) { xCellMax = width; } @@ -1338,7 +1450,7 @@ public class SwingTerminal extends LogicalScreen xCellMin = 0; } yCellMin = textRow(bounds.y); - yCellMax = textRow(bounds.y + bounds.height); + yCellMax = textRow(bounds.y + bounds.height) + 1; if (yCellMax > height) { yCellMax = height; } @@ -1360,7 +1472,7 @@ public class SwingTerminal extends LogicalScreen /* System.err.printf("bounds %s X %d %d Y %d %d\n", bounds, xCellMin, xCellMax, yCellMin, yCellMax); - */ + */ for (int y = yCellMin; y < yCellMax; y++) { for (int x = xCellMin; x < xCellMax; x++) { @@ -1807,6 +1919,7 @@ public class SwingTerminal extends LogicalScreen break; default: if (!alt && ctrl && !shift) { + // Control character, replace ch with 'A', 'B', etc. ch = KeyEvent.getKeyText(key.getKeyCode()).charAt(0); } // Not a special key, put it together @@ -2065,7 +2178,7 @@ public class SwingTerminal extends LogicalScreen * @param mouse mouse event received */ public void mouseEntered(final MouseEvent mouse) { - // Ignore + swing.requestFocusInWindow(); } /**