Swing/IsoscelesTrapezoidTabs のバックアップ(No.4)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/IsoscelesTrapezoidTabs へ行く。
- category: swing
folder: IsoscelesTrapezoidTabs
title: JTabbedPaneのタブの形を台形に変更する
tags: [JTabbedPane, UIManager, Shape]
author: aterai
pubdate: 2017-01-16T03:46:40+09:00
description: JTabbedPaneのタブの形を台形に変更し、左側にあるタブが上に表示されるよう設定します。
image: https://drive.google.com/uc?export=view&id=1NeVPi85J0fLf7nSH0xB03Rk9tclob08S7w
hreflang:
href: https://java-swing-tips.blogspot.com/2017/01/change-tab-shape-of-jtabbedpane-to.html lang: en
概要
JTabbedPane
のタブの形を台形に変更し、左側にあるタブが上に表示されるよう設定します。
Screenshot
Advertisement
サンプルコード
class IsoscelesTrapezoidTabbedPaneUI extends BasicTabbedPaneUI {
private static final int ADJ2 = 3;
private final Color selectedTabColor = UIManager.getColor("TabbedPane.selected");
private final Color tabBackgroundColor = Color.LIGHT_GRAY;
private final Color tabBorderColor = Color.GRAY;
@Override protected void paintTabArea(Graphics g, int tabPlacement, int selectedIndex) { //NOPMD
int tabCount = tabPane.getTabCount();
Rectangle iconRect = new Rectangle(),
textRect = new Rectangle();
Rectangle clipRect = g.getClipBounds();
for (int i = runCount - 1; i >= 0; i--) {
int start = tabRuns[i];
int next = tabRuns[(i == runCount - 1) ? 0 : i + 1];
int end = next != 0 ? next - 1 : tabCount - 1; //NOPMD
// for (int j = start; j <= end; j++) {
// http://stackoverflow.com/questions/41566659/tabs-rendering-order-in-custom-jtabbedpane
for (int j = end; j >= start; j--) {
if (j != selectedIndex && rects[j].intersects(clipRect)) {
paintTab(g, tabPlacement, rects, j, iconRect, textRect);
}
}
}
if (selectedIndex >= 0 && rects[selectedIndex].intersects(clipRect)) {
paintTab(g, tabPlacement, rects, selectedIndex, iconRect, textRect);
}
}
@Override protected void paintTabBorder(
Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h, boolean isSelected) {
// Do nothing
}
@Override protected void paintFocusIndicator(
Graphics g, int tabPlacement, Rectangle[] rects, int tabIndex,
Rectangle iconRect, Rectangle textRect, boolean isSelected) {
// Do nothing
}
@Override protected void paintContentBorderTopEdge(
Graphics g, int tabPlacement, int selectedIndex, int x, int y, int w, int h) {
super.paintContentBorderTopEdge(g, tabPlacement, selectedIndex, x, y, w, h);
Rectangle selRect = getTabBounds(selectedIndex, calcRect);
Graphics2D g2 = (Graphics2D) g.create();
g2.setColor(selectedTabColor);
g2.drawLine(selRect.x - ADJ2 + 1, y, selRect.x + selRect.width + ADJ2 - 1, y);
g2.dispose();
}
@Override protected void paintTabBackground(
Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h, boolean isSelected) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
int textShiftOffset = isSelected ? 0 : 1;
Rectangle clipRect = g2.getClipBounds();
clipRect.grow(ADJ2 + 1, 0);
g2.setClip(clipRect);
GeneralPath trapezoid = new GeneralPath();
trapezoid.moveTo(x - ADJ2, y + h);
trapezoid.lineTo(x + ADJ2, y + textShiftOffset);
trapezoid.lineTo(x + w - ADJ2, y + textShiftOffset);
trapezoid.lineTo(x + w + ADJ2, y + h);
//trapezoid.closePath();
g2.setColor(isSelected ? selectedTabColor : tabBackgroundColor);
g2.fill(trapezoid);
g2.setColor(tabBorderColor);
g2.draw(trapezoid);
g2.dispose();
}
}
View in GitHub: Java, Kotlin解説
上記のサンプルでは、タブの形を台形に変更し、左側にあるタブが上に表示されるように、BasicTabbedPaneUI
の各描画メソッドをオーバーライドし、これをsetUI(...)
メソッドでJTabbedPane
に設定しています。
BasicTabbedPaneUI#paintTabArea(...)
をオーバーライドして、右側のタブを先に描画するよう変更BasicTabbedPaneUI#paintTabBorder(...)
、BasicTabbedPaneUI#paintFocusIndicator(...)
メソッドをオーバーライドして、なにも描画しないように変更- タブのフチの罫線などは、
BasicTabbedPaneUI#paintTabBackground(...)
でまとめて描画する
- タブのフチの罫線などは、
BasicTabbedPaneUI#paintContentBorderTopEdge(...)
をオーバーライドして、台形タブの拡大した部分に掛かるコンテンツエリアの罫線を上書きで塗り潰すJTabbedPane#setTabPlacement (JTabbedPane.TOP)
のみに対応
BasicTabbedPaneUI#paintTabBackground(...)
をオーバーライドして、タブの形を台形に変更- タブ矩形の外側に台形がはみ出すので、
Graphics2D#setClip(...)
で描画領域を拡大する必要がある
- タブ矩形の外側に台形がはみ出すので、
参考リンク
- JTabbedPaneのタブエリア背景色などをテスト
- JTabbedPaneのNimbusLookAndFeelにおけるスタイルを変更する
SynthLookAndFeel
などの場合は、javax.swing.plaf.Painter
を変更する
- java - Tabs Rendering Order in Custom JTabbedPane - Stack Overflow