I am implementing my own Look&Feel for a JTabbedPane using BasicTabbedPaneUI . Following this tutorial , I want to add close buttons at the end of my tabs.
So far, I have managed to paint my closing icons on the right of the tab but it overlays my tab title. Therefore, I would like to reduce the width of the Rectangle used for the textRect parameter in the overridden method paintTab().
I have tried this but it has no effect:
@Override
protected void paintTab(Graphics g, int tabPlacement, Rectangle[] rects, int tabIndex,
Rectangle iconRect, Rectangle textRect) {
//reduce textrect width to leave space for close icon
textRect.setSize(textRect.width - (2 * WIDTHDELTA + icon.getIconWidth()), textRect.height);
super.paintTab(g, tabPlacement, rects, tabIndex, iconRect, textRect);
Rectangle tabRect = rects[tabIndex];
// Calculate the coordinates where the button should be.
int dx = tabRect.x + tabRect.width - icon.getIconWidth() - WIDTHDELTA;
int dy = tabRect.y + (tabRect.height - icon.getIconHeight()) / 2;
//Paint the Close button
icon.paintIcon(tabPane, g, dx, dy);
}
How and where can I shrink the rectangle used to paint the tab's text?
Try to play with the fields of BasicTabbedPaneUI
protected Insets tabInsets;
protected Insets selectedTabPadInsets;
protected Insets tabAreaInsets;
protected Insets contentBorderInsets;
The tabInsets are used in the method you can try to override
protected int calculateTabWidth(int tabPlacement, int tabIndex, FontMetrics metrics)
Here is the solution I came up with:
private String clipText(FontMetrics metrics, String text) {
String clipped = "...";
if (metrics.stringWidth(clipped) < MAX_TEXT_WIDTH) {
StringBuilder sb = new StringBuilder(clipped);
int index = 0;
for (char c : text.toCharArray()) {
sb.insert(index, c);
if (metrics.stringWidth(sb.toString()) > MAX_TEXT_WIDTH) {
clipped = sb.deleteCharAt(index).toString();
break;
}
index++;
}
}
return clipped;
}
I use it in:
@Override
protected void paintText(Graphics g, int tabPlacement, Font font, FontMetrics metrics,
int tabIndex, String title, Rectangle textRect, boolean isSelected) {
g.setFont(font);
View v = getTextViewForTab(tabIndex);
if (v != null) {
// html
v.paint(g, textRect);
} else {
// plain text
int mnemIndex = tabPane.getDisplayedMnemonicIndexAt(tabIndex);
g.setColor(isSelected ? ANZ_BLUE : Color.WHITE);
String text;
int rectX;
if (metrics.stringWidth(title) <= MAX_TEXT_WIDTH) {
text = title;
rectX = textRect.x - (icon.getIconWidth() / 2); //center text
} else {
text = clipText(metrics, title); //clip text
rectX = textRect.x;
}
if (tabPane.isEnabled() && tabPane.isEnabledAt(tabIndex)) {
BasicGraphicsUtils.drawStringUnderlineCharAt(g, text, mnemIndex, rectX,
textRect.y + metrics.getAscent());
} else { // tab disabled
Color bg = tabPane.getBackgroundAt(tabIndex);
g.setColor(bg.brighter());
BasicGraphicsUtils.drawStringUnderlineCharAt(g, text, mnemIndex, rectX,
textRect.y + metrics.getAscent());
g.setColor(bg.darker());
BasicGraphicsUtils.drawStringUnderlineCharAt(g, text, mnemIndex, rectX - 1,
textRect.y + metrics.getAscent() - 1);
}
}
}
It works fine for me.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.