Java: Create array of predefined Colors - java

I wish to create an array of all the Colors predefined in java.awt.Color in order to randomly select one of them.
My current best attempt is:
` Color[] colors = Color.getClass().getEnumConstants();
which was suggested in the top answer to the question: Color Class in Java
but that generates the error:
Cannot make a static reference to the non-static method getClass() from the type Object
The constructor in which the erroneous call is made is below:
private Ball() {
Random initialSetter = new Random();
ballX = marginSize + initialSetter.nextInt(xSize - 2 * marginSize);
ballY = marginSize + initialSetter.nextInt(ySize - 2 * marginSize);
ballXV = initialSetter.nextInt(doubleMaxV) - doubleMaxV/2;
ballYV = initialSetter.nextInt(doubleMaxV) - doubleMaxV/2;
Color[] colors = Color.getClass().getEnumConstants();
color = colors[initialSetter.nextInt(colors.length)];
}
Replacing ".getClass().getEnumConstants()" with ".values()" generates much the same error (static reference to non-static method).

To fix your immediate error, you can do:
Color[] colors = Color.class.getEnumConstants();
But this only works if Color is an enum. According to your comments, Color refers to java.awt.Color, which is not an enum. The first way suggested by the linked answer is quite incorrect (Maybe it was 6 years ago?).
As far as I know, the best thing you can do here is to list them all out. There's not much - only 13. It's not like this number is going to change any time soon, as AWT is pretty old, they are unlikely to add new colours in at this stage.
For fun (this is only for fun), you can do it with reflection:
List<Color> colors = Arrays.stream(Color.class.getFields())
// fields of type Color, and in all caps, snake case
.filter(x -> x.getType() == Color.class && x.getName().matches("[A-Z_]+"))
.map(x -> {
try {
return (Color)x.get(null);
} catch (IllegalAccessException e) {
e.printStackTrace();
return Color.BLACK;
}
}).collect(Collectors.toList());
Note that reflection is really slow though, which is why your best choice is to hardcode it.

Related

Fill ArrayList with colors for Android

I want to create 2 ArrayList. One holding 16 colors, the other one holding 139.
I have the list with colors (both RGB as 255,126,32 and Hex as 0xFFFF2552). I want to use the ArrayList to later pick random colors from.
I've tried int[], that doesn't work. I've tried ArrayList<Integer> and ArrayList<Color>. My problem is; I don't understand how to add the colors to the ArrayLists.
Thanks!!
For now, I'm exploring this:
Color cBlue = new Color(0,0,255);
Color cRed = new Color(255,0,0);
ArrayList colors = new ArrayList();
colors.add(cBlue);
colors.add(cRed);
and so on...
I really like int[] colors = = new int[] {4,5}; because it's only one line of code... but how do I get colors in, to later on, pick from?
or.. would it be better to store the colors in a strings.xml file and then fill the ArrayList from there? If so, how should I do that?
Thanks!!
You could try:
int[] colors = new int[] {Color.rgb(1,1,1), Color.rgb(...)};
For example, but I don't think it's a good idea to decide only using "one line" argument.
List<Integer> coloras = Arrays.asList(new Integer[]{Color.rgb(1, 1, 1), Color.rgb(...)});
Will also work.
You can create an arraylist in arrays.xml file:
<resources>
<string-array name="colors">
<item>#ff0000</item>
<item>#00ff00</item>
<item>#0000ff</item>
</string-array>
</resources>
Then use the loop to read them:
String[] colorsTxt = getApplicationContext().getResources().getStringArray(R.array.colors);
List<Integer> colors = new ArrayList<Integer>();
for (int i = 0; i < colorsTxt.length; i++) {
int newColor = Color.parseColor(colorsTxt[i]);
colors.add(newColor);
}
In my opinion keeping colors in the list is the most convinient solution.
To take a color from the list randomly, you do:
int rand = new Random().nextInt(colors.size());
Integer color = colors.get(rand);
I would make a text file or xml file populated with the color info and have a function that reads in each line of the file using a loop, creates a Color object for each line and adds it to the array list and then goes to the next line until there are no lines left.
I would recommend against using a configuration file unless you want to be able to change your colors without code changes. I suspect your colors are constant though, so the file would just add unnecessary complexity to your application.
The code sample in your question assumes java.awt.Color when you would actually use the utility class android.graphics.Color which cannot be instantiated.
Therefore I recommend the following solution as a static variable (and be careful not to modify the contents of the array later):
static final int[] colors16 = {
Color.rgb(255, 0, 0),
Color.rgb(0, 255, 0),
Color.rgb(0, 0, 255)
};
Now add a static instance of Random to use for selecting random colors from the list.
static final Random random = new Random();
And then pick your color!
int colorIndex = random.nextInt(colors16.size());
Color color = colors16.get(colorIndex);
If you feel it's important to protect the contents of your list, you can make it immutable as follows, at the small expense of boxing your color ints into Integer objects.
static final List<Integer> colors = Collections.unmodifiableList(
Arrays.asList(
Integer.valueOf(Color.rgb(255, 0, 0)),
Integer.valueOf(Color.rgb(0, 255, 0)),
Integer.valueOf(Color.rgb(0, 0, 255))
)
);
Technically you can leave out the Integer.valueOf() conversion in the above snippet and Java will autobox the ints.
You can also can use int[] colors = new int[]{color1.getRGB(),color2.getRGB()};
And decode using: Color color = new Color(colors[0]);
What you have looks like it makes sense, but you should specify the type of the ArrayList.
List<Color> colorList = new ArrayList<Color>();
colorList.add(cBlue);
... etc
(The difference between declaring it as a List or an ArrayList is that List is the interface that ArrayList implements. This is a generally pretty good practice, but for your purposes it probably won't make a difference if you declare it as a List or an ArrayList).
If you want to do it in fewer lines of code, you can use an ArrayList initializer block, like this:
List<Color> colorList = new ArrayList<Color> { new Color(...), cBlue };
Or with Arrays.asList, which takes in an array and returns a List.
But in general you should get used to verbosity with Java, don't try to optimize your lines of code so much as the performance of those lines.
(Sidenote: make sure you're using the correct Color class. There's android.graphics.Color and java.awt.Color, and they're totally different, incompatible types. The constructor you're using is from java.awt.Color, and with Android you're probably going to want to use android.graphics.Color).

Creating setColor method without parameter being passed?

I'm working on a homework project for an intro to java course. To practice calling methods and organizing tasks, we have to create two balloon objects s1 and s2 and modify their colors and altitudes using methods in a separate java class.
I have everything working fine, but not exactly to the requirements of the assignment. The sheet lists the method declarations and they cannot be changed, only the code within them can.
The method that is used to change a balloon's color is to be created as public void setColor(). This doesn't make sense to me, though. I'm using public void setColor(String color) for now.
How can I change the color property of a balloon object without passing anything to the setColor method?
I totally agree with #RealSkeptic but as your question says that changing the color without passing any value it means you need to generate the color each time your could use the following code. I'm not sure do this code is what you need.
public void setColor()
{
int red,green,blue;
red = green = blue = 0;
Random random = new Random();
int high = 255, low = 0;
red = random.nextInt(high-low)+low;
green = random.nextInt(high-low)+low;
blue = random.nextInt(high-low)+low;
color = new Color(red,green,blue);
//set this color to your balloon
}
Well, you can't specify any particular color without a parameter in the method. You can hardcode so that the color changes.
class Baloon {
private String[] colors = {"blue", "red" , "green"};
private int index = 0;
private String currentColor = colors[index];
public void setColor(){
index ++;
if (index = colors.length)
index = 0;
currentColor = colors[index];
}
}

Color Class in Java

I have a question regarding the awt Color class in Java.
I am currently using the class abbreviations such as Color.RED and Color.BLACK. I also have a list of three integers such as the following:
int var1 = 0
int var2 = 0
int var3 = 255
Is there a method to convert these integers into the appropriate Java Color name?
There is no way to do this with a single method in the Java core classes. However, you can fairly easily do this yourself in two ways.
First way
First, create a HashMap of Colors that contains all the colors you want:
HashMap<Color, String> colors = new HashMap<Color, String>();
colors.put(Color.BLACK, "BLACK");
colors.put(Color.BLUE, "BLUE");
colors.put(Color.CYAN, "CYAN");
colors.put(Color.DARK_GRAY, "DARK_GRAY");
colors.put(Color.GRAY, "GRAY");
colors.put(Color.GREEN, "GREEN");
colors.put(Color.LIGHT_GRAY, "LIGHT_GRAY");
colors.put(Color.MAGENTA, "MAGENTA");
colors.put(Color.ORANGE, "ORANGE");
colors.put(Color.PINK, "PINK");
colors.put(Color.RED, "RED");
colors.put(Color.WHITE, "WHITE");
colors.put(new Color(192, 0, 255), "PURPLE");
colors.put(new Color(0xBADA55), "BADASS_GREEN");
colors.put(new Color(0, 0, 128), "DARK_BLUE");
Then, create a new Color out of the RGB values you have:
Color color = new Color(var1, var2, var3);
Last, get the value in colors for the key color:
String colorName = colors.get(color);
Second way
This is potentially a less brittle way, but does have issues, and doesn't work as-is. You'll need to catch some exceptions, and maybe handle the case where a field isn't static and you can't just do f.get(null).
Create a new Color out of the RGB values you have:
Color color = new Color(var1, var2, var3);
Then
Get the Class object from the Color class with getClass().
Get the fields from that with getDeclaredFields().
Stream it using Arrays.stream()
Filter it by calling filter(), so it only contains all the enum constants that equal the color you made (there should be either one or zero).
Use toArray() to turn the stream into an array.
Get the first element of that array with [0]. This will throw an ArrayIndexOutOfBoundsException if there isn't a predefined color matching your color.
Get the name of that color with Enum's toString().
String colorName = Arrays.stream(Color.getClass().getDeclaredFields())
.filter(f -> f.get(null).equals(color))
.toArray()[0]
.toString();
There is no set function for this kind of behavior, but you could do something like this:
public static String getColorName(int r, int g, int b) {
String[] colorNames = new String[] {
"BLACK",
"BLUE",
"GREEN",
"CYAN",
"DARK_GRAY",
"GRAY",
"LIGHT_GRAY",
"MAGENTA",
"ORANGE",
"PINK",
"RED",
"WHITE",
"YELLOW"
};
Color userProvidedColor = new Color(r,g,b);
Color color;
Field field;
for (String colorName : colorNames) {
try {
field = Class.forName("java.awt.Color").getField(colorName);
color = (Color)field.get(null);
if (color.equals(userProvidedColor)) {
return colorName; // Or maybe return colorName.toLowerCase() for aesthetics
}
} catch (Exception e) {
}
}
Color someOtherCustomDefinedColorMaybePurple = new Color(128,0,128);
if (someOtherCustomDefinedColorMaybePurple.equals(userProvidedColor)) {
return "Purple";
}
return "Undefined";
}
There are a few options from here as well, maybe you want the nearest color? In which case you could try and resolve the distance somehow (here by distance from each r,g,b coordinate, admittedly not the best method but simple enough for this example, this wiki page has a good discussion on more rigorous methods)
// ...
String minColorName = "";
float minColorDistance = 10000000;
float thisColorDistance = -1;
for (String colorName : colorNames) {
try {
field = Class.forName("java.awt.Color").getField(colorName);
color = (Color)field.get(null);
thisColorDistance = ( Math.abs(color.red - userProvidedColor.red) + Math.abs(color.green - userProvidedColor.green) + Math.abs(color.blue - userProvidedColor.blue) );
if (thisColorDistance < minColorDistance) {
minColorName = colorName;
minColorDistance = thisColorDistance;
}
} catch (Exception e) {
// exception that should only be raised in the case color name is not defined, which shouldnt happen
}
}
if (minColorName.length > 0) {
return minColorName;
}
// Tests on other custom defined colors
This should outline how you would be able to compare to the built in colors from the Color library. You could use a Map to expand the functionality further to allow for you to define as many custom colors as you like (Something #TheGuywithTheHat suggests as well) which gives you more control over the return names of matched colors, and allows for you to go by more colors than just the predefined ones:
HashMap<String,Color> colorMap = new HashMap<String,Color>();
colorMap.put("Red",Color.RED);
colorMap.put("Purple",new Color(128,0,128));
colorMap.put("Some crazy name for a color", new Color(50,199,173));
// etc ...
String colorName;
Color color;
for (Map.Entry<String, Color> entry : colorMap.entrySet()) {
colorName = entry.getKey();
color= entry.getValue();
// Testing against users color
}
As far as i know, we don't have any such library to directly access the colors from the Constants.
But we can manage do it using Hex Color Library in Java.
References :
Hex
Color Class
Without any helping libraries I would say: No. Especially because not every RGB-Color has a specific name. However, you could of course build an own function, which tries to match some of the available colors and deliver something like "Unknown" if there is no match.
The matching attempt could theoretically be done using the Java reflection API...

Adding colours to custom edges

I want to add colours to the edges of the graph which I created using the JUNG library. I have edges which are in the type of custom edges where I set the labels and weights to the edges.
Transformer<CustomEdge, Paint> edgesPaint = new Transformer<CustomEdge, Paint>() {
private final Color[] palette = {Color.GREEN,
Color.YELLOW, Color.RED};
public Paint transform(CustomEdge edgeValue) {
String stringvalue=edgeValue.toString();
stringvalue=stringvalue.replaceAll("%","");
int value=Integer.valueOf(stringvalue);
if (value<= 10) {
return palette[0];
}
if (value> 10 && value<=20 ) {
return palette[1];
}
else {
return palette[2];
}
}
};
The following line returns an error message saying that the type of the edgesPaint should be (string,Paint):
visualizationViewer.getRenderContext().setEdgeFillPaintTransformer(edgesPaint);
Please help me with this.
Offhand I'd guess that your VisualizationViewer was declared to have edge type "String" (i.e., VisualizationViewer. But without more context it's hard to be sure.
Please print the exact error message and stack trace. Showing the declaration of the VisualizationViewer would also probably be helpful.

How does java.awt.Color.getColor(String colorName) work?

I'm trying to get colors by name, and I came across Converting a String to Color in Java, which suggests using java.awt.getColor.
I can't work out what to pass it as a string though. The following
System.out.println( java.awt.Color.getColor( "black", Color.red ) );
prints out
java.awt.Color[r=255,g=0,b=0]
i.e. it is going with the default color in there.
I've put this in a text box, and tried alternative capitalisations etc. The docs aren't very helpful here. Can anyone suggest what magic strings to put in?
The non-accepted answer uses Color.getColor. This method reads from system properties which may or may not be present. You should not use this method.
Instead, you should use the upvoted reflection method to find the static member of the Color class. Either this, or you should import your own color database which maps string names to RGB values.
Color color;
try {
Field field = Color.class.getField("yellow");
color = (Color)field.get(null);
} catch (Exception e) {
color = null; // Not defined
}

Categories

Resources