Well, but then it sounds as if the initFunction has some issue, not the DF library. Could you create a small, compiling and running example so I could test it on my machine too?
@Andrei: The design of the framework expects a developer to know all Single-Dockables he will ever use. Multi-Dockables are more dynamic. But in general the framework is not yet designed for highly dynamic content.
@HHH: An additional suggestion: use MultipleCDockable instead of SingleCDockable. As you can see in the example below, this way you would not need to know all the ViewFunctions in advance. In fact the framework would tell you, which ViewFunctions it requires to create the layout. Of course you need some way to get from an identifier to the ViewFunction.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import bibliothek.gui.dock.common.CControl;
import bibliothek.gui.dock.common.CGrid;
import bibliothek.gui.dock.common.DefaultMultipleCDockable;
import bibliothek.gui.dock.common.MultipleCDockableFactory;
import bibliothek.gui.dock.common.MultipleCDockableLayout;
import bibliothek.util.xml.XElement;
import bibliothek.util.xml.XIO;
public class Dock18 {
public static void main(String[] args) throws IOException {
// set up frame and control
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(1, 1));
CControl control = new CControl(frame);
frame.add(control.getContentArea());
frame.setSize(new Dimension(700, 700));
frame.setLocationRelativeTo(null);
// register factory
ViewFunctionFactory factory = new ViewFunctionFactory();
control.addMultipleDockableFactory( "view", factory );
// load layout
XElement root = XIO.read( createTestLayoutData() );
control.readXML( root );
frame.setVisible(true);
}
// create a layout (yeah, not very nice. But currently there is no other way)
private static String createTestLayoutData(){
CControl control = new CControl();
ViewFunctionFactory factory = new ViewFunctionFactory();
control.addMultipleDockableFactory( "view", factory );
CGrid grid = new CGrid( control );
grid.add( 0, 0, 50, 100, new ViewFunctionDockable( factory, createFunctionFor( "red" ) ));
grid.add( 50, 0, 50, 50, new ViewFunctionDockable( factory, createFunctionFor( "green" ) ));
grid.add( 50, 50, 50, 50, new ViewFunctionDockable( factory, createFunctionFor( "blue" ) ));
control.getContentArea().deploy( grid );
XElement root = new XElement( "root" );
control.writeXML( root );
return root.toString();
}
// A method that works some magic and can translate an "id" to a view-function
public static ViewFunction createFunctionFor( String id ){
if( "red".equals( id )){
return new ColorViewFunction( id, Color.RED );
} else if( "green".equals( id )){
return new ColorViewFunction( id, Color.GREEN );
} else if( "blue".equals( id )){
return new ColorViewFunction( id, Color.BLUE );
} else if( "yellow".equals( id )){
return new ColorViewFunction( id, Color.YELLOW );
} else {
return null;
}
}
// A factory
private static class ViewFunctionFactory implements MultipleCDockableFactory<ViewFunctionDockable, ViewFunctionLayout> {
public ViewFunctionLayout create(){
return new ViewFunctionLayout();
}
public boolean match( ViewFunctionDockable dockable, ViewFunctionLayout layout ){
return layout.getId().equals( dockable.getFunction().getTitle() );
}
public ViewFunctionDockable read( ViewFunctionLayout layout ){
ViewFunction function = createFunctionFor( layout.getId() );
if( function == null ){
return null;
}
return new ViewFunctionDockable( this, function );
}
public ViewFunctionLayout write( ViewFunctionDockable dockable ){
ViewFunctionLayout layout = new ViewFunctionLayout();
layout.setId( dockable.getFunction().getTitle() );
return layout;
}
}
// your view-function (simplified version)
private static interface ViewFunction{
public String getTitle();
public JComponent getContent();
}
// this layout describes the contents of a Dockable that shows a view-function
private static class ViewFunctionLayout implements MultipleCDockableLayout{
private String id;
public void setId( String id ){
this.id = id;
}
public String getId(){
return id;
}
public void readStream( DataInputStream in ) throws IOException{
id = in.readUTF();
}
public void readXML( XElement element ){
id = element.getString();
}
public void writeStream( DataOutputStream out ) throws IOException{
out.writeUTF( id );
}
public void writeXML( XElement element ){
element.setString( id );
}
}
// this dockable shows a view function
private static class ViewFunctionDockable extends DefaultMultipleCDockable{
private ViewFunction function;
public ViewFunctionDockable( ViewFunctionFactory factory, ViewFunction function ){
super( factory, function.getTitle(), function.getContent() );
this.function = function;
setRemoveOnClose( false );
}
public ViewFunction getFunction(){
return function;
}
}
// finally an implementation of a view-function (also simplified)
private static class ColorViewFunction implements ViewFunction{
private String title;
private Color color;
public ColorViewFunction( String title, Color color ){
this.title = title;
this.color = color;
}
public String getTitle(){
return title;
}
public JComponent getContent(){
JPanel panel = new JPanel();
panel.setOpaque(true);
panel.setBackground(color);
return panel;
}
}
}```