JTabbedPane: tab placement set to LEFT but icons are not aligned

I have a

JTabbedPane

with tab placement set to LEFT. The problem is that icons in each tab are not vertically aligned with one another.

Consider this picture:

As you can see the icon of "Editar Protocolo" (second tab) is not perfectly aligned with the icon of "Distribuir Protocolo" (first tab) and this also happen with the other tabs. I want all icons be vertically aligned to the left.

What I want: the icons ALL in the LEFT, not based on the Text Size
[...]

The tab's content is centered by typical implementations, and it makes sense because the area needed to fit this content is unpredictable until the tab is effectively rendered. Since the area depends on the content and different tabs will likely have different title lengths, then there has to be a policy about how to render those tabs. The criteria was to center tabs content and fit the tab area to this content. When we have a default tabbed pane with tabs placed at the top, we don't care much about icon/text alignment:

The only concern could be tabs having different length, but who cares? After all, icons and text are visible and tabbed pane looks good enough. However, when you set the tabs placement to LEFT or RIGHT things are different and it looks unappealing:

Apparently this default behavior is a long standing problem, and there's a really interesting discussion here. Some SO members are involved there: @camickr, @kleopatra, @splungebob. As discussed in that post, a simple solution is not possible, and several workarounds were proposed: basically a custom UI implementation or using panels as renderers and playing with preferred width/height based on text length. Both alternatives involve quite a lot of work.

In order to avoid dealing with UI delegates and taking advantage of setTabComponentAt(...) method, I've started some time ago a tabbed pane extension that I'd like to share here. The approach is based on Swing concept of renderer: a class that has to generate a component to render another component's part, and the goal is to provide a flexible mechanism to add custom tab components.

I have included an example below using my custom tabbed pane and here is an overview of all interfaces/classes needed to provide the aforementioned mechanism.

ITabRenderer interface

The first step is to define an iterface to offer a contract to render a tab component.

AbstractTabRenderer class

An abstract class to provide base methods to help in the getTabRendererComponent(...) method implementation. This abstract class has three main properties:

prototypeText: used to define a prototype text to generate a default renderer component.

prototypeIcon: used to define a prototype icon to generate a default renderer.

horizontalTextAlignment: tab's text horizontal alignment.

Note this class is abstract because it doesn't implement getTabRendererComponent(...) method.

DefaultTabRenderer class

A concrete implementation by extending AbstractTabRenderer class. Note that if you want to include a close button as shown in tutorial demo, then a little work in this class would be enough. As a matter of fact, I already did, but I won't include that part to not extend this (already large) post.

JXTabbedPane

Finally the tabbed pane's extension which includes tab renderer support and overrides addTab(...) methods.

Example

I have run this example with positive results using these PLAFs:

WindowsLookAndFeel

WindowsClassicLookAndFeel

NimbusLookAndFeel

MetalLookAndFeel

SeaglassLookAndFeel

Additionaly if you switch tab placement from LEFT to TOP (default) or BOTTOM then all tabs still having the same width, solving the concern described at the second paragraph of this answer.