From d9869d428fe4284e3d17de76761acbb7ee292023 Mon Sep 17 00:00:00 2001 From: zsalch Date: Fri, 5 Oct 2018 23:49:17 +0800 Subject: [PATCH 1/3] The theme allow to use external image, set font & color by config --- .../featurecat/lizzie/gui/BoardRenderer.java | 41 +++-- .../featurecat/lizzie/gui/LizzieFrame.java | 11 +- .../java/featurecat/lizzie/theme/Theme.java | 147 ++++++++++++++++++ 3 files changed, 174 insertions(+), 25 deletions(-) create mode 100644 src/main/java/featurecat/lizzie/theme/Theme.java diff --git a/src/main/java/featurecat/lizzie/gui/BoardRenderer.java b/src/main/java/featurecat/lizzie/gui/BoardRenderer.java index 53b3895f7..1e246d915 100644 --- a/src/main/java/featurecat/lizzie/gui/BoardRenderer.java +++ b/src/main/java/featurecat/lizzie/gui/BoardRenderer.java @@ -16,10 +16,10 @@ import java.awt.image.BufferedImage; import java.awt.image.ImageObserver; import java.util.HashMap; -import java.io.IOException; import java.util.List; import java.util.Map; -import javax.imageio.ImageIO; + +import featurecat.lizzie.theme.Theme; public class BoardRenderer { private static final double MARGIN = 0.03; // percentage of the boardLength to offset before drawing black lines @@ -53,6 +53,7 @@ public class BoardRenderer { private boolean lastInScoreMode = false; + public Theme theme; public List variation; // special values of displayedBranchLength @@ -68,6 +69,8 @@ public class BoardRenderer { public BoardRenderer(boolean isMainBoard) { uiConfig = Lizzie.config.config.getJSONObject("ui"); + // The theme to allow use external image and config file + theme = new Theme(uiConfig.optString("theme")); uiPersist = Lizzie.config.persisted.getJSONObject("ui-persist"); try { maxAlpha = uiPersist.getInt("max-alpha"); @@ -453,7 +456,12 @@ private void drawMoveNumbers(Graphics2D g) { // set color to the opposite color of whatever is on the board g.setColor(Lizzie.board.getStones()[Board.getIndex(lastMove[0], lastMove[1])].isWhite() ? Color.BLACK : Color.WHITE); - drawCircle(g, stoneX, stoneY, lastMoveMarkerRadius); + if (theme.solidStoneIndicator()) { + // Use a solid circle instead of + fillCircle(g, stoneX, stoneY, (int)(lastMoveMarkerRadius * 0.65)); + } else { + drawCircle(g, stoneX, stoneY, lastMoveMarkerRadius); + } } else if (lastMove == null && Lizzie.board.getData().moveNumber != 0 && !Lizzie.board.inScoreMode()) { g.setColor(Lizzie.board.getData().blackToPlay ? new Color(255, 255, 255, 150) : new Color(0, 0, 0, 150)); g.fillOval(x + boardLength / 2 - 4 * stoneRadius, y + boardLength / 2 - 4 * stoneRadius, stoneRadius * 8, stoneRadius * 8); @@ -643,14 +651,10 @@ private void drawNextMoves(Graphics2D g) { private void drawWoodenBoard(Graphics2D g) { if (uiConfig.getBoolean("fancy-board")) { + // fancy version if (cachedBoardImage == null) { - try { - cachedBoardImage = ImageIO.read(getClass().getResourceAsStream("/assets/board.png")); - } catch (IOException e) { - e.printStackTrace(); - } + cachedBoardImage = theme.getBoard(); } - int shadowRadius = (int) (boardLength * MARGIN / 6); drawTextureImage(g, cachedBoardImage, x - 2 * shadowRadius, y - 2 * shadowRadius, boardLength + 4 * shadowRadius, boardLength + 4 * shadowRadius); @@ -661,6 +665,7 @@ private void drawWoodenBoard(Graphics2D g) { g.setStroke(new BasicStroke(1)); } else { + // simple version JSONArray boardColor = uiConfig.getJSONArray("board-color"); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); g.setColor(new Color(boardColor.getInt(0), boardColor.getInt(1), boardColor.getInt(2))); @@ -780,18 +785,12 @@ private void drawStone(Graphics2D g, Graphics2D gShadow, int centerX, int center /** * Get scaled stone, if cached then return cached */ - private BufferedImage getScaleStone(boolean isBlack, int size) { + public BufferedImage getScaleStone(boolean isBlack, int size) { BufferedImage stone = isBlack ? cachedBlackStoneImage : cachedWhiteStoneImage; - if (stone == null) { + if (stone == null || stone.getWidth() != size || stone.getHeight() != size) { stone = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB); - String imgPath = isBlack ? "/assets/black0.png" : "/assets/white0.png"; - Image img = null; - try { - img = ImageIO.read(getClass().getResourceAsStream(imgPath)); - } catch (IOException e) { - e.printStackTrace(); - } Graphics2D g2 = stone.createGraphics(); + Image img = isBlack ? theme.getBlackStone(new int[]{x, y}) : theme.getWhiteStone(new int[]{x, y}); g2.drawImage(img.getScaledInstance(size, size, java.awt.Image.SCALE_SMOOTH), 0, 0, null); g2.dispose(); if (isBlack) { @@ -805,11 +804,7 @@ private BufferedImage getScaleStone(boolean isBlack, int size) { public BufferedImage getWallpaper() { if (cachedWallpaperImage == null) { - try { - cachedWallpaperImage = ImageIO.read(getClass().getResourceAsStream("/assets/background.jpg")); - } catch (IOException e) { - e.printStackTrace(); - } + cachedWallpaperImage = theme.getBackground(); } return cachedWallpaperImage; } diff --git a/src/main/java/featurecat/lizzie/gui/LizzieFrame.java b/src/main/java/featurecat/lizzie/gui/LizzieFrame.java index 526b2bfeb..fa0ee5ad0 100644 --- a/src/main/java/featurecat/lizzie/gui/LizzieFrame.java +++ b/src/main/java/featurecat/lizzie/gui/LizzieFrame.java @@ -130,6 +130,13 @@ public LizzieFrame() { JSONArray windowSize = Lizzie.config.uiConfig.getJSONArray("window-size"); setSize(windowSize.getInt(0), windowSize.getInt(1)); // use config file window size + // Allow change font in the config + if (boardRenderer.theme.getFontName() != null) { + systemDefaultFontName = boardRenderer.theme.getFontName(); + OpenSansRegularBase = new Font(systemDefaultFontName, Font.PLAIN, 12); + OpenSansSemiboldBase = new Font(systemDefaultFontName, Font.BOLD, 12); + } + if (Lizzie.config.startMaximized) { setExtendedState(Frame.MAXIMIZED_BOTH); // start maximized } @@ -138,8 +145,8 @@ public LizzieFrame() { commentPane = new JTextPane(); commentPane.setEditable(false); commentPane.setMargin(new Insets(5, 5, 5, 5)); - commentPane.setBackground(new Color(0, 0, 0, 200)); - commentPane.setForeground(Color.WHITE); + commentPane.setBackground(boardRenderer.theme.commentBackgroundColor()); + commentPane.setForeground(boardRenderer.theme.commentFontColor()); scrollPane = new JScrollPane(); scrollPane.setViewportView(commentPane); scrollPane.setBorder(null); diff --git a/src/main/java/featurecat/lizzie/theme/Theme.java b/src/main/java/featurecat/lizzie/theme/Theme.java new file mode 100644 index 000000000..714becc1e --- /dev/null +++ b/src/main/java/featurecat/lizzie/theme/Theme.java @@ -0,0 +1,147 @@ +package featurecat.lizzie.theme; + +import java.awt.Color; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import javax.imageio.ImageIO; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.json.JSONTokener; + +/** + * Theme + * Allow to load the external image & theme config + */ +public class Theme { + BufferedImage blackStoneCached = null; + BufferedImage whiteStoneCached = null; + BufferedImage boardCached = null; + BufferedImage backgroundCached = null; + + private String themeName = null; + private String configFile = "theme.txt"; + private String pathPrefix = "theme"; + private String path = null; + private JSONObject config = new JSONObject(); + + public Theme(String themeName) { + this.themeName = themeName; + this.path = this.pathPrefix + File.separator + this.themeName; + File file = new File(this.path + File.separator + this.configFile); + if (file.canRead()) { + FileInputStream fp; + try { + fp = new FileInputStream(file); + config = new JSONObject(new JSONTokener(fp)); + fp.close(); + } catch (FileNotFoundException e) { + } catch (IOException e) { + } catch (JSONException e) { + } + } + } + + public BufferedImage getBlackStone(int[] position) { + if (blackStoneCached == null) { + try { + blackStoneCached = ImageIO.read(new File(this.path + File.separator + config.optString("black-stone-image", "black.png"))); + } catch (IOException e) { + try { + blackStoneCached = ImageIO.read(getClass().getResourceAsStream("/assets/black0.png")); + } catch (IOException e1) { + e1.printStackTrace(); + } + } + } + return blackStoneCached; + } + + public BufferedImage getWhiteStone(int[] position) { + if (whiteStoneCached == null) { + try { + whiteStoneCached = ImageIO.read(new File(this.path + File.separator + config.optString("white-stone-image", "white.png"))); + } catch (IOException e) { + try { + whiteStoneCached = ImageIO.read(getClass().getResourceAsStream("/assets/white0.png")); + } catch (IOException e1) { + e1.printStackTrace(); + } + } + } + return whiteStoneCached; + } + + public BufferedImage getBoard() { + if (boardCached == null) { + try { + boardCached = ImageIO.read(new File(this.path + File.separator + config.optString("board-image", "board.png"))); + } catch (IOException e) { + try { + boardCached = ImageIO.read(getClass().getResourceAsStream("/assets/board.png")); + } catch (IOException e1) { + e1.printStackTrace(); + } + } + } + return boardCached; + } + + public BufferedImage getBackground() { + if (backgroundCached == null) { + try { + backgroundCached = ImageIO.read(new File(this.path + File.separator + config.optString("background-image", "background.png"))); + } catch (IOException e) { + + try { + backgroundCached = ImageIO.read(getClass().getResourceAsStream("/assets/background.jpg")); + } catch (IOException e1) { + e1.printStackTrace(); + } + } + } + return backgroundCached; + } + + /** + * Use custom font + */ + public String getFontName() { + return config.optString("font-name", null); + } + + /** + * Use solid current stone indicator + */ + public boolean solidStoneIndicator() { + return config.optBoolean("solid-stone-indicator"); + } + + /** + * The background color of the comment panel + * @return + */ + public Color commentBackgroundColor() { + JSONArray color = config.optJSONArray("comment-background-color"); + if (color != null) { + return new Color(color.getInt(0), color.getInt(1), color.getInt(2), color.getInt(3)); + } else { + return new Color(0, 0, 0, 200); + } + } + + /** + * The font color of the comment + */ + public Color commentFontColor() { + JSONArray color = config.optJSONArray("comment-font-color"); + if (color != null) { + return new Color(color.getInt(0), color.getInt(1), color.getInt(2), color.getInt(3)); + } else { + return Color.WHITE; + } + } +} \ No newline at end of file From d042ca1b7be7a5b2d2d629fd608b93bf0948f49a Mon Sep 17 00:00:00 2001 From: zsalch Date: Mon, 8 Oct 2018 15:43:31 +0800 Subject: [PATCH 2/3] Move theme to frame and add winrate & blunder bar color --- .../featurecat/lizzie/gui/BoardRenderer.java | 18 ++++----- .../featurecat/lizzie/gui/LizzieFrame.java | 20 ++++++---- .../java/featurecat/lizzie/theme/Theme.java | 40 ++++++++++++++++--- 3 files changed, 55 insertions(+), 23 deletions(-) diff --git a/src/main/java/featurecat/lizzie/gui/BoardRenderer.java b/src/main/java/featurecat/lizzie/gui/BoardRenderer.java index 87f271f9d..4b8f89368 100644 --- a/src/main/java/featurecat/lizzie/gui/BoardRenderer.java +++ b/src/main/java/featurecat/lizzie/gui/BoardRenderer.java @@ -14,7 +14,6 @@ import featurecat.lizzie.rules.BoardHistoryNode; import featurecat.lizzie.rules.Stone; import featurecat.lizzie.rules.Zobrist; -import featurecat.lizzie.theme.Theme; import java.awt.*; import java.awt.font.TextAttribute; import java.awt.geom.Point2D; @@ -58,7 +57,6 @@ public class BoardRenderer { private boolean lastInScoreMode = false; - public Theme theme; public List variation; // special values of displayedBranchLength @@ -74,8 +72,6 @@ public class BoardRenderer { public BoardRenderer(boolean isMainBoard) { uiConfig = Lizzie.config.config.getJSONObject("ui"); - // The theme to allow use external image and config file - theme = new Theme(uiConfig.optString("theme")); uiPersist = Lizzie.config.persisted.getJSONObject("ui-persist"); try { maxAlpha = uiPersist.getInt("max-alpha"); @@ -451,7 +447,7 @@ private void drawMoveNumbers(Graphics2D g) { boolean isWhite = board.getStones()[Board.getIndex(lastMove[0], lastMove[1])].isWhite(); g.setColor(isWhite ? Color.BLACK : Color.WHITE); - if (theme.solidStoneIndicator()) { + if (Lizzie.frame.theme.solidStoneIndicator()) { // Use a solid circle instead of fillCircle(g, stoneX, stoneY, (int) (lastMoveMarkerRadius * 0.65)); } else { @@ -683,8 +679,9 @@ private void drawWoodenBoard(Graphics2D g) { if (uiConfig.getBoolean("fancy-board")) { // fancy version if (cachedBoardImage == null) { - cachedBoardImage = theme.getBoard(); + cachedBoardImage = Lizzie.frame.theme.board(); } + int shadowRadius = (int) (boardLength * MARGIN / 6); drawTextureImage( g, @@ -847,10 +844,9 @@ private void drawStone( public BufferedImage getScaleStone(boolean isBlack, int size) { BufferedImage stone = isBlack ? cachedBlackStoneImage : cachedWhiteStoneImage; if (stone == null || stone.getWidth() != size || stone.getHeight() != size) { - stone = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB); + stone = new BufferedImage(size, size, TYPE_INT_ARGB); Graphics2D g2 = stone.createGraphics(); - Image img = - isBlack ? theme.getBlackStone(new int[] {x, y}) : theme.getWhiteStone(new int[] {x, y}); + Image img = isBlack ? Lizzie.frame.theme.blackStone() : Lizzie.frame.theme.whiteStone(); g2.drawImage(img.getScaledInstance(size, size, java.awt.Image.SCALE_SMOOTH), 0, 0, null); g2.dispose(); if (isBlack) { @@ -864,7 +860,7 @@ public BufferedImage getScaleStone(boolean isBlack, int size) { public BufferedImage getWallpaper() { if (cachedWallpaperImage == null) { - cachedWallpaperImage = theme.getBackground(); + cachedWallpaperImage = Lizzie.frame.theme.background(); } return cachedWallpaperImage; } @@ -964,7 +960,7 @@ private void drawString( font = font.deriveFont((float) (font.getSize2D() * maximumFontWidth / fm.stringWidth(string))); font = font.deriveFont(min(maximumFontHeight, font.getSize())); g.setFont(font); - + fm = g.getFontMetrics(font); int height = fm.getAscent() - fm.getDescent(); int verticalOffset; if (aboveOrBelow == -1) { diff --git a/src/main/java/featurecat/lizzie/gui/LizzieFrame.java b/src/main/java/featurecat/lizzie/gui/LizzieFrame.java index 9c07e5ea1..36d022dd6 100644 --- a/src/main/java/featurecat/lizzie/gui/LizzieFrame.java +++ b/src/main/java/featurecat/lizzie/gui/LizzieFrame.java @@ -9,6 +9,7 @@ import featurecat.lizzie.rules.BoardData; import featurecat.lizzie.rules.GIBParser; import featurecat.lizzie.rules.SGFParser; +import featurecat.lizzie.theme.Theme; import java.awt.*; import java.awt.BasicStroke; import java.awt.Color; @@ -71,6 +72,7 @@ public class LizzieFrame extends JFrame { resourceBundle.getString("LizzieFrame.commands.keyControl"), }; private static final String DEFAULT_TITLE = "Lizzie - Leela Zero Interface"; + public static Theme theme; private static BoardRenderer boardRenderer; private static BoardRenderer subBoardRenderer; private static VariationTree variationTree; @@ -121,6 +123,8 @@ public class LizzieFrame extends JFrame { } catch (IOException | FontFormatException e) { e.printStackTrace(); } + // The theme to allow use external image and config file + theme = new Theme(Lizzie.config.config.getJSONObject("ui").optString("theme")); } /** Creates a window */ @@ -138,8 +142,8 @@ public LizzieFrame() { setSize(windowSize.getInt(0), windowSize.getInt(1)); // use config file window size // Allow change font in the config - if (boardRenderer.theme.getFontName() != null) { - systemDefaultFontName = boardRenderer.theme.getFontName(); + if (theme.fontName() != null) { + systemDefaultFontName = theme.fontName(); OpenSansRegularBase = new Font(systemDefaultFontName, Font.PLAIN, 12); OpenSansSemiboldBase = new Font(systemDefaultFontName, Font.BOLD, 12); } @@ -152,8 +156,8 @@ public LizzieFrame() { commentPane = new JTextPane(); commentPane.setEditable(false); commentPane.setMargin(new Insets(5, 5, 5, 5)); - commentPane.setBackground(boardRenderer.theme.commentBackgroundColor()); - commentPane.setForeground(boardRenderer.theme.commentFontColor()); + commentPane.setBackground(theme.commentBackgroundColor()); + commentPane.setForeground(theme.commentFontColor()); scrollPane = new JScrollPane(); scrollPane.setViewportView(commentPane); scrollPane.setBorder(null); @@ -447,9 +451,11 @@ public void paint(Graphics g0) { if (Lizzie.leelaz != null && Lizzie.leelaz.isLoaded()) { if (Lizzie.config.showStatus) { String pondKey = "LizzieFrame.display." + (Lizzie.leelaz.isPondering() ? "on" : "off"); - String pondText = resourceBundle.getString(pondKey); + String pondText = + resourceBundle.getString("LizzieFrame.display.pondering") + + resourceBundle.getString(pondKey); String switchText = resourceBundle.getString("LizzieFrame.prompt.switching"); - String weightText = Lizzie.leelaz.currentWeight().toString(); + String weightText = Lizzie.leelaz.currentWeight(); String text = pondText + " " + weightText + (Lizzie.leelaz.switching() ? switchText : ""); drawPonderingState(g, text, ponderingX, ponderingY, ponderingSize); } @@ -962,7 +968,7 @@ public void onMouseMoved(int x, int y) { public boolean isMouseOver(int x, int y) { return mouseOverCoordinate != null && mouseOverCoordinate[0] == x - && mouseOverCoordinate[1] == x; + && mouseOverCoordinate[1] == y; } public void onMouseDragged(int x, int y) { diff --git a/src/main/java/featurecat/lizzie/theme/Theme.java b/src/main/java/featurecat/lizzie/theme/Theme.java index 3ce878d72..772c3ad93 100644 --- a/src/main/java/featurecat/lizzie/theme/Theme.java +++ b/src/main/java/featurecat/lizzie/theme/Theme.java @@ -42,7 +42,7 @@ public Theme(String themeName) { } } - public BufferedImage getBlackStone(int[] position) { + public BufferedImage blackStone() { if (blackStoneCached == null) { try { blackStoneCached = @@ -62,7 +62,7 @@ public BufferedImage getBlackStone(int[] position) { return blackStoneCached; } - public BufferedImage getWhiteStone(int[] position) { + public BufferedImage whiteStone() { if (whiteStoneCached == null) { try { whiteStoneCached = @@ -82,7 +82,7 @@ public BufferedImage getWhiteStone(int[] position) { return whiteStoneCached; } - public BufferedImage getBoard() { + public BufferedImage board() { if (boardCached == null) { try { boardCached = @@ -100,7 +100,7 @@ public BufferedImage getBoard() { return boardCached; } - public BufferedImage getBackground() { + public BufferedImage background() { if (backgroundCached == null) { try { backgroundCached = @@ -122,7 +122,7 @@ public BufferedImage getBackground() { } /** Use custom font */ - public String getFontName() { + public String fontName() { return config.optString("font-name", null); } @@ -154,4 +154,34 @@ public Color commentFontColor() { return Color.WHITE; } } + + /** The color of the winrate line */ + public Color winrateLineColor() { + JSONArray color = config.optJSONArray("winrate-line-color"); + if (color != null) { + return new Color(color.getInt(0), color.getInt(1), color.getInt(2), color.getInt(3)); + } else { + return Color.green; + } + } + + /** The color of the line that missed the winrate */ + public Color winrateMissLineColor() { + JSONArray color = config.optJSONArray("winrate-miss-line-color"); + if (color != null) { + return new Color(color.getInt(0), color.getInt(1), color.getInt(2), color.getInt(3)); + } else { + return Color.blue.darker(); + } + } + + /** The color of the blunder bar */ + public Color blunderBarColor() { + JSONArray color = config.optJSONArray("blunder-bar-color"); + if (color != null) { + return new Color(color.getInt(0), color.getInt(1), color.getInt(2), color.getInt(3)); + } else { + return new Color(255, 0, 0, 150); + } + } } From d331672f984fa33f7655571050c1c825b4e839fa Mon Sep 17 00:00:00 2001 From: zsalch Date: Sun, 14 Oct 2018 13:37:06 +0800 Subject: [PATCH 3/3] Change Theme Logic --- src/main/java/featurecat/lizzie/Config.java | 63 +++++- src/main/java/featurecat/lizzie/Lizzie.java | 1 - .../featurecat/lizzie/gui/BoardRenderer.java | 32 +-- .../featurecat/lizzie/gui/LizzieFrame.java | 38 ++-- .../featurecat/lizzie/gui/WinrateGraph.java | 10 +- .../java/featurecat/lizzie/theme/Theme.java | 194 +++++++++--------- 6 files changed, 195 insertions(+), 143 deletions(-) diff --git a/src/main/java/featurecat/lizzie/Config.java b/src/main/java/featurecat/lizzie/Config.java index 169880605..460f2b0c4 100644 --- a/src/main/java/featurecat/lizzie/Config.java +++ b/src/main/java/featurecat/lizzie/Config.java @@ -1,5 +1,7 @@ package featurecat.lizzie; +import featurecat.lizzie.theme.Theme; +import java.awt.Color; import java.io.*; import java.nio.file.Files; import java.nio.file.Paths; @@ -13,9 +15,12 @@ public class Config { public boolean showMoveNumber = false; public boolean showWinrate = true; + public boolean largeWinrate = false; + public boolean showBlunderBar = true; + public boolean weightedBlunderBarHeight = false; + public boolean dynamicWinrateGraphWidth = false; public boolean showVariationGraph = true; - public boolean showComment = false; - public int commentFontSize = 0; + public boolean showComment = true; public boolean showRawBoard = false; public boolean showCaptured = true; public boolean handicapInsteadOfWinrate = false; @@ -37,6 +42,21 @@ public class Config { private String configFilename = "config.txt"; private String persistFilename = "persist"; + public Theme theme; + public float winrateStrokeWidth = 3; + public int minimumBlunderBarWidth = 3; + public int shadowSize = 100; + public String fontName = null; + public String uiFontName = null; + public String winrateFontName = null; + public int commentFontSize = 0; + public Color commentFontColor = null; + public Color commentBackgroundColor = null; + public Color winrateLineColor = null; + public Color winrateMissLineColor = null; + public Color blunderBarColor = null; + public boolean solidStoneIndicator = false; + private JSONObject loadAndMergeConfig( JSONObject defaultCfg, String fileName, boolean needValidation) throws IOException { File file = new File(fileName); @@ -127,13 +147,18 @@ public Config() throws IOException { leelazConfig = config.getJSONObject("leelaz"); uiConfig = config.getJSONObject("ui"); + theme = new Theme(uiConfig); + showMoveNumber = uiConfig.getBoolean("show-move-number"); showStatus = uiConfig.getBoolean("show-status"); showBranch = uiConfig.getBoolean("show-leelaz-variation"); showWinrate = uiConfig.getBoolean("show-winrate"); + largeWinrate = uiConfig.optBoolean("large-winrate", false); + showBlunderBar = uiConfig.optBoolean("show-blunder-bar", true); + weightedBlunderBarHeight = uiConfig.optBoolean("weighted-blunder-bar-height", false); + dynamicWinrateGraphWidth = uiConfig.optBoolean("dynamic-winrate-graph-width", false); showVariationGraph = uiConfig.getBoolean("show-variation-graph"); - showComment = uiConfig.optBoolean("show-comment", false); - commentFontSize = uiConfig.optInt("comment-font-size", 0); + showComment = uiConfig.optBoolean("show-comment", true); showCaptured = uiConfig.getBoolean("show-captured"); showBestMoves = uiConfig.getBoolean("show-best-moves"); showNextMoves = uiConfig.getBoolean("show-next-moves"); @@ -142,6 +167,20 @@ public Config() throws IOException { handicapInsteadOfWinrate = uiConfig.getBoolean("handicap-instead-of-winrate"); startMaximized = uiConfig.getBoolean("window-maximized"); showDynamicKomi = uiConfig.getBoolean("show-dynamic-komi"); + + winrateStrokeWidth = theme.winrateStrokeWidth(); + minimumBlunderBarWidth = theme.minimumBlunderBarWidth(); + shadowSize = theme.shadowSize(); + fontName = theme.fontName(); + uiFontName = theme.uiFontName(); + winrateFontName = theme.winrateFontName(); + commentFontSize = theme.commentFontSize(); + commentFontColor = theme.commentFontColor(); + commentBackgroundColor = theme.commentBackgroundColor(); + winrateLineColor = theme.winrateLineColor(); + winrateMissLineColor = theme.winrateMissLineColor(); + blunderBarColor = theme.blunderBarColor(); + solidStoneIndicator = theme.solidStoneIndicator(); } // Modifies config by adding in values from default_config that are missing. @@ -181,6 +220,10 @@ public void toggleShowWinrate() { this.showWinrate = !this.showWinrate; } + public void toggleLargeWinrate() { + this.largeWinrate = !this.largeWinrate; + } + public void toggleShowVariationGraph() { this.showVariationGraph = !this.showVariationGraph; } @@ -209,6 +252,10 @@ public boolean showLargeSubBoard() { return showSubBoard && largeSubBoard; } + public boolean showLargeWinrate() { + return showWinrate && largeWinrate; + } + /** * Scans the current directory as well as the current PATH to find a reasonable default leelaz * binary. @@ -265,6 +312,14 @@ private JSONObject createDefaultConfig() { ui.put("show-status", true); ui.put("show-leelaz-variation", true); ui.put("show-winrate", true); + ui.put("large-winrate", false); + ui.put("winrate-stroke-width", 3); + ui.put("show-blunder-bar", true); + ui.put("minimum-blunder-bar-width", 3); + ui.put("weighted-blunder-bar-height", false); + ui.put("dynamic-winrate-graph-width", false); + ui.put("show-comment", true); + ui.put("comment-font-size", 0); ui.put("show-variation-graph", true); ui.put("show-captured", true); ui.put("show-best-moves", true); diff --git a/src/main/java/featurecat/lizzie/Lizzie.java b/src/main/java/featurecat/lizzie/Lizzie.java index 15a3b6de2..0b189f6da 100644 --- a/src/main/java/featurecat/lizzie/Lizzie.java +++ b/src/main/java/featurecat/lizzie/Lizzie.java @@ -7,7 +7,6 @@ import java.io.IOException; import javax.swing.*; import org.json.JSONArray; -import org.json.JSONException; /** Main class. */ public class Lizzie { diff --git a/src/main/java/featurecat/lizzie/gui/BoardRenderer.java b/src/main/java/featurecat/lizzie/gui/BoardRenderer.java index 4b8f89368..0e5f22744 100644 --- a/src/main/java/featurecat/lizzie/gui/BoardRenderer.java +++ b/src/main/java/featurecat/lizzie/gui/BoardRenderer.java @@ -71,8 +71,8 @@ public class BoardRenderer { private int maxAlpha = 240; public BoardRenderer(boolean isMainBoard) { - uiConfig = Lizzie.config.config.getJSONObject("ui"); - uiPersist = Lizzie.config.persisted.getJSONObject("ui-persist"); + uiConfig = Lizzie.config.uiConfig; + uiPersist = Lizzie.config.persisted; try { maxAlpha = uiPersist.getInt("max-alpha"); } catch (JSONException e) { @@ -201,7 +201,7 @@ private void drawGoban(Graphics2D g0) { g, x + scaledMargin + squareLength * i, y + scaledMargin / 2, - LizzieFrame.OpenSansRegularBase, + LizzieFrame.uiFont, "" + alphabet.charAt(i), stoneRadius * 4 / 5, stoneRadius); @@ -209,7 +209,7 @@ private void drawGoban(Graphics2D g0) { g, x + scaledMargin + squareLength * i, y - scaledMargin / 2 + boardLength, - LizzieFrame.OpenSansRegularBase, + LizzieFrame.uiFont, "" + alphabet.charAt(i), stoneRadius * 4 / 5, stoneRadius); @@ -219,7 +219,7 @@ private void drawGoban(Graphics2D g0) { g, x + scaledMargin / 2, y + scaledMargin + squareLength * i, - LizzieFrame.OpenSansRegularBase, + LizzieFrame.uiFont, "" + (Board.BOARD_SIZE - i), stoneRadius * 4 / 5, stoneRadius); @@ -227,7 +227,7 @@ private void drawGoban(Graphics2D g0) { g, x - scaledMargin / 2 + +boardLength, y + scaledMargin + squareLength * i, - LizzieFrame.OpenSansRegularBase, + LizzieFrame.uiFont, "" + (Board.BOARD_SIZE - i), stoneRadius * 4 / 5, stoneRadius); @@ -447,7 +447,7 @@ private void drawMoveNumbers(Graphics2D g) { boolean isWhite = board.getStones()[Board.getIndex(lastMove[0], lastMove[1])].isWhite(); g.setColor(isWhite ? Color.BLACK : Color.WHITE); - if (Lizzie.frame.theme.solidStoneIndicator()) { + if (Lizzie.config.solidStoneIndicator) { // Use a solid circle instead of fillCircle(g, stoneX, stoneY, (int) (lastMoveMarkerRadius * 0.65)); } else { @@ -467,7 +467,7 @@ private void drawMoveNumbers(Graphics2D g) { g, x + boardLength / 2, y + boardLength / 2, - LizzieFrame.OpenSansRegularBase, + LizzieFrame.uiFont, "pass", stoneRadius * 4, stoneRadius * 6); @@ -514,7 +514,7 @@ private void drawMoveNumbers(Graphics2D g) { g, stoneX, stoneY, - LizzieFrame.OpenSansRegularBase, + LizzieFrame.uiFont, moveNumberString, (float) (stoneRadius * 1.4), (int) (stoneRadius * 1.4)); @@ -630,7 +630,7 @@ private void drawLeelazSuggestions(Graphics2D g) { g, suggestionX, suggestionY, - LizzieFrame.OpenSansSemiboldBase, + LizzieFrame.winrateFont, Font.PLAIN, text, stoneRadius, @@ -641,7 +641,7 @@ private void drawLeelazSuggestions(Graphics2D g) { g, suggestionX, suggestionY + stoneRadius * 2 / 5, - LizzieFrame.OpenSansRegularBase, + LizzieFrame.uiFont, getPlayoutsString(move.playouts), (float) (stoneRadius * 0.8), stoneRadius * 1.4); @@ -679,7 +679,7 @@ private void drawWoodenBoard(Graphics2D g) { if (uiConfig.getBoolean("fancy-board")) { // fancy version if (cachedBoardImage == null) { - cachedBoardImage = Lizzie.frame.theme.board(); + cachedBoardImage = Lizzie.config.theme.board(); } int shadowRadius = (int) (boardLength * MARGIN / 6); @@ -748,8 +748,8 @@ private void drawShadow( Graphics2D g, int centerX, int centerY, boolean isGhost, float shadowStrength) { if (!uiConfig.getBoolean("shadows-enabled")) return; - final int shadowSize = (int) (stoneRadius * 0.3 * uiConfig.getInt("shadow-size") / 100); - final int fartherShadowSize = (int) (stoneRadius * 0.17 * uiConfig.getInt("shadow-size") / 100); + final int shadowSize = (int) (stoneRadius * 0.3 * Lizzie.config.shadowSize / 100); + final int fartherShadowSize = (int) (stoneRadius * 0.17 * Lizzie.config.shadowSize / 100); final Paint TOP_GRADIENT_PAINT; final Paint LOWER_RIGHT_GRADIENT_PAINT; @@ -846,7 +846,7 @@ public BufferedImage getScaleStone(boolean isBlack, int size) { if (stone == null || stone.getWidth() != size || stone.getHeight() != size) { stone = new BufferedImage(size, size, TYPE_INT_ARGB); Graphics2D g2 = stone.createGraphics(); - Image img = isBlack ? Lizzie.frame.theme.blackStone() : Lizzie.frame.theme.whiteStone(); + Image img = isBlack ? Lizzie.config.theme.blackStone() : Lizzie.config.theme.whiteStone(); g2.drawImage(img.getScaledInstance(size, size, java.awt.Image.SCALE_SMOOTH), 0, 0, null); g2.dispose(); if (isBlack) { @@ -860,7 +860,7 @@ public BufferedImage getScaleStone(boolean isBlack, int size) { public BufferedImage getWallpaper() { if (cachedWallpaperImage == null) { - cachedWallpaperImage = Lizzie.frame.theme.background(); + cachedWallpaperImage = Lizzie.config.theme.background(); } return cachedWallpaperImage; } diff --git a/src/main/java/featurecat/lizzie/gui/LizzieFrame.java b/src/main/java/featurecat/lizzie/gui/LizzieFrame.java index 36d022dd6..726440234 100644 --- a/src/main/java/featurecat/lizzie/gui/LizzieFrame.java +++ b/src/main/java/featurecat/lizzie/gui/LizzieFrame.java @@ -9,7 +9,6 @@ import featurecat.lizzie.rules.BoardData; import featurecat.lizzie.rules.GIBParser; import featurecat.lizzie.rules.SGFParser; -import featurecat.lizzie.theme.Theme; import java.awt.*; import java.awt.BasicStroke; import java.awt.Color; @@ -72,14 +71,13 @@ public class LizzieFrame extends JFrame { resourceBundle.getString("LizzieFrame.commands.keyControl"), }; private static final String DEFAULT_TITLE = "Lizzie - Leela Zero Interface"; - public static Theme theme; private static BoardRenderer boardRenderer; private static BoardRenderer subBoardRenderer; private static VariationTree variationTree; private static WinrateGraph winrateGraph; - public static Font OpenSansRegularBase; - public static Font OpenSansSemiboldBase; + public static Font uiFont; + public static Font winrateFont; private final BufferStrategy bs; @@ -90,9 +88,6 @@ public class LizzieFrame extends JFrame { public boolean playerIsBlack = true; public int winRateGridLines = 3; - // Get the font name in current system locale - private String systemDefaultFontName = new JLabel().getFont().getFontName(); - private long lastAutosaveTime = System.currentTimeMillis(); // Save the player title @@ -108,13 +103,13 @@ public class LizzieFrame extends JFrame { static { // load fonts try { - OpenSansRegularBase = + uiFont = Font.createFont( Font.TRUETYPE_FONT, Thread.currentThread() .getContextClassLoader() .getResourceAsStream("fonts/OpenSans-Regular.ttf")); - OpenSansSemiboldBase = + winrateFont = Font.createFont( Font.TRUETYPE_FONT, Thread.currentThread() @@ -123,8 +118,6 @@ public class LizzieFrame extends JFrame { } catch (IOException | FontFormatException e) { e.printStackTrace(); } - // The theme to allow use external image and config file - theme = new Theme(Lizzie.config.config.getJSONObject("ui").optString("theme")); } /** Creates a window */ @@ -142,10 +135,11 @@ public LizzieFrame() { setSize(windowSize.getInt(0), windowSize.getInt(1)); // use config file window size // Allow change font in the config - if (theme.fontName() != null) { - systemDefaultFontName = theme.fontName(); - OpenSansRegularBase = new Font(systemDefaultFontName, Font.PLAIN, 12); - OpenSansSemiboldBase = new Font(systemDefaultFontName, Font.BOLD, 12); + if (Lizzie.config.uiFontName != null) { + uiFont = new Font(Lizzie.config.uiFontName, Font.PLAIN, 12); + } + if (Lizzie.config.winrateFontName != null) { + winrateFont = new Font(Lizzie.config.winrateFontName, Font.BOLD, 12); } if (Lizzie.config.startMaximized) { @@ -156,8 +150,8 @@ public LizzieFrame() { commentPane = new JTextPane(); commentPane.setEditable(false); commentPane.setMargin(new Insets(5, 5, 5, 5)); - commentPane.setBackground(theme.commentBackgroundColor()); - commentPane.setForeground(theme.commentFontColor()); + commentPane.setBackground(Lizzie.config.commentBackgroundColor); + commentPane.setForeground(Lizzie.config.commentFontColor); scrollPane = new JScrollPane(); scrollPane.setViewportView(commentPane); scrollPane.setBorder(null); @@ -561,7 +555,7 @@ private void drawVariationTreeContainer(Graphics2D g, int vx, int vy, int vw, in private void drawPonderingState(Graphics2D g, String text, int x, int y, double size) { int fontSize = (int) (Math.max(getWidth(), getHeight()) * size); - Font font = new Font(systemDefaultFontName, Font.PLAIN, fontSize); + Font font = new Font(Lizzie.config.fontName, Font.PLAIN, fontSize); FontMetrics fm = g.getFontMetrics(font); int stringWidth = fm.stringWidth(text); // Truncate too long text when display switching prompt @@ -625,7 +619,7 @@ void drawControls() { Graphics2D g = cachedImage.createGraphics(); int maxSize = Math.min(getWidth(), getHeight()); - Font font = new Font(systemDefaultFontName, Font.PLAIN, (int) (maxSize * 0.034)); + Font font = new Font(Lizzie.config.fontName, Font.PLAIN, (int) (maxSize * 0.034)); g.setFont(font); FontMetrics metrics = g.getFontMetrics(font); @@ -688,7 +682,7 @@ private void drawCommandString(Graphics2D g) { int maxSize = (int) (Math.min(getWidth(), getHeight()) * 0.98); - Font font = new Font(systemDefaultFontName, Font.PLAIN, (int) (maxSize * 0.03)); + Font font = new Font(Lizzie.config.fontName, Font.PLAIN, (int) (maxSize * 0.03)); String commandString = resourceBundle.getString("LizzieFrame.prompt.showControlsHint"); int strokeRadius = 2; @@ -906,7 +900,7 @@ private void drawCaptured(Graphics2D g, int posX, int posY, int width, int heigh } private void setPanelFont(Graphics2D g, float size) { - Font font = OpenSansRegularBase.deriveFont(Font.PLAIN, size); + Font font = uiFont.deriveFont(Font.PLAIN, size); g.setFont(font); } @@ -1145,7 +1139,7 @@ private int drawComment(Graphics2D g, int x, int y, int w, int h, boolean full) } else if (fontSize < 16) { fontSize = 16; } - Font font = new Font(systemDefaultFontName, Font.PLAIN, fontSize); + Font font = new Font(Lizzie.config.fontName, Font.PLAIN, fontSize); commentPane.setFont(font); commentPane.setText(comment); commentPane.setSize(w, cHeight); diff --git a/src/main/java/featurecat/lizzie/gui/WinrateGraph.java b/src/main/java/featurecat/lizzie/gui/WinrateGraph.java index 3b4915c96..0ab6351af 100644 --- a/src/main/java/featurecat/lizzie/gui/WinrateGraph.java +++ b/src/main/java/featurecat/lizzie/gui/WinrateGraph.java @@ -73,8 +73,8 @@ public void draw(Graphics2D g, int posx, int posy, int width, int height) { g.drawLine(posx, y, posx + width, y); } - g.setColor(Color.green); - g.setStroke(new BasicStroke(3)); + g.setColor(Lizzie.config.winrateLineColor); + g.setStroke(new BasicStroke(Lizzie.config.winrateStrokeWidth)); BoardHistoryNode topOfVariation = null; int numMoves = 0; @@ -139,8 +139,8 @@ public void draw(Graphics2D g, int posx, int posy, int width, int height) { wr = lastWr; } - if (lastNodeOk) g.setColor(Color.green); - else g.setColor(Color.blue.darker()); + if (lastNodeOk) g.setColor(Lizzie.config.winrateLineColor); + else g.setColor(Lizzie.config.winrateMissLineColor); if (lastOkMove > 0) { g.drawLine( @@ -151,7 +151,7 @@ public void draw(Graphics2D g, int posx, int posy, int width, int height) { } if (node == curMove) { - g.setColor(Color.green); + g.setColor(Lizzie.config.winrateLineColor); g.fillOval( posx + (movenum * width / numMoves) - DOT_RADIUS, posy + height - (int) (convertWinrate(wr) * height / 100) - DOT_RADIUS, diff --git a/src/main/java/featurecat/lizzie/theme/Theme.java b/src/main/java/featurecat/lizzie/theme/Theme.java index 772c3ad93..b55674692 100644 --- a/src/main/java/featurecat/lizzie/theme/Theme.java +++ b/src/main/java/featurecat/lizzie/theme/Theme.java @@ -1,12 +1,14 @@ package featurecat.lizzie.theme; +import static java.io.File.separator; + import java.awt.Color; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; import javax.imageio.ImageIO; +import javax.swing.JLabel; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -19,23 +21,23 @@ public class Theme { BufferedImage boardCached = null; BufferedImage backgroundCached = null; - private String themeName = null; private String configFile = "theme.txt"; - private String pathPrefix = "theme"; + private String pathPrefix = "theme" + separator; private String path = null; private JSONObject config = new JSONObject(); + private JSONObject uiConfig = null; - public Theme(String themeName) { - this.themeName = themeName; - this.path = this.pathPrefix + File.separator + this.themeName; - File file = new File(this.path + File.separator + this.configFile); + public Theme(JSONObject uiConfig) { + this.uiConfig = uiConfig; + String themeName = uiConfig.optString("theme"); + this.path = this.pathPrefix + (themeName.isEmpty() ? "" : themeName + separator); + File file = new File(this.path + this.configFile); if (file.canRead()) { FileInputStream fp; try { fp = new FileInputStream(file); config = new JSONObject(new JSONTokener(fp)); fp.close(); - } catch (FileNotFoundException e) { } catch (IOException e) { } catch (JSONException e) { } @@ -44,91 +46,74 @@ public Theme(String themeName) { public BufferedImage blackStone() { if (blackStoneCached == null) { - try { - blackStoneCached = - ImageIO.read( - new File( - this.path - + File.separator - + config.optString("black-stone-image", "black.png"))); - } catch (IOException e) { - try { - blackStoneCached = ImageIO.read(getClass().getResourceAsStream("/assets/black0.png")); - } catch (IOException e1) { - e1.printStackTrace(); - } - } + blackStoneCached = getImageByKey("black-stone-image", "black.png", "black0.png"); } return blackStoneCached; } public BufferedImage whiteStone() { if (whiteStoneCached == null) { - try { - whiteStoneCached = - ImageIO.read( - new File( - this.path - + File.separator - + config.optString("white-stone-image", "white.png"))); - } catch (IOException e) { - try { - whiteStoneCached = ImageIO.read(getClass().getResourceAsStream("/assets/white0.png")); - } catch (IOException e1) { - e1.printStackTrace(); - } - } + whiteStoneCached = getImageByKey("white-stone-image", "white.png", "white0.png"); } return whiteStoneCached; } public BufferedImage board() { if (boardCached == null) { - try { - boardCached = - ImageIO.read( - new File( - this.path + File.separator + config.optString("board-image", "board.png"))); - } catch (IOException e) { - try { - boardCached = ImageIO.read(getClass().getResourceAsStream("/assets/board.png")); - } catch (IOException e1) { - e1.printStackTrace(); - } - } + boardCached = getImageByKey("board-image", "board.png", "board.png"); } return boardCached; } public BufferedImage background() { if (backgroundCached == null) { - try { - backgroundCached = - ImageIO.read( - new File( - this.path - + File.separator - + config.optString("background-image", "background.png"))); - } catch (IOException e) { - - try { - backgroundCached = ImageIO.read(getClass().getResourceAsStream("/assets/background.jpg")); - } catch (IOException e1) { - e1.printStackTrace(); - } - } + backgroundCached = getImageByKey("background-image", "background.png", "background.jpg"); } return backgroundCached; } - /** Use custom font */ + /** Use custom font for general text */ public String fontName() { - return config.optString("font-name", null); + String key = "font-name"; + return config.optString(key, uiConfig.optString(key, new JLabel().getFont().getFontName())); + } + + /** Use custom font for the UI */ + public String uiFontName() { + String key = "ui-font-name"; + return config.optString(key, uiConfig.optString(key, null)); + } + + /** Use custom font for the Leela Zero winrate on the stone */ + public String winrateFontName() { + String key = "winrate-font-name"; + return config.optString(key, uiConfig.optString(key, null)); } /** Use solid current stone indicator */ public boolean solidStoneIndicator() { - return config.optBoolean("solid-stone-indicator"); + String key = "solid-stone-indicator"; + return config.optBoolean(key, uiConfig.optBoolean(key)); + } + + /** The size of the shadow */ + public int shadowSize() { + return getIntByKey("shadow-size", 100); + } + + /** The stroke width of the winrate line */ + public int winrateStrokeWidth() { + return getIntByKey("winrate-stroke-width", 3); + } + + /** The minimum width of the blunder bar */ + public int minimumBlunderBarWidth() { + return getIntByKey("minimum-blunder-bar-width", 3); + } + + /** The font size of the comment */ + public int commentFontSize() { + return getIntByKey("comment-font-size", 3); } /** @@ -137,51 +122,70 @@ public boolean solidStoneIndicator() { * @return */ public Color commentBackgroundColor() { - JSONArray color = config.optJSONArray("comment-background-color"); - if (color != null) { - return new Color(color.getInt(0), color.getInt(1), color.getInt(2), color.getInt(3)); - } else { - return new Color(0, 0, 0, 200); - } + return getColorByKey("comment-background-color", new Color(0, 0, 0, 200)); } /** The font color of the comment */ public Color commentFontColor() { - JSONArray color = config.optJSONArray("comment-font-color"); - if (color != null) { - return new Color(color.getInt(0), color.getInt(1), color.getInt(2), color.getInt(3)); - } else { - return Color.WHITE; - } + return getColorByKey("comment-font-color", Color.WHITE); } /** The color of the winrate line */ public Color winrateLineColor() { - JSONArray color = config.optJSONArray("winrate-line-color"); - if (color != null) { - return new Color(color.getInt(0), color.getInt(1), color.getInt(2), color.getInt(3)); - } else { - return Color.green; - } + return getColorByKey("winrate-line-color", Color.green); } /** The color of the line that missed the winrate */ public Color winrateMissLineColor() { - JSONArray color = config.optJSONArray("winrate-miss-line-color"); - if (color != null) { - return new Color(color.getInt(0), color.getInt(1), color.getInt(2), color.getInt(3)); - } else { - return Color.blue.darker(); - } + return getColorByKey("winrate-miss-line-color", Color.blue.darker()); } /** The color of the blunder bar */ public Color blunderBarColor() { - JSONArray color = config.optJSONArray("blunder-bar-color"); - if (color != null) { - return new Color(color.getInt(0), color.getInt(1), color.getInt(2), color.getInt(3)); - } else { - return new Color(255, 0, 0, 150); + return getColorByKey("blunder-bar-color", new Color(255, 0, 0, 150)); + } + + private Color getColorByKey(String key, Color defaultColor) { + Color color = array2Color(config.optJSONArray(key), null); + if (color == null) { + color = array2Color(uiConfig.optJSONArray(key), defaultColor); } + return color; + } + + /** Convert option color array to Color */ + private Color array2Color(JSONArray a, Color defaultColor) { + if (a != null) { + if (a.length() == 3) { + return new Color(a.getInt(0), a.getInt(1), a.getInt(2)); + } else if (a.length() == 4) { + return new Color(a.getInt(0), a.getInt(1), a.getInt(2), a.getInt(3)); + } + } + return defaultColor; + } + + private BufferedImage getImageByKey(String key, String defaultValue, String defaultImg) { + BufferedImage image = null; + String p = this.path + config.optString(key, defaultValue); + try { + image = ImageIO.read(new File(p)); + } catch (IOException e) { + try { + p = this.pathPrefix + uiConfig.optString(key, defaultValue); + image = ImageIO.read(new File(p)); + } catch (IOException e1) { + try { + image = ImageIO.read(getClass().getResourceAsStream("/assets/" + defaultImg)); + } catch (IOException e2) { + e2.printStackTrace(); + } + } + } + return image; + } + + private int getIntByKey(String key, int defaultValue) { + return config.optInt(key, uiConfig.optInt(key, defaultValue)); } }