After some hours of research I have finally found a clean solution.
First, figure out which UI class you are using. Put the following code after you initialize the L&F with UIManager.setLookAndFeel()
:
for (Map.Entry<Object, Object> entry : UIManager.getDefaults().entrySet()) {
boolean isStringKey = entry.getKey().getClass() == String.class ;
String key = isStringKey ? ((String) entry.getKey()):"";
if (key.equals("TabbedPaneUI")) {
System.out.println(entry.getValue());
}
}
In my case, it prints com.sun.java.swing.plaf.windows.WindowsTabbedPaneUI
. If you are using a different L&F, this may be another class (or even if you are using another OS, if you take the OS default).
Next, just instantiate that class (which extends BasicTabbedPaneUI), and override the problematic method:
WindowsTabbedPaneUI jtpui = new WindowsTabbedPaneUI() {
@Override protected boolean shouldRotateTabRuns(int i) {
return false;
}
};
If eclipse does not recognize the class, and gives you an "access restriction" error if you type the full name of the class, see this question: Access restriction: The type 'Application' is not API (restriction on required library rt.jar)
Finally, just set that UI for your JTabbedPane:
JTabbedPane jtp = new JTabbedPane();
jtp.setUI(jtpui);
However, there is a problem: some L&F don't take into account the non-scrolling of tabs rows, and it turns out ugly.

To fix this (I only tested on the Windows L&F), add the following immediately after initializing the L&F:
UIManager.getDefaults().put("TabbedPane.tabRunOverlay", 0);
