Java Swing 模块化配色方案
Java Swing modular color scheme
我正在使用 Java 的 Swing 工具包设置一个大型 GUI(比我以前做过的任何东西都大),我想设置我自己的自定义配色方案来绘制颜色,以便所有颜色定义都在一个地方。为此,我决定创建一个名为 ColorPalette
的伪静态顶级 class(应用自 post ) 其中包含一个 SchemeEnum
,程序员可以在其中设置整个 GUI 的配色方案。
我希望颜色 selection 独立于配色方案知识。有谁知道设计模式或有效的方法来做到这一点?我不完全相信我当前的设置是实现它的最佳方式,但我想设置一个模块化设计,这样添加更多 ColorEnums
[=55 不会造成干扰=] 或 SchemeEnums
(在编译时,而不是运行时)。
为了澄清起见,我希望程序员能够简单地 select a ColorEnum
并得到 returned a java.awt.Color
对象基于 ColorEnum
和定义的 SchemeEnum
.
例如:
// 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());
应该 return 与
不同的 Color
个对象
// 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());
因为他们有不同的 SchemeEnums
,即使他们要求 ColorPalette
的颜色相同。这样,更改 SchemeEnum
会通过一行代码更改更改 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();
}
}
看起来和听起来您只需要将 SchemeEnum 组合成由 ColorEnum 组成,就像您让 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());
在您重新发明轮子之前,Swing 基于可插入的外观 API,请参阅 Modifying the Look and Feel。
正确的方法是定义您自己的外观并加载它。因为您想提供可变数量的更改,所以使用 Synth 之类的东西可能会更好。这允许您为对象定义级联属性并允许您从其他属性继承(因此您可以设计一组基本属性,然后只更改您在每个后续外观中需要的属性)。
欺骗方式是直接修改UIManager
,改变当前外观使用的各种属性。如果您想进行小的调整,这有时会更容易。
无论哪种方式,这都将影响您的应用程序创建的所有组件,您无需再做任何事情,然后在启动时更改外观
我正在使用 Java 的 Swing 工具包设置一个大型 GUI(比我以前做过的任何东西都大),我想设置我自己的自定义配色方案来绘制颜色,以便所有颜色定义都在一个地方。为此,我决定创建一个名为 ColorPalette
的伪静态顶级 class(应用自 post ) 其中包含一个 SchemeEnum
,程序员可以在其中设置整个 GUI 的配色方案。
我希望颜色 selection 独立于配色方案知识。有谁知道设计模式或有效的方法来做到这一点?我不完全相信我当前的设置是实现它的最佳方式,但我想设置一个模块化设计,这样添加更多 ColorEnums
[=55 不会造成干扰=] 或 SchemeEnums
(在编译时,而不是运行时)。
为了澄清起见,我希望程序员能够简单地 select a ColorEnum
并得到 returned a java.awt.Color
对象基于 ColorEnum
和定义的 SchemeEnum
.
例如:
// 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());
应该 return 与
不同的Color
个对象
// 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());
因为他们有不同的 SchemeEnums
,即使他们要求 ColorPalette
的颜色相同。这样,更改 SchemeEnum
会通过一行代码更改更改 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();
}
}
看起来和听起来您只需要将 SchemeEnum 组合成由 ColorEnum 组成,就像您让 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());
在您重新发明轮子之前,Swing 基于可插入的外观 API,请参阅 Modifying the Look and Feel。
正确的方法是定义您自己的外观并加载它。因为您想提供可变数量的更改,所以使用 Synth 之类的东西可能会更好。这允许您为对象定义级联属性并允许您从其他属性继承(因此您可以设计一组基本属性,然后只更改您在每个后续外观中需要的属性)。
欺骗方式是直接修改UIManager
,改变当前外观使用的各种属性。如果您想进行小的调整,这有时会更容易。
无论哪种方式,这都将影响您的应用程序创建的所有组件,您无需再做任何事情,然后在启动时更改外观