As suggested here, a custom renderer can query the model to condition the result returned by getItemPaint()
. In this example, subtasks are rendered using a palette of varying saturations of the default color for a given series. The approach assumes that the renderer makes two passes; some care should be given to documenting the dependency.
/** @see https://stackoverflow.com/questions/8938690 */
private static class MyRenderer extends GanttRenderer {
private static final int PASS = 2; // assumes two passes
private final List<Color> clut = new ArrayList<Color>();
private final TaskSeriesCollection model;
private int row;
private int col;
private int index;
public MyRenderer(TaskSeriesCollection model) {
this.model = model;
}
@Override
public Paint getItemPaint(int row, int col) {
if (clut.isEmpty() || this.row != row || this.col != col) {
initClut(row, col);
this.row = row;
this.col = col;
index = 0;
}
int clutIndex = index++ / PASS;
return clut.get(clutIndex);
}
private void initClut(int row, int col) {
clut.clear();
Color c = (Color) super.getItemPaint(row, col);
float[] a = new float[3];
Color.RGBtoHSB(c.getRed(), c.getGreen(), c.getBlue(), a);
TaskSeries series = (TaskSeries) model.getRowKeys().get(row);
List<Task> tasks = series.getTasks(); // unchecked
int taskCount = tasks.get(col).getSubtaskCount();
taskCount = Math.max(1, taskCount);
for (int i = 0; i < taskCount; i++) {
clut.add(Color.getHSBColor(a[0], a[1] / i, a[2]));
}
}
}