JTabbedPane:如果堆叠/ Nimbus,则避免自动重新排序选项卡

时间:2011-09-20 08:09:53

标签: java swing constants jtabbedpane nimbus

JTabbedPane就是我的目的所需要的。 我的水平空间非常有限,所以我的标签堆叠,这是完全可以的。

但默认行为是,如果用户点击标签,则* 标签会重新排序,以便活动标签成为低级别的 * t。在理论上看起来非常直观和合乎逻辑的是实际使用中的噩梦,因为用户松散地追踪“哪个是哪个”。它只是简单的混乱,我一次又一次地被告知。

我想应该可以覆盖UI的某些方法来避免这种行为(我不关心这是否在物理上可以使用纸卡:-)。

有谁知道我需要做什么?我正在使用Nimbus LAF,这似乎并不容易。

(我考虑过使用radiobuttons / cardLayout,但我需要在标签标题中放置一个自定义面板,而radiobuttons只能有一个字符串或图标。与JToggleButton相同......)

非常欢迎任何提示!

谢谢&亲切的问候, 菲利普

3 个答案:

答案 0 :(得分:3)

sscce对于Nimbus L& f的潜在回答者(通过使用另一个L& f不可能重现这个有趣的问题),如果容器#Size包装选项卡到两个或更多Linesenter image description here enter image description here

据我所知,possible solutions只有一个aephyr(没有覆盖NimbusTabbedPaneUI)

来自sscce

import java.awt.BorderLayout;
import javax.swing.*;

public class TabbedPane {

    private static final long serialVersionUID = 1L;

    public TabbedPane() {
        JPanel jp = new JPanel();
        jp.setLayout(new BorderLayout());
        JTabbedPane tb = new JTabbedPane();
        //tb.setUI(new CustomTabbedPaneUI());
        tb.add("Tab1", new JTextArea(10, 20));
        tb.add("Tab2", new JTextArea(10, 20));
        tb.add("Tab3", new JTextArea(10, 20));
        tb.add("Tab4", new JTextArea(10, 20));
        tb.add("Tab5", new JTextArea(10, 20));
        jp.add(tb, BorderLayout.CENTER);
        //add(jp, BorderLayout.CENTER);
        //tb.setEnabledAt(1, false);
        //tb.setEnabledAt(3, false);
        JFrame frame = new JFrame();
        frame.setLayout(new BorderLayout());
        frame.add(jp, BorderLayout.CENTER);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        try {
            for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (Exception system) {
            system.printStackTrace();
        }
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                TabbedPane tP = new TabbedPane();
            }
        });
    }
}

答案 1 :(得分:2)

好的,我找到了问题。在

package javax.swing.plaf.basic.BasicTabbedPaneUI;

它说的是这样的

// Rotate run array so that selected run is first
            if (shouldRotateTabRuns(tabPlacement)) {
                rotateTabRuns(tabPlacement, selectedRun);
            }

遗憾的是,似乎没有简单的设置 - 标志 - 并且你在那里改变它。

虽然如果您省略了对rotateTabRuns(tabPlacement, selectedRun);的调用或更改shouldRotateTabRuns(tabPlacement)的问题,您应该没问题......但是,为此,您必须覆盖一大堆类...取决于你使用的plaf。

它继承了这样的

Basic > Synth > Nimbus

在每个L& F级别,有几个类可以自定义......我没有计算。

希望它有所帮助! :D

修改 哦是的... @mkorbel已经提供了这种 aephyr 的解决方案,为什么不使用它呢?

答案 2 :(得分:1)

它有点像黑客但你可以覆盖Nimbus默认值,使标签窗格具有普通的旧Java外观,同时保持其他所有内容相同。标签窗格的纯Java外观并不会令人讨厌的重新排序。只需在设置外观之前存储默认值,然后将其设置回来。

// get the defaults to keep
HashMap<Object, Object> defaultsToKeep = new HashMap<>();
for (Map.Entry<Object, Object> entry : UIManager.getDefaults().entrySet()) {
    boolean isStringKey = entry.getKey().getClass() == String.class ;
    String key = isStringKey ? ((String) entry.getKey()):"";    
    if (key.startsWith("TabbedPane")) {
        defaultsToKeep.put(entry.getKey(), entry.getValue());
    }
}

// set nimbus look and feel
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
    if ("Nimbus".equals(info.getName())) {
        UIManager.setLookAndFeel(info.getClassName());
        break;
    }
}

// set back your originals
for (Map.Entry<Object, Object> entry : defaultsToKeep.entrySet()) {
    UIManager.getDefaults().put(entry.getKey(), entry.getValue());
}

JFrame.setDefaultLookAndFeelDecorated(true);