Setting the focused tab during program deserialization

Hi,

I have an application that can save and load configurations. It stores two configuration files - one for the docking resources and one for the application resources.

I have a working area that contains dockables. If I load anything that was saved with anything other than the first tab selected, issues arise with the configs becoming out of sync. A quick solution I am attempting to use is to force the first tab to always be the favorite/focused child when starting up.

I am having trouble with the mechanisms that should be setting the focused child. I have tried the following:

  • workingArea.getStation().getController().setFocusedDockable( … )
  • workingArea.getStation().setFrontDockable( … )
  • dockable.toFront()
  • applying the above in a invokeLater

Another issue that is happening along with this one is with setTitleIcon. I have an Icon that indicates which tab has focus. All other tabs have no icon (null, IconHandling.KEEP_NULL_ICON). These are set in the same area above and from other focus events. For some reason, the icon for the favorite child (the first one) is not being set (works fine when program is running, just not during deserialization). I am using dockable.setTitleIcon( … ) on a CDockable.

I traced through the code in the debugger and discovered that the else branch in the DefaultFocusController.run method is taken ( and hence execute is not called ).

I also found that the getTab( dockable ) in the CombinedStackDockComponent.Meta.forward() is null. Although I don’t think this is relevent, the menu is also null. Hence it appears that my icon is never set. This getTab method does not return null during normal program operation - instead it is an EclipseTab.

The deserialization occurs after the program creates the docking components, but before the main frame becomes visible. My findings suggest that the tab part of the dockable does not exist / is not configured properly at the time that I try to synchronize the client and docking configurations after deserialization. It would be messy to attempt to wait until the main frame is visible to synchronize.

So basically what I’m asking is a I need a way to set the favorite / focused child in a working area during deserialization of my program. I’m not sure if I am doing something wrong, or if there is some timing issue that is arising.

Thanks,
Mark

Follow up: For kicks I put the code inside of an invokeLater that was inside of an invokeLater. That appears to work - so I am doing something out of order. That isn’t really a solution however. As a side note, the first invokeLater is called after the frame is visible, since the deserialization and frame visibility portion is done inside of an invokeAndWait call.

Hi

So basically what I’m asking is a I need a way to set the favorite / focused child in a working area during deserialization of my program. I’m not sure if I am doing something wrong, or if there is some timing issue that is arising.

I’ve upgraded the mechanism to set the focused Dockable, click here to download a temporary version of the new code. This should cause „toFront“ to work even if the application is not yet visible. I wrote myself a little test-app, and it seemed to work fine. But let me know if this solution works on your system as well.

As for the other questions:

[QUOTE=Mark]
I have a working area that contains dockables. If I load anything that was saved with anything other than the first tab selected, issues arise with the configs becoming out of sync. A quick solution I am attempting to use is to force the first tab to always be the favorite/focused child when starting up.[/quote]
I do not understand what you mean with this. Why and how does one config depend on the focused tab? What do you save in the „application resources“?

I am having trouble with the mechanisms that should be setting the focused child.

Focus is quite tricky, because Swing is handling focus really strange. That is the reason why the focus support of the framework is sometimes failing. In this case the methods you called just did not do anything as long as the application was invisible.

Another issue that is happening along with this one is with setTitleIcon. I have an Icon that indicates which tab has focus. All other tabs have no icon (null, IconHandling.KEEP_NULL_ICON). These are set in the same area above and from other focus events. For some reason, the icon for the favorite child (the first one) is not being set (works fine when program is running, just not during deserialization). I am using dockable.setTitleIcon( … ) on a CDockable.

A new application does not necessarily have a focused Dockable. The framework itself does not save which dockable was focused (to set the focus it would need store the Component which had the focus, but that Component belongs to the client, not the framework.). If you print out „CControl.getFocusedCDockable“ you will notice it is „null“ for quite a long time.

Well, I wrote myself a test-app calling „toFront“, and that test-app works with the newest version.

I also found that the getTab( dockable ) in the CombinedStackDockComponent.Meta.forward() is null. Although I don’t think this is relevent, the menu is also null. Hence it appears that my icon is never set. This getTab method does not return null during normal program operation - instead it is an EclipseTab.

The Dockable stores the Icon until tabs, menus, etc… are created. You should not need to care about the order in which the visual elements are created. If you find a place where you need to care: that would be a bug of the framework.

Docking serialization is done using the ApplicationResourceManager write/read XML methods. The client serialization saves components that are inside of tabs - for example JXTable configurations. Some data is used in both of the serialized files. The client data is deserialized first, and then the docking data.

I was able to get everything working using the code you uploaded with this:

workArea.getStation().getController().setFocusedDockable( dock.intern(), true );
workArea.getStation().getController().ensureFocusSet();
dock.toFront();

However, some things do not happen as I would expect:

I can’t just use toFront because the UI doesn’t seem to be updated. For example, I have tabs A, B, and C on the same stack station and close with B being the last one selected. I now restart the program, and use only the dock.toFront() call of the code above with dock being A. The UI still indicates that B is selected (the B tab has the selected L&F effects), and the contents of B (a JXTable) are showing. The client config will assume that A is selected, and so other components in the application will correspond to A. That is what I meant regarding items becoming out of sync - the program thinks A is selected but visually some of the items show B instead of A.

Adding the two other lines in the code above fixes the problem. What I would expect is that setting A toFront would cause A and it’s components to be showing (if visible), and the tab to indicate that A is selected (if visible). Instead this does not happen, and B remains selected and showing.

Doesn’t happen in my test app. Perhaps some issues with a JXTable having the focus… there can be many reasons. But if you say you can fix it with two additional method calls, then I would suggest keeping the current solution unless it turns out to be wrong.