Hi all,
The behaviour described here is with df 1.1.2 preview 1f. I also describe below the behaviour with 1.1.2 preview 8e.
I’m using DockingFrames to display (among other things) a bunch of editors designed like forms in DefaultMultipleCDockables. Each editor contains text fields which are validated when the text field looses the focus.
To do this, I’m using a standard Swing mechanism called InputVerifier as defined here: http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html#inputVerification
Now, use case 1:
- I open 2 editors
- In the second editor, I modify the content of one text field
- I close the first editor with the cross in the tab (a standard CCloseAction)
- I open it again
=> The InputVerifier has been executed (this means that another component gained the focus). In the use case, a listener on the defautKeyboardFocusManager says:
focus listener: comp class = MyTextField; comp name = null
focus listener: comp class = MyTextField; comp name = null
// Click on the cross
InputVerifier.shouldYieldFocus() value = true
focus listener: comp class = bibliothek.gui.dock.StackDockStation$Background; comp name = null
focus listener: comp class = bibliothek.gui.dock.StackDockStation$Background; comp name = null
focus listener: comp class = bibliothek.extension.gui.dock.theme.eclipse.displayer.EclipseDockableDisplayer2; comp name = null
focus listener: comp class = MyTextField; comp name = null
focus listener: comp class = MyTextField; comp name = null
My modifications have been saved, and the editor shows the modified data. This is correct.
Use case 2:
Now I do the same thing except that I open only one editor. I do modifications, and I close it with the cross in the tab.
=> When I reopen the editor, it does not contain the modifications.
The focus listener says:
focus listener: comp class = MyTextField; comp name = null
// Click on the cross
focus listener: comp class = javax.swing.JFrame; comp name = frame0
focus listener: comp class = javax.swing.JFrame; comp name = frame0
focus listener: comp class = javax.swing.JFrame; comp name = frame0
The docs about input verifiers says that: ‘However, InputVerifier is not called when the focus is transferred to another toplevel component’.
Because the focus is going to a JFrame, my input verifier is not executed. What make it is executed in the first case is that bibliothek.gui.dock.StackDockStation$Background gains the focus.
With df 1.1.2 preview 8e, the behaviour is slightly different but not better.
In the use case 1, I get an exception on the EDT so my app is broken:
at bibliothek.gui.dock.DockHierarchyLock.ensureUnlinked(DockHierarchyLock.java:359)
at bibliothek.gui.dock.DockHierarchyLock.access$500(DockHierarchyLock.java:45)
at bibliothek.gui.dock.DockHierarchyLock$Token.release(DockHierarchyLock.java:420)
at bibliothek.gui.dock.StackDockStation.remove(StackDockStation.java:1536)
at bibliothek.gui.dock.StackDockStation.drag(StackDockStation.java:1267)
at bibliothek.gui.dock.control.SingleParentRemover.test(SingleParentRemover.java:184)
at bibliothek.gui.dock.control.SingleParentRemover.testAll(SingleParentRemover.java:99)
at bibliothek.gui.dock.control.SingleParentRemover$DockRegisterObserver.dockableUnregistered(SingleParentRemover.java:218)
at bibliothek.gui.dock.control.DockRegister.fireDockableUnregistered(DockRegister.java:441)
at bibliothek.gui.dock.control.DockRegister.unregister(DockRegister.java:363)
at bibliothek.gui.dock.control.DockRegister$StationListener.removeDockable(DockRegister.java:723)
at bibliothek.gui.dock.control.DockRegister$StationListener.fire(DockRegister.java:574)
at bibliothek.gui.dock.control.DockRegister.setStalled(DockRegister.java:533)
at bibliothek.gui.dock.common.CControl$Access.hide(CControl.java:2761)
at bibliothek.gui.dock.common.intern.AbstractCDockable.setVisible(AbstractCDockable.java:319)
at bibliothek.gui.dock.common.action.predefined.CCloseAction.close(CCloseAction.java:96)
at bibliothek.gui.dock.common.action.predefined.CCloseAction$Action.close(CCloseAction.java:119)
at bibliothek.gui.dock.facile.action.CloseAction.action(CloseAction.java:128)
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(AWTEventMulticaster.java:272)
at java.awt.Component.processMouseEvent(Component.java:6288)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
at java.awt.Component.processEvent(Component.java:6053)
at java.awt.Container.processEvent(Container.java:2041)
at java.awt.Component.dispatchEventImpl(Component.java:4651)
at java.awt.Container.dispatchEventImpl(Container.java:2099)
at java.awt.Component.dispatchEvent(Component.java:4481)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4577)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4238)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168)
at java.awt.Container.dispatchEventImpl(Container.java:2085)
at java.awt.Window.dispatchEventImpl(Window.java:2478)
at java.awt.Component.dispatchEvent(Component.java:4481)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:643)
at java.awt.EventQueue.access$000(EventQueue.java:84)
at java.awt.EventQueue$1.run(EventQueue.java:602)
at java.awt.EventQueue$1.run(EventQueue.java:600)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:98)
at java.awt.EventQueue$2.run(EventQueue.java:616)
at java.awt.EventQueue$2.run(EventQueue.java:614)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:613)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)```
In this stack, EditorDockableImpl is my implementation of DefaultMultipleCDockable.
In use case 2, I get the same behaviour (the frame gets the focus).
Sorry for this long description... Any idea ?
One thing I don't understand, is that the close button never gains the focus (an instance of RoundRectButton) even if it is visible and focusable. Maybe because it doesn't have any parent ? If the button gained the focus, the problem would be solved.