2015-02-09 87 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