Для представления Списка Объектов с различными цветами в GWT-виджете мы должны получить динамично Список цветов с так же различными цветами как объекты. Так как размер Списка может варьироваться, мы должны смочь вычислить такой Список цветов.
Другая версия моего решения с диапазонами:
List<int> getUniqueColors(int amount) {
final int lowerLimit = 0x10;
final int upperLimit = 0xE0;
final int colorStep = (upperLimit-lowerLimit)/Math.pow(amount,1f/3);
final List<int> colors = new ArrayList<int>(amount);
for (int R = lowerLimit;R < upperLimit; R+=colorStep)
for (int G = lowerLimit;G < upperLimit; G+=colorStep)
for (int B = lowerLimit;B < upperLimit; B+=colorStep) {
if (colors.size() >= amount) { //The calculated step is not very precise, so this safeguard is appropriate
return colors;
} else {
int color = (R<<16)+(G<<8)+(B);
colors.add(color);
}
}
return colors;
}
Эта более продвинутая, поскольку генерирует цвета, которые максимально отличаются друг от друга (что-то вроде @aiiobe).
Обычно мы разделяем диапазон на 3 поддиапазона: красный, зеленый и синий, вычисляем, сколько шагов нам нужно для итерации каждого из них (применяя pow (range, 1f / 3)), и повторяем их.
Например, для числа 3 будет сгенерировано 0x0000B1, 0x00B100, 0x00B1B1
. Для номера 10 это будет: 0x000076, 0x0000EC, 0x007600, 0x007676, 0x0076EC, 0x00EC00, 0x00EC76, 0x00ECEC, 0x760000, 0x760076
Если я правильно понял вашу ситуацию, вам нужно несколько цветов, которые выглядят как бы "как можно более разными"? В таком случае я бы предложил вам варьировать значение оттенка (два красных цвета с немного разной яркостью не будут выглядеть по-разному), чтобы получить что-то вроде "радужной палитры":
Этого можно достичь с помощью следующего кода:
Color[] cols = new Color[n];
for (int i = 0; i < n; i++)
cols[i] = Color.getHSBColor((float) i / n, 1, 1);
Пример использования со снимками экрана ниже:
import java.awt.*;
public class TestComponent extends JPanel {
int numCols = 6;
public void paint(Graphics g) {
float h = 0, dh = (float) getHeight() / numCols;
Color[] cols = getDifferentColors(numCols);
for (int i = 0; i < numCols; i++) {
g.setColor(cols[i]);
g.fillRect(0, (int) h, getWidth(), (int) (h += dh));
}
}
public static Color[] getDifferentColors(int n) {
Color[] cols = new Color[n];
for (int i = 0; i < n; i++)
cols[i] = Color.getHSBColor((float) i / n, 1, 1);
return cols;
}
public static void main(String s[]) {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new TestComponent());
f.setSize(200, 200);
f.setVisible(true);
}
}
numCols = 6
и numCols = 40
дает следующие два скриншота:
Если вам нужно более 30 цветов, вы, конечно, можете изменить яркость и, возможно, насыщенность, и иметь, например, 10 темных цветов, 10 средних тонов и 10 ярких цветов.
Думаю, подойдет что-то вроде этого. Никакой случайности, просто вычисляется, какой цветовой шаг нужно сделать и разбивает весь цветовой диапазон на эти шаги. Если вы ограничите нижний предел - вы удалите слишком темные цвета, а ограничение верхнего предела удалит слишком яркие цвета.
List<Integer> getUniqueColors(int amount) {
final int lowerLimit = 0x101010;
final int upperLimit = 0xE0E0E0;
final int colorStep = (upperLimit-lowerLimit)/amount;
final List<Integer> colors = new ArrayList<Integer>(amount);
for (int i=0;i<amount;i++) {
int color = lowerLimit+colorStep*i;
colors.add(color);
}
return colors;
}