Exception in SplittingExternalizedDockablesExample

Hi, I am trying SplittingExternalizedDockablesExample. When I externalize one dockable, then put other dockable inside of it, maximise that other dockable, and try to shrink dockable back, I get this exception:

java.lang.IllegalStateException: the parent of ‘DefaultCommonDockable[dockable=ColorSingleCDockable[unique id=single green]]’ is not ‘bibliothek.gui.dock.common.intern.station.CScreenDockStation@191f64b’ but ‘null’
at bibliothek.gui.dock.DockHierarchyLock.ensureLinked(DockHierarchyLock.java:342)
at bibliothek.gui.dock.DockHierarchyLock.access$2(DockHierarchyLock.java:340)
at bibliothek.gui.dock.DockHierarchyLock$Token.release(DockHierarchyLock.java:417)
at bibliothek.gui.dock.ScreenDockStation.addDockable(ScreenDockStation.java:1359)
at bibliothek.gui.dock.ScreenDockStation.executeDrop(ScreenDockStation.java:1539)
at bibliothek.gui.dock.ScreenDockStation.drop(ScreenDockStation.java:1415)
at bibliothek.gui.dock.common.mode.station.CScreenDockStationHandle$Maximal.setMaximized(CScreenDockStationHandle.java:388)
at bibliothek.gui.dock.common.mode.station.CScreenDockStationHandle$Maximal.onApply(CScreenDockStationHandle.java:330)
at bibliothek.gui.dock.facile.mode.MaximizedMode.applyStarting(MaximizedMode.java:554)
at bibliothek.gui.dock.facile.mode.MaximizedMode$Listener.applyStarting(MaximizedMode.java:788)
at bibliothek.gui.dock.facile.mode.AbstractLocationMode.apply(AbstractLocationMode.java:395)
at bibliothek.gui.dock.facile.mode.AbstractLocationMode.apply(AbstractLocationMode.java:1)
at bibliothek.gui.dock.support.mode.ModeManager$4.run(ModeManager.java:700)
at bibliothek.gui.dock.support.mode.ModeManager.runTransaction(ModeManager.java:514)
at bibliothek.gui.dock.support.mode.ModeManager.runTransaction(ModeManager.java:493)
at bibliothek.gui.dock.support.mode.ModeManager.apply(ModeManager.java:694)
at bibliothek.gui.dock.support.mode.ModeManager.apply(ModeManager.java:625)
at bibliothek.gui.dock.support.mode.ModeManager.apply(ModeManager.java:561)
at bibliothek.gui.dock.support.mode.ModeManager.apply(ModeManager.java:541)
at bibliothek.gui.dock.facile.mode.LocationModeManager$6$1.setMode(LocationModeManager.java:296)
at bibliothek.gui.dock.common.group.SingleGroupMovement.apply(SingleGroupMovement.java:52)
at bibliothek.gui.dock.facile.mode.LocationModeManager$6.run(LocationModeManager.java:294)
at bibliothek.gui.dock.support.mode.ModeManager$3.run(ModeManager.java:476)
at bibliothek.gui.dock.support.mode.ModeManager.runTransaction(ModeManager.java:514)
at bibliothek.gui.dock.support.mode.ModeManager.runTransaction(ModeManager.java:474)
at bibliothek.gui.dock.support.mode.ModeManager.runTransaction(ModeManager.java:455)
at bibliothek.gui.dock.facile.mode.LocationModeManager.apply(LocationModeManager.java:289)
at bibliothek.gui.dock.facile.mode.LocationModeManager$5.run(LocationModeManager.java:265)
at bibliothek.gui.dock.support.mode.ModeManager.runTransaction(ModeManager.java:514)
at bibliothek.gui.dock.support.mode.ModeManager.runTransaction(ModeManager.java:493)
at bibliothek.gui.dock.facile.mode.LocationModeManager.setMode(LocationModeManager.java:258)
at bibliothek.gui.dock.common.intern.AbstractCDockable.setExtendedMode(AbstractCDockable.java:469)
at bibliothek.gui.dock.common.intern.action.CExtendedModeAction.action(CExtendedModeAction.java:189)
at bibliothek.gui.dock.common.intern.action.CExtendedModeAction$Action.action(CExtendedModeAction.java:227)
at bibliothek.gui.dock.themes.basic.action.BasicButtonHandler.triggered(BasicButtonHandler.java:48)
at bibliothek.gui.dock.themes.basic.action.BasicButtonModel.trigger(BasicButtonModel.java:704)
at bibliothek.gui.dock.themes.basic.action.BasicButtonModel$Listener.mouseReleased(BasicButtonModel.java:742)
at java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$200(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Exception in thread “AWT-EventQueue-0” java.lang.IllegalStateException: there is already a window in the group dock.single.green, add the element directly to that window or do not use a placeholder
at bibliothek.gui.dock.ScreenDockStation.register(ScreenDockStation.java:1819)
at bibliothek.gui.dock.ScreenDockStation.addDockable(ScreenDockStation.java:1324)
at bibliothek.gui.dock.ScreenDockStation.executeDrop(ScreenDockStation.java:1539)
at bibliothek.gui.dock.ScreenDockStation.drop(ScreenDockStation.java:1415)
at bibliothek.gui.dock.common.mode.station.CScreenDockStationHandle$Maximal.setMaximized(CScreenDockStationHandle.java:388)
at bibliothek.gui.dock.common.mode.station.CScreenDockStationHandle$Maximal.onApply(CScreenDockStationHandle.java:330)
at bibliothek.gui.dock.facile.mode.MaximizedMode.applyStarting(MaximizedMode.java:554)
at bibliothek.gui.dock.facile.mode.MaximizedMode$Listener.applyStarting(MaximizedMode.java:788)
at bibliothek.gui.dock.facile.mode.AbstractLocationMode.apply(AbstractLocationMode.java:395)
at bibliothek.gui.dock.facile.mode.AbstractLocationMode.apply(AbstractLocationMode.java:1)
at bibliothek.gui.dock.support.mode.ModeManager$4.run(ModeManager.java:700)
at bibliothek.gui.dock.support.mode.ModeManager.runTransaction(ModeManager.java:514)
at bibliothek.gui.dock.support.mode.ModeManager.runTransaction(ModeManager.java:493)
at bibliothek.gui.dock.support.mode.ModeManager.apply(ModeManager.java:694)
at bibliothek.gui.dock.support.mode.ModeManager.apply(ModeManager.java:625)
at bibliothek.gui.dock.support.mode.ModeManager.apply(ModeManager.java:561)
at bibliothek.gui.dock.support.mode.ModeManager.apply(ModeManager.java:541)
at bibliothek.gui.dock.facile.mode.LocationModeManager$6$1.setMode(LocationModeManager.java:296)
at bibliothek.gui.dock.common.group.SingleGroupMovement.apply(SingleGroupMovement.java:52)
at bibliothek.gui.dock.facile.mode.LocationModeManager$6.run(LocationModeManager.java:294)
at bibliothek.gui.dock.support.mode.ModeManager$3.run(ModeManager.java:476)
at bibliothek.gui.dock.support.mode.ModeManager.runTransaction(ModeManager.java:514)
at bibliothek.gui.dock.support.mode.ModeManager.runTransaction(ModeManager.java:474)
at bibliothek.gui.dock.support.mode.ModeManager.runTransaction(ModeManager.java:455)
at bibliothek.gui.dock.facile.mode.LocationModeManager.apply(LocationModeManager.java:289)
at bibliothek.gui.dock.facile.mode.LocationModeManager$5.run(LocationModeManager.java:265)
at bibliothek.gui.dock.support.mode.ModeManager.runTransaction(ModeManager.java:514)
at bibliothek.gui.dock.support.mode.ModeManager.runTransaction(ModeManager.java:493)
at bibliothek.gui.dock.facile.mode.LocationModeManager.setMode(LocationModeManager.java:258)
at bibliothek.gui.dock.common.intern.AbstractCDockable.setExtendedMode(AbstractCDockable.java:469)
at bibliothek.gui.dock.common.intern.action.CExtendedModeAction.action(CExtendedModeAction.java:189)
at bibliothek.gui.dock.common.intern.action.CExtendedModeAction$Action.action(CExtendedModeAction.java:227)
at bibliothek.gui.dock.themes.basic.action.BasicButtonHandler.triggered(BasicButtonHandler.java:48)
at bibliothek.gui.dock.themes.basic.action.BasicButtonModel.trigger(BasicButtonModel.java:704)
at bibliothek.gui.dock.themes.basic.action.BasicButtonModel$Listener.mouseReleased(BasicButtonModel.java:742)
at java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$200(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

But the behavior is not consistent, it doesn’t always generate an exception (it is mostly generated on brazilian combination - yellow green :slight_smile: ). I am using jre7 on Win XP. But I can send you my test project where it happens always on some specific situations.

By the way, I noticed that the externalized dockable is shrinking when it gets dragged every time. So, I changed method checkAndReplace in ExternalizingCGridAreaConfiguration (actually made another class) like this:

@LayoutLocked(locked=false)
    protected class SplitInserter extends DockStationAdapter {
        public void dockableAdded( DockStation station, final Dockable dockable ){
            if( !(dockable instanceof SplitDockStation) ) {
                DockHierarchyLock lock = control.getController().getHierarchyLock();

                lock.onRelease( new Runnable(){
                    public void run(){
                        checkAndReplace( dockable );
                    }
                });
            }
        }
        
        private void checkAndReplace( Dockable dockable ){
            DockStation station = dockable.getDockParent();
            if( !(station instanceof ScreenDockStation) ) {
                return;
            }
            
            DockController controller = control.getController();
            
            try {
                controller.freezeLayout();
            
                ExternalizingCGridArea split = createGridArea();
                control.addDockable( split );
                
                if (control.getFocusedCDockable() != null) {
                    if (control.getFocusedCDockable().getBaseLocation() instanceof CExternalizedLocation) {
                        CExternalizedLocation location = (CExternalizedLocation)control.getFocusedCDockable().getBaseLocation();
                        
                        station.replace( dockable, split.getStation() );
                        
                        split.setResizeRequest(new Dimension(location.getWidth() + 24, location.getHeight()), true);
                        split.asDockable().getAndClearResizeRequest();
                    } else
                        station.replace( dockable, split.getStation() );
                } else
                    station.replace( dockable, split.getStation() );
                split.getStation().drop( dockable );
            }
            finally {
                controller.meltLayout();
            }
        }
    }; 

But it is tuned only for the case when SplitDockStations have a title. Actually, can you parametrize that 24pix to some title or the border width?
Regards,
Branko Ilic

I’m not around in the next few days. You have to wait for an answer until next week. Sorry about that.

OK, thanks for responding.

Sorry about the late response, currently I’m either invited at weekend-long events - or working on the release of another piece of software that should have been finished yesterday…

I could not reproduce your exception - but I did find another one :open_mouth: Maybe they are related, maybe they are not. In any case I fixed the one bug that I did find. [Edit: and once Javaforge is online again, I will even upload the new JAR files. But for now they are in the Github repository].

About the listener: a little trick is just to wait until title and border are properly set up, and then read and update the sizes. Try out this piece of code:

	protected class SplitInserter extends DockStationAdapter {
		public void dockableAdded( DockStation station, final Dockable dockable ){
			if( !(dockable instanceof SplitDockStation) ) {
				DockHierarchyLock lock = control.getController().getHierarchyLock();

				lock.onRelease( new Runnable(){
					public void run(){
						EventQueue.invokeLater( new Runnable() {
							public void run() {
								checkAndReplace( dockable );
							}
						} );
					}
				});
			}
		}
		
		private void checkAndReplace( Dockable dockable ){
			DockStation station = dockable.getDockParent();
			if( !(station instanceof ScreenDockStation) ) {
				return;
			}
			
			DockController controller = control.getController();
			
			try {
				controller.freezeLayout();
				ScreenDockStation screenDockStation = (ScreenDockStation)station;
				
				Dimension oldSize = dockable.getComponent().getSize();
							
				ExternalizingCGridArea split = createGridArea();
				control.addDockable( split );
				
				station.replace( dockable, split.getStation() );
				split.getStation().drop( dockable );
				
				resizeDelayed( screenDockStation, split.getStation(), dockable, oldSize );
			}
			finally {
				controller.meltLayout();
			}
		}
		
		private void resizeDelayed( final ScreenDockStation station, final Dockable parent, final Dockable dockable, final Dimension oldSize ){
			EventQueue.invokeLater( new Runnable() {
				public void run() {
					ScreenDockWindow window = station.getWindow( parent );
					if( window != null ){
						window.validate();
					
						Dimension newSize = dockable.getComponent().getSize();
						int dw = oldSize.width - newSize.width; 
						int dh = oldSize.height - newSize.height;

						Rectangle bounds = window.getWindowBounds();
						bounds.width += dw;
						bounds.height += dh;
						window.setWindowBounds( bounds );
					}
				}
			} );
		}
	};	```