Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Swing modular color scheme

I am setting up a large scale GUI (larger than anything I have done before) using Java's Swing toolkit and I would like to set up my own custom color scheme to draw colors from so that all color definitions are in one place. To do this, I have decided to make a pseudo-static top-level class called ColorPalette (applied from https://stackoverflow.com/a/7486111/4547020 post) that contains a SchemeEnum where the programmer sets a color scheme for the entire GUI.

I would like the color selection to be independent to knowledge of color scheme. Does anyone know a design pattern or an efficient way to do this? I'm not entirely confident that my current setup is the best way to implement this, but I would like to set up a modular design where it would not be intrusive to add more ColorEnums or SchemeEnums (at compile time, not runtime).

For clarification sake, I want the programmer to be able to simply select a ColorEnum and get returned a java.awt.Color object based on the ColorEnum and the defined SchemeEnum.

For instance:

        // Use the BASIC color scheme
        ColorPalette.setCurrentScheme(ColorPalette.SchemeEnum.BASIC);

        // Set button backgrounds
        testButton.setBackground(ColorPalette.ColorEnum.DARK_RED.getColor());
        testButton2.setBackground(ColorPalette.ColorEnum.BLUE.getColor());

should return different Color objects than

        // Use the DARK color scheme
        ColorPalette.setCurrentScheme(ColorPalette.SchemeEnum.DARK);

        // Set button backgrounds
        testButton.setBackground(ColorPalette.ColorEnum.DARK_RED.getColor());
        testButton2.setBackground(ColorPalette.ColorEnum.BLUE.getColor());

because they have different SchemeEnums even though they are requesting the same color from ColorPalette. This way, changing the SchemeEnum changes every color in the GUI with a one line code change (or Colors could even be changed at runtime).

I've heard of HashTables being used for large data storage such as this, but I don't know how they work. Might that apply here?

Here is my code thus far. Thanks in advance!

package common.lookandfeel;

import java.awt.Color;

/**
 * Class which contains the members for the color scheme used throughout the project.
 * <p>This class is essentially static (no constructor, class is final, all members static) and
 * should not be instantiated.
 */
public final class ColorPalette
{
    /**
     * The list of color schemes to choose from.
     */
    public static enum SchemeEnum
    {
        BASIC, DARK, METALLIC
    }

    /**
     * The list of color descriptions to choose from.
     */
    public static enum ColorEnum
    {
        LIGHT_RED(256,0,0), RED(192,0,0), DARK_RED(128,0,0),
        LIGHT_GREEN(0,256,0), GREEN(0,192,0), DARK_GREEN(0,128,0),
        LIGHT_BLUE(0,0,256), BLUE(0,0,192), DARK_BLUE(0,0,128),
        LIGHT_ORANGE(256,102,0), ORANGE(256,102,0), DARK_ORANGE(192,88,0),
        LIGHT_YELLOW(256,204,0), YELLOW(256,204,0), DARK_YELLOW(192,150,0),
        LIGHT_PURPLE(136,0,182), PURPLE(102,0,153), DARK_PURPLE(78,0,124);

        private int red;
        private int green;
        private int blue;

        private ColorEnum(int r, int g, int b)
        {
            this.red = r;
            this.green = g;
            this.blue = b;
        }

        /**
         * Get the selected color object for this Enum.
         * @return The color description as a Color object.
         */
        public Color getColor()
        {
            // WANT TO RETURN A COLOR BASED ON currentScheme
            return new Color(red, green, blue);
        }
    }

    private static SchemeEnum currentScheme = SchemeEnum.BASIC;

    /**
     * Default constructor is private to prevent instantiation of this makeshift 'static' class.
     */
    private ColorPalette()
    {
    }

    /**
     * Get the color scheme being used on this project.
     * @return The current color scheme in use on this project.
     */
    public static SchemeEnum getCurrentScheme()
    {
        return currentScheme;
    }

    /**
     * Set the overall color scheme of this project.
     * @param currentPalette The color scheme to set for use on this project.
     */
    public static void setCurrentScheme(SchemeEnum cp)
    {
        currentScheme = cp;
    }

    /**
     * Main method for test purposes only.  Unpredictable results.
     * @param args Command line arguments.  Should not be present.
     */
    public static void main(String[] args)
    {
        // Declare and define swing data members
        JFrame frame = new JFrame("Test Environment");
        CustomButton testButton = new CustomButton ("Hello World");
        CustomButton testButton2 = new CustomButton ("I am a button!");

        // Use a particular color scheme
        ColorPalette.setCurrentScheme(ColorPalette.SchemeEnum.BASIC);

        // Set button backgrounds
        testButton.setBackground(ColorPalette.ColorEnum.DARK_RED.getColor());
        testButton2.setBackground(ColorPalette.ColorEnum.BLUE.getColor());

        // Place swing components in Frame
        frame.getContentPane().setLayout(new BorderLayout());
        frame.getContentPane().add(testButton, BorderLayout.NORTH);
        frame.getContentPane().add(testButton2, BorderLayout.SOUTH);
        frame.pack();
        frame.setVisible(true);

        // Set allocated memory to null
        frame = null;
        testButton = null;
        testButton2 = null;

        // Suggest garbage collecting to deallocate memory
        System.gc();
    }
}
like image 891
FallDownT Avatar asked Mar 17 '23 02:03

FallDownT


1 Answers

It looks and sounds like you just need to compose SchemeEnum to be made up of ColorEnums just like how you have the ColorEnum made up of rgb values.

public static enum SchemeEnum
{
    // Don't really know what colors you actually want
    BASIC(ColorEnum.RED, ColorEnum.GREEN, ColorEnum.ORANGE),
    DARK(ColorEnum.DARK_RED, ColorEnum.DARK_GREEN, ColorEnum.DARK_ORANGE),
    METALLIC(ColorEnum.LIGHT_RED, ColorEnum.LIGHT_GREEN, ColorEnum.LIGHT_ORANGE);

    // nor know how many colors make up a scheme
    public ColorEnum mainColor;
    public ColorEnum secondaryColor;
    public ColorEnum borderColor;

    private SchemeEnum(ColorEnum mainColor, ColorEnum secondaryColor, 
                       ColorEnum borderColor)
    {
        this.mainColor = mainColor;
        this.secondaryColor = secondaryColor;
        this.borderColor = borderColor;
    }
}

Then, use code like the following, where the colors are based on the selected scheme:

testButton.setBackground(ColorPalette.getCurrentScheme().mainColor.getColor());
like image 179
NESPowerGlove Avatar answered Mar 23 '23 04:03

NESPowerGlove