I found the solution myself and it is an unorthodox one, but at least it seems to do what I want.
In LayeredBarRenderer#drawVerticalItem
there is this part:
// draw the item labels if there are any...
CategoryItemLabelGenerator generator = getItemLabelGenerator(row, column);
if (generator != null && isItemLabelVisible(row, column)) {
double transX1 = rangeAxis.valueToJava2D(base, dataArea, edge);
double transX2 = rangeAxis.valueToJava2D(value, dataArea, edge);
drawItemLabel(g2, dataset, row, column, plot, generator, bar, (transX1 > transX2));
}
I extended LayeredBarRenderer
and @Override
this method with the transX1>transX2
inverted to transX1<=transX2
:
//....
// draw the item labels if there are any...
CategoryItemLabelGenerator generator = getItemLabelGenerator(row, column);
if (generator != null && isItemLabelVisible(row, column)) {
double transX1 = rangeAxis.valueToJava2D(base, dataArea, edge);
double transX2 = rangeAxis.valueToJava2D(value, dataArea, edge);
drawItemLabel(g2, dataset, row, column, plot, generator, bar, !(transX1 > transX2)); //here
}
//....
This combined with an exclusive CategoryItemLabelGenerator
gave me the result I want:
renderer.setDefaultItemLabelGenerator(new StandardCategoryItemLabelGenerator());
renderer.setSeriesItemLabelsVisible(0, true);
renderer.setSeriesItemLabelsVisible(1, true);
The result:

The full overrided class:
@SuppressWarnings("serial")
public class LabelFixedLayeredBarRenderer extends LayeredBarRenderer {
@Override
protected void drawVerticalItem(Graphics2D g2, CategoryItemRendererState state, Rectangle2D dataArea, CategoryPlot plot,
CategoryAxis domainAxis, ValueAxis rangeAxis, CategoryDataset dataset, int row, int column) {
// nothing is drawn for null values...
Number dataValue = dataset.getValue(row, column);
if (dataValue == null) {
return;
}
// BAR X
double rectX = domainAxis.getCategoryMiddle(column, getColumnCount(), dataArea, plot.getDomainAxisEdge())
- state.getBarWidth() / 2.0;
int seriesCount = getRowCount();
// BAR Y
double value = dataValue.doubleValue();
double base = 0.0;
double lclip = getLowerClip();
double uclip = getUpperClip();
if (uclip <= 0.0) { // cases 1, 2, 3 and 4
if (value >= uclip) {
return; // bar is not visible
}
base = uclip;
if (value <= lclip) {
value = lclip;
}
} else if (lclip <= 0.0) { // cases 5, 6, 7 and 8
if (value >= uclip) {
value = uclip;
} else {
if (value <= lclip) {
value = lclip;
}
}
} else { // cases 9, 10, 11 and 12
if (value <= lclip) {
return; // bar is not visible
}
base = getLowerClip();
if (value >= uclip) {
value = uclip;
}
}
RectangleEdge edge = plot.getRangeAxisEdge();
double transY1 = rangeAxis.valueToJava2D(base, dataArea, edge);
double transY2 = rangeAxis.valueToJava2D(value, dataArea, edge);
double rectY = Math.min(transY2, transY1);
double rectWidth;
double rectHeight = Math.abs(transY2 - transY1);
// draw the bar...
double shift = 0.0;
double widthFactor = 1.0;
double seriesBarWidth = getSeriesBarWidth(row);
if (!Double.isNaN(seriesBarWidth)) {
widthFactor = seriesBarWidth;
}
rectWidth = widthFactor * state.getBarWidth();
rectX = rectX + (1 - widthFactor) * state.getBarWidth() / 2.0;
if (seriesCount > 1) {
// needs to be improved !!!
shift = rectWidth * 0.20 / (seriesCount - 1);
}
Rectangle2D bar = new Rectangle2D.Double((rectX + ((seriesCount - 1 - row) * shift)), rectY,
(rectWidth - (seriesCount - 1 - row) * shift * 2), rectHeight);
if (state.getElementHinting()) {
beginElementGroup(g2, dataset.getRowKey(row), dataset.getColumnKey(column));
}
Paint itemPaint = getItemPaint(row, column);
GradientPaintTransformer t = getGradientPaintTransformer();
if (t != null && itemPaint instanceof GradientPaint) {
itemPaint = t.transform((GradientPaint) itemPaint, bar);
}
g2.setPaint(itemPaint);
g2.fill(bar);
if (isDrawBarOutline() && state.getBarWidth() > BAR_OUTLINE_WIDTH_THRESHOLD) {
g2.setStroke(getItemOutlineStroke(row, column));
g2.setPaint(getItemOutlinePaint(row, column));
g2.draw(bar);
}
if (state.getElementHinting()) {
endElementGroup(g2);
}
// draw the item labels if there are any...
CategoryItemLabelGenerator generator = getItemLabelGenerator(row, column);
if (generator != null && isItemLabelVisible(row, column)) {
double transX1 = rangeAxis.valueToJava2D(base, dataArea, edge);
double transX2 = rangeAxis.valueToJava2D(value, dataArea, edge);
drawItemLabel(g2, dataset, row, column, plot, generator, bar, !(transX1 > transX2));
}
// collect entity and tool tip information...
EntityCollection entities = state.getEntityCollection();
if (entities != null) {
addItemEntity(entities, dataset, row, column, bar);
}
}
}
P.S: I did not test if it works by default when the plot is oriented horizontally and if it requires to do the same thing for drawHorizontalItem
.