JTabbedPaneのタブが配置されたランの位置を取得する
Total: 302
, Today: 1
, Yesterday: 0
Posted by aterai at
Last-modified:
概要
JTabbedPane
のタブがどのタブランに配置されているかを取得してJToolTip
で表示します。
Screenshot
Advertisement
サンプルコード
JTabbedPane tabs = new JTabbedPane() {
@Override public void addTab(String title, Icon icon, Component component) {
super.addTab(title, icon, component, title);
}
@Override public String getToolTipText(MouseEvent e) {
String tip = super.getToolTipText(e);
int idx = indexAtLocation(e.getX(), e.getY());
if (idx >= 0 && isHorizontalTabPlacement()) {
int run = getRunForTab(getTabCount(), idx);
tip = String.format("%s: Run: %d", tip, run);
}
return tip;
}
private int getRunForTab(int tabCount, int tabIndex) {
int runCount = getTabRunCount();
Rectangle taRect = getTabAreaRect(tabCount);
int runHeight = taRect.height / runCount;
Rectangle tabRect = getBoundsAt(tabIndex);
Point2D pt = new Point2D.Double(
tabRect.getCenterX(), tabRect.getCenterY());
Rectangle runRect = new Rectangle(
taRect.x, taRect.y, taRect.width, runHeight);
int run = -1;
for (int i = 0; i < runCount; i++) {
if (runRect.contains(pt)) {
run = i;
}
runRect.translate(0, runHeight);
}
return getTabPlacement() == TOP ? runCount - run - 1 : run;
}
private Rectangle getTabAreaRect(int tabCount) {
Rectangle rect = getBoundsAt(0);
for (int i = 0; i < tabCount; i++) {
rect.add(getBoundsAt(i));
}
return rect;
}
private boolean isHorizontalTabPlacement() {
return getTabPlacement() == TOP || getTabPlacement() == BOTTOM;
}
};
View in GitHub: Java, Kotlin解説
JTabbedPane
にラップタブレイアウト(WRAP_TAB_LAYOUT
)が設定されて複数ランが生成される場合、任意のタブがどのランに配置されているかを計算する- このサンプルではタブ配置(
tabPlacement
)がTOP
またはBOTTOM
でランが行になる場合のみ対応し、LEFT
、RIGHT
で列になる場合は未対応
- このサンプルではタブ配置(
- タブエリア領域を計算して取得し、その高さを
JTabbedPane#getTabRunCount()
で取得したランの行数で割ってランの高さを計算し、ひとつのランが占める領域を求める- 対象タブの中心が上で求めた何番目のラン領域に含まれるかを調査する
- タブ配置が
TOP
の場合、表示上タブコンテンツ領域に接するランを0
とした順番になるようrunCount - run - 1
と反転する
BasicTabbedPaneUI#getRunForTab(...)
で配置されたラン位置を求める方法もあるが、このメソッドはprotected
かつタブランの入れ替え(BasicTabbedPaneUI#shouldRotateTabRuns() == true
)発生前のラン位置を返すのでこのサンプルでは使用不可