have a problem to clone DefaultStyledDocument

Hi!

I my application I need to clone DefaultStyledDocument. So I have written a clone-method in class MyDefaultStyledDocument which extends DefaultStyledDocument. But obviously I made a mistake and I can't find out what I am doing wrong. I hope someone here can help me, I will appreciate it!

Here is my SSCCE to demonstrate the problem:

import java.awt.Font;

import java.awt.GridLayout;

import javax.swing.*;

import javax.swing.text.BadLocationException;

import javax.swing.text.DefaultStyledDocument;

import javax.swing.text.Element;

import javax.swing.text.MutableAttributeSet;

import javax.swing.text.SimpleAttributeSet;

import javax.swing.text.StyleConstants;

publicclass CloneStyledDocumentSSCCE{

public CloneStyledDocumentSSCCE(){

UIManager.put("TextPane.font",

new javax.swing.plaf.FontUIResource(

new Font("SansSerif", Font.PLAIN, 20)));

JFrame frame =new JFrame("CloneStyledDocumentSSCCE");

frame.setLayout(new GridLayout(1,2,2,2));

MyDefaultStyledDocument doc =new MyDefaultStyledDocument();

MyDefaultStyledDocument clonedDoc = (MyDefaultStyledDocument)doc.clone();

JTextPane tp1 =new JTextPane(clonedDoc);

frame.add(tp1);

JTextPane tp2 =new JTextPane(new MyDefaultStyledDocument());

frame.add(tp2);

tp1.setText("clone");

tp2.setText("no clone");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.setLocationByPlatform(true);

frame.setSize(400,400);

frame.setVisible(true);

}

publicstaticvoid main(String[] args){

new CloneStyledDocumentSSCCE();

}

class MyDefaultStyledDocumentextends DefaultStyledDocument{

public Object clone(){

MyDefaultStyledDocument clonedDocument =new MyDefaultStyledDocument();

Element styledRootElement = this.getDefaultRootElement();

cloneRec(styledRootElement, clonedDocument);

return clonedDocument;

}

privatevoid cloneRec(Element element, MyDefaultStyledDocument clonedDocument){

for (int i=0; i<element.getElementCount(); i++){

Element child = element.getElement(i);

if (child.isLeaf()){

MutableAttributeSet as =new SimpleAttributeSet(child.getAttributes());

if (StyleConstants.getComponent(as) !=null){

// clone Component

}

String text =new String(this.getTextOfElement(child));

try{

clonedDocument.insertString(clonedDocument.getLength(), text, as);

}

catch (BadLocationException x){

x.printStackTrace();

}

if (i == element.getElementCount()-1){

Element paragraphElement = child.getParentElement();

int offset = paragraphElement.getStartOffset();

int length = paragraphElement.getEndOffset() - offset;

clonedDocument.setParagraphAttributes(

offset, length, paragraphElement.getAttributes(),false);

}

}

elseif (childinstanceof BranchElement){

this.cloneRec(child, clonedDocument);

}

else{

this.cloneRec(child, clonedDocument);

}

}

}

private String getTextOfElement(Element styledElement){

String text ="";

int startOffset = styledElement.getStartOffset();

int endOffset = styledElement.getEndOffset();

try{

text = this.getText(startOffset, endOffset-startOffset);

}

catch (BadLocationException x){

x.printStackTrace();

}

return text;

}

}

}

The problem is that the Font that I set with

UIManager.put("TextPane.font",

new javax.swing.plaf.FontUIResource(

new Font("SansSerif", Font.PLAIN, 20)));

gets lost in the cloned document.

Thank you for your time!>

[6846 byte] By [the12huntersa] at [2007-11-26 19:02:32]
# 1
I would appreciate any suggestions very much. If you do not know the solution just give me some ideas what I could try.I know that DefaultStyledDocument might have serveral root-elements. I only clone the default one. Could this be the problem?
the12huntersa at 2007-7-9 20:48:31 > top of Java-index,Desktop,Core GUI APIs...
# 2

This posting shows how to copy/paste styled text from one document to another. It simply copies the text and attributes and doesn't worry about the structure of the document. Maybe this approach can be modified for your requirement.

http://forum.java.sun.com/thread.jspa?forumID=57&threadID=5137992

camickra at 2007-7-9 20:48:31 > top of Java-index,Desktop,Core GUI APIs...
# 3
Thanks for your answer, camickr.I have read this posting. I will check if I can modify it for my clone method.
the12huntersa at 2007-7-9 20:48:31 > top of Java-index,Desktop,Core GUI APIs...
# 4
I found something that seems to work. For it is getting late in my time zone I will check it again tomorrow and if it is OK I will post the solution.
the12huntersa at 2007-7-9 20:48:31 > top of Java-index,Desktop,Core GUI APIs...
# 5

Well, it seems that I am stuck. And I noticed that I did not explain correctly what is going wrong...

My problem occurs only when I clone an empty document. And if I change in my SSCCE

MyDefaultStyledDocument doc = new MyDefaultStyledDocument();

MyDefaultStyledDocument clonedDoc = (MyDefaultStyledDocument)doc.clone();

JTextPane tp1 = new JTextPane(clonedDoc);

frame.add(tp1);

//difference is in following line!

JTextPane tp2 = new JTextPane(new MyDefaultStyledDocument());

frame.add(tp2);

to

MyDefaultStyledDocument doc = new MyDefaultStyledDocument();

MyDefaultStyledDocument clonedDoc = (MyDefaultStyledDocument)doc.clone();

JTextPane tp1 = new JTextPane(clonedDoc);

frame.add(tp1);

//difference is in following line!

JTextPane tp2 = new JTextPane(doc);

frame.add(tp2);

tp1 magically has the correct font. I really can't understand what is going on.

I think I have to understand how the default-font for JTextPane is set. Can someone point me to something that might help? Any ressources or where to look in the swing-source-code or something.... Thanks!

the12huntersa at 2007-7-9 20:48:32 > top of Java-index,Desktop,Core GUI APIs...
# 6

Hello again!

I found something useful in this forum:

http://forum.java.sun.com/thread.jspa?forumID=57&threadID=769001

My SSCCE is working now. I added method getFont to MyDefaultStyledDocument.

public Font getFont(AttributeSet attr) {

String family = (String) attr.getAttribute(StyleConstants.FontFamily);

if (family == null) {

System.out.println("family == null");

Font f = UIManager.getFont("TextPane.font");

SimpleAttributeSet newAttr=new SimpleAttributeSet (attr);

StyleConstants.setFontFamily(newAttr, f.getFamily());

StyleConstants.setFontSize(newAttr, f.getSize());

return super.getFont(newAttr);

}

return super.getFont(attr);

}

But in my application still something is (sometimes.....) going wrong...... It is a bit weird.... I guess I am a specialist for producing weird problems.

the12huntersa at 2007-7-9 20:48:32 > top of Java-index,Desktop,Core GUI APIs...
# 7
> My problem occurs only when I clone an empty document.Then add a check to only do the clone if the document length is greater than 0.
camickra at 2007-7-9 20:48:32 > top of Java-index,Desktop,Core GUI APIs...
# 8

Thank you again for your answer! What a surprise! I already closed that subject and added a FIXME_LATER mark in my project.... And I have just removed it because it is working now!

So you get the remaining 6 Dukes. Did you know that you can't remove Dukes from a Thread when you already have rewarded some? So, camickr, you would have got the remaining Dukes anyway..... But I am happy to give them now to you for your last answer! But those Dukes are some kind of play money aren't they? Do you really care to get some more? You are very rich from my point of view.....

the12huntersa at 2007-7-9 20:48:32 > top of Java-index,Desktop,Core GUI APIs...