Visibility of a dockable

Hi Beni,

is there a way to determine, if a stacked dockable is visible or not?

If I call the isVisible() method of SingleCDockable, I’m getting always true. Even if the dockable is not the selected one in a stack.

I’m using DockingFrames 1.0.8.

Greetz,
Thomas

BTW, last weekend I tried the current preview of DF 1.1.0. Great improvements :slight_smile: I think I have to update the GlassEclipseTheme :wink:

Hi Thomas, nice to hear from you

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
}```

Hi Beni,

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.

Greetz,
Thomas

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.

Hi Beni,

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.

Greetz,
Thomas

Ok, I understand. I can already guarantee that the “DockStationListeners” will suffer from the same issue.

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() );
		}
	}
}```

Hi Beni,

thanks for your testing :slight_smile:
I will add this debug code to our application and let you know if there is something interesting or strange happening.

To your questions:

  1. 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 :wink:
  2. 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.
  3. 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?

Greetz and a nice weekend… :slight_smile:
Thomas

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.

Hi Beni,

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 :slight_smile:

Greetz,
Thomas

I’m relieved to hear that. Having objects twice is really annoying to debug.