Java tutorial
/* * Forge: Play Magic: the Gathering. * Copyright (C) 2011 Forge Team * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package forge.toolbox; import forge.FThreads; import forge.Singletons; import forge.assets.FSkinProp; import forge.assets.ISkinImage; import forge.gui.GuiUtils; import forge.gui.framework.ILocalRepaint; import forge.model.FModel; import forge.properties.ForgeConstants; import forge.properties.ForgePreferences; import forge.properties.ForgePreferences.FPref; import forge.view.FView; import org.apache.commons.lang3.text.WordUtils; import javax.imageio.ImageIO; import javax.swing.*; import javax.swing.border.Border; import javax.swing.border.LineBorder; import javax.swing.border.TitledBorder; import javax.swing.plaf.basic.BasicScrollBarUI; import javax.swing.table.JTableHeader; import javax.swing.table.TableColumnModel; import javax.swing.text.JTextComponent; import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.util.*; import java.util.List; import java.util.Map.Entry; /** * Assembles settings from selected or default theme as appropriate. Saves in a * hashtable, access using .get(settingName) method. */ public class FSkin { /** * Retrieves a color from this skin's color map. * * @param c0   Colors property (from enum) * @return {@link forge.toolbox.FSkin.SkinColor} */ public static SkinColor getColor(final Colors c0) { return SkinColor.baseColors.get(c0); } /** Steps RGB components of a color up or down. * Returns opaque (non-alpha) stepped color. * Plus for lighter, minus for darker. * * @param clr0 {@link java.awt.Color} * @param step int * @return {@link java.awt.Color} */ public static Color stepColor(final Color clr0, final int step) { int r = clr0.getRed(); int g = clr0.getGreen(); int b = clr0.getBlue(); // Darker if (step < 0) { r = ((r + step > 0) ? r + step : 0); g = ((g + step > 0) ? g + step : 0); b = ((b + step > 0) ? b + step : 0); } else { r = ((r + step < 255) ? r + step : 255); g = ((g + step < 255) ? g + step : 255); b = ((b + step < 255) ? b + step : 255); } return new Color(r, g, b); } /** Returns RGB components of a color, with a new * value for alpha. 0 = transparent, 255 = opaque. * * @param clr0 {@link java.awt.Color} * @param alpha int * @return {@link java.awt.Color} */ public static Color alphaColor(final Color clr0, final int alpha) { return new Color(clr0.getRed(), clr0.getGreen(), clr0.getBlue(), alpha); } /** * @see <a href="http://www.nbdtech.com/Blog/archive/2008/04/27/Calculating-the-Perceived-Brightness-of-a-Color.aspx"> * http://www.nbdtech.com/Blog/archive/2008/04/27/Calculating-the-Perceived-Brightness-of-a-Color.aspx</a> */ public static boolean isColorBright(final Color c) { final int v = (int) Math.sqrt(c.getRed() * c.getRed() * 0.241 + c.getGreen() * c.getGreen() * 0.691 + c.getBlue() * c.getBlue() * 0.068); return v >= 130; } public static Color getHighContrastColor(final Color c) { return isColorBright(c) ? Color.BLACK : Color.WHITE; } public static void setGraphicsColor(final Graphics g, final SkinColor skinColor) { g.setColor(skinColor.color); } public static void setGraphicsGradientPaint(final Graphics2D g2d, final float x1, final float y1, final SkinColor skinColor1, final float x2, final float y2, final SkinColor skinColor2) { g2d.setPaint(new GradientPaint(x1, y1, skinColor1.color, x2, y2, skinColor2.color)); } public static void setGraphicsGradientPaint(final Graphics2D g2d, final float x1, final float y1, final Color color1, final float x2, final float y2, final SkinColor skinColor2) { g2d.setPaint(new GradientPaint(x1, y1, color1, x2, y2, skinColor2.color)); } public static void setGraphicsGradientPaint(final Graphics2D g2d, final float x1, final float y1, final SkinColor skinColor1, final float x2, final float y2, final Color color2) { g2d.setPaint(new GradientPaint(x1, y1, skinColor1.color, x2, y2, color2)); } //set background color for component that's temporary //only use if can't use ISkinnedComponent class public static void setTempBackground(final Component comp, final SkinColor skinColor) { comp.setBackground(skinColor.color); } public static class SkinColor { private static final HashMap<Colors, SkinColor> baseColors = new HashMap<>(); private static final HashMap<String, SkinColor> derivedColors = new HashMap<>(); private static final int NO_BRIGHTNESS_DELTA = 0; private static final int NO_STEP = -999; //needs to be large negative since small negative values are valid private static final int NO_ALPHA = -1; private final Colors baseColor; private final int brightnessDelta; private final int step; private final int contrastStep; private final int alpha; protected Color color; public Color getColor() { return color; } //private constructors for color that changes with skin (use getColor()) private SkinColor(final Colors baseColor0) { this(baseColor0, NO_BRIGHTNESS_DELTA, NO_STEP, NO_STEP, NO_ALPHA); } private SkinColor(final Colors baseColor0, final int brightnessDelta0, final int step0, final int contrastStep0, final int alpha0) { this.baseColor = baseColor0; this.brightnessDelta = brightnessDelta0; this.step = step0; this.contrastStep = contrastStep0; this.alpha = alpha0; this.updateColor(); } private SkinColor getDerivedColor(final int brightnessDelta0, final int step0, final int contrastStep0, final int alpha0) { final String key = this.baseColor.name() + "|" + brightnessDelta0 + "|" + step0 + "|" + contrastStep0 + "|" + alpha0; SkinColor derivedColor = derivedColors.get(key); if (derivedColor == null) { derivedColor = new SkinColor(this.baseColor, brightnessDelta0, step0, contrastStep0, alpha0); derivedColors.put(key, derivedColor); } return derivedColor; } public SkinColor brighter() { return getDerivedColor(this.brightnessDelta + 1, this.step, this.contrastStep, this.alpha); } public SkinColor darker() { return getDerivedColor(this.brightnessDelta - 1, this.step, this.contrastStep, this.alpha); } public SkinColor stepColor(int step0) { if (this.step != NO_STEP) { step0 += this.step; } return getDerivedColor(this.brightnessDelta, step0, this.contrastStep, this.alpha); } public SkinColor getContrastColor(int contrastStep0) { if (this.contrastStep != NO_STEP) { contrastStep0 += this.contrastStep; } return getDerivedColor(this.brightnessDelta, this.step, contrastStep0, this.alpha); } public SkinColor getHighContrastColor() { return getContrastColor(255); } public SkinColor alphaColor(final int alpha0) { return getDerivedColor(this.brightnessDelta, this.step, this.contrastStep, alpha0); } protected void updateColor() { this.color = this.baseColor.color; if (this.brightnessDelta != NO_BRIGHTNESS_DELTA) { if (this.brightnessDelta < 0) { for (int i = 0; i > this.brightnessDelta; i--) { this.color = this.color.darker(); } } else { for (int i = 0; i < this.brightnessDelta; i++) { this.color = this.color.brighter(); } } } if (this.step != NO_STEP) { this.color = FSkin.stepColor(this.color, this.step); } if (this.contrastStep != NO_STEP) { this.color = FSkin.stepColor(this.color, isColorBright(this.color) ? -this.contrastStep : this.contrastStep); } if (this.alpha != NO_ALPHA) { this.color = FSkin.alphaColor(this.color, this.alpha); } } } //set border for component that's temporary //only use if can't use ISkinnedComponent class public static void setTempBorder(final JComponent comp, final SkinBorder skinBorder) { comp.setBorder(skinBorder.createBorder()); } public static abstract class SkinBorder { protected abstract Border createBorder(); } public static class LineSkinBorder extends SkinBorder { private final SkinColor skinColor; private final int thickness; public LineSkinBorder(final SkinColor skinColor0) { this(skinColor0, 1); } public LineSkinBorder(final SkinColor skinColor0, final int thickness0) { this.skinColor = skinColor0; this.thickness = thickness0; } @Override protected Border createBorder() { return BorderFactory.createLineBorder(this.skinColor.color, this.thickness); } } public static class MatteSkinBorder extends SkinBorder { private final int top, left, bottom, right; private final SkinColor skinColor; public MatteSkinBorder(final int top0, final int left0, final int bottom0, final int right0, final SkinColor skinColor0) { this.top = top0; this.left = left0; this.bottom = bottom0; this.right = right0; this.skinColor = skinColor0; } @Override protected Border createBorder() { return BorderFactory.createMatteBorder(this.top, this.left, this.bottom, this.right, this.skinColor.color); } } public static class CompoundSkinBorder extends SkinBorder { private Border outsideBorder, insideBorder; private SkinBorder outsideSkinBorder, insideSkinBorder; public CompoundSkinBorder(final SkinBorder outsideSkinBorder0, final SkinBorder insideSkinBorder0) { this.outsideSkinBorder = outsideSkinBorder0; this.insideSkinBorder = insideSkinBorder0; } public CompoundSkinBorder(final SkinBorder outsideSkinBorder0, final Border insideBorder0) { this.outsideSkinBorder = outsideSkinBorder0; this.insideBorder = insideBorder0; } public CompoundSkinBorder(final Border outsideBorder0, final SkinBorder insideSkinBorder0) { this.outsideBorder = outsideBorder0; this.insideSkinBorder = insideSkinBorder0; } @Override protected Border createBorder() { Border outBorder = this.outsideBorder; if (this.outsideSkinBorder != null) { outBorder = this.outsideSkinBorder.createBorder(); } Border inBorder = this.insideBorder; if (this.insideSkinBorder != null) { inBorder = this.insideSkinBorder.createBorder(); } return BorderFactory.createCompoundBorder(outBorder, inBorder); } } public static class TitledSkinBorder extends SkinBorder { private final SkinColor foreColor; private final String title; private Border insideBorder; private SkinBorder insideSkinBorder; public TitledSkinBorder(final Border insideBorder0, final String title0, final SkinColor foreColor0) { this.insideBorder = insideBorder0; this.title = title0; this.foreColor = foreColor0; } public TitledSkinBorder(final SkinBorder insideSkinBorder0, final String title0, final SkinColor foreColor0) { this.insideSkinBorder = insideSkinBorder0; this.title = title0; this.foreColor = foreColor0; } @Override protected Border createBorder() { Border inBorder = this.insideBorder; if (this.insideSkinBorder != null) { inBorder = this.insideSkinBorder.createBorder(); } final TitledBorder border = new TitledBorder(inBorder, this.title); border.setTitleColor(foreColor.color); return border; } } public enum Colors { CLR_THEME(FSkinProp.CLR_THEME), CLR_BORDERS(FSkinProp.CLR_BORDERS), CLR_ZEBRA( FSkinProp.CLR_ZEBRA), CLR_HOVER(FSkinProp.CLR_HOVER), CLR_ACTIVE( FSkinProp.CLR_ACTIVE), CLR_INACTIVE(FSkinProp.CLR_INACTIVE), CLR_TEXT( FSkinProp.CLR_TEXT), CLR_PHASE_INACTIVE_ENABLED( FSkinProp.CLR_PHASE_INACTIVE_ENABLED), CLR_PHASE_INACTIVE_DISABLED( FSkinProp.CLR_PHASE_INACTIVE_DISABLED), CLR_PHASE_ACTIVE_ENABLED( FSkinProp.CLR_PHASE_ACTIVE_ENABLED), CLR_PHASE_ACTIVE_DISABLED( FSkinProp.CLR_PHASE_ACTIVE_DISABLED), CLR_THEME2( FSkinProp.CLR_THEME2), CLR_OVERLAY( FSkinProp.CLR_OVERLAY), CLR_COMBAT_TARGETING_ARROW( FSkinProp.CLR_COMBAT_TARGETING_ARROW), CLR_NORMAL_TARGETING_ARROW( FSkinProp.CLR_NORMAL_TARGETING_ARROW); private Color color; private final FSkinProp skinProp; Colors(final FSkinProp skinProp0) { skinProp = skinProp0; } public static Colors fromSkinProp(final FSkinProp skinProp) { for (final Colors c : Colors.values()) { if (c.skinProp == skinProp) { return c; } } return null; } public static void updateAll() { for (final Colors c : Colors.values()) { c.updateColor(); } if (SkinColor.baseColors.isEmpty()) { //initialize base skin colors if needed for (final Colors c : Colors.values()) { SkinColor.baseColors.put(c, new SkinColor(c)); } } else { //update existing SkinColors if baseColors already initialized for (final SkinColor c : SkinColor.baseColors.values()) { c.updateColor(); } for (final SkinColor c : SkinColor.derivedColors.values()) { c.updateColor(); } } } private void updateColor() { tempCoords = skinProp.getCoords(); x0 = tempCoords[0]; y0 = tempCoords[1]; color = bimPreferredSprite.getData().getBounds().contains(x0, y0) ? getColorFromPixel(bimPreferredSprite.getRGB(x0, y0)) : new Color(0, 0, 0, 0); } } public static void drawImage(final Graphics g, final SkinImage skinImage, final int x, final int y) { skinImage.draw(g, x, y); } public static void drawImage(final Graphics g, final SkinImage skinImage, final int x, final int y, final int w, final int h) { skinImage.draw(g, x, y, w, h); } public static void drawImage(final Graphics g, final SkinImage skinImage, final int dx1, final int dy1, final int dx2, final int dy2, final int sx1, final int sy1, final int sx2, final int sy2) { skinImage.draw(g, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2); } /** * Gets an image. * * @param s0   FSkinProp enum * @return {@link forge.toolbox.FSkin.SkinImage} */ public static SkinImage getImage(final FSkinProp s0) { SkinImage image = SkinImage.images.get(s0); if (image == null) { image = SkinIcon.icons.get(s0); if (image == null) { throw new NullPointerException("Can't find an image for FSkinProp " + s0); } } return image; } /** * Gets a scaled version of an image from this skin's image map. * * @param s0 * String image enum * @param w0 * int new width * @param h0 * int new height * @return {@link forge.toolbox.FSkin.SkinImage} */ public static SkinImage getImage(final FSkinProp s0, int w0, int h0) { w0 = (w0 < 1) ? 1 : w0; h0 = (h0 < 1) ? 1 : h0; return getImage(s0).resize(w0, h0); } public static class SkinImage implements ISkinImage { private static final Map<FSkinProp, SkinImage> images = new HashMap<>(); private static void setImage(final FSkinProp s0, final Image image0) { SkinImage skinImage = images.get(s0); if (skinImage == null) { skinImage = new SkinImage(image0); images.put(s0, skinImage); } else { skinImage.changeImage(image0, null); } } /** * setImage, with auto-scaling assumed true. * @param s0 */ private static void setImage(final FSkinProp s0) { setImage(s0, true); } /** * Checks the preferred sprite for existence of a sub-image * defined by X, Y, W, H. * * If an image is not present at those coordinates, default * icon is substituted. * * The result is saved in a HashMap. * * @param s0   An address in the hashmap, derived from FSkinProp enum */ private static void setImage(final FSkinProp s0, final boolean scale) { tempCoords = s0.getCoords(); x0 = tempCoords[0]; y0 = tempCoords[1]; w0 = tempCoords[2]; h0 = tempCoords[3]; newW = (tempCoords.length == 6 ? tempCoords[4] : 0); newH = (tempCoords.length == 6 ? tempCoords[5] : 0); final BufferedImage img = testPreferredSprite(s0); final BufferedImage bi0 = img.getSubimage(x0, y0, w0, h0); if (scale && newW != 0) { setImage(s0, bi0.getScaledInstance(newW, newH, Image.SCALE_AREA_AVERAGING)); } else { setImage(s0, bi0); } } protected Image image; protected ImageIcon imageIcon; protected HashMap<String, SkinImage> scaledImages; private HashMap<String, SkinCursor> cursors; private SkinImage(final Image image0) { this.image = image0; } protected void changeImage(final Image image0, final ImageIcon imageIcon0) { this.image = image0; this.imageIcon = imageIcon0; this.updateScaledImages(); this.updateCursors(); } @Override protected SkinImage clone() { return new SkinImage(this.image); } public SkinImage resize(final int w, final int h) { if (this.scaledImages == null) { this.scaledImages = new HashMap<>(); } final String key = w + "x" + h; SkinImage scaledImage = this.scaledImages.get(key); if (scaledImage == null) { scaledImage = this.clone(); scaledImage.createResizedImage(this, w, h); this.scaledImages.put(key, scaledImage); } return scaledImage; } public boolean save(final String path, final int w, final int h) { final BufferedImage resizedImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); final Graphics2D g2d = resizedImage.createGraphics(); g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); g2d.drawImage(this.image, 0, 0, w, h, 0, 0, this.getWidth(), this.getHeight(), null); g2d.dispose(); final File outputfile = new File(path); try { ImageIO.write(resizedImage, "png", outputfile); return true; } catch (final IOException e) { e.printStackTrace(); } return false; } public SkinImage scale(final double scale) { return scale(scale, scale); } public SkinImage scale(final double scaleX, final double scaleY) { if (this.scaledImages == null) { this.scaledImages = new HashMap<>(); } final String key = scaleX + "|" + scaleY; SkinImage scaledImage = this.scaledImages.get(key); if (scaledImage == null) { scaledImage = this.clone(); scaledImage.createScaledImage(this, scaleX, scaleY); this.scaledImages.put(key, scaledImage); } return scaledImage; } protected void updateScaledImages() { if (this.scaledImages == null) { return; } for (final Entry<String, SkinImage> i : this.scaledImages.entrySet()) { String[] dims = i.getKey().split("x"); if (dims.length == 2) { //static scale i.getValue().createResizedImage(this, Integer.parseInt(dims[0]), Integer.parseInt(dims[1])); } else { //dynamic scale dims = i.getKey().split("\\|"); //must escape since "|" is regex operator i.getValue().createScaledImage(this, Double.parseDouble(dims[0]), Double.parseDouble(dims[1])); } } } protected void createResizedImage(final SkinImage baseImage, final int w, final int h) { final BufferedImage resizedImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); final Graphics2D g2d = resizedImage.createGraphics(); g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); g2d.drawImage(baseImage.image, 0, 0, w, h, 0, 0, baseImage.getWidth(), baseImage.getHeight(), null); g2d.dispose(); this.changeImage(resizedImage, null); } private void createScaledImage(final SkinImage baseImage, final double scaleX, final double scaleY) { createResizedImage(baseImage, (int) (baseImage.getWidth() * scaleX), (int) (baseImage.getHeight() * scaleY)); } private SkinCursor toCursor(final int hotSpotX, final int hotSpotY, final String name) { if (this.cursors == null) { this.cursors = new HashMap<>(); } final String key = hotSpotX + "|" + hotSpotY + "|" + name; SkinCursor cursor = this.cursors.get(key); if (cursor == null) { cursor = new SkinCursor(new Point(hotSpotX, hotSpotY), name); cursor.updateCursor(this.image); this.cursors.put(key, cursor); } return cursor; } private void updateCursors() { if (this.cursors == null) { return; } for (final SkinCursor cursor : this.cursors.values()) { cursor.updateCursor(this.image); } } public Dimension getSizeForPaint(final Graphics g) { if (g == null) { throw new NullPointerException("Must pass Graphics to get size for paint"); } return new Dimension(this.getWidth(), this.getHeight()); } protected int getWidth() { return this.image.getWidth(null); } protected int getHeight() { return this.image.getHeight(null); } protected ImageIcon getIcon() { if (this.imageIcon == null) { this.imageIcon = new ImageIcon(this.image); } return this.imageIcon; } protected void draw(final Graphics g, final int x, final int y) { g.drawImage(image, x, y, null); } protected void draw(final Graphics g, final int x, final int y, final int w, final int h) { g.drawImage(image, x, y, w, h, null); } protected void draw(final Graphics g, final int dx1, final int dy1, final int dx2, final int dy2, final int sx1, final int sy1, final int sx2, final int sy2) { g.drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null); } } /** * Gets an image. * * @param s0   FSkinProp enum * @return {@link forge.toolbox.FSkin.SkinCursor} */ public static SkinCursor getCursor(final FSkinProp s0, final int hotSpotX, final int hotSpotY, final String name) { return getImage(s0).toCursor(hotSpotX, hotSpotY, name); } public static class SkinCursor { private static final Toolkit TOOLS = Toolkit.getDefaultToolkit(); private final Point hotSpot; private final String name; private Cursor cursor; private SkinCursor(final Point hotSpot0, final String name0) { this.hotSpot = hotSpot0; this.name = name0; } private void updateCursor(final Image image) { this.cursor = TOOLS.createCustomCursor(image, this.hotSpot, this.name); } } /** * Gets an icon. * * @param s0   FSkinProp enum * @return {@link forge.toolbox.FSkin.SkinImage} */ public static SkinIcon getIcon(final FSkinProp s0) { final SkinIcon icon = SkinIcon.icons.get(s0); if (icon == null) { throw new NullPointerException("Can't find an icon for FSkinProp " + s0); } return icon; } public static class SkinIcon extends SkinImage { private static final Map<FSkinProp, SkinIcon> icons = new HashMap<>(); private static void setIcon(final FSkinProp s0, final ImageIcon imageIcon0) { SkinIcon skinIcon = icons.get(s0); if (skinIcon == null) { skinIcon = new SkinIcon(imageIcon0); icons.put(s0, skinIcon); } else { skinIcon.changeImage(imageIcon0.getImage(), imageIcon0); } } private static void setIcon(final FSkinProp s0) { tempCoords = s0.getCoords(); x0 = tempCoords[0]; y0 = tempCoords[1]; w0 = tempCoords[2]; h0 = tempCoords[3]; final BufferedImage img = testPreferredSprite(s0); setIcon(s0, new ImageIcon(img.getSubimage(x0, y0, w0, h0))); } /** * Sets an icon in this skin's icon map from a file address. * Throws IO exception for debugging if needed. * * @param s0 *   Skin property (from enum) * @param s1 *   File address */ private static void setIcon(final FSkinProp s0, final String s1) { try { final File file = new File(s1); ImageIO.read(file); } catch (final IOException e) { e.printStackTrace(); } setIcon(s0, new ImageIcon(s1)); } /** * Sets an icon in this skin's icon map from a buffered image. * * @param s0   Skin property (from enum) * @param bi0   BufferedImage */ private static void setIcon(final FSkinProp s0, final BufferedImage bi0) { setIcon(s0, new ImageIcon(bi0)); } private SkinIcon(final ImageIcon imageIcon0) { super(imageIcon0.getImage()); this.imageIcon = imageIcon0; } @Override protected SkinIcon clone() { return new SkinIcon(this.imageIcon); } @Override public SkinIcon resize(final int w, final int h) { return (SkinIcon) super.resize(w, h); } @Override public SkinIcon scale(final double scale) { return scale(scale, scale); } @Override public SkinIcon scale(final double scaleX, final double scaleY) { return (SkinIcon) super.scale(scaleX, scaleY); } @Override protected void createResizedImage(final SkinImage baseImage, final int w, final int h) { final Image image0 = baseImage.image.getScaledInstance(w, h, java.awt.Image.SCALE_SMOOTH); this.changeImage(image0, new ImageIcon(image0)); } @Override protected int getWidth() { return this.imageIcon.getIconWidth(); } @Override protected int getHeight() { return this.imageIcon.getIconHeight(); } @Override protected ImageIcon getIcon() { //can skip null check since imageIcon will always be set return this.imageIcon; } } //allow creating dynamic icons that can be used in place of skin icons public static class UnskinnedIcon extends SkinIcon { private final float opacity; public UnskinnedIcon(final String path0) { super(new ImageIcon(path0)); opacity = 1; } public UnskinnedIcon(final BufferedImage i0) { this(i0, 1); } public UnskinnedIcon(final BufferedImage i0, final float opacity0) { super(new ImageIcon(i0)); opacity = opacity0; } @Override public ImageIcon getIcon() { return super.getIcon(); } @Override protected void draw(final Graphics g, final int x, final int y) { if (opacity == 1) { super.draw(g, x, y); return; } final Graphics2D g2d = (Graphics2D) g; final Composite oldComp = g2d.getComposite(); g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, opacity)); super.draw(g2d, x, y); g2d.setComposite(oldComp); } @Override protected void draw(final Graphics g, final int x, final int y, final int w, final int h) { if (opacity == 1) { super.draw(g, x, y, w, h); return; } final Graphics2D g2d = (Graphics2D) g; final Composite oldComp = g2d.getComposite(); g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, opacity)); super.draw(g, x, y, w, h); g2d.setComposite(oldComp); } @Override protected void draw(final Graphics g, final int dx1, final int dy1, final int dx2, final int dy2, final int sx1, final int sy1, final int sx2, final int sy2) { if (opacity == 1) { super.draw(g, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2); return; } final Graphics2D g2d = (Graphics2D) g; final Composite oldComp = g2d.getComposite(); g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, opacity)); super.draw(g, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2); g2d.setComposite(oldComp); } } private static Map<Integer, SkinImage> avatars; private static Map<Integer, Font> fixedFonts = new HashMap<>(); /** @return {@link java.awt.font} */ public static Font getFixedFont(final int size) { Font fixedFont = fixedFonts.get(size); if (fixedFont == null) { fixedFont = new Font("Monospaced", Font.PLAIN, size); fixedFonts.put(size, fixedFont); } return fixedFont; } /** * @return {@link forge.toolbox.FSkin.SkinFont} */ public static SkinFont getFont() { return getFont(defaultFontSize); } /** * @param size - integer, pixel size * @return {@link forge.toolbox.FSkin.SkinFont} */ public static SkinFont getFont(final int size) { return SkinFont.get(Font.PLAIN, size); } /** * @return {@link forge.toolbox.FSkin.SkinFont} */ public static SkinFont getBoldFont() { return getBoldFont(defaultFontSize); } /** * @param size - integer, pixel size * @return {@link forge.toolbox.FSkin.SkinFont} */ public static SkinFont getBoldFont(final int size) { return SkinFont.get(Font.BOLD, size); } /** * @return {@link forge.toolbox.FSkin.SkinFont} */ public static SkinFont getItalicFont() { return getItalicFont(defaultFontSize); } /** * @param size - integer, pixel size * @return {@link forge.toolbox.FSkin.SkinFont} */ public static SkinFont getItalicFont(final int size) { return SkinFont.get(Font.ITALIC, size); } public static void setGraphicsFont(final Graphics g, final SkinFont skinFont) { g.setFont(skinFont.font); } public static class SkinFont { private static Font baseFont; private static Map<String, SkinFont> fonts = new HashMap<>(); private static SkinFont get(final int style0, final int size0) { final String key = style0 + "|" + size0; SkinFont skinFont = fonts.get(key); if (skinFont == null) { skinFont = new SkinFont(style0, size0); fonts.put(key, skinFont); } return skinFont; } private static void setBaseFont(final Font baseFont0) { baseFont = baseFont0; //update all cached skin fonts for (final SkinFont skinFont : fonts.values()) { skinFont.updateFont(); } } private final int style, size; private Font font; private SkinFont(final int style0, final int size0) { this.style = style0; this.size = size0; this.updateFont(); } public int getSize() { return this.font.getSize(); } public int measureTextWidth(final Graphics g, final String text) { return g.getFontMetrics(this.font).stringWidth(text); } public FontMetrics getFontMetrics() { return Singletons.getView().getFrame().getGraphics().getFontMetrics(this.font); } private void updateFont() { this.font = baseFont.deriveFont(this.style, this.size); } } private static void addEncodingSymbol(final String key, final FSkinProp skinProp) { final String path = ForgeConstants.CACHE_SYMBOLS_DIR + "/" + key.replace("/", "") + ".png"; getImage(skinProp).save(path, 13, 13); } public static String encodeSymbols(String str, final boolean formatReminderText) { String pattern, replacement; if (formatReminderText) { //format reminder text in italics (or hide if preference set) pattern = "\\((.+)\\)"; replacement = FModel.getPreferences().getPrefBoolean(FPref.UI_HIDE_REMINDER_TEXT) ? "" : "<i>\\($1\\)</i>"; str = str.replaceAll(pattern, replacement); } //format mana symbols to display as icons pattern = "\\{([A-Z0-9]+)\\}|\\{([A-Z0-9]+)/([A-Z0-9]+)\\}"; //fancy pattern needed so "/" can be omitted from replacement try { replacement = "<img src='" + new File(ForgeConstants.CACHE_SYMBOLS_DIR + "/$1$2$3.png").toURI().toURL().toString() + "'>"; str = str.replaceAll(pattern, replacement); } catch (final MalformedURLException e) { e.printStackTrace(); } //ensure paragraph and line breaks aren't lost str = str.replaceAll("\r?\n", "<br>"); return "<html>" + str + "</html>"; //must wrap in <html> tag for images to appear } private static List<String> allSkins; private static int currentSkinIndex; private static String preferredDir; private static String preferredName; private static BufferedImage bimDefaultSprite, bimPreferredSprite, bimFoils, bimQuestDraftDeck, bimOldFoils, bimDefaultAvatars, bimPreferredAvatars, bimTrophies; private static int x0, y0, w0, h0, newW, newH, preferredW, preferredH; private static int[] tempCoords; private static int defaultFontSize = 12; private static boolean loaded = false; public static void changeSkin(final String skinName) { final ForgePreferences prefs = FModel.getPreferences(); if (skinName.equals(prefs.getPref(FPref.UI_SKIN))) { return; } //save skin preference prefs.setPref(FPref.UI_SKIN, skinName); prefs.save(); //load skin loaded = false; //reset this temporarily until end of loadFull() loadLight(skinName, false); loadFull(false); //refresh certain components skinned via look and feel Singletons.getControl().getForgeMenu().refresh(); FComboBoxWrapper.refreshAllSkins(); FComboBoxPanel.refreshAllSkins(); //repaint main frame to ensure all visible components apply the new skin Singletons.getView().getFrame().repaint(); } /** * Loads a "light" version of FSkin, just enough for the splash screen: * skin name. Generates custom skin settings, fonts, and backgrounds. * * * @param skinName * the skin name */ public static void loadLight(final String skinName, final boolean onInit) { if (onInit) { // No need for this method to be loaded while on the EDT. FThreads.assertExecutedByEdt(false); if (allSkins == null) { //initialize allSkins = new ArrayList<>(); final List<String> skinDirectoryNames = getSkinDirectoryNames(); for (String skinDirectoryName : skinDirectoryNames) { allSkins.add(WordUtils.capitalize(skinDirectoryName.replace('_', ' '))); } Collections.sort(allSkins); } } currentSkinIndex = allSkins.indexOf(skinName); // Non-default (preferred) skin name and dir. preferredName = skinName.toLowerCase().replace(' ', '_'); preferredDir = ForgeConstants.SKINS_DIR + preferredName + "/"; if (onInit) { final File f = new File(preferredDir + ForgeConstants.SPLASH_BG_FILE); if (!f.exists()) { if (skinName.equals("default")) { throw new RuntimeException( String.format("Cannot find default skin at %s", f.getAbsolutePath())); } loadLight("default", true); return; } final BufferedImage img; try { img = ImageIO.read(f); final int h = img.getHeight(); final int w = img.getWidth(); SkinIcon.setIcon(FSkinProp.BG_SPLASH, img.getSubimage(0, 0, w, h - 100)); UIManager.put("ProgressBar.background", getColorFromPixel(img.getRGB(25, h - 75))); UIManager.put("ProgressBar.selectionBackground", getColorFromPixel(img.getRGB(75, h - 75))); UIManager.put("ProgressBar.foreground", getColorFromPixel(img.getRGB(25, h - 25))); UIManager.put("ProgressBar.selectionForeground", getColorFromPixel(img.getRGB(75, h - 25))); UIManager.put("ProgressBar.border", new LineBorder(Color.BLACK, 0)); } catch (final IOException e) { e.printStackTrace(); } loaded = true; } } /** * Loads two sprites: the default (which should be a complete * collection of all symbols) and the preferred (which may be * incomplete). * * Font must be present in the skin folder, and will not * be replaced by default. The fonts are pre-derived * in this method and saved in a HashMap for future access. * * Color swatches must be present in the preferred * sprite, and will not be replaced by default. * * Background images must be present in skin folder, * and will not be replaced by default. * * Icons, however, will be pulled from the two sprites. Obviously, * preferred takes precedence over default, but if something is * missing, the default picture is retrieved. */ public static void loadFull(final boolean onInit) { if (onInit) { // No need for this method to be loaded while on the EDT. FThreads.assertExecutedByEdt(false); // Preferred skin name must be called via loadLight() method, // which does some cleanup and init work. if (preferredName.isEmpty()) { loadLight("default", true); } } FView.SINGLETON_INSTANCE.setSplashProgessBarMessage("Processing image sprites: ", 7); // Grab and test various sprite files. final String defaultDir = ForgeConstants.DEFAULT_SKINS_DIR; final File f1 = new File(defaultDir + ForgeConstants.SPRITE_ICONS_FILE); final File f2 = new File(preferredDir + ForgeConstants.SPRITE_ICONS_FILE); final File f3 = new File(defaultDir + ForgeConstants.SPRITE_FOILS_FILE); final File f4 = new File(defaultDir + ForgeConstants.SPRITE_AVATARS_FILE); final File f5 = new File(preferredDir + ForgeConstants.SPRITE_AVATARS_FILE); final File f6 = new File(defaultDir + ForgeConstants.SPRITE_OLD_FOILS_FILE); final File f7 = new File(defaultDir + ForgeConstants.SPRITE_TROPHIES_FILE); final File f8 = new File(defaultDir + ForgeConstants.DRAFT_DECK_IMG_FILE); try { int p = 0; bimDefaultSprite = ImageIO.read(f1); FView.SINGLETON_INSTANCE.incrementSplashProgessBar(++p); bimPreferredSprite = ImageIO.read(f2); FView.SINGLETON_INSTANCE.incrementSplashProgessBar(++p); bimFoils = ImageIO.read(f3); FView.SINGLETON_INSTANCE.incrementSplashProgessBar(++p); bimOldFoils = f6.exists() ? ImageIO.read(f6) : ImageIO.read(f3); FView.SINGLETON_INSTANCE.incrementSplashProgessBar(++p); bimDefaultAvatars = ImageIO.read(f4); FView.SINGLETON_INSTANCE.incrementSplashProgessBar(++p); bimTrophies = ImageIO.read(f7); FView.SINGLETON_INSTANCE.incrementSplashProgessBar(++p); bimQuestDraftDeck = ImageIO.read(f8); if (f5.exists()) { bimPreferredAvatars = ImageIO.read(f5); } FView.SINGLETON_INSTANCE.incrementSplashProgessBar(++p); preferredH = bimPreferredSprite.getHeight(); preferredW = bimPreferredSprite.getWidth(); } catch (final Exception e) { System.err.println("FSkin$loadFull: Missing a sprite (default icons, " + "preferred icons, or foils."); e.printStackTrace(); } // Initialize fonts if (onInit) { //set default font size only once onInit final Font f = UIManager.getDefaults().getFont("Label.font"); if (f != null) { defaultFontSize = f.getSize(); } } SkinFont.setBaseFont(GuiUtils.newFont(preferredDir + ForgeConstants.FONT_FILE)); // Put various images into map (except sprite and splash). // Exceptions handled inside method. SkinIcon.setIcon(FSkinProp.BG_TEXTURE, preferredDir + ForgeConstants.TEXTURE_BG_FILE); SkinIcon.setIcon(FSkinProp.BG_MATCH, preferredDir + ForgeConstants.MATCH_BG_FILE); // Run through enums and load their coords. Colors.updateAll(); for (final FSkinProp prop : FSkinProp.values()) { switch (prop.getType()) { case IMAGE: SkinImage.setImage(prop); break; case ICON: SkinIcon.setIcon(prop); break; case FOIL: setImage(prop, bimFoils); break; case OLD_FOIL: setImage(prop, bimOldFoils); break; case TROPHY: setImage(prop, bimTrophies); break; default: break; } } // Assemble avatar images assembleAvatars(); // Images loaded; can start UI init. FView.SINGLETON_INSTANCE.setSplashProgessBarMessage("Creating display components."); loaded = true; // Clear references to buffered images bimDefaultSprite.flush(); bimFoils.flush(); bimOldFoils.flush(); bimPreferredSprite.flush(); bimDefaultAvatars.flush(); bimQuestDraftDeck.flush(); bimTrophies.flush(); if (bimPreferredAvatars != null) { bimPreferredAvatars.flush(); } bimDefaultSprite = null; bimFoils = null; bimOldFoils = null; bimPreferredSprite = null; bimDefaultAvatars = null; bimPreferredAvatars = null; bimQuestDraftDeck = null; bimTrophies = null; //establish encoding symbols final File dir = new File(ForgeConstants.CACHE_SYMBOLS_DIR); if (!dir.mkdir()) { //ensure symbols directory exists and is empty File[] files = dir.listFiles(); assert files != null; for (final File file : files) { file.delete(); } } addEncodingSymbol("W", FSkinProp.IMG_MANA_W); addEncodingSymbol("U", FSkinProp.IMG_MANA_U); addEncodingSymbol("B", FSkinProp.IMG_MANA_B); addEncodingSymbol("R", FSkinProp.IMG_MANA_R); addEncodingSymbol("G", FSkinProp.IMG_MANA_G); addEncodingSymbol("W/U", FSkinProp.IMG_MANA_HYBRID_WU); addEncodingSymbol("U/B", FSkinProp.IMG_MANA_HYBRID_UB); addEncodingSymbol("B/R", FSkinProp.IMG_MANA_HYBRID_BR); addEncodingSymbol("R/G", FSkinProp.IMG_MANA_HYBRID_RG); addEncodingSymbol("G/W", FSkinProp.IMG_MANA_HYBRID_GW); addEncodingSymbol("W/B", FSkinProp.IMG_MANA_HYBRID_WB); addEncodingSymbol("U/R", FSkinProp.IMG_MANA_HYBRID_UR); addEncodingSymbol("B/G", FSkinProp.IMG_MANA_HYBRID_BG); addEncodingSymbol("R/W", FSkinProp.IMG_MANA_HYBRID_RW); addEncodingSymbol("G/U", FSkinProp.IMG_MANA_HYBRID_GU); addEncodingSymbol("2/W", FSkinProp.IMG_MANA_2W); addEncodingSymbol("2/U", FSkinProp.IMG_MANA_2U); addEncodingSymbol("2/B", FSkinProp.IMG_MANA_2B); addEncodingSymbol("2/R", FSkinProp.IMG_MANA_2R); addEncodingSymbol("2/G", FSkinProp.IMG_MANA_2G); addEncodingSymbol("P/W", FSkinProp.IMG_MANA_PHRYX_W); addEncodingSymbol("P/U", FSkinProp.IMG_MANA_PHRYX_U); addEncodingSymbol("P/B", FSkinProp.IMG_MANA_PHRYX_B); addEncodingSymbol("P/R", FSkinProp.IMG_MANA_PHRYX_R); addEncodingSymbol("P/G", FSkinProp.IMG_MANA_PHRYX_G); for (int i = 0; i <= 20; i++) { addEncodingSymbol(String.valueOf(i), FSkinProp.valueOf("IMG_MANA_" + i)); } addEncodingSymbol("X", FSkinProp.IMG_MANA_X); addEncodingSymbol("Y", FSkinProp.IMG_MANA_Y); addEncodingSymbol("Z", FSkinProp.IMG_MANA_Z); addEncodingSymbol("C", FSkinProp.IMG_CHAOS); addEncodingSymbol("Q", FSkinProp.IMG_UNTAP); addEncodingSymbol("S", FSkinProp.IMG_MANA_SNOW); addEncodingSymbol("T", FSkinProp.IMG_TAP); // Set look and feel after skin loaded FView.SINGLETON_INSTANCE.setSplashProgessBarMessage("Setting look and feel..."); final ForgeLookAndFeel laf = new ForgeLookAndFeel(); laf.setForgeLookAndFeel(Singletons.getView().getFrame()); } /** * Gets the skins. * * @return the skins */ public static List<String> getSkinDirectoryNames() { final List<String> mySkins = new ArrayList<>(); final File dir = new File(ForgeConstants.SKINS_DIR); final String[] children = dir.list(); if (children == null) { System.err.println("FSkin > can't find skins directory!"); } else { for (String aChildren : children) { if (aChildren.equalsIgnoreCase(".svn")) { continue; } if (aChildren.equalsIgnoreCase(".DS_Store")) { continue; } mySkins.add(aChildren); } } return mySkins; } public static Iterable<String> getAllSkins() { return allSkins; } public static Map<Integer, SkinImage> getAvatars() { return avatars; } public static boolean isLoaded() { return loaded; } /** * getColorFromPixel * @param pixel * @return */ private static Color getColorFromPixel(final int pixel) { int r, g, b, a; a = (pixel >> 24) & 0x000000ff; r = (pixel >> 16) & 0x000000ff; g = (pixel >> 8) & 0x000000ff; b = (pixel) & 0x000000ff; return new Color(r, g, b, a); } private static BufferedImage testPreferredSprite(final FSkinProp s0) { tempCoords = s0.getCoords(); x0 = tempCoords[0]; y0 = tempCoords[1]; w0 = tempCoords[2]; h0 = tempCoords[3]; if (s0.equals(FSkinProp.IMG_QUEST_DRAFT_DECK)) { final Color c = getColorFromPixel(bimQuestDraftDeck.getRGB((x0 + w0 / 2), (y0 + h0 / 2))); if (c.getAlpha() != 0) { return bimQuestDraftDeck; } } // Test if requested sub-image in inside bounds of preferred sprite. // (Height and width of preferred sprite were set in loadFontAndImages.) if (x0 > preferredW || x0 + w0 > preferredW || y0 > preferredH || y0 + h0 > preferredH) { return bimDefaultSprite; } // Test if various points of requested sub-image are transparent. // If any return true, image exists. int x, y; Color c; // Center x = (x0 + w0 / 2); y = (y0 + h0 / 2); c = getColorFromPixel(bimPreferredSprite.getRGB(x, y)); if (c.getAlpha() != 0) { return bimPreferredSprite; } x += 2; y += 2; c = getColorFromPixel(bimPreferredSprite.getRGB(x, y)); if (c.getAlpha() != 0) { return bimPreferredSprite; } x -= 4; c = getColorFromPixel(bimPreferredSprite.getRGB(x, y)); if (c.getAlpha() != 0) { return bimPreferredSprite; } y -= 4; c = getColorFromPixel(bimPreferredSprite.getRGB(x, y)); if (c.getAlpha() != 0) { return bimPreferredSprite; } x += 4; c = getColorFromPixel(bimPreferredSprite.getRGB(x, y)); if (c.getAlpha() != 0) { return bimPreferredSprite; } return bimDefaultSprite; } private static void assembleAvatars() { avatars = new HashMap<>(); int counter = 0; Color pxTest; if (bimPreferredAvatars != null) { final int pw = bimPreferredAvatars.getWidth(); final int ph = bimPreferredAvatars.getHeight(); for (int j = 0; j < ph; j += 100) { for (int i = 0; i < pw; i += 100) { if (i == 0 && j == 0) { continue; } pxTest = getColorFromPixel(bimPreferredAvatars.getRGB(i + 50, j + 50)); if (pxTest.getAlpha() == 0) { continue; } avatars.put(counter++, new SkinImage(bimPreferredAvatars.getSubimage(i, j, 100, 100))); } } } else { final int aw = bimDefaultAvatars.getWidth(); final int ah = bimDefaultAvatars.getHeight(); for (int j = 0; j < ah; j += 100) { for (int i = 0; i < aw; i += 100) { if (i == 0 && j == 0) { continue; } pxTest = getColorFromPixel(bimDefaultAvatars.getRGB(i + 50, j + 50)); if (pxTest.getAlpha() == 0) { continue; } avatars.put(counter++, new SkinImage(bimDefaultAvatars.getSubimage(i, j, 100, 100))); } } } } private static void setImage(final FSkinProp s0, final BufferedImage bim) { tempCoords = s0.getCoords(); x0 = tempCoords[0]; y0 = tempCoords[1]; w0 = tempCoords[2]; h0 = tempCoords[3]; SkinImage.setImage(s0, bim.getSubimage(x0, y0, w0, h0)); } /** * Sets the look and feel of the GUI based on the selected Forge theme. * * @see <a href="http://tips4java.wordpress.com/2008/10/09/uimanager-defaults/">UIManager Defaults</a> */ private static class ForgeLookAndFeel { //needs to live in FSkin for access to skin colors private static boolean onInit = true; private static boolean isMetalLafSet = false; private final Color FORE_COLOR = getColor(Colors.CLR_TEXT).color; private final Color BACK_COLOR = getColor(Colors.CLR_THEME2).color; private final Color HIGHLIGHT_COLOR = BACK_COLOR.brighter(); private final Border LINE_BORDER = BorderFactory.createLineBorder(FORE_COLOR.darker(), 1); private final Border EMPTY_BORDER = BorderFactory.createEmptyBorder(2, 2, 2, 2); /** * Sets the look and feel of the GUI based on the selected Forge theme. */ private void setForgeLookAndFeel(final JFrame appFrame) { if (setMetalLookAndFeel(appFrame)) { setMenusLookAndFeel(); setComboBoxLookAndFeel(); setTabbedPaneLookAndFeel(); setButtonLookAndFeel(); setToolTipLookAndFeel(); } onInit = false; } /** * Sets the standard "Java L&F" (also called "Metal") that looks the same on all platforms. * <p> * If not explicitly set then the Mac uses its native L&F which does * not support various settings (eg. combobox background color). */ private boolean setMetalLookAndFeel(final JFrame appFrame) { if (onInit) { //only attempt to set Metal Look and Feel the first time try { UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel"); SwingUtilities.updateComponentTreeUI(appFrame); isMetalLafSet = true; } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) { // Auto-generated catch block ignores the exception, but sends it to System.err and probably forge.log. e.printStackTrace(); } } return isMetalLafSet; } /** * Sets the look and feel for a JMenuBar, JMenu, JMenuItem & variations. */ private void setMenusLookAndFeel() { // JMenuBar final Color clrTheme = getColor(Colors.CLR_THEME).color; final Color backgroundColor = stepColor(clrTheme, 0); final Color menuBarEdgeColor = stepColor(clrTheme, -80); UIManager.put("MenuBar.foreground", FORE_COLOR); UIManager.put("MenuBar.gradient", getColorGradients(backgroundColor.darker(), backgroundColor)); UIManager.put("MenuBar.border", BorderFactory.createMatteBorder(0, 0, 1, 0, menuBarEdgeColor)); // JMenu UIManager.put("Menu.foreground", FORE_COLOR); UIManager.put("Menu.background", BACK_COLOR); UIManager.put("Menu.borderPainted", false); UIManager.put("Menu.selectionBackground", HIGHLIGHT_COLOR); UIManager.put("Menu.selectionForeground", FORE_COLOR); UIManager.put("Menu.border", EMPTY_BORDER); UIManager.put("Menu.opaque", false); // JPopupMenu UIManager.put("PopupMenu.border", LINE_BORDER); UIManager.put("PopupMenu.background", BACK_COLOR); UIManager.put("PopupMenu.foreground", FORE_COLOR); // JMenuItem UIManager.put("MenuItem.foreground", FORE_COLOR); UIManager.put("MenuItem.background", BACK_COLOR); UIManager.put("MenuItem.border", EMPTY_BORDER); UIManager.put("MenuItem.selectionBackground", HIGHLIGHT_COLOR); UIManager.put("MenuItem.selectionForeground", FORE_COLOR); UIManager.put("MenuItem.acceleratorForeground", FORE_COLOR.darker()); UIManager.put("MenuItem.opaque", true); // JSeparator (needs to be opaque!). UIManager.put("Separator.foreground", FORE_COLOR.darker()); UIManager.put("Separator.background", BACK_COLOR); // JRadioButtonMenuItem UIManager.put("RadioButtonMenuItem.foreground", FORE_COLOR); UIManager.put("RadioButtonMenuItem.background", BACK_COLOR); UIManager.put("RadioButtonMenuItem.selectionBackground", HIGHLIGHT_COLOR); UIManager.put("RadioButtonMenuItem.selectionForeground", FORE_COLOR); UIManager.put("RadioButtonMenuItem.border", EMPTY_BORDER); UIManager.put("RadioButtonMenuItem.acceleratorForeground", FORE_COLOR.darker()); // JCheckboxMenuItem UIManager.put("CheckBoxMenuItem.foreground", FORE_COLOR); UIManager.put("CheckBoxMenuItem.background", BACK_COLOR); UIManager.put("CheckBoxMenuItem.selectionBackground", HIGHLIGHT_COLOR); UIManager.put("CheckBoxMenuItem.selectionForeground", FORE_COLOR); UIManager.put("CheckBoxMenuItem.border", EMPTY_BORDER); UIManager.put("CheckBoxMenuItem.acceleratorForeground", FORE_COLOR.darker()); } private void setTabbedPaneLookAndFeel() { UIManager.put("TabbedPane.selected", HIGHLIGHT_COLOR); UIManager.put("TabbedPane.contentOpaque", getColor(Colors.CLR_THEME)); UIManager.put("TabbedPane.unselectedBackground", BACK_COLOR); } /** * Sets the look and feel for a <b>non-editable</b> JComboBox. */ private void setComboBoxLookAndFeel() { UIManager.put("ComboBox.background", BACK_COLOR); UIManager.put("ComboBox.foreground", FORE_COLOR); UIManager.put("ComboBox.selectionBackground", HIGHLIGHT_COLOR); UIManager.put("ComboBox.selectionForeground", FORE_COLOR); UIManager.put("ComboBox.disabledBackground", BACK_COLOR); UIManager.put("ComboBox.disabledForeground", BACK_COLOR.darker()); UIManager.put("ComboBox.font", getDefaultFont("ComboBox.font")); final boolean isBright = isColorBright(FORE_COLOR); UIManager.put("ComboBox.border", BorderFactory.createLineBorder(isBright ? FORE_COLOR.darker() : FORE_COLOR.brighter(), 1)); } private void setButtonLookAndFeel() { UIManager.put("Button.foreground", FORE_COLOR); UIManager.put("Button.background", BACK_COLOR); UIManager.put("Button.select", HIGHLIGHT_COLOR); UIManager.put("Button.focus", FORE_COLOR.darker()); UIManager.put("Button.rollover", false); } private void setToolTipLookAndFeel() { UIManager.put("ToolTip.background", BACK_COLOR); UIManager.put("ToolTip.foreground", FORE_COLOR); UIManager.put("ToolTip.border", LINE_BORDER); } private static Font getDefaultFont(final String component) { return getFont(UIManager.getFont(component).getSize()).font; } private static List<Object> getColorGradients(final Color bottom, final Color top) { final List<Object> gradients = new ArrayList<>(); gradients.add(0.0); gradients.add(0.0); gradients.add(top); gradients.add(bottom); gradients.add(bottom); return gradients; } } public static class ComponentSkin<T extends Component> { private SkinColor foreground, background; private SkinFont font; private SkinCursor cursor; private int appliedSkinIndex = currentSkinIndex; protected ComponentSkin() { } protected boolean update(final T comp) { if (appliedSkinIndex == currentSkinIndex) { return false; } appliedSkinIndex = currentSkinIndex; reapply(comp); return true; } public SkinColor getForeground() { return this.foreground; } protected void setForeground(final T comp, final SkinColor skinColor) { comp.setForeground(skinColor != null ? skinColor.color : null); this.foreground = skinColor; } protected void resetForeground() { this.foreground = null; } public SkinColor getBackground() { return this.background; } protected void setBackground(final T comp, final SkinColor skinColor) { comp.setBackground(skinColor != null ? skinColor.color : null); this.background = skinColor; } protected void resetBackground() { this.background = null; } public SkinFont getFont() { return this.font; } protected void setFont(final T comp, final SkinFont skinFont) { comp.setFont(skinFont != null ? skinFont.font : null); this.font = skinFont; } protected void resetFont() { this.font = null; } protected void setCursor(final T comp, final SkinCursor skinCursor) { comp.setCursor(skinCursor != null ? skinCursor.cursor : null); this.cursor = skinCursor; } protected void resetCursor() { this.cursor = null; } protected void reapply(final T comp) { if (this.foreground != null) { setForeground(comp, this.foreground); } if (this.background != null) { setBackground(comp, this.background); } if (this.font != null) { setFont(comp, this.font); } if (this.cursor != null) { setCursor(comp, this.cursor); } } } public static class WindowSkin<T extends Window> extends ComponentSkin<T> { private SkinImage iconImage; protected WindowSkin() { } protected void setIconImage(final T comp, final SkinImage skinImage) { comp.setIconImage(skinImage != null ? skinImage.image : null); this.iconImage = skinImage; } protected void resetIconImage() { this.iconImage = null; } @Override protected void reapply(final T comp) { if (this.iconImage != null) { setIconImage(comp, this.iconImage); } super.reapply(comp); } } public static class JComponentSkin<T extends JComponent> extends ComponentSkin<T> { private SkinBorder border; protected JComponentSkin() { } protected void setBorder(final T comp, final SkinBorder skinBorder) { comp.setBorder(skinBorder != null ? skinBorder.createBorder() : null); this.border = skinBorder; } protected void resetBorder() { this.border = null; } @Override protected void reapply(final T comp) { if (this.border != null) { setBorder(comp, this.border); } super.reapply(comp); } } public static class JLabelSkin<T extends JLabel> extends JComponentSkin<T> { private SkinImage icon; protected JLabelSkin() { } protected void setIcon(final T comp, final SkinImage skinImage) { comp.setIcon(skinImage != null ? skinImage.getIcon() : null); this.icon = skinImage; } protected void resetIcon() { this.icon = null; } @Override protected void reapply(final T comp) { if (this.icon != null) { setIcon(comp, this.icon); } super.reapply(comp); } } public static class AbstractButtonSkin<T extends AbstractButton> extends JComponentSkin<T> { private SkinImage icon, pressedIcon, rolloverIcon; protected AbstractButtonSkin() { } protected void setIcon(final T comp, final SkinImage skinImage) { comp.setIcon(skinImage != null ? skinImage.getIcon() : null); this.icon = skinImage; } protected void resetIcon() { this.icon = null; } protected void setPressedIcon(final T comp, final SkinImage skinImage) { comp.setPressedIcon(skinImage != null ? skinImage.getIcon() : null); this.pressedIcon = skinImage; } protected void resetPressedIcon() { this.pressedIcon = null; } protected void setRolloverIcon(final T comp, final SkinImage skinImage) { comp.setRolloverIcon(skinImage != null ? skinImage.getIcon() : null); this.rolloverIcon = skinImage; } protected void resetRolloverIcon() { this.rolloverIcon = null; } @Override protected void reapply(final T comp) { if (this.icon != null) { setIcon(comp, this.icon); } if (this.pressedIcon != null) { setPressedIcon(comp, this.pressedIcon); } if (this.rolloverIcon != null) { setRolloverIcon(comp, this.rolloverIcon); } super.reapply(comp); } } public static class JTextComponentSkin<T extends JTextComponent> extends JComponentSkin<T> { private SkinColor caretColor; protected JTextComponentSkin() { } protected void setCaretColor(final T comp, final SkinColor skinColor) { comp.setCaretColor(skinColor != null ? skinColor.color : null); this.caretColor = skinColor; } protected void resetCaretColor() { this.caretColor = null; } @Override protected void reapply(final T comp) { if (this.caretColor != null) { setCaretColor(comp, this.caretColor); } super.reapply(comp); } } public static class JTableSkin<T extends JTable> extends JComponentSkin<T> { private SkinColor selectionForeground, selectionBackground, gridColor; protected JTableSkin() { } protected void setSelectionForeground(final T comp, final SkinColor skinColor) { comp.setSelectionForeground(skinColor != null ? skinColor.color : null); this.selectionForeground = skinColor; } protected void resetSelectionForeground() { this.selectionForeground = null; } protected void setSelectionBackground(final T comp, final SkinColor skinColor) { comp.setSelectionBackground(skinColor != null ? skinColor.color : null); this.selectionBackground = skinColor; } protected void resetSelectionBackground() { this.selectionBackground = null; } protected void setGridColor(final T comp, final SkinColor skinColor) { comp.setGridColor(skinColor != null ? skinColor.color : null); this.gridColor = skinColor; } protected void resetGridColor() { this.gridColor = null; } @Override protected void reapply(final T comp) { if (this.selectionForeground != null) { setSelectionForeground(comp, this.selectionForeground); } if (this.selectionBackground != null) { setSelectionBackground(comp, this.selectionBackground); } if (this.gridColor != null) { setGridColor(comp, this.gridColor); } super.reapply(comp); } } public static class JSkinSkin<T extends JList<?>> extends JComponentSkin<T> { private SkinColor selectionForeground, selectionBackground; protected JSkinSkin() { } protected void setSelectionForeground(final T comp, final SkinColor skinColor) { comp.setSelectionForeground(skinColor != null ? skinColor.color : null); this.selectionForeground = skinColor; } protected void resetSelectionForeground() { this.selectionForeground = null; } protected void setSelectionBackground(final T comp, final SkinColor skinColor) { comp.setSelectionBackground(skinColor != null ? skinColor.color : null); this.selectionBackground = skinColor; } protected void resetSelectionBackground() { this.selectionBackground = null; } @Override protected void reapply(final T comp) { if (this.selectionForeground != null) { setSelectionForeground(comp, this.selectionForeground); } if (this.selectionBackground != null) { setSelectionBackground(comp, this.selectionBackground); } super.reapply(comp); } } public interface ISkinnedComponent<T extends Component> { ComponentSkin<T> getSkin(); } public static class SkinnedFrame extends JFrame implements ISkinnedComponent<JFrame> { private static final long serialVersionUID = -7737786252990479019L; private SkinBorder border; private WindowSkin<JFrame> skin; @Override public WindowSkin<JFrame> getSkin() { if (skin == null) { skin = new WindowSkin<>(); } return skin; } public SkinnedFrame() { super(); } public void setForeground(final SkinColor skinColor) { getSkin().setForeground(this, skinColor); } @Override public void setForeground(final Color color) { getSkin().resetForeground(); super.setForeground(color); } public void setBackground(final SkinColor skinColor) { getSkin().setBackground(this, skinColor); } @Override public void setBackground(final Color color) { getSkin().resetBackground(); super.setBackground(color); } public void setFont(final SkinFont skinFont) { getSkin().setFont(this, skinFont); } @Override public void setFont(final Font font) { getSkin().resetFont(); super.setFont(font); } public void setCursor(final SkinCursor skinCursor) { getSkin().setCursor(this, skinCursor); } @Override public void setCursor(final Cursor cursor) { getSkin().resetCursor(); super.setCursor(cursor); } public void setIconImage(final SkinImage skinImage) { getSkin().setIconImage(this, skinImage); } @Override public void setIconImage(final Image image) { getSkin().resetIconImage(); super.setIconImage(image); } //relay border to root pane public void setBorder(final SkinBorder skinBorder) { getRootPane().setBorder(skinBorder != null ? skinBorder.createBorder() : null); this.border = skinBorder; } public void setBorder(final Border border) { getRootPane().setBorder(border); this.border = null; } @Override public void paint(final Graphics g) { if (getSkin().update(this)) { if (this.border != null) { setBorder(this.border); } } super.paint(g); } } public static class SkinnedDialog extends JDialog implements ISkinnedComponent<JDialog> { private static final long serialVersionUID = -1086360770925335844L; private SkinBorder border; private WindowSkin<JDialog> skin; @Override public WindowSkin<JDialog> getSkin() { if (skin == null) { skin = new WindowSkin<>(); } return skin; } public SkinnedDialog() { super(); } public SkinnedDialog(final Frame owner, final boolean modal) { super(owner, modal); } public void setForeground(final SkinColor skinColor) { getSkin().setForeground(this, skinColor); } @Override public void setForeground(final Color color) { getSkin().resetForeground(); super.setForeground(color); } public void setBackground(final SkinColor skinColor) { getSkin().setBackground(this, skinColor); } @Override public void setBackground(final Color color) { getSkin().resetBackground(); super.setBackground(color); } public void setFont(final SkinFont skinFont) { getSkin().setFont(this, skinFont); } @Override public void setFont(final Font font) { getSkin().resetFont(); super.setFont(font); } public void setCursor(final SkinCursor skinCursor) { getSkin().setCursor(this, skinCursor); } @Override public void setCursor(final Cursor cursor) { getSkin().resetCursor(); super.setCursor(cursor); } public void setIconImage(final SkinImage skinImage) { getSkin().setIconImage(this, skinImage); } @Override public void setIconImage(final Image image) { getSkin().resetIconImage(); super.setIconImage(image); } //relay border to root pane public void setBorder(final SkinBorder skinBorder) { getRootPane().setBorder(skinBorder != null ? skinBorder.createBorder() : null); this.border = skinBorder; } public void setBorder(final Border border) { getRootPane().setBorder(border); this.border = null; } @Override public void paint(final Graphics g) { if (getSkin().update(this)) { if (this.border != null) { setBorder(this.border); } } super.paint(g); } } public static class SkinnedLayeredPane extends JLayeredPane implements ISkinnedComponent<JLayeredPane> { private static final long serialVersionUID = -8325505112790327931L; private JComponentSkin<JLayeredPane> skin; @Override public JComponentSkin<JLayeredPane> getSkin() { if (skin == null) { skin = new JComponentSkin<>(); } return skin; } public SkinnedLayeredPane() { super(); } public void setCursor(final SkinCursor skinCursor) { getSkin().setCursor(this, skinCursor); } @Override public void setCursor(final Cursor cursor) { getSkin().resetCursor(); super.setCursor(cursor); } @Override protected void paintComponent(final Graphics g) { getSkin().update(this); super.paintComponent(g); } } public static class SkinnedMenuBar extends JMenuBar implements ISkinnedComponent<JMenuBar> { private static final long serialVersionUID = -183434586261989294L; private JComponentSkin<JMenuBar> skin; @Override public JComponentSkin<JMenuBar> getSkin() { if (skin == null) { skin = new JComponentSkin<>(); } return skin; } public SkinnedMenuBar() { super(); } public void setForeground(final SkinColor skinColor) { getSkin().setForeground(this, skinColor); } @Override public void setForeground(final Color color) { getSkin().resetForeground(); super.setForeground(color); } public void setBackground(final SkinColor skinColor) { getSkin().setBackground(this, skinColor); } @Override public void setBackground(final Color color) { getSkin().resetBackground(); super.setBackground(color); } public void setFont(final SkinFont skinFont) { getSkin().setFont(this, skinFont); } @Override public void setFont(final Font font) { getSkin().resetFont(); super.setFont(font); } public void setCursor(final SkinCursor skinCursor) { getSkin().setCursor(this, skinCursor); } @Override public void setCursor(final Cursor cursor) { getSkin().resetCursor(); super.setCursor(cursor); } public void setBorder(final SkinBorder skinBorder) { getSkin().setBorder(this, skinBorder); } @Override public void setBorder(final Border border) { getSkin().resetBorder(); super.setBorder(border); } @Override protected void paintComponent(final Graphics g) { getSkin().update(this); super.paintComponent(g); } } public static class SkinnedLabel extends JLabel implements ISkinnedComponent<JLabel> { private static final long serialVersionUID = 7046941724535782054L; private JLabelSkin<JLabel> skin; @Override public JLabelSkin<JLabel> getSkin() { if (skin == null) { skin = new JLabelSkin<>(); } return skin; } public SkinnedLabel() { super(); } public SkinnedLabel(final String text) { super(text); } public void setForeground(final SkinColor skinColor) { getSkin().setForeground(this, skinColor); } @Override public void setForeground(final Color color) { getSkin().resetForeground(); super.setForeground(color); } public void setBackground(final SkinColor skinColor) { getSkin().setBackground(this, skinColor); } @Override public void setBackground(final Color color) { getSkin().resetBackground(); super.setBackground(color); } public void setFont(final SkinFont skinFont) { getSkin().setFont(this, skinFont); } @Override public void setFont(final Font font) { getSkin().resetFont(); super.setFont(font); } public void setCursor(final SkinCursor skinCursor) { getSkin().setCursor(this, skinCursor); } @Override public void setCursor(final Cursor cursor) { getSkin().resetCursor(); super.setCursor(cursor); } public void setBorder(final SkinBorder skinBorder) { getSkin().setBorder(this, skinBorder); } @Override public void setBorder(final Border border) { getSkin().resetBorder(); super.setBorder(border); } public void setIcon(final SkinImage skinImage) { getSkin().setIcon(this, skinImage); } @Override public void setIcon(final Icon icon) { getSkin().resetIcon(); super.setIcon(icon); } @Override protected void paintComponent(final Graphics g) { getSkin().update(this); super.paintComponent(g); } } public static class SkinnedComboBox<E> extends JComboBox<E> implements ISkinnedComponent<JComboBox<E>> { private static final long serialVersionUID = 9032839876990765149L; private JComponentSkin<JComboBox<E>> skin; @Override public JComponentSkin<JComboBox<E>> getSkin() { if (skin == null) { skin = new JComponentSkin<>(); } return skin; } public SkinnedComboBox() { super(); } public SkinnedComboBox(final ComboBoxModel<E> model0) { super(model0); } public SkinnedComboBox(final E[] items) { super(items); } public SkinnedComboBox(final Vector<E> items) { super(items); } public void setForeground(final SkinColor skinColor) { getSkin().setForeground(this, skinColor); } @Override public void setForeground(final Color color) { getSkin().resetForeground(); super.setForeground(color); } public void setBackground(final SkinColor skinColor) { getSkin().setBackground(this, skinColor); } @Override public void setBackground(final Color color) { getSkin().resetBackground(); super.setBackground(color); } public void setFont(final SkinFont skinFont) { getSkin().setFont(this, skinFont); } @Override public void setFont(final Font font) { getSkin().resetFont(); super.setFont(font); } public void setCursor(final SkinCursor skinCursor) { getSkin().setCursor(this, skinCursor); } @Override public void setCursor(final Cursor cursor) { getSkin().resetCursor(); super.setCursor(cursor); } public void setBorder(final SkinBorder skinBorder) { getSkin().setBorder(this, skinBorder); } @Override public void setBorder(final Border border) { getSkin().resetBorder(); super.setBorder(border); } @Override protected void paintComponent(final Graphics g) { getSkin().update(this); super.paintComponent(g); } } public static class SkinnedList<E> extends JList<E> implements ISkinnedComponent<JList<E>> { private static final long serialVersionUID = -2449981390420167627L; private JSkinSkin<JList<E>> skin; @Override public JSkinSkin<JList<E>> getSkin() { if (skin == null) { skin = new JSkinSkin<>(); } return skin; } public SkinnedList() { super(); } public SkinnedList(final ListModel<E> model0) { super(model0); } public SkinnedList(final E[] items) { super(items); } public void setForeground(final SkinColor skinColor) { getSkin().setForeground(this, skinColor); } @Override public void setForeground(final Color color) { getSkin().resetForeground(); super.setForeground(color); } public void setBackground(final SkinColor skinColor) { getSkin().setBackground(this, skinColor); } @Override public void setBackground(final Color color) { getSkin().resetBackground(); super.setBackground(color); } public void setFont(final SkinFont skinFont) { getSkin().setFont(this, skinFont); } @Override public void setFont(final Font font) { getSkin().resetFont(); super.setFont(font); } public void setCursor(final SkinCursor skinCursor) { getSkin().setCursor(this, skinCursor); } @Override public void setCursor(final Cursor cursor) { getSkin().resetCursor(); super.setCursor(cursor); } public void setBorder(final SkinBorder skinBorder) { getSkin().setBorder(this, skinBorder); } @Override public void setBorder(final Border border) { getSkin().resetBorder(); super.setBorder(border); } public void setSelectionForeground(final SkinColor skinColor) { getSkin().setSelectionForeground(this, skinColor); } @Override public void setSelectionForeground(final Color color) { getSkin().resetSelectionForeground(); super.setSelectionForeground(color); } public void setSelectionBackground(final SkinColor skinColor) { getSkin().setSelectionBackground(this, skinColor); } @Override public void setSelectionBackground(final Color color) { getSkin().resetSelectionBackground(); super.setSelectionBackground(color); } @Override protected void paintComponent(final Graphics g) { getSkin().update(this); super.paintComponent(g); } } public static class SkinnedPanel extends JPanel implements ISkinnedComponent<JPanel> { private static final long serialVersionUID = -1842620489613307379L; private JComponentSkin<JPanel> skin; @Override public JComponentSkin<JPanel> getSkin() { if (skin == null) { skin = new JComponentSkin<>(); } return skin; } public SkinnedPanel() { super(); } public SkinnedPanel(final LayoutManager layoutManager) { super(layoutManager); } public void setForeground(final SkinColor skinColor) { getSkin().setForeground(this, skinColor); } @Override public void setForeground(final Color color) { getSkin().resetForeground(); super.setForeground(color); } public void setBackground(final SkinColor skinColor) { getSkin().setBackground(this, skinColor); } @Override public void setBackground(final Color color) { getSkin().resetBackground(); super.setBackground(color); } public void setFont(final SkinFont skinFont) { getSkin().setFont(this, skinFont); } @Override public void setFont(final Font font) { getSkin().resetFont(); super.setFont(font); } public void setCursor(final SkinCursor skinCursor) { getSkin().setCursor(this, skinCursor); } @Override public void setCursor(final Cursor cursor) { getSkin().resetCursor(); super.setCursor(cursor); } public void setBorder(final SkinBorder skinBorder) { getSkin().setBorder(this, skinBorder); } @Override public void setBorder(final Border border) { getSkin().resetBorder(); super.setBorder(border); } @Override protected void paintComponent(final Graphics g) { getSkin().update(this); super.paintComponent(g); } } public static abstract class FPanelBase extends SkinnedPanel { private static final long serialVersionUID = -7223626737375474132L; private SkinImage foregroundImage, backgroundTexture; private SkinColor backgroundTextureOverlay; protected FPanelBase() { super(); } public FPanelBase(final LayoutManager layoutManager) { super(layoutManager); } protected abstract void onSetForegroundImage(final Image image); public final void setForegroundImage(final SkinImage skinImage) { onSetForegroundImage(skinImage.image); this.foregroundImage = skinImage; } public final void setForegroundImage(final Image image) { onSetForegroundImage(image); this.foregroundImage = null; } public final void setForegroundImage(final ImageIcon imageIcon) { onSetForegroundImage(imageIcon.getImage()); this.foregroundImage = null; } protected abstract void onSetBackgroundTexture(final Image image); public final void setBackgroundTexture(final SkinImage skinImage) { onSetBackgroundTexture(skinImage.image); this.backgroundTexture = skinImage; } public final void setBackgroundTexture(final Image image) { onSetBackgroundTexture(image); this.backgroundTexture = null; } public final void setBackgroundTexture(final ImageIcon imageIcon) { onSetBackgroundTexture(imageIcon.getImage()); this.backgroundTexture = null; } protected abstract void onSetBackgroundTextureOverlay(final Color color); public final void setBackgroundTextureOverlay(final SkinColor skinColor) { onSetBackgroundTextureOverlay(skinColor.color); this.backgroundTextureOverlay = skinColor; } public final void setBackgroundTextureOverlay(final Color color) { onSetBackgroundTextureOverlay(color); this.backgroundTextureOverlay = null; } @Override protected void paintComponent(final Graphics g) { if (getSkin().update(this)) { if (this.foregroundImage != null) { this.setForegroundImage(this.foregroundImage); } if (this.backgroundTexture != null) { this.setBackgroundTexture(this.backgroundTexture); } if (this.backgroundTextureOverlay != null) { this.setBackgroundTextureOverlay(this.backgroundTextureOverlay); } } super.paintComponent(g); } } public static class SkinnedScrollPane extends JScrollPane implements ISkinnedComponent<JScrollPane> { private static final long serialVersionUID = 8958616297664604107L; private JComponentSkin<JScrollPane> skin; @Override public JComponentSkin<JScrollPane> getSkin() { if (skin == null) { skin = new JComponentSkin<>(); } return skin; } public SkinnedScrollPane() { super(); init(); } public SkinnedScrollPane(final Component comp) { super(comp); init(); } public SkinnedScrollPane(final int vsbPolicy, final int hsbPolicy) { super(vsbPolicy, hsbPolicy); init(); } public SkinnedScrollPane(final Component comp, final int vsbPolicy, final int hsbPolicy) { super(comp, vsbPolicy, hsbPolicy); init(); } private void init() { new SkinScrollBarUI(getVerticalScrollBar(), true); new SkinScrollBarUI(getHorizontalScrollBar(), false); } private static class SkinScrollBarUI extends BasicScrollBarUI implements ILocalRepaint { @SuppressWarnings("serial") private static JButton hiddenButton = new JButton() { @Override public Dimension getPreferredSize() { return new Dimension(0, 0); } }; private static final SkinColor backColor = getColor(Colors.CLR_THEME2); private static final SkinColor borderColor = getColor(Colors.CLR_TEXT); private static final SkinColor grooveColor = borderColor.alphaColor(200); private static final AlphaComposite alphaDim = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.7f); private static final int grooveSpace = 3; private final boolean vertical; private boolean hovered; private SkinScrollBarUI(final JScrollBar scrollbar, final boolean vertical0) { vertical = vertical0; scrollbar.setOpaque(false); scrollbar.addMouseListener(new MouseAdapter() { @Override public void mouseEntered(final MouseEvent e) { hovered = true; repaintSelf(); } @Override public void mouseExited(final MouseEvent e) { hovered = false; repaintSelf(); } }); scrollbar.setUI(this); } @Override public void repaintSelf() { final Dimension d = scrollbar.getSize(); scrollbar.repaint(0, 0, d.width, d.height); } @Override protected JButton createIncreaseButton(final int orientation) { return hiddenButton; //hide increase button } @Override protected JButton createDecreaseButton(final int orientation) { return hiddenButton; //hide decrease button } @Override protected void paintTrack(final Graphics g, final JComponent c, final Rectangle trackBounds) { //make track transparent } @Override protected void paintThumb(final Graphics g, final JComponent c, final Rectangle thumbBounds) { int x = thumbBounds.x; int y = thumbBounds.y; int width = thumbBounds.width - 1; int height = thumbBounds.height - 1; //build polygon for thumb int[] xPoints, yPoints; if (vertical) { x += 2; width -= 4; final int x2 = x + width / 2; final int x3 = x + width; int arrowThickness = width / 2; int maxArrowThickness = height / 2 - grooveSpace * 2; if (maxArrowThickness < 0) { maxArrowThickness = 0; } if (arrowThickness > maxArrowThickness) { arrowThickness = maxArrowThickness; } final int y2 = y + arrowThickness; final int y3 = y + height - arrowThickness; final int y4 = y + height; xPoints = new int[] { x, x2, x3, x3, x2, x }; yPoints = new int[] { y2, y, y2, y3, y4, y3 }; } else { y += 2; height -= 4; final int y2 = y + height / 2; final int y3 = y + height; int arrowThickness = height / 2; int maxArrowThickness = width / 2 - grooveSpace * 2; if (maxArrowThickness < 0) { maxArrowThickness = 0; } if (arrowThickness > maxArrowThickness) { arrowThickness = maxArrowThickness; } final int x2 = x + arrowThickness; final int x3 = x + width - arrowThickness; final int x4 = x + width; yPoints = new int[] { y, y2, y3, y3, y2, y }; xPoints = new int[] { x2, x, x2, x3, x4, x3 }; } //draw thumb final Graphics2D g2d = (Graphics2D) g; if (!hovered) { g2d.setComposite(alphaDim); } g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); setGraphicsColor(g2d, backColor); g2d.fillPolygon(xPoints, yPoints, xPoints.length); setGraphicsColor(g2d, borderColor); g2d.drawPolygon(xPoints, yPoints, xPoints.length); //draw grooves if needed if (vertical) { if (height > grooveSpace * 4) { setGraphicsColor(g2d, grooveColor); final int x2 = x + grooveSpace; final int x3 = x + width - grooveSpace; final int y3 = y + height / 2; final int y2 = y3 - grooveSpace; final int y4 = y3 + grooveSpace; g2d.drawLine(x2, y2, x3, y2); g2d.drawLine(x2, y3, x3, y3); g2d.drawLine(x2, y4, x3, y4); } } else if (width > grooveSpace * 4) { setGraphicsColor(g2d, grooveColor); final int y2 = y + grooveSpace; final int y3 = y + height - grooveSpace; final int x3 = x + width / 2; final int x2 = x3 - grooveSpace; final int x4 = x3 + grooveSpace; g2d.drawLine(x2, y2, x2, y3); g2d.drawLine(x3, y2, x3, y3); g2d.drawLine(x4, y2, x4, y3); } } } public void setForeground(final SkinColor skinColor) { getSkin().setForeground(this, skinColor); } @Override public void setForeground(final Color color) { getSkin().resetForeground(); super.setForeground(color); } public void setBackground(final SkinColor skinColor) { getSkin().setBackground(this, skinColor); } @Override public void setBackground(final Color color) { getSkin().resetBackground(); super.setBackground(color); } public void setFont(final SkinFont skinFont) { getSkin().setFont(this, skinFont); } @Override public void setFont(final Font font) { getSkin().resetFont(); super.setFont(font); } public void setCursor(final SkinCursor skinCursor) { getSkin().setCursor(this, skinCursor); } @Override public void setCursor(final Cursor cursor) { getSkin().resetCursor(); super.setCursor(cursor); } public void setBorder(final SkinBorder skinBorder) { getSkin().setBorder(this, skinBorder); } @Override public void setBorder(final Border border) { getSkin().resetBorder(); super.setBorder(border); } @Override protected void paintComponent(final Graphics g) { getSkin().update(this); super.paintComponent(g); } } public static class SkinnedTabbedPane extends JTabbedPane implements ISkinnedComponent<JTabbedPane> { private static final long serialVersionUID = 6069807433509074270L; private JComponentSkin<JTabbedPane> skin; @Override public JComponentSkin<JTabbedPane> getSkin() { if (skin == null) { skin = new JComponentSkin<>(); } return skin; } public SkinnedTabbedPane() { super(); } public void setForeground(final SkinColor skinColor) { getSkin().setForeground(this, skinColor); } @Override public void setForeground(final Color color) { getSkin().resetForeground(); super.setForeground(color); } public void setBackground(final SkinColor skinColor) { getSkin().setBackground(this, skinColor); } @Override public void setBackground(final Color color) { getSkin().resetBackground(); super.setBackground(color); } public void setFont(final SkinFont skinFont) { getSkin().setFont(this, skinFont); } @Override public void setFont(final Font font) { getSkin().resetFont(); super.setFont(font); } public void setCursor(final SkinCursor skinCursor) { getSkin().setCursor(this, skinCursor); } @Override public void setCursor(final Cursor cursor) { getSkin().resetCursor(); super.setCursor(cursor); } public void setBorder(final SkinBorder skinBorder) { getSkin().setBorder(this, skinBorder); } @Override public void setBorder(final Border border) { getSkin().resetBorder(); super.setBorder(border); } @Override protected void paintComponent(final Graphics g) { getSkin().update(this); super.paintComponent(g); } } public static class SkinnedButton extends JButton implements ISkinnedComponent<JButton> { private static final long serialVersionUID = -1868724405885582324L; private AbstractButtonSkin<JButton> skin; @Override public AbstractButtonSkin<JButton> getSkin() { if (skin == null) { skin = new AbstractButtonSkin<>(); } return skin; } public SkinnedButton() { super(); } public SkinnedButton(final String text) { super(text); } public void setForeground(final SkinColor skinColor) { getSkin().setForeground(this, skinColor); } @Override public void setForeground(final Color color) { getSkin().resetForeground(); super.setForeground(color); } public void setBackground(final SkinColor skinColor) { getSkin().setBackground(this, skinColor); } @Override public void setBackground(final Color color) { getSkin().resetBackground(); super.setBackground(color); } public void setFont(final SkinFont skinFont) { getSkin().setFont(this, skinFont); } @Override public void setFont(final Font font) { getSkin().resetFont(); super.setFont(font); } public void setCursor(final SkinCursor skinCursor) { getSkin().setCursor(this, skinCursor); } @Override public void setCursor(final Cursor cursor) { getSkin().resetCursor(); super.setCursor(cursor); } public void setBorder(final SkinBorder skinBorder) { getSkin().setBorder(this, skinBorder); } @Override public void setBorder(final Border border) { getSkin().resetBorder(); super.setBorder(border); } public void setIcon(final SkinImage skinImage) { getSkin().setIcon(this, skinImage); } @Override public void setIcon(final Icon icon) { getSkin().resetIcon(); super.setIcon(icon); } public void setPressedIcon(final SkinImage skinImage) { getSkin().setPressedIcon(this, skinImage); } @Override public void setPressedIcon(final Icon icon) { getSkin().resetPressedIcon(); super.setPressedIcon(icon); } public void setRolloverIcon(final SkinImage skinImage) { getSkin().setRolloverIcon(this, skinImage); } @Override public void setRolloverIcon(final Icon icon) { getSkin().resetRolloverIcon(); super.setRolloverIcon(icon); } @Override protected void paintComponent(final Graphics g) { getSkin().update(this); super.paintComponent(g); } } public static class SkinnedCheckBox extends JCheckBox implements ISkinnedComponent<JCheckBox> { private static final long serialVersionUID = 6283239481504889377L; private AbstractButtonSkin<JCheckBox> skin; @Override public AbstractButtonSkin<JCheckBox> getSkin() { if (skin == null) { skin = new AbstractButtonSkin<>(); } return skin; } public SkinnedCheckBox() { super(); } public SkinnedCheckBox(final String text) { super(text); } public void setForeground(final SkinColor skinColor) { getSkin().setForeground(this, skinColor); } @Override public void setForeground(final Color color) { getSkin().resetForeground(); super.setForeground(color); } public void setBackground(final SkinColor skinColor) { getSkin().setBackground(this, skinColor); } @Override public void setBackground(final Color color) { getSkin().resetBackground(); super.setBackground(color); } public void setFont(final SkinFont skinFont) { getSkin().setFont(this, skinFont); } @Override public void setFont(final Font font) { getSkin().resetFont(); super.setFont(font); } public void setCursor(final SkinCursor skinCursor) { getSkin().setCursor(this, skinCursor); } @Override public void setCursor(final Cursor cursor) { getSkin().resetCursor(); super.setCursor(cursor); } public void setBorder(final SkinBorder skinBorder) { getSkin().setBorder(this, skinBorder); } @Override public void setBorder(final Border border) { getSkin().resetBorder(); super.setBorder(border); } @Override protected void paintComponent(final Graphics g) { getSkin().update(this); super.paintComponent(g); } } public static class SkinnedRadioButton extends JRadioButton implements ISkinnedComponent<JRadioButton> { private static final long serialVersionUID = 2724598726704588129L; private AbstractButtonSkin<JRadioButton> skin; @Override public AbstractButtonSkin<JRadioButton> getSkin() { if (skin == null) { skin = new AbstractButtonSkin<>(); } return skin; } public SkinnedRadioButton() { super(); } public SkinnedRadioButton(final String text) { super(text); } public void setForeground(final SkinColor skinColor) { getSkin().setForeground(this, skinColor); } @Override public void setForeground(final Color color) { getSkin().resetForeground(); super.setForeground(color); } public void setBackground(final SkinColor skinColor) { getSkin().setBackground(this, skinColor); } @Override public void setBackground(final Color color) { getSkin().resetBackground(); super.setBackground(color); } public void setFont(final SkinFont skinFont) { getSkin().setFont(this, skinFont); } @Override public void setFont(final Font font) { getSkin().resetFont(); super.setFont(font); } public void setCursor(final SkinCursor skinCursor) { getSkin().setCursor(this, skinCursor); } @Override public void setCursor(final Cursor cursor) { getSkin().resetCursor(); super.setCursor(cursor); } public void setBorder(final SkinBorder skinBorder) { getSkin().setBorder(this, skinBorder); } @Override public void setBorder(final Border border) { getSkin().resetBorder(); super.setBorder(border); } @Override protected void paintComponent(final Graphics g) { getSkin().update(this); super.paintComponent(g); } } public static class SkinnedMenu extends JMenu implements ISkinnedComponent<JMenu> { private static final long serialVersionUID = -1067731457894672601L; private AbstractButtonSkin<JMenu> skin; @Override public AbstractButtonSkin<JMenu> getSkin() { if (skin == null) { skin = new AbstractButtonSkin<>(); } return skin; } public SkinnedMenu() { super(); } public SkinnedMenu(final String text) { super(text); } public SkinnedMenu(final Action a) { super(a); } public void setIcon(final SkinImage skinImage) { getSkin().setIcon(this, skinImage); } @Override public void setIcon(final Icon icon) { getSkin().resetIcon(); super.setIcon(icon); } @Override protected void paintComponent(final Graphics g) { getSkin().update(this); super.paintComponent(g); } } public static class SkinnedMenuItem extends JMenuItem implements ISkinnedComponent<JMenuItem> { private static final long serialVersionUID = 3738616219203986847L; private AbstractButtonSkin<JMenuItem> skin; @Override public AbstractButtonSkin<JMenuItem> getSkin() { if (skin == null) { skin = new AbstractButtonSkin<>(); } return skin; } public SkinnedMenuItem() { super(); } public SkinnedMenuItem(final String text) { super(text); } public SkinnedMenuItem(final Action a) { super(a); } public void setIcon(final SkinImage skinImage) { getSkin().setIcon(this, skinImage); } @Override public void setIcon(final Icon icon) { getSkin().resetIcon(); super.setIcon(icon); } @Override protected void paintComponent(final Graphics g) { getSkin().update(this); super.paintComponent(g); } } public static class SkinnedCheckBoxMenuItem extends JCheckBoxMenuItem implements ISkinnedComponent<JCheckBoxMenuItem> { private static final long serialVersionUID = 7972531296466954594L; private AbstractButtonSkin<JCheckBoxMenuItem> skin; @Override public AbstractButtonSkin<JCheckBoxMenuItem> getSkin() { if (skin == null) { skin = new AbstractButtonSkin<>(); } return skin; } public SkinnedCheckBoxMenuItem() { super(); } public SkinnedCheckBoxMenuItem(final String text) { super(text); } public SkinnedCheckBoxMenuItem(final Action a) { super(a); } public void setIcon(final SkinImage skinImage) { getSkin().setIcon(this, skinImage); } @Override public void setIcon(final Icon icon) { getSkin().resetIcon(); super.setIcon(icon); } @Override protected void paintComponent(final Graphics g) { getSkin().update(this); super.paintComponent(g); } } public static class SkinnedRadioButtonMenuItem extends JRadioButtonMenuItem implements ISkinnedComponent<JRadioButtonMenuItem> { private static final long serialVersionUID = -3609854793671399210L; private AbstractButtonSkin<JRadioButtonMenuItem> skin; @Override public AbstractButtonSkin<JRadioButtonMenuItem> getSkin() { if (skin == null) { skin = new AbstractButtonSkin<>(); } return skin; } public SkinnedRadioButtonMenuItem() { super(); } public SkinnedRadioButtonMenuItem(final String text) { super(text); } public SkinnedRadioButtonMenuItem(final Action a) { super(a); } public void setIcon(final SkinImage skinImage) { getSkin().setIcon(this, skinImage); } @Override public void setIcon(final Icon icon) { getSkin().resetIcon(); super.setIcon(icon); } @Override protected void paintComponent(final Graphics g) { getSkin().update(this); super.paintComponent(g); } } public static class SkinnedTextField extends JTextField implements ISkinnedComponent<JTextField> { private static final long serialVersionUID = 5133370343400427635L; private JTextComponentSkin<JTextField> skin; @Override public JTextComponentSkin<JTextField> getSkin() { if (skin == null) { skin = new JTextComponentSkin<>(); } return skin; } public SkinnedTextField() { super(); } public SkinnedTextField(final String text) { super(text); } public void setForeground(final SkinColor skinColor) { getSkin().setForeground(this, skinColor); } @Override public void setForeground(final Color color) { getSkin().resetForeground(); super.setForeground(color); } public void setBackground(final SkinColor skinColor) { getSkin().setBackground(this, skinColor); } @Override public void setBackground(final Color color) { getSkin().resetBackground(); super.setBackground(color); } public void setFont(final SkinFont skinFont) { getSkin().setFont(this, skinFont); } @Override public void setFont(final Font font) { getSkin().resetFont(); super.setFont(font); } public void setCursor(final SkinCursor skinCursor) { getSkin().setCursor(this, skinCursor); } @Override public void setCursor(final Cursor cursor) { getSkin().resetCursor(); super.setCursor(cursor); } public void setBorder(final SkinBorder skinBorder) { getSkin().setBorder(this, skinBorder); } @Override public void setBorder(final Border border) { getSkin().resetBorder(); super.setBorder(border); } public void setCaretColor(final SkinColor skinColor) { getSkin().setCaretColor(this, skinColor); } @Override public void setCaretColor(final Color color) { getSkin().resetCaretColor(); super.setCaretColor(color); } @Override protected void paintComponent(final Graphics g) { getSkin().update(this); super.paintComponent(g); } } public static class SkinnedPasswordField extends JPasswordField implements ISkinnedComponent<JTextField> { private static final long serialVersionUID = 1557674285031452868L; private JTextComponentSkin<JTextField> skin; @Override public JTextComponentSkin<JTextField> getSkin() { if (skin == null) { skin = new JTextComponentSkin<>(); } return skin; } public SkinnedPasswordField() { super(); } public void setForeground(final SkinColor skinColor) { getSkin().setForeground(this, skinColor); } @Override public void setForeground(final Color color) { getSkin().resetForeground(); super.setForeground(color); } public void setBackground(final SkinColor skinColor) { getSkin().setBackground(this, skinColor); } @Override public void setBackground(final Color color) { getSkin().resetBackground(); super.setBackground(color); } public void setFont(final SkinFont skinFont) { getSkin().setFont(this, skinFont); } @Override public void setFont(final Font font) { getSkin().resetFont(); super.setFont(font); } public void setCursor(final SkinCursor skinCursor) { getSkin().setCursor(this, skinCursor); } @Override public void setCursor(final Cursor cursor) { getSkin().resetCursor(); super.setCursor(cursor); } public void setBorder(final SkinBorder skinBorder) { getSkin().setBorder(this, skinBorder); } @Override public void setBorder(final Border border) { getSkin().resetBorder(); super.setBorder(border); } public void setCaretColor(final SkinColor skinColor) { getSkin().setCaretColor(this, skinColor); } @Override public void setCaretColor(final Color color) { getSkin().resetCaretColor(); super.setCaretColor(color); } @Override protected void paintComponent(final Graphics g) { getSkin().update(this); super.paintComponent(g); } } public static class SkinnedTextArea extends JTextArea implements ISkinnedComponent<JTextArea> { private static final long serialVersionUID = 4191648156716570907L; private JTextComponentSkin<JTextArea> skin; @Override public JTextComponentSkin<JTextArea> getSkin() { if (skin == null) { skin = new JTextComponentSkin<>(); } return skin; } public SkinnedTextArea() { super(); } public SkinnedTextArea(final String text) { super(text); } public void setForeground(final SkinColor skinColor) { getSkin().setForeground(this, skinColor); } @Override public void setForeground(final Color color) { getSkin().resetForeground(); super.setForeground(color); } public void setBackground(final SkinColor skinColor) { getSkin().setBackground(this, skinColor); } @Override public void setBackground(final Color color) { getSkin().resetBackground(); super.setBackground(color); } public void setFont(final SkinFont skinFont) { getSkin().setFont(this, skinFont); } @Override public void setFont(final Font font) { getSkin().resetFont(); super.setFont(font); } public void setCursor(final SkinCursor skinCursor) { getSkin().setCursor(this, skinCursor); } @Override public void setCursor(final Cursor cursor) { getSkin().resetCursor(); super.setCursor(cursor); } public void setBorder(final SkinBorder skinBorder) { getSkin().setBorder(this, skinBorder); } @Override public void setBorder(final Border border) { getSkin().resetBorder(); super.setBorder(border); } public void setCaretColor(final SkinColor skinColor) { getSkin().setCaretColor(this, skinColor); } @Override public void setCaretColor(final Color color) { getSkin().resetCaretColor(); super.setCaretColor(color); } @Override protected void paintComponent(final Graphics g) { getSkin().update(this); super.paintComponent(g); } } public static class SkinnedTextPane extends JTextPane implements ISkinnedComponent<JTextPane> { private static final long serialVersionUID = -209191600467610844L; private JTextComponentSkin<JTextPane> skin; @Override public JTextComponentSkin<JTextPane> getSkin() { if (skin == null) { skin = new JTextComponentSkin<>(); } return skin; } public SkinnedTextPane() { super(); } public void setForeground(final SkinColor skinColor) { getSkin().setForeground(this, skinColor); } @Override public void setForeground(final Color color) { getSkin().resetForeground(); super.setForeground(color); } public void setBackground(final SkinColor skinColor) { getSkin().setBackground(this, skinColor); } @Override public void setBackground(final Color color) { getSkin().resetBackground(); super.setBackground(color); } public void setFont(final SkinFont skinFont) { getSkin().setFont(this, skinFont); } @Override public void setFont(final Font font) { getSkin().resetFont(); super.setFont(font); } public void setCursor(final SkinCursor skinCursor) { getSkin().setCursor(this, skinCursor); } @Override public void setCursor(final Cursor cursor) { getSkin().resetCursor(); super.setCursor(cursor); } public void setBorder(final SkinBorder skinBorder) { getSkin().setBorder(this, skinBorder); } @Override public void setBorder(final Border border) { getSkin().resetBorder(); super.setBorder(border); } public void setCaretColor(final SkinColor skinColor) { getSkin().setCaretColor(this, skinColor); } @Override public void setCaretColor(final Color color) { getSkin().resetCaretColor(); super.setCaretColor(color); } @Override protected void paintComponent(final Graphics g) { getSkin().update(this); super.paintComponent(g); } } public static class SkinnedEditorPane extends JEditorPane implements ISkinnedComponent<JEditorPane> { private static final long serialVersionUID = 88434642461539322L; private JTextComponentSkin<JEditorPane> skin; @Override public JTextComponentSkin<JEditorPane> getSkin() { if (skin == null) { skin = new JTextComponentSkin<>(); } return skin; } public SkinnedEditorPane() { super(); } public void setForeground(final SkinColor skinColor) { getSkin().setForeground(this, skinColor); } @Override public void setForeground(final Color color) { getSkin().resetForeground(); super.setForeground(color); } public void setBackground(final SkinColor skinColor) { getSkin().setBackground(this, skinColor); } @Override public void setBackground(final Color color) { getSkin().resetBackground(); super.setBackground(color); } public void setFont(final SkinFont skinFont) { getSkin().setFont(this, skinFont); } @Override public void setFont(final Font font) { getSkin().resetFont(); super.setFont(font); } public void setCursor(final SkinCursor skinCursor) { getSkin().setCursor(this, skinCursor); } @Override public void setCursor(final Cursor cursor) { getSkin().resetCursor(); super.setCursor(cursor); } public void setBorder(final SkinBorder skinBorder) { getSkin().setBorder(this, skinBorder); } @Override public void setBorder(final Border border) { getSkin().resetBorder(); super.setBorder(border); } public void setCaretColor(final SkinColor skinColor) { getSkin().setCaretColor(this, skinColor); } @Override public void setCaretColor(final Color color) { getSkin().resetCaretColor(); super.setCaretColor(color); } @Override protected void paintComponent(final Graphics g) { getSkin().update(this); super.paintComponent(g); } } public static class SkinnedSpinner extends JSpinner implements ISkinnedComponent<JFormattedTextField> { private static final long serialVersionUID = -7379547491760852368L; //special case to treat as text component private JTextComponentSkin<JFormattedTextField> skin; @Override public JTextComponentSkin<JFormattedTextField> getSkin() { if (skin == null) { skin = new JTextComponentSkin<>(); } return skin; } private JFormattedTextField textField; public JFormattedTextField getTextField() { return textField; } public SkinnedSpinner() { updateTextField(); } @Override public void setEditor(final JComponent editor) { super.setEditor(editor); updateTextField(); } private void updateTextField() { try { textField = ((JSpinner.NumberEditor) this.getEditor()).getTextField(); } catch (final Exception ex) { textField = null; } } public void setForeground(final SkinColor skinColor) { getSkin().setForeground(textField, skinColor); } @Override public void setForeground(final Color color) { if (textField == null) { super.setForeground(color); return; } getSkin().resetForeground(); textField.setForeground(color); } public void setBackground(final SkinColor skinColor) { getSkin().setBackground(textField, skinColor); } @Override public void setBackground(final Color color) { if (textField == null) { super.setBackground(color); return; } getSkin().resetBackground(); textField.setBackground(color); } public void setFont(final SkinFont skinFont) { getSkin().setFont(textField, skinFont); } @Override public void setFont(final Font font) { if (textField == null) { super.setFont(font); return; } getSkin().resetFont(); textField.setFont(font); } public void setCursor(final SkinCursor skinCursor) { getSkin().setCursor(textField, skinCursor); } @Override public void setCursor(final Cursor cursor) { if (textField == null) { super.setCursor(cursor); return; } getSkin().resetCursor(); textField.setCursor(cursor); } public void setCaretColor(final SkinColor skinColor) { getSkin().setCaretColor(textField, skinColor); } public void setCaretColor(final Color color) { if (textField == null) { return; } getSkin().resetCaretColor(); textField.setCaretColor(color); } @Override protected void paintComponent(final Graphics g) { getSkin().update(textField); super.paintComponent(g); } } public static class SkinnedSlider extends JSlider implements ISkinnedComponent<JSlider> { private static final long serialVersionUID = -7846549500200072420L; private JComponentSkin<JSlider> skin; @Override public JComponentSkin<JSlider> getSkin() { if (skin == null) { skin = new JComponentSkin<>(); } return skin; } public SkinnedSlider() { super(); } public SkinnedSlider(final int orientation) { super(orientation); } public SkinnedSlider(final int min, final int max) { super(min, max); } public SkinnedSlider(final int min, final int max, final int value) { super(min, max, value); } public SkinnedSlider(final int orientation, final int min, final int max, final int value) { super(orientation, min, max, value); } public void setForeground(final SkinColor skinColor) { getSkin().setForeground(this, skinColor); } @Override public void setForeground(final Color color) { getSkin().resetForeground(); super.setForeground(color); } public void setBackground(final SkinColor skinColor) { getSkin().setBackground(this, skinColor); } @Override public void setBackground(final Color color) { getSkin().resetBackground(); super.setBackground(color); } public void setFont(final SkinFont skinFont) { getSkin().setFont(this, skinFont); } @Override public void setFont(final Font font) { getSkin().resetFont(); super.setFont(font); } public void setCursor(final SkinCursor skinCursor) { getSkin().setCursor(this, skinCursor); } @Override public void setCursor(final Cursor cursor) { getSkin().resetCursor(); super.setCursor(cursor); } public void setBorder(final SkinBorder skinBorder) { getSkin().setBorder(this, skinBorder); } @Override public void setBorder(final Border border) { getSkin().resetBorder(); super.setBorder(border); } @Override protected void paintComponent(final Graphics g) { getSkin().update(this); super.paintComponent(g); } } public static class SkinnedTable extends JTable implements ISkinnedComponent<JTable> { private static final long serialVersionUID = -4194423897092773473L; private JTableSkin<JTable> skin; @Override public JTableSkin<JTable> getSkin() { if (skin == null) { skin = new JTableSkin<>(); } return skin; } public SkinnedTable() { super(); } public void setForeground(final SkinColor skinColor) { getSkin().setForeground(this, skinColor); } @Override public void setForeground(final Color color) { getSkin().resetForeground(); super.setForeground(color); } public void setBackground(final SkinColor skinColor) { getSkin().setBackground(this, skinColor); } @Override public void setBackground(final Color color) { getSkin().resetBackground(); super.setBackground(color); } public void setFont(final SkinFont skinFont) { getSkin().setFont(this, skinFont); } @Override public void setFont(final Font font) { getSkin().resetFont(); super.setFont(font); } public void setCursor(final SkinCursor skinCursor) { getSkin().setCursor(this, skinCursor); } @Override public void setCursor(final Cursor cursor) { getSkin().resetCursor(); super.setCursor(cursor); } public void setBorder(final SkinBorder skinBorder) { getSkin().setBorder(this, skinBorder); } @Override public void setBorder(final Border border) { getSkin().resetBorder(); super.setBorder(border); } public void setSelectionForeground(final SkinColor skinColor) { getSkin().setSelectionForeground(this, skinColor); } @Override public void setSelectionForeground(final Color color) { getSkin().resetSelectionForeground(); super.setSelectionForeground(color); } public void setSelectionBackground(final SkinColor skinColor) { getSkin().setSelectionBackground(this, skinColor); } @Override public void setSelectionBackground(final Color color) { getSkin().resetSelectionBackground(); super.setSelectionBackground(color); } public void setGridColor(final SkinColor skinColor) { getSkin().setGridColor(this, skinColor); } @Override public void setGridColor(final Color color) { getSkin().resetGridColor(); super.setGridColor(color); } @Override protected void paintComponent(final Graphics g) { getSkin().update(this); super.paintComponent(g); } } public static class SkinnedTableHeader extends JTableHeader implements ISkinnedComponent<JTableHeader> { private static final long serialVersionUID = -1842620489613307379L; private JComponentSkin<JTableHeader> skin; @Override public JComponentSkin<JTableHeader> getSkin() { if (skin == null) { skin = new JComponentSkin<>(); } return skin; } public SkinnedTableHeader() { super(); } public SkinnedTableHeader(final TableColumnModel columnModel0) { super(columnModel0); } public void setForeground(final SkinColor skinColor) { getSkin().setForeground(this, skinColor); } @Override public void setForeground(final Color color) { getSkin().resetForeground(); super.setForeground(color); } public void setBackground(final SkinColor skinColor) { getSkin().setBackground(this, skinColor); } @Override public void setBackground(final Color color) { getSkin().resetBackground(); super.setBackground(color); } public void setFont(final SkinFont skinFont) { getSkin().setFont(this, skinFont); } @Override public void setFont(final Font font) { getSkin().resetFont(); super.setFont(font); } public void setCursor(final SkinCursor skinCursor) { getSkin().setCursor(this, skinCursor); } @Override public void setCursor(final Cursor cursor) { getSkin().resetCursor(); super.setCursor(cursor); } public void setBorder(final SkinBorder skinBorder) { getSkin().setBorder(this, skinBorder); } @Override public void setBorder(final Border border) { getSkin().resetBorder(); super.setBorder(border); } @Override protected void paintComponent(final Graphics g) { getSkin().update(this); super.paintComponent(g); } } }