Palette de couleurs modulaire Java Swing


Je configure une interface graphique à grande échelle (plus grande que tout ce que j'ai fait auparavant) en utilisant la boîte à outils Swing de Java et je voudrais configurer mon propre schéma de couleurs personnalisé pour dessiner des couleurs afin que toutes les définitions de couleurs soient au même endroit. Pour ce faire, j'ai décidé de créer une classe de niveau supérieur pseudo-statique appelée ColorPalette (appliqué à partir de https://stackoverflow.com/a/7486111/4547020 post) qui contient un SchemeEnum où le programmeur définit un schéma de couleurs pour l'ensemble GUI.

Je voudrais que la sélection des couleurs soit indépendante de la connaissance du schéma de couleurs. Quelqu'un connaît-il un modèle de conception ou un moyen efficace de le faire? Je ne suis pas entièrement convaincu que ma configuration actuelle est la meilleure façon de l'implémenter, mais je voudrais mettre en place une conception modulaire où il ne serait pas intrusif d'en ajouter plus ColorEnums ou SchemeEnums (au moment de la compilation, pas à l'exécution).

Pour des raisons de clarification, je veux que le programmeur puisse simplement sélectionner un ColorEnum et le renvoi d'un java.awt.Color objet basé sur le ColorEnum et le SchemeEnum.

Par exemple:

        // 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());

Devrait revenir différentes Color les objets que

        // 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());

, Car ils ont différents SchemeEnums même s'ils demandent la même couleur de ColorPalette. De cette façon, en changeant le SchemeEnum change chaque couleur dans l'interface graphique avec un changement de code d'une ligne (ou les couleurs peuvent même être modifiées à Runtime).

J'ai entendu parler de HashTables utilisés pour un stockage de données volumineux comme celui-ci, mais je ne sais pas comment ils fonctionnent. Cela peut s'appliquer ici?

Voici mon code jusqu'à présent. Merci à l'avance!

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();
    }
}
Author: Community, 2015-02-09

2 answers

Il semble que vous ayez juste besoin de composer SchemeEnum pour être composé de ColorEnums, tout comme vous avez le ColorEnum composé de valeurs rvb.

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;
    }
}

Ensuite, utilisez le code suivant, où les couleurs sont basées sur le schéma sélectionné:

testButton.setBackground(ColorPalette.getCurrentScheme().mainColor.getColor());
 4
Author: NESPowerGlove, 2015-02-09 19:07:29

Avant de réinventer la roue, Swing est basé sur une API d'apparence et de sensation enfichable, voir Modification de l'apparence et de la sensation .

La bonne façon serait de définir votre propre apparence et de charger cela. Parce que vous voulez fournir un nombre variable de changements, il serait probablement préférable d'utiliser quelque chose comme Synthé. Cela vous permet de définir des propriétés en cascade pour les objets et vous permet également d'hériter d'autres propriétés (vous pouvez donc concevoir un ensemble de base de propriétés, puis ne modifiez que les propriétés dont vous avez besoin dans chaque look and feel suivant).

La méthode de triche serait de modifier directement le UIManager, en modifiant les différentes propriétés utilisées par l'apparence actuelle. C'est parfois plus facile si vous souhaitez effectuer de petits réglages.

De toute façon, cela affectera TOUS les composants créés par votre application sans que vous ayez besoin de faire quoi que ce soit de plus que de changer l'apparence au démarrage

 3
Author: MadProgrammer, 2015-02-09 20:53:32