what it is quite expectable because I converted XElement to String, but I don’t see any better way to put docking information as XML into the XML session file.
Maybe this forum is a wrong place to ask this question, and I need to dig into XMLEncoder that is responsible for that…
Well, XElement.toString should produce correct XML, but I guess the XMLEncoder then converts the string… so yeah, there is not much I can do from this end of the line.
I don’t know why XElement can’t be stored directly, maybe because of non-standard getter and setter methods there, see http://java.sun.com/products/jfc/tsc/articles/persistence4/
Probably it can be solved with persistence delegates also.
Playing with dockable menus and toolbars I moved from the 1.0.8 to 1.1.0_p5b version and found that above solution that serializes state of dockables doesn’t work anymore. It fails with the following exception:
bibliothek.util.xml.XException: not a boolean:
at bibliothek.util.xml.XContainer.getBoolean(Unknown Source)
at bibliothek.gui.dock.station.split.SplitDockStationFactory.read(Unknown Source)
at bibliothek.gui.dock.station.split.SplitDockStationFactory.read(Unknown Source)
at bibliothek.gui.dock.layout.PredefinedDockSituation$PreloadFactory.read(Unknown Source)
at bibliothek.gui.dock.layout.PredefinedDockSituation$PreloadFactory.read(Unknown Source)
at bibliothek.gui.dock.layout.DockSituation.readEntry(Unknown Source)
at bibliothek.gui.dock.layout.DockSituation.readCompositionXML(Unknown Source)
at bibliothek.gui.dock.frontend.Setting.readXML(Unknown Source)
at bibliothek.gui.DockFrontend.readXML(Unknown Source)
at bibliothek.gui.DockFrontend.readXML(Unknown Source)
at com.cass.ecass.app.MainFrame$DockingPropertySupport.setSessionState(MainFrame.java:137)
at org.jdesktop.application.SessionStorage.restoreTree(SessionStorage.java:342)
at org.jdesktop.application.SessionStorage.restoreTree(SessionStorage.java:357)
at org.jdesktop.application.SessionStorage.restoreTree(SessionStorage.java:357)
at org.jdesktop.application.SessionStorage.restoreTree(SessionStorage.java:357)
at org.jdesktop.application.SessionStorage.restoreTree(SessionStorage.java:357)
at org.jdesktop.application.SessionStorage.restore(SessionStorage.java:383)
at com.cass.ecass.app.MainApp.startup(MainApp.java:46)
at org.jdesktop.application.Application$1.run(Application.java:187)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
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)
boolean fullscreenAction = true;
if( xfullscreenAction != null ){
fullscreenAction = xfullscreenAction.getBoolean();
}```
This item is written at only one position, so in the current version it should not be stored wrong.
[Edit: your class DockState needs to store the value of the XElements as well. See "XElement.getValue". Most likely the missing content causes this error]
Recently I extended above example with two tool bars (just JToolBars with BorderLayouts), also I implemented ToolBarProperty and ToolBarState classes to serialize them using the BSAF serialization. The first toolbar that is located on the MainForm was serialized without any problems. But the second one that is located on the JPanel that is wrapped with Dockable and placed into SplitDockStation that is placed on MainForm wasn’t.
I have discovered that the second toolbar was saved to XML, but wasn’t loaded. It happened because its path was different from the saved one. For example here the saved path
DF does not care in which order Components are added to their parents (the z-order is irrelevant for Components that do not overlap). BSAF on the other hand uses the z-order to build these paths.
Changing DF such that BSAF resolves these paths always the same way is too much work for too little benefit, but the other way could work:
These paths seem to be generated by the SessionStorage.getComponentPathname method, which is part of the BSAF. I suggest to take the entire Sourcecode of BSAF and rewrite this method such that it returns something that is more configurable, for example a unique identifier that you assign to your toolbar yourself.
Following you suggestions I overrode the SessionStorage.getComponentPathname method. In case if it will be useful for somebody here my steps
create subclass from SessionStorage
because getComponentPathname is a private method copy and paste following methods also
— checkSaveRestoreArgs, getComponentName, saveTree, save, restoreTree, restore
in getComponentPathname comment concatenation of component’s ZOrder to its name
int n = c.getParent().getComponentZOrder(c);
if (n >= 0) {
Class cls = c.getClass();
name = cls.getSimpleName();
if (name.length() == 0) {
name = "Anonymous" + cls.getSuperclass().getSimpleName();
}
//name = name + n;
}
because ApplicationContext.setSessionStorage is a protected method invoke it using Reflection API
Class c = ApplicationContext.class;
Method m = c.getDeclaredMethod("setSessionStorage", new Class[]{SessionStorage.class});
m.setAccessible(true);
CustomSessionStorage s = new CustomSessionStorage(getContext());
m.invoke(getContext(), new Object[]{s});