Store layout

i want to save positions of my dockables in sql i tried to do somethink like that

File a = new File( “C:/a.txt”);

	control.read(a);

but it doesnt works

java.lang.NullPointerException
at java.awt.Container.addImpl(Unknown Source)
at java.awt.Container.add(Unknown Source)
at bibliothek.gui.dock.common.intern.DefaultCDockable.add(DefaultCDockable.java:238)
at EditorDockable.(EditorDockable.java:65)
at EditorFactory.read(EditorFactory.java:22)
at EditorFactory.read(EditorFactory.java:1)
at bibliothek.gui.dock.common.intern.CommonMultipleDockableFactory.layout(CommonMultipleDockableFactory.java:167)
at bibliothek.gui.dock.common.intern.CommonMultipleDockableFactory.layout(CommonMultipleDockableFactory.java:162)
at bibliothek.gui.dock.common.intern.CommonMultipleDockableFactory.layout(CommonMultipleDockableFactory.java:57)
at bibliothek.gui.dock.layout.DockSituation.convert(DockSituation.java:377)
at bibliothek.gui.dock.layout.DockSituation.convert(DockSituation.java:363)
at bibliothek.gui.dock.layout.DockSituation.convert(DockSituation.java:363)
at bibliothek.gui.dock.frontend.DefaultLayoutChangeStrategy.applyLayout(DefaultLayoutChangeStrategy.java:309)
at bibliothek.gui.dock.frontend.DefaultLayoutChangeStrategy.setLayout(DefaultLayoutChangeStrategy.java:97)
at bibliothek.gui.DockFrontend.setSetting(DockFrontend.java:1481)
at bibliothek.gui.dock.common.intern.CDockFrontend.access$001(CDockFrontend.java:48)
at bibliothek.gui.dock.common.intern.CDockFrontend$1.run(CDockFrontend.java:163)
at bibliothek.gui.dock.support.mode.ModeManager.runTransaction(ModeManager.java:512)
at bibliothek.gui.dock.facile.mode.LocationModeManager.runLayoutTransaction(LocationModeManager.java:474)
at bibliothek.gui.dock.common.intern.CDockFrontend.setSetting(CDockFrontend.java:161)
at bibliothek.gui.DockFrontend.read(DockFrontend.java:1841)
at bibliothek.gui.dock.common.CControl$8.read(CControl.java:809)
at bibliothek.gui.dock.support.util.ApplicationResourceManager.readStream(ApplicationResourceManager.java:144)
at bibliothek.gui.dock.support.util.ApplicationResourceManager.readFile(ApplicationResourceManager.java:204)
at bibliothek.gui.dock.common.CControl.read(CControl.java:2609)

there a my classes :

import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JTextArea;

import bibliothek.gui.dock.common.DefaultMultipleCDockable;
import bibliothek.gui.dock.common.action.CAction;
import bibliothek.gui.dock.common.event.CDockableLocationEvent;
import bibliothek.gui.dock.common.event.CDockableLocationListener;
import bibliothek.gui.dock.common.event.CDockablePropertyListener;
import bibliothek.gui.dock.common.event.CDockableStateListener;
import bibliothek.gui.dock.common.intern.CDockable;
import bibliothek.gui.dock.common.mode.ExtendedMode;

 class EditorDockable extends DefaultMultipleCDockable{
		
	 private EditorLayout itsLayout=null;
	 private DataRoom room=null;
	 private boolean mousePressed=false;
		public EditorDockable( EditorFactory factory, final EditorLayout layout, DataRoom room ){
			/* it is mandatory to set the factory, the EditorDockable cannot be created 
			 * without it. */
			super( factory );
			this.itsLayout=layout;
			this.setDataRoom(room);
			
			
			/* and then we just set up the editor */
			setTitleText( layout.getFileName() );
			
			if(layout.getFileContent()!=null){
				for(ImageComponent e: layout.getFileContent()){
					e.setParentDockable(this);
					add(e);
				}
			}
			add(layout.getBackground());
			
			
			//verbinde RaumPanel mit dem EditorDockable
			if(layout.getBackground() instanceof RaumPanel){
				((RaumPanel) layout.getBackground()).setEditor(this);
			}
			
		}
		
		public EditorDockable( EditorFactory factory, final EditorLayout layout ){
			/* it is mandatory to set the factory, the EditorDockable cannot be created 
			 * without it. */
			super( factory );
			this.itsLayout=layout;
			
			/* and then we just set up the editor */
			setTitleText( layout.getFileName() );
			
			if(layout.getFileContent()!=null){
				for(ImageComponent e: layout.getFileContent()){
					e.setParentDockable(this);
					add(e);
				}
			}
			add(layout.getBackground());
			
			
			//verbinde RaumPanel mit dem EditorDockable
			if(layout.getBackground() instanceof RaumPanel){
				((RaumPanel) layout.getBackground()).setEditor(this);
			}
		
			
		}
		
		
	
		/* This convenient method allows us to grab the entire content of this dockable
		 * in one step. */
		public EditorLayout getLayout(){
			
			return itsLayout;
		}


		public DataRoom getDataRoom() {
			return room;
		}


		public void setDataRoom(DataRoom room) {
			this.room = room;
		}
		
	
	}```


import bibliothek.gui.dock.common.MultipleCDockableFactory;

/* This factory builds a link between EditorDockable and EditorLayout */

class EditorFactory implements MultipleCDockableFactory<EditorDockable, EditorLayout>{
/* An empty layout is required to read a layout from an XML file or from a byte stream */
public EditorLayout create(){
return new EditorLayout();
}

	/* An optional method allowing to reuse 'dockable' when loading a new layout */
	public boolean match( EditorDockable dockable, EditorLayout layout ){
		System.out.println("factory");
		return dockable.getLayout().equals( layout );
	}

	/* Called when applying a stored layout */
	public EditorDockable read( EditorLayout layout ){
		System.out.println("factory");
		return new EditorDockable( this, layout );
	}

	/* Called when storing the current layout */
	public EditorLayout write( EditorDockable dockable ){
		System.out.println("factory");
		return dockable.getLayout();
	}
	
}



import java.awt.Color;
import java.awt.Cursor;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragGestureRecognizer;
import java.awt.dnd.DragSource;
import java.awt.dnd.DragSourceDragEvent;
import java.awt.dnd.DragSourceDropEvent;
import java.awt.dnd.DragSourceEvent;
import java.awt.dnd.DragSourceListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;

import javax.swing.JPanel;

import bibliothek.gui.dock.common.MultipleCDockableLayout;
import bibliothek.util.xml.XElement;

class EditorLayout implements MultipleCDockableLayout {
private String fileName=null;
private JPanel background=null;
private ArrayList pc;

	public EditorLayout(){
		// nothing
	}
	
	public EditorLayout( String fileName,  ArrayList <ImageComponent>pc, JPanel background ){
		
	
		this.fileName = fileName;
		this.pc=pc;
		this.background=background;
		
	}
	
	public String getFileName(){
		return fileName;
	}
	
	public ArrayList<ImageComponent> getFileContent(){
		return pc;
	}
	
	public JPanel getBackground(){
		return background;
	}
	
	@Override
	public boolean equals( Object obj ){
		if( this == obj ){
			return true;
		}
		if( obj == null ){
			return false;
		}
		if( getClass() != obj.getClass() ){
			return false;
		}
		EditorLayout other = (EditorLayout) obj;
		return equals( background, other.background ) && 
			equals( fileName, other.fileName ); /*&& 
			/*equals( fileContent, other.fileContent );*/
	}
	
	private boolean equals( Object a, Object b ){
		if( a == null ){
			return b == null;
		}
		else{
			return a.equals( b );
		}
	}

	public void readStream( DataInputStream in ) throws IOException{
		fileName = in.readUTF();
		
	}

	public void readXML( XElement element ){
		fileName = element.getElement( "name" ).getString();
		
	}

	public void writeStream( DataOutputStream out ) throws IOException{
		out.writeUTF( fileName );
		
	}

	public void writeXML( XElement element ){
		element.addElement( "name" ).setString( fileName );
		
	}
	
	public EditorLayout clone(){
		
		return this;
	}

	

	
	
}


i dont understand what im doing wrong an who can i store the "layout"(dockable positions an state if they are open ore closed ) in the data base  , it can u halp me please ?

at EditorDockable.(EditorDockable.java:65)

Well, what happens at this location? EditorLayout.background is null.
Why is EditorLayout.background „null“? Because you never create it.
Why do you never create it? I can’t answer this question, but the EditorLayout.read methods would be a place to do that.

A more basic question would be: why is there a field EditorLayout.background in the first place? Storing the name of the file should be enough, storing a Component (!) in a datastructure that is specifically designed to be independent from the UI is certainly wrong :wink:

[QUOTE=Beni]Well, what happens at this location? EditorLayout.background is null.
Why is EditorLayout.background „null“? Because you never create it.
Why do you never create it? I can’t answer this question, but the EditorLayout.read methods would be a place to do that.

A more basic question would be: why is there a field EditorLayout.background in the first place? Storing the name of the file should be enough, storing a Component (!) in a datastructure that is specifically designed to be independent from the UI is certainly wrong ;-)[/QUOTE]

thx i got it :slight_smile:

i use the layout to store a JPanel and another components on it -< is it ok to do this (i dont sore this with layout just use it by creating new dockable )

CLocation location = CLocation.base().normalNorth( 0.7).east( 0.76 ).stack( 0 );
EditorDockable tempEditor= new EditorDockable( factory, new EditorLayout( roomName , pc ,new RaumPanel(this) ),roomNameExist(roomName) );
tempEditor.setLocation(location);

first i get data from db than with this data i create dockables and anoder component on it an than i use control.read() to get the layout , as I understand it it needs just the fileName from the dockable

changed a little bit this methode and just compare the names

/* An optional method allowing to reuse ‚dockable‘ when loading a new layout */
public boolean match( EditorDockable dockable, EditorLayout layout ){

		return dockable.getLayout().getFileName().equals( layout.getFileName() );
	}

and i check if layout!=null in the EditroDockable than it works great
what do u think about it ? :slight_smile:

but i works just with a file and i dont have any ideas how to store it to data base because i want that each user has he own layout

how can i overwrite the public void readStream( DataInputStream in ) throws IOException{
fileName = in.readUTF();
System.out.println("read stream ");

	}

and write stream to store it on my database ?

Do you know MVC? The Model View Controller pattern?

Dockable: is a view.
EditorLayout: is part of the model.
CControl: is the controller.

RaumPanel, ImagePanel: are views.
A filename: is part of the model.
Other things: are part of the controller.

You already see which things belong together? All your issues are caused by your attempts to mix view and model - and the framework which is not designed to support that.

Get rid of anything in EditorLayout that is not „filename“ and find a way to create new panels insides of the constructor of EditorDockable. I guarantee, this approach will save you from a world of pain.

[QUOTE=Unregistered]i use the layout to store a JPanel and another components on it -< is it ok to do this (i dont sore this with layout just use it by creating new dockable )

CLocation location = CLocation.base().normalNorth( 0.7).east( 0.76 ).stack( 0 );
EditorDockable tempEditor= new EditorDockable( factory, new EditorLayout( roomName , pc ,new RaumPanel(this) ),roomNameExist(roomName) );
tempEditor.setLocation(location);

first i get data from db than with this data i create dockables and anoder component on it an than i use control.read() to get the layout , as I understand it it needs just the fileName from the dockable

changed a little bit this methode and just compare the names

/* An optional method allowing to reuse ‚dockable‘ when loading a new layout */
public boolean match( EditorDockable dockable, EditorLayout layout ){

		return dockable.getLayout().getFileName().equals( layout.getFileName() );
	}

and i check if layout!=null in the EditroDockable than it works great
what do u think about it ? :slight_smile:
[/quote]
This works as long as you do not allow the user to store more than one layout. If you do, then some Dockables could be created lazy. You would have create them beforehand, it would be really inefficient if the user never opens these Dockables…

but i works just with a file and i dont have any ideas how to store it to data base because i want that each user has he own layout

how can i overwrite the public void readStream( DataInputStream in ) throws IOException{
fileName = in.readUTF();
System.out.println("read stream ");

  }

and write stream to store it on my database ?

So you want to write the entire file in „write/readStream“? And if you have more than one layout you write the same file more than once? Store the file independent from the layout, they don’t belong together :wink:

[QUOTE=Beni]Do you know MVC? The Model View Controller pattern?

Dockable: is a view.
EditorLayout: is part of the model.
CControl: is the controller.

RaumPanel, ImagePanel: are views.
A filename: is part of the model.
Other things: are part of the controller.

You already see which things belong together? All your issues are caused by your attempts to mix view and model - and the framework which is not designed to support that.

Get rid of anything in EditorLayout that is not „filename“ and find a way to create new panels insides of the constructor of EditorDockable. I guarantee, this approach will save you from a world of pain.

This works as long as you do not allow the user to store more than one layout. If you do, then some Dockables could be created lazy. You would have create them beforehand, it would be really inefficient if the user never opens these Dockables…

So you want to write the entire file in „write/readStream“? And if you have more than one layout you write the same file more than once? Store the file independent from the layout, they don’t belong together ;)[/QUOTE]

yeah i know the mvc but not very good as i should :slight_smile: i thought layout belongs to the views :slight_smile: , ill rid all from layout expect the fileName

I have just one layout and and store always just one by overwriting the old … its a school project :slight_smile:

about poin 3 : i don’t want to have any files i want to save that to db :slight_smile: for example connect.write(file name ) instead of that i wanna have something like that connect.write(sql_tab) i dot exactly know what happens in the connect.write() and how to do this :slight_smile: i write this because i didn’t understand what you mean in point 3 :slight_smile:

[QUOTE=Unregistered]yeah i know the mvc but not very good as i should :slight_smile: i thought layout belongs to the views :slight_smile: , ill rid all from layout expect the fileName

I have just one layout and and store always just one by overwriting the old … its a school project :slight_smile:

about poin 3 : i don’t want to have any files i want to save that to db :slight_smile: for example connect.write(file name ) instead of that i wanna have something like that connect.write(sql_tab) i dot exactly know what happens in the connect.write() and how to do this :slight_smile: i write this because i didn’t understand what you mean in point 3 :)[/QUOTE]

and to do something like that is not good idea :slight_smile:

connect.write(tempFile.txt);
String layout=readFile(tempFile);
sqlConn.insert(layout ) …

[QUOTE=Unregistered]yeah i know the mvc but not very good as i should :slight_smile: i thought layout belongs to the views :slight_smile: , ill rid all from layout expect the fileName

I have just one layout and and store always just one by overwriting the old … its a school project :slight_smile: [/QUOTE]
In a way the entire framework belongs to the view, but within the framework there are parts that do not belong to the view directly… it is not easy to understand how everything connects the first time you use the framework. :wink:

[QUOTE=Unregistered;16302]about poin 3 : i don’t want to have any files i want to save that to db :slight_smile: for example connect.write(file name ) instead of that i wanna have something like that connect.write(sql_tab) i dot exactly know what happens in the connect.write() and how to do this :slight_smile: i write this because i didn’t understand what you mean in point 3 :slight_smile:

and to do something like that is not good idea :slight_smile:

connect.write(tempFile.txt);
String layout=readFile(tempFile);
sqlConn.insert(layout ) …[/QUOTE]

Point 3 is this?

Store the file independent from the layout, they don’t belong together

The layout information is one big blob of data. Because no one has to look at that data directly, and it is only processed by the framework, it can use an efficient yet really ugly format. If your EditorLayout makes things like…

  out.write( 'an image requiring 5 MB' );
}```
... then there are some disadvantages:
- You can't get the data without starting the entire application. If you ever make big modifications to the application, you might no longer be able to read an old layout.
- You can't use the DB to do anything interesting like sorting, filtering, replacing or sharing the data with other users.
- And you might even store the same data twice, which is just a wast of space.

But if the EditorLayout only stores an identifier, a key, and not the data (e.g. image, or whatever a RaumPanel shows) directly, you don't run into this problem. Then you can:
- Have two tables: one for the layout, one for the data.
- You can edit the data table, e.g. you can replace an ugly image with a good looking image.
- You can use space efficient
- You can easily add new items for a room (e.g. an image of a chair) by just inserting them into the data table. Your application could just read the entire data table and show a list of available items to the user.

I'm not sure if this answer really helped... perhaps I completely misunderstood how your application works. But then you just have to ask again.

[QUOTE=Beni]In a way the entire framework belongs to the view, but within the framework there are parts that do not belong to the view directly… it is not easy to understand how everything connects the first time you use the framework. :wink:

Point 3 is this?

The layout information is one big blob of data. Because no one has to look at that data directly, and it is only processed by the framework, it can use an efficient yet really ugly format. If your EditorLayout makes things like…

  out.write( 'an image requiring 5 MB' );
}```
... then there are some disadvantages:
- You can't get the data without starting the entire application. If you ever make big modifications to the application, you might no longer be able to read an old layout.
- You can't use the DB to do anything interesting like sorting, filtering, replacing or sharing the data with other users.
- And you might even store the same data twice, which is just a wast of space.

But if the EditorLayout only stores an identifier, a key, and not the data (e.g. image, or whatever a RaumPanel shows) directly, you don't run into this problem. Then you can:
- Have two tables: one for the layout, one for the data.
- You can edit the data table, e.g. you can replace an ugly image with a good looking image.
- You can use space efficient
- You can easily add new items for a room (e.g. an image of a chair) by just inserting them into the data table. Your application could just read the entire data table and show a list of available items to the user.

I'm not sure if this answer really helped... perhaps I completely misunderstood how your application works. But then you just have to ask again.[/QUOTE]

wrote u an email :)