Nimbus JTabbedPane shuffles tabs

F

FutureScalper

I'd like to over-ride Nimbus JTabbedPane behavior of shuffling the
tabs. I want every tab to stay where it is, and not to shuffle when a
tab is selected. This is on Windows.

I want each tabs to "stay put" and not have tabs reorient themselves
when a tab is selected.

Could someone put me on the right track of somehow disabling that
behavior?

Otherwise, I think Nimbus is pretty good.
 
J

John B. Matthews

FutureScalper said:
I'd like to over-ride Nimbus JTabbedPane behavior of shuffling the
tabs. I want every tab to stay where it is, and not to shuffle when
a tab is selected. This is on Windows.

I want each tabs to "stay put" and not have tabs reorient themselves
when a tab is selected.

Could someone put me on the right track of somehow disabling that
behavior?

Otherwise, I think Nimbus is pretty good.

Try setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT).
 
F

FutureScalper

Try setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT).

Thanks for the tips, but I want the tabs to wrap and stack. I just
don't want the row stacking order to change.

I suppose it's trying to emulate the behavior on Windows, where tabbed
rows reorganize themselves, but I want to disable that behavior.

I just want it to work like the older plafs and not change tab
placement on tab selection.

I need the tabs to be visible at all times, so scrolling tabs won't
work in this application.
 
M

markspace

FutureScalper said:
Thanks for the tips, but I want the tabs to wrap and stack. I just
don't want the row stacking order to change.

Huh, how does that actually work? If you have some rows of tabs and one
is displaying:


/ Tab 1 \/ Tab 2 \/ Tab 3\
/ Tab 4 longer name \ |
/ Tab 5 \/ Tab 6 \ |
| -----------------|
| |
| Tab 5 |
| |
| |
+-------------------------+


Now you want to see tab two, it won't be connected to the display pane
if you display it it without reordering. I think this would be very
confusing to the users.

/ Tab 1 \/ Tab 2?\/ Tab 3\
/ Tab 4 longer name \ |
/ Tab 5 \/ Tab 6 \ |
|-------------------------|
| |
| Tab 2 |
| |
| |
+-------------------------+


Not sure I like that. And I don't think anyone would write code to make
it work that way, so I think you're on your own. Maybe subclass tabbed
pane and redo the tabs. Might be able to fake them with buttons and a Box.
 
J

John B. Matthews

FutureScalper said:
Thanks for the tips, but I want the tabs to wrap and stack. I just
don't want the row stacking order to change.

I suppose it's trying to emulate the behavior on Windows, where
tabbed rows reorganize themselves, but I want to disable that
behavior.

Nimbus' WRAP_TAB_LAYOUT is like that on Mac OS X and Ubuntu, too. It
looks like it's trying to make the "last" selected tab appear in the
"last" row and column, perhaps as a navigational aid.

I guess you'd have to replace BasicTabbedPaneUI.TabbedPaneLayout by
overriding createLayoutManager().
 
F

FutureScalper

Huh, how does that actually work?  If you have some rows of tabs and one
is displaying:

  / Tab 1 \/ Tab 2 \/ Tab 3\
  / Tab 4 longer name \     |
  / Tab 5 \/ Tab 6 \        |
  |        -----------------|
  |                         |
  |   Tab 5                 |
  |                         |
  |                         |
  +-------------------------+

Now you want to see tab two, it won't be connected to the display pane
if you display it it without reordering.  I think this would be very
confusing to the users.

  / Tab 1 \/ Tab 2?\/ Tab 3\
  / Tab 4 longer name \     |
  / Tab 5 \/ Tab 6 \        |
  |-------------------------|
  |                         |
  |   Tab 2                 |
  |                         |
  |                         |
  +-------------------------+

Not sure I like that.  And I don't think anyone would write code to make
it work that way, so I think you're on your own.  Maybe subclass tabbed
pane and redo the tabs.  Might be able to fake them with buttons and a Box.

All that I am asking for is that it work like this one works:

-Dswing.defaultlaf=com.sun.java.swing.plaf.windows.WindowsLookAndFeel -
Dswing.metalTheme=steel

This does NOT re-order tabs simply as a result of an individual tab
being selected.

Re-ordering tabs seems odd (to me) as a GUI principle. Unless there
is some reason that a row needs to be re-ordered "closer" to the
tabbed pane, then this forces the user to "hunt" for the re-ordered
information, rather than to be able to rely upon the cluster of tabs
remaining in a fixed configuration.

Naturally, this is debatable. Would be best if a Layout Policy could
be set NOT to re-order wrapped rows of tabs, simply as a result of tab
selection. Tab order should be tied to the order in which the code
adds tabs to the JTabbedPane, or at least that should be an option.

I will dig into the code and see whether I can over-ride the behavior,
as one poster suggested.

THANKS FOR YOUR HELP.
 
F

FutureScalper

Huh, how does that actually work?  If you have some rows of tabs and one
is displaying:

  / Tab 1 \/ Tab 2 \/ Tab 3\
  / Tab 4 longer name \     |
  / Tab 5 \/ Tab 6 \        |
  |        -----------------|
  |                         |
  |   Tab 5                 |
  |                         |
  |                         |
  +-------------------------+

Now you want to see tab two, it won't be connected to the display pane
if you display it it without reordering.  I think this would be very
confusing to the users.

  / Tab 1 \/ Tab 2?\/ Tab 3\
  / Tab 4 longer name \     |
  / Tab 5 \/ Tab 6 \        |
  |-------------------------|
  |                         |
  |   Tab 2                 |
  |                         |
  |                         |
  +-------------------------+

Not sure I like that.  And I don't think anyone would write code to make
it work that way, so I think you're on your own.  Maybe subclass tabbed
pane and redo the tabs.  Might be able to fake them with buttons and a Box.

In my view it's not "connected" to the display pane because its row is
shifted down.

It's "connected" or, rather "selected" because the tab itself is
highlighted, indicating it is selected.

You're thinking of proximity, I guess, but that is at odds with a
consistent spatial positioning.

I'm arguing for fixed spatial positioning of the tabs, unless
something forces a layout change.
 
F

FutureScalper

In my view it's not "connected" to the display pane because its row is
shifted down.

It's "connected" or, rather "selected" because the tab itself is
highlighted, indicating it is selected.

You're thinking of proximity, I guess, but that is at odds with a
consistent spatial positioning.

I'm arguing for fixed spatial positioning of the tabs, unless
something forces a layout change.

Imagine a user wants to click through all of the tabs, from upper left
down through lower right.

But this results in operator error when the rows keep shifting, and
the user must visually "hunt" for the tab she wishes to click. 1, 2,
3 is the first row, 4, 5, 6 the second 7, 8, 9 the third. But, woops!
when 1 is clicked, it suddenly moves 2 rows down (assuming tabs at the
top of the display area), swapping rows with what was the third row.
From a human factors perspective, perhaps not so good.

And, for a fixed layout, a given functional tab, I would suggest,
should always be in the same location.

Now, there might be exceptions to the rule but, for me, it has always
been confusing when tabbed rows suddenly change their row rankings
because I selected a tab in that row and it was non-adjacent to the
displayed panel area.
 
J

John B. Matthews

FutureScalper said:
I will dig into the code and see whether I can over-ride the
behavior, as one poster suggested.

It looks like MetalTabbedPaneUI.TabbedPaneLayout achieves the effect you
want by overriding the methods rotateTabRuns(), padSelectedTab() and
normalizeTabRuns(). These methods are inherited from the superclass
BasicTabbedPaneUI.TabbedPaneLayout.
 
F

FutureScalper

It looks like MetalTabbedPaneUI.TabbedPaneLayout achieves the effect you
want by overriding the methods rotateTabRuns(), padSelectedTab() and
normalizeTabRuns(). These methods are inherited from the superclass
BasicTabbedPaneUI.TabbedPaneLayout.

Thanks John for the tips on possible code workarounds. This app is a
high performance online Futures trading application and I can't afford
"operator error" due to the GUI arbitrarily reorganizing itself. So I
may try and work around it, or just stay with what I have, or find
another LAF which does not do this.

All I wanted to do was to "skin" it a bit, and I found myself in all
of these "gotchas" :(
 
J

John B. Matthews

FutureScalper said:
Thanks John for the tips on possible code workarounds. This app is a
high performance online Futures trading application and I can't
afford "operator error" due to the GUI arbitrarily reorganizing
itself. So I may try and work around it, or just stay with what I
have, or find another LAF which does not do this.

I think the behavior is part of BasicTabbedPaneUI.TabbedPaneLayout
unless overridden. Another LAF may or may not rely on it. Ignoring form,
here's how I'd change the function:

/** @author John B. Matthews */
class MyTabbedPane extends JTabbedPane {

public MyTabbedPane() {
this.setUI(new MyTabbedPaneUI());
}

@Override
public String getUIClassID() {
return "MyTabbedPaneUI";
}

@Override
public void updateUI() {
// preclude others
}

private class MyTabbedPaneUI extends BasicTabbedPaneUI {

@Override
protected LayoutManager createLayoutManager() {
return new BasicTabbedPaneUI.TabbedPaneLayout() {

@Override
protected void rotateTabRuns(
int tabPlacement, int selectedRun) {
}

@Override
protected void padSelectedTab(
int tabPlacement, int selectedIndex) {
}
};
}
}
}
 
F

FutureScalper

I think the behavior is part of BasicTabbedPaneUI.TabbedPaneLayout
unless overridden. Another LAF may or may not rely on it. Ignoring form,
here's how I'd change the function:

/** @author John B. Matthews */
class MyTabbedPane extends JTabbedPane {

    public MyTabbedPane() {
        this.setUI(new MyTabbedPaneUI());
    }

    @Override
    public String getUIClassID() {
        return "MyTabbedPaneUI";
    }

    @Override
    public void updateUI() {
        // preclude others
    }

    private class MyTabbedPaneUI extends BasicTabbedPaneUI {

        @Override
        protected LayoutManager createLayoutManager() {
            return new BasicTabbedPaneUI.TabbedPaneLayout() {

                @Override
                protected void rotateTabRuns(
                    int tabPlacement, int selectedRun) {
                }

                @Override
                protected void padSelectedTab(
                    int tabPlacement, int selectedIndex) {
                }
            };
        }
    }



}

Thanks very much for that contribution which I may try to implement.
One thing is clear: I can't have tabs moving all over the place. Too
much operator error confusion in my application, which puts real money
on the line for the trader.

Off-topic is the further issue of the Security Warning (posted
elsewhere) which is another Java "innovation" that kills my app's
reliability, far more serious than this GUI issue. As in the GUI
case, I may abandon using Nimbus; I may also have to abandon upgrading
beyond Java 6 Update 17 as well unless I can find a workaround...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top