Yeah, “isVisible” returns true if the user has a possibility to see the Dockable, not if he can actually see the Dockable.
Each DockStation has a method “getFrontDockable” which returns the selected Dockable. For a StackDockStation and a FlapDockStation this is the only visible child (Does not make much sense for a SplitDockStation or a ScreenDockStation which show all their children all the time). Try something like the code below, this should work with 1.0.8.
CDockable cdockable = ...
DockStation parent = cdockable.intern().getDockParent();
if( parent.getFrontDockable() == cdockable.intern() ){
// the item should be visible on its parent
// recursively check
Dockable dockable = parent.asDockable();
if( dockable != null ){
parent = dockable.getDockParent();
... // etc
}
}
else{
// the item may not be visible on its parent
}```
I’ve tried your suggestion and it works most of the time for my use case ;-). But I have a little problem.
As you said, I get the parent station of a dockable. Next, I check if it is a SplitDockStation, ScreenDockStation, StackDockStation, a FlapDockStation or null. And only if it is a StackDockStation I check the frontDockable. Now, I can determine if a dockable is visible or not.
But sometimes I’m facing a strange behavoir. If a dockable is closed and I ask for it’s parent it returns a SplitDockStation (or similar) and not null. Sometimes getDockParent returns null even if the dockable is visible on a SplitDockStation.
I’ve seen that you have done a lot of bugfixes, is it possible that this behavoir is fixed in the current version?
A brief background information on what I’m trying to do. The app we are developing contains a lot of views/dockables which have to be updated after a calculation. For performance reasons these updates should only be invoked on those views which are really visible and will be invoked on invisible views as soon as they are shown.
Hm, that should not happen. I did not fix anything like that, at least not on purpose. But I’ll make some tests during the weekend. You have any specific case when that happens or is it completely random?
Btw. I’m a bit of an idiot, I forgot there is a small API dealing with visibility. Check out “DockStation.isVisible( Dockable )” and “DockStationListener.dockableVisibilitySet”. May make things easier, especially if you know when a Dockable gets visible.
in our application, we have ~20 views/dockables and 7 different layouts (recoverable) in one XML.
I’m using the layout save/load mechanism to implement a perspective manager (you had posted an example some time ago (dock8 or so)).
The problem occures rather randomly, but if it occures almost every call to getDockParent or isVisible returns the wrong value. E.g. the view is visible and getDockParent returns null or the view was closed (is invisible) and getDockParent returns the SplitDockStation were it was when it was visible. This problem does not happen for all dockables, only some of them and not always the same ones.
When did this happen (probalbly ;-)): The current layout shows 4 dockables with different views (not stacked). Some of the dockables are closed (by the user). Then the updater checks every dockable if it is visible and updates the view if so. This check goes sometimes wrong, returns true even if the dockable is hidden.
Unfortunately, I can’t give you an example, because it is the software we are developing at work.
At the weekend, I will give those DockStationListeners a try. Thanks for your help.
I did some testing, loaded layouts and moved around Dockables a few million times, but so far I could not reproduce the bug.
[ul]
[li]Do you execute all the changes (in particular loading/saving the layout) in the EDT? Also your updater should access the Dockables only in the EDT. Unfortunately the framework does not handle well with concurrency.
[/li][li]Is there any chance that your updater and the framework are not using the same Dockable objects? Loading a layout may trigger some factories to create new Dockables (especially if you are using MultipleCDockables).
[/li][li]Is it possible that some Dockables just are too small to see? They look as if they were closed, but in reality they have a size of 0/0 or something like that (although the framework has safeguards against this kind of error).
[/li][/ul]
Could you add some debugging code, like the code below, to your application? The code below makes some sanity checks whenever the user does something with the mouse (e.g. click on the close-button…). It would be very interesting to know if - and when - the check fails.
long eventMask = AWTEvent.MOUSE_EVENT_MASK;
Toolkit.getDefaultToolkit().addAWTEventListener( new AWTEventListener(){
@Override
public void eventDispatched( AWTEvent event ){
dispatch( 5, control );
}
}, eventMask );
}
private static void dispatch( final int round, final CControl control ){
EventQueue.invokeLater( new Runnable(){
public void run(){
for( int i = 0, n = control.getCDockableCount(); i < n; i++ ){
test( control.getCDockable( i ));
}
if( round > 0 ) {
dispatch( round - 1, control );
}
}
} );
}
private static void test( CDockable dockable ){
test( dockable.intern() );
}
private static void test( Dockable dockable ){
DockStation parent = dockable.getDockParent();
if( parent != null ) {
boolean found = false;
for( int i = 0, n = parent.getDockableCount(); i < n; i++ ) {
if( parent.getDockable( i ) == dockable ) {
found = true;
break;
}
}
if( !found ) {
throw new IllegalStateException( parent + " " + dockable );
}
}
else {
if( dockable.getComponent().isDisplayable() ) {
throw new IllegalStateException( dockable.toString() );
}
}
}```
thanks for your testing
I will add this debug code to our application and let you know if there is something interesting or strange happening.
To your questions:
In this particular situation no layout is explicitly loaded, only the current layout is modified (not saved). I think those updates and visibility checks are on the EDT, but I will check this next week. Damn threads
They should use the same dockables. I use getSingleDockable(ID) of CControl to get the dockable with the specified ID (the one which I gave the dockables when they were created).
I’m just using SingleDockables for now.
The involved dockables are closed with the close button. If they are restored the have a size > 0.
But it could be possible that there could something went wrong during the initialization of the app. I will check that next week, too.
One other question. Have you already planned a release date of DF 1.1.0?
I think no more than another month or so until 1.1.0 is finished. I’m currently completing the last features and then I have to do some checks in order to get everything running.
I’ve found the problem in our app. It was some sort of initialization failure (as I said: „Damn threads“ ;-)), no bug in DF.
The DF instance was initialized two times, so some dockables were created twice and sometimes the wrong dockable was checked. Strangely, the app worked well with no errors (except those visibility check errors).
Thanks anyway for your time and testing, even if it was not a problem of DF