Which tab becomes active after closing a tab?

Hello,

Closing a tab in the eclipse IDE follows a certain behavior, different from the one in DockingFrames.

Consider three tabs: String|Integer|Boolean

Assume the active tab is String.
I move to Boolean. So the active tab is now Boolean.
When I close the Boolean tab, I’ll be taken back to the String tab, which is the last tab I’ve been in before Boolean.

Whereas in DockingFrames, when I close Boolean, the active tab becomes the one next to it (in this case the Integer tab).

Is it possible to implement this behavior? It is something eclipse users are used to.

Also, what is the proper way for listening to changes in the current active tab? Does DockingFrames notify me of changes in the active/selected tab?

Thanks a lot,
Shant

Alright, finally got the time to answer your question. Better late than never :wink:

  • The easiest way to find out about the active tab is probably adding a CFocusListener to the CControl. This listener will be informed whenever the user focuses a new Dockable.
  • About automatically focusing the latest Dockable: the necessary mechanics are already in the framework, but they are not yet used. I think I’ll add the missing pieces in the next release.

[QUOTE=Beni]

  • About automatically focusing the latest Dockable: the necessary mechanics are already in the framework, but they are not yet used. I think I’ll add the missing pieces in the next release.[/QUOTE]

Hi, Beni.

Can you, plz, give some little code example on how we can use this existing mechanics in current release?

Thanks.

Hi Beni,

Thank you for your reply!

  • So about automatically focusing the latest Dockable: can you give us something really soon? :smiley:

  • And about using CFocusListener, the problem is the listener will not be informed until the user focuses the Dockable himself. So for example, in case you give us the feature above, the latest Dockable will become the active tab, but in the code, I won’t know about it until the user focuses the Dockable.

Using a CFocusListener can actually work, if a Dockable requests focus by itself when it becomes the active tab.

By the way, when describing the feature of displaying the latest dockable, you already said: „focusing the latest Dockable“, so if you also request focus upon displaying the active tab it would work! But I don’t think currently this is the case: i.e. currently, upon closing a tab, the one next to it becomes active, but the CFocusListener doesn’t get informed, which means the dockable doesn’t request focus by itself.

Thanks a lot,
Shant

I was able to implement „activate most recent“ logic by simply using new FocusHistory api. I used code like that:

    ...
    public static class MyDockable extends DefaultSingleCDockable {
        public MyDockable(String id) {
            super(id);
            addCDockableStateListener(new AcivateRecentDockAdapter());
        }
    }

    private static class AcivateRecentDockAdapter extends CDockableAdapter {
        @Override
        public void visibilityChanged(CDockable cdockable) {
            MyDockable dockable = (MyDockable) cdockable;

            if (!cdockable.isVisible()) {
                dockable.getControl().removeDockable(dockable);
                Dockable prevDockable = dockable.getControl().getController().getFocusHistory().getNewestOn(dockable.getWorkingArea().getStation());
                if (prevDockable != null) {
                    ((AbstractCDockable)((DefaultCommonDockable)prevDockable).getDockable()).toFront();
                }
            }
        }
    }

It maybe not exactly the prettiest solution, but it works :slight_smile:

Hi Beni,

Any updates on this?

Thanks,
Shant

Hi Beni, Dmitry,

Wanted to note that Dmitry’s code didn’t work for me… :frowning:

Because in my case dockable.getWorkingArea() is returning null.

Usually, I get my DockStation as follows: dockable.intern().getDockParent(); but in this case, once setVisible(false) is called, that one is returning null too.

Thanks,
Shant

Hi again,

Instead of implementing the “activate most recent” logic inside visibilityChanged(…) as Dmitry did, I implemented it inside the close method of my custom CCloseAction, right after the remove logic, as follows:

    public void close(CDockable dockable) {
    	CControl control = dockable.getControl();
    	DockStation dockStation = dockable.intern().getDockParent();
    	
    	dockable.setVisible(false);
    	control.removeDockable((SingleCDockable) dockable);
    	
    	Dockable prevDockable = control.getController().getFocusHistory().getNewestOn(dockStation);
    	if (prevDockable != null) {
    		//this line is not producing any effect:
    		//((AbstractCDockable) ((DefaultCommonDockable) prevDockable).getDockable()).toFront();
    		
    		//this line is working:
    		((DefaultCommonDockable) prevDockable).getDockable().intern().getDockParent().setFrontDockable(prevDockable);
    	}
    }```

This way, I avoided calling dockable.getWorkingArea().

For some reason, the toFront() method didn't work for me, but setFrontDockable(...) did.

What do you think Beni?

Regards,
Shant

If you want to try out how the solution in the next release works: download here . But it works differently then your solution: the StackDockStation itself finds out that one of its children was removed, and changes its selected tab according to the focus-history. It’s actually much closer to calling “setFrontDockable” than to calling “toFront”.

Focus is always very messy (thanks to the very … strange … design of Swing). A “good” trick is to wait a few milliseconds before doing anything related to focus after big changes to the UI. Maybe just calling “toFront” in SwingUtilities.invokeLater would do the trick.

Thank you Beni! The solution in the link works exactly as desired. :slight_smile:

Looking forward to update to the latest version once my problem (http://forum.byte-welt.net/showthread.php?p=18423#post18423) is solved.

Thanks,
Shant