Reputation: 91
I want to make my tab labels share the JTabbedPane width. If there's one tab, fit whole width, if two tabs, share width, if three, 1/3 for each and so on...
i don't even know if it's possible to do it without putting a component there and resizing it, maybe JTabbedPane has a way of resizing it's tab label via method and i don't know...
Anyone got any idea how to make it by the easiest way possible?
Upvotes: 2
Views: 1393
Reputation: 51525
As @trashgod already noted, the tab layout is handled by the LAF-specific SomeLAFTabbedPaneUI, more specifically the TabbedPaneLayout. So the way to go is
The first boils down to hook into the calculation of the rectangles which are used for painting the tabs/locating custom tabComponents. Something like (note: obviously not production ready :-)
public class XMetalTabbedPaneUI extends MetalTabbedPaneUI {
public static ComponentUI createUI(JComponent c) {
return new XMetalTabbedPaneUI();
}
@Override
protected LayoutManager createLayoutManager() {
return new XTabbedPaneLayout();
}
protected class XTabbedPaneLayout extends MetalTabbedPaneUI.TabbedPaneLayout {
protected Container tabContainer;
@Override
protected void calculateTabRects(int tabPlacement, int tabCount) {
super.calculateTabRects(tabPlacement, tabCount);
// TODO: check if it makes sense to stretch
int max = 0;
int sum = 0;
Rectangle r = new Rectangle();
for (int i = 0; i < tabCount; i++) {
getTabBounds(i, r);
max = Math.max(max, r.width);
sum += r.width;
}
// TODO: calculate real width, that is -insets
int paneWidth = tabPane.getWidth() - 10;
int free = paneWidth - sum;
// nothing to distribute
if (free < tabCount) return;
int add = free /tabCount;
int offset = 0;
for (int i = 0; i < tabCount; i++) {
r = rects[i];
r.x += offset;
r.width += add;
offset += add;
}
}
}
}
The second is highly simplified (biased me, as the maintainer of the project :-) by the plaf enhancement mechanism provided by SwingX (actually all you need is its plaf module and dependencies). Its basic building block is a TabbedPaneAddon which loads the custom ui:
public class TabbedPaneAddon extends AbstractComponentAddon {
/**
* @param name
*/
public TabbedPaneAddon() {
super("TabbedPane");
}
@Override
protected void addMetalDefaults(LookAndFeelAddons addon,
DefaultsList defaults) {
// remove old ui
UIManager.getLookAndFeelDefaults().put("TabbedPaneUI", null);
defaults.add("TabbedPaneUI",
// here goes the full classname of your custom ui
// this is an example only :-)
"org.jdesktop.swingx.XMetalTabbedPaneUI");
}
// implement other addXXDefault as needed for
// supporting more LAFs
}
The make the replacement happen, you have to contribute the addon ("early") in your application:
LookAndFeelAddons.contribute(new TabbedPaneAddon());
Upvotes: 6
Reputation: 205785
Is there a Look & Feel that has this "tab fitting" capability?
I don't know of one, but you might post an illustration for others who may have seen something similar. As the appearance is controlled by the L&F's UI delegate, TabbedPaneUI
, you need to either look for an existing implementation or subclass one of its descendants: BasicTabbedPaneUI
or MetalTabbedPaneUI
.
Upvotes: 2