JTabbedPane: avoid automatic re-ordering tabs if stacked / Nimbus

后端 未结 3 1855
天涯浪人
天涯浪人 2021-01-06 11:49

a JTabbedPane is just what I need for my purpose. I have very limited horizontal space, so my Tabs get stacked, which is perfectly ok.

But the default behaviour is t

相关标签:
3条回答
  • 2021-01-06 12:25

    sscce for potential answerer(s) for Nimbus L&f (by using another L&f isn't possible to reproduce this funny issue), in case that Containers#Size packed Tabs to the two or more Lines, enter image description hereenter image description here

    as I know there is only one possible solutions (without override NimbusTabbedPaneUI) by aephyr

    from 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();
                }
            });
        }
    }
    
    0 讨论(0)
  • 2021-01-06 12:37

    Okay, I found the Problem. In

    package javax.swing.plaf.basic.BasicTabbedPaneUI;
    

    it says something like this

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

    Its a pity that there seems to be no easy set-a-flag-and-there-you-go-way is for changing that.

    Although you should be fine if you omitted the call to rotateTabRuns(tabPlacement, selectedRun); or change shouldRotateTabRuns(tabPlacement) for that matter... however, to do so you would have to override a whole bunch of classes... depending on which plaf you use.

    It inherits like this

    Basic > Synth > Nimbus
    

    And on each L&F-level there are several classes to customize... I didn't count.

    Hope it helps! :D

    Edit Oh yeah... @mkorbel already provided sort of the solution with this aephyr why not use that?

    0 讨论(0)
  • 2021-01-06 12:38

    It's a bit of a hack but you can override the Nimbus defaults to have the plain old Java look-and-feel for the tabbed pane, whilst keeping everything else the same. The plain Java look-and-feel for a tabbed pane doesn't do the annoying reordering. Just store the defaults before you set the look-and-feel and then set them back.

    // 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);
    
    0 讨论(0)
提交回复
热议问题