Missing factory when saving frontend to XML

Hello,

I’ve been [re]building some docking components as per the Demo04_LoadAndSave et al demos. These work well, and I tend to have more control over using the just the common wrappers, grids etc.

I’ve run into a bit of problem hopefully someone might be able to help with?

When I try to save (to XML) my frontend object, I get:
java.lang.IllegalStateException: Missing factory: delegate_ccontrol backup factory id

It looks like I don’t have a CControl delegate property or similar (which I don’t - I’m not using CControl)

This exception happens in:
frontend.writeXML(myxelement);

I’m not doing anything essentially different than the demo, as far as the frontend is concerned (the demos have no reference to CControl).

My init code looks like this:

{
frontend = new DockFrontend(CReportFrame.GetReportFrame());
RegisterSpecialTitles(frontend);

// some stations
station = new SplitDockStation();
screen = new ScreenDockStation(CReportFrame.GetReportFrame());
east = new FlapDockStation();
west = new FlapDockStation();

CPanel dckPanel = new CPanel();

dckPanel.add( station, BorderLayout.CENTER );
dckPanel.add( east.getComponent(), BorderLayout.EAST );
dckPanel.add( west.getComponent(), BorderLayout.WEST );
this.add(dckPanel);

frontend.addRoot("east", east);
frontend.addRoot("west", west);
frontend.addRoot("center", station);
frontend.addRoot("screen", screen);
}

```I then add panels etc. like this:

```CVisualizerDockable dckTree = new CVisualizerDockable(new CVisualElementConfig("Tree View"), configChangeDelegate); //these are my own subclasses
dckTree.setTitleText("Tree View");
dckTree.add(treeView);

SplitDockPathProperty prpTree = new SplitDockPathProperty();
prpTree.insert(Location.TOP, 0.6, 0, -1);
station.drop(dckTree.intern(), prpTree);
frontend.addDockable(dckTree.getUniqueId(), dckTree.intern());
frontend.setHideable(dckTree.intern(), false);

Has anyone encountered this issue before when writing info to XML? Any ideas what’s wrong?

Many thanks!
midiman

How does your class „CVisualizerDockable“ look like? I assume it does extend „DefaultSingleCDockable“? If so: you can try and install a DockFactory (DockFrontend.registerFactory/registerBackupFactory) with the identifier „ccontrol backup factory id“, or you use CControl because that is how the framework was designed and that is how it will work properly :wink:

(Most classes from the Common-project will only work properly with the configuration a CControl sets up. A CControl is a wrapper around a DockFrontend, if you create a CControl you don’t need to create a DockFrontend. In the newest release there is a „tutorial/demo“ project with some examples using CControl. A CControl will install several factories and replace strategies that are normally used by the Core framework.)

Hi Beni,

Many thanks for your quick reply.

You’re quite right, my CVisualizerDockable class extends DefaultSingleCDockable. I can see now that this is a common layer class, whereas frontend etc classes aren’t.

This is actually a bit of redesign, as I was using CControl and common layer only, and this was saving xml just fine. I was having some problems with controlling positions etc. (because of my lack of understanding of the API :-), so I thought I’d have a go using frontend.

One of the things I was having trouble with was I used CGrid/grid.deploy() to realize the dockables, but this seems problematic when adding new dockables, changing etc.

Maybe I should go back to using CControl etc.? What is the best way, once a ‘base’ set of dockables is dispalyed, to add/remove - re-realize changes to the layout etc [programmatically]?

Many thanks for your excellent work!
midiman

Hi,

I’ve gone back to my original CControl/common-based design. I’ve made some changes to my CVisualizerDockable which is breaking the read/write to/from disk - just need to find where the problem is.

Many thanks,
midiman

Hello Beni,

I believe I have found the problem with my load/save changes – I think this is perhaps a bug in CDockable code?

I noticed when I changed my DefaultSingleCDockable subclass to start using a configuration data class, the ccontrol.readXML() stopped working.

What I found is this:

If I use a ‘simple’ name for the dockable’s uniqueId (e.g. ‘TreeView’, no spaces, no numbers, not very long), everything is fine.
But if I use a ‘computer-generated’ id (I’m using a modified/stringified UUID) like:
vedb091c9ce26a413794688a2175a2796b (this is a UUID with '-'s removed and ‘ve’ stuck on the front - for xml should need no escaping),
the dockable saves ok to XML (or appears to - there is no error), but when it’s loaded using ccontrol.readXML(file), there’s no exception, but no dockables are visible.

If you remember a while back I reported a somewhat related issue if the ID has a space in it. Could this be a similar problem with long and/or numeric ids? As the id is a string, it would be good if it could take any string.

Please let me know if you’d like me to try anything out/test etc.

Thanks!
Peter

Hi,

After doing some more testing, I don’t think there is a problem with the CDockable code and xml generation with regards length/characters etc. - The issue seems to arise from existing dockables needing to have the same id as those stored in the xml. When I use a consistent id across ‘in-memory’ dockables and ‘xml-read in’ dockables, it works great. Need to do some more testing to see why that would be.

Many thanks,
midiman

Trying to mix the two projects will get you into more problems than it will solve… Yes, CGrid/deploy can only be used for an initial layout, afterwards you’ll have to use CLocations and CDockable.setLocation. You can always ask an existing CDockable for its location (getBaseLocation) and use the method “CLocation.aside” to generate a position pointing to the “next” dockable. Or you generate new location using the static factory methods of CLocation.

Finally you can set up the initial layout with a CPerspective, add all/most SingleCDockables and remove those dockables that should not be visible initially. Adding and removing a Dockable in a CPerspective leaves a placeholder that will later be used to position the Dockable. If you then make such a dockable visible and use “setExtendedMode” it will automatically jump to its correct position.

The idea behind the identifiers is, that they remain constant forever. I would use some consistent naming scheme for chosing them, and make sure they don’t ever change again. As you noticed, every modified identifier will lead to missing information.

Hi Beni,

Many thanks for your comments/advice. Yes, mixing core and common isn’t for the faint of heart, so I’m staying consistent with the common apis.

That’s great stuff to know about CPerspective and aside. :smiley:

Thanks!
midiman