JTabbedPane:如何从上到下而不是从下到上排序选项卡?

问题描述 投票:0回答:2

JTabbedPane
中,选项卡的顺序是从下到上:

我希望它是从上到下,这意味着 tab0 将在顶行,而 tab60 将在底行。

代码:

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.UIManager;

public class Class1 {

    public static JTabbedPane jtp;

    public static void main(String[] args) {
        JFrame window = new JFrame();
        window.setTitle("Parent frame");
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setSize(600, 400);
        window.setLocationRelativeTo(null);

        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            e.printStackTrace();
        }

        jtp = new JTabbedPane();
        window.add(jtp);

        /*WindowsTabbedPaneUI btpui = new WindowsTabbedPaneUI() {
            @Override protected void paintTabArea(Graphics g, int tabPlacement, int selectedIndex) {
                int tabCount = tabPane.getTabCount();

                Rectangle iconRect = new Rectangle(),
                          textRect = new Rectangle();
                Rectangle clipRect = g.getClipBounds();

                // Paint tabRuns of tabs from front to back
                for (int i = 0; i < runCount; i++) {
                    int start = tabRuns[i];
                    int next = tabRuns[(i == runCount - 1)? 0 : i + 1];
                    int end = (next != 0? next - 1: tabCount - 1);
                    for (int j = start; j <= end; j++) {
                        if (j != selectedIndex && rects[j].intersects(clipRect)) {
                            paintTab(g, tabPlacement, rects, j, iconRect, textRect);
                        }
                    }
                }

                // Paint selected tab if its in the front run
                // since it may overlap other tabs
                if (selectedIndex >= 0 && rects[selectedIndex].intersects(clipRect)) {
                    paintTab(g, tabPlacement, rects, selectedIndex, iconRect, textRect);
                }
            }
        };
        jtp.setUI(btpui);*/

        //jtp.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);

        for (int i = 0; i <= 60; i++) {
            jtp.addTab("tab"+i, new JPanel());
        }
        window.setVisible(true);
    }
}

我试过覆盖

paintTabArea()
中的
WindowsTabbedPaneUI
方法从上到下绘画,但它似乎没有做任何事情。

我找到了 2 个解决方法:

  • 将标签放在底部,以便它们以正确的方式对齐(但我想将它们放在顶部)

  • 以相反的顺序排列选项卡,然后将组件从右到左对齐。然而,这会产生视觉故障:左侧的选项卡太靠近边框,左侧的选项卡与其他选项卡之间有空间,右侧的选项卡在边框上形成凹痕。我还必须重写

    addTab()
    方法,并在只有一行时放入 LTR,这感觉像是 hack。

有没有办法做到这一点而不会出现故障?我想我必须重写

BasicTabbedPaneUI
的一些方法,但我找不到哪个。

java swing jtabbedpane
2个回答
2
投票

我终于找到了解决方案

正如@Joe Coder 所说,您必须重写

calculateTabRects()
方法。但是,此方法位于内部类中。没有办法扩展
BasicTabbedPaneUI
或内部类,因为有太多的受保护和私有字段。解决方案是通过复制粘贴所有代码来重新创建相关类。

源码来自这里.

相关修改在

calculateTabRects()
方法中,更具体地说是在那个for循环中:

// Step through runs from back to front to calculate
// tab y locations and to pad runs appropriately
for (i = runCount - 1; i >= 0; i--) {
    //...
}

简单地反向迭代就可以了:

for (i = 0; i < runCount; i++) {...}

现在,如果你复制粘贴

BasicTabbedPaneUI
的代码,你会发现你还需要复制粘贴
LazyActionMap
BasicGraphicsUtils

为方便起见,这里是您需要复制粘贴的所有代码。确保不要覆盖包,如果它不在包中

javax.swing.plaf.basic
它将无法工作。

FixedTabbedPaneUI.java:https://pastebin.com/W8RBD4vg

LazyActionMap2.java:https://pastebin.com/RKtDgJB5

BasicGraphicsUtils2.java:https://pastebin.com/Au4hcSyp

但是,就我而言,我需要一个

WindowsTabbedPaneUI
。所以这是 WindowsTabbedPaneUI2.java:https://pastebin.com/89UedgbQ

..XPStyle2.java:https://pastebin.com/xCsm8DZc

..和AnimationController2.java:https://pastebin.com/7Pm0s5eG

OOP 地狱到此结束,但在当前状态下,“运行”(制表符行)之间的线消失了:

解决方案是在选择带有

UIManager.setLookAndFeel()
的UI后放入以下内容:

    UIManager.getDefaults().put("TabbedPane.tabRunOverlay", 0);
    UIManager.getDefaults().put("TabbedPane.focus", new Color(0, 0, 0, 0));

结果:


0
投票

您可以通过扩展

BasicTabbedPaneUI
和覆盖
createLayoutManager
来更容易地实现它,并在那里返回
TabbedPaneLayout
覆盖必要的方法。

© www.soinside.com 2019 - 2024. All rights reserved.