3

JTabbedPane 正是我所需要的。我的水平空间非常有限,所以我的标签会堆叠起来,这完全没问题。

但默认行为是,如果用户单击某个选项卡,*选项卡会重新排序,以便活动选项卡变为 lower-mos *t。理论上看起来非常直观和合乎逻辑的东西,在实际使用中却是一场噩梦,因为用户会忘记“哪个是哪个”。它只是简单地令人困惑,我一次又一次地被告知。

我想应该可以覆盖 UI 的某些方法以避免这种行为(而且我不在乎这在纸卡上是否可行:-)。

有人知道我需要在哪里做吗?我正在使用 Nimbus LAF,这似乎并不容易。

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

非常欢迎任何提示!

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

4

3 回答 3

3

sscce寻找 Nimbus L&f 的潜在回答者(通过使用另一个 L&f 不可能重现这个有趣的问题),以防 Containers#Size 将选项卡打包到两个或更多Lines在此处输入图像描述在此处输入图像描述

据我所知,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();
            }
        });
    }
}
于 2011-09-20T08:55:35.850 回答
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提供了某种解决方案,为什么不使用它呢?

于 2011-11-21T10:01:05.103 回答
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);
于 2015-09-18T09:00:23.230 回答