2015-02-09 86 views
4

我使用Java的Swing工具箱設置了一個大型GUI(比以前做的任何工作都大),並且我想設置自己的自定義配色方案來繪製顏色,以便所有顏色定義在一個地方。爲此,我決定製作一個名爲ColorPalette(應用於https://stackoverflow.com/a/7486111/4547020後)的僞靜態頂級類別,其中包含SchemeEnum,其中程序員爲整個GUI設置顏色方案。Java Swing模塊化配色方案

我希望顏色選擇獨立於顏色方案的知識。有沒有人知道設計模式或有效的方法來做到這一點?我不完全相信,我目前的設置是實現這一目標的最佳方式,但我想建立一個模塊化的設計,它不會打擾添加更多ColorEnumsSchemeEnums(在編譯時,不運行)。

爲了清楚起見,我想程序員能夠簡單地選擇一個ColorEnum並獲得返回的基礎上,ColorEnum和定義SchemeEnum一個java.awt.Color對象。

例如:

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

應該比

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

返回不同Color對象,因爲它們有不同的SchemeEnums,即使它們是從ColorPalette請求相同的顏色。這樣,更改一行代碼更改(或顏色甚至可以在運行時更改)GUI中更改GUI中的每種顏色。

我聽說過HashTables被用於這種大型數據存儲,但我不知道它們是如何工作的。可能在這裏適用?

這是我的代碼到目前爲止。提前致謝!

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(); 
    } 
} 
+0

覺得這將是簡單直接定義顏色到UIManager的或創建自己的外觀和感覺,也許使用[Synth](http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/synth.html) – MadProgrammer 2015-02-09 20:43:32

+0

大多數JComponents都有屬性數組,例如作爲JButton,這些屬性對於所有可能的事件(選擇,按下,武裝,...)都是不同的,使用自定義L&F,在某些情況下可以設置顏色方案(以避免重新發明輪子) – mKorbel 2015-02-10 08:30:35

+0

Java Swing模塊化顏色方案== UIManager中的密鑰循環 – mKorbel 2015-02-10 08:31:38

回答

4

它看起來和聽起來像你只需要編寫SchemeEnum要由ColorEnums的只是怎麼樣,你有ColorEnum由RGB值。

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

然後,使用如下代碼,這裏的顏色是根據所選擇的方案:

testButton.setBackground(ColorPalette.getCurrentScheme().mainColor.getColor()); 
+0

這種方法看起來非常模塊化,不需要太多改變!我也喜歡爲顏色標記*目的*,而不是命名標籤描述(即'mainColor','borderColor'等,而不是'YELLOW','DARK_GREEN'等)。 我最初的想法是調整每種顏色的外觀(即'DARK'方案只是'BASIC'方案,但陰影有點暗)。如果我不是新成員,我會提供+1 :) – FallDownT 2015-02-09 19:30:22

+0

@FallDownT新用戶可以通過查看和滾動瀏覽幫助 - >遊覽頁面來獲得大量的代表點。 – NESPowerGlove 2015-02-09 19:36:55

+0

@FallDownT此外,您可能會感興趣的是查看能夠設置顏色方案的Nimbus外觀。 http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/color.html – NESPowerGlove 2015-02-09 19:39:10

3

你去重新發明輪子之前,Swing是基於一個可插拔的外觀和感覺API,見Modifying the Look and Feel

正確的方法是定義你自己的外觀和感覺並加載它。由於您想提供可變數量的更改,因此最好使用Synth之類的內容。這使您可以爲對象定義級聯屬性,並允許您從其他屬性繼承(因此您可以設計一組基本屬性,然後僅更改每個後續外觀所需的屬性)。

作弊方式是直接修改UIManager,更改當前外觀使用的各種屬性。如果你想進行小的調整,這有時會更容易。

無論哪種方式,這會影響您的應用程序創建的所有組件,而你需要做什麼都那麼改變一下,並在啓動時

+0

我剛剛閱讀了關於Synth的Oracle教程,它看起來很有希望。在編寫簡單的Android應用程序時,我只碰過幾次XML,所以我對它比較陌生。不過,從我讀過的內容來看,這似乎是一種更有效的方式來改變GUI的整體外觀,而無需爲了改變外觀而改變「JComponents」。 – FallDownT 2015-02-09 21:09:00

+0

去年年底,我爲我的工作場所做了一個原型,它使用了基本的外觀和感覺,並構建了4種不同的外觀和感覺。我不會說開始很容易,但最終的結果非常棒,尤其是當您可以簡單地基於組件'name'屬性爲單個組件(如JButton)提供自定義時,您可以擁有一個基本按鈕的外觀和感覺以及一些自定義的外觀和感覺,例如「Ok」和「Cancel」按鈕... – MadProgrammer 2015-02-09 21:34:28

+0

我一直在嘗試使用xml文件,但我不確定哪些選項是可用/如何充分利用xml文件。我已經閱讀了關於oracle的教程,並使用xml示例作爲資源,但您是否會碰巧知道其他任何資源,以幫助我快速學習如何開發Synth xml文件?我真的很喜歡這種技術將laf從代碼中分離出來的方式。 – FallDownT 2015-02-10 16:27:28