aspose file tools*
The moose likes Swing / AWT / SWT and the fly likes font family of empty DefaultStyledDocument Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Java » Swing / AWT / SWT
Bookmark "font family of empty DefaultStyledDocument" Watch "font family of empty DefaultStyledDocument" New topic
Author

font family of empty DefaultStyledDocument

Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
I am currently implementing a small text editor component with a combo box for the font family used, using a JTextPane with a DefaultStyledDocument.

Problem is, when I initialize it with an empty DefaultStyledDocument, the font family is "Dialog". I want it to be a different one, for example "Times New Roman".

The only way I've found to change the "default font" is to override the document's createDefaultRoot() method, but this feels really clumsy. I assume that there must be a better way to do it, but no matter how long I look at the javadoc or google the net, I can't find it.

Any hint in the right direction would be highly appreciated. We are using JDK 1.4.2.


The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Alan Moore
Ranch Hand

Joined: May 06, 2004
Posts: 262
First off, the font is a property of the JTextComponent, not of the Document. The default font is set by the LookAndFeel, which stores it in the UIDefaults table. To change the default font for all JTextPanes, place your own font in the table under the appropriate key:
Do this before you create any components.
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Alan Moore:
First off, the font is a property of the JTextComponent, not of the Document.


Ah, no. A JTextPane can show text for which the font changes inside the text itself. In this case, it's a property of the content inside the document.
H Lander
Greenhorn

Joined: Oct 23, 2005
Posts: 15
You can do it using actions defined by javax.swing.text.StyledEditorKit.
The code below demonstrates this.

Good luck,
Henry

Alan Moore
Ranch Hand

Joined: May 06, 2004
Posts: 262
But in an empty document, the only font setting that makes any sense is the UIDefaults setting. There's no point querying the document to find out which Style is in effect if you haven't set any yet.
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by H Lander:
You can do it using actions defined by javax.swing.text.StyledEditorKit.
The code below demonstrates this.


Thanks Henry. That still looks clumsy to me, but I will take a look at the source code of the action to see wether it gives me new ideas...
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Alan Moore:
But in an empty document, the only font setting that makes any sense is the UIDefaults setting. There's no point querying the document to find out which Style is in effect if you haven't set any yet.


We must still be misunderstanding. I *want* to set the style of the empty document, so that when I type something in the the JTextPane, it's in the style I've set, not in the default style. And I'm able to do that, by overriding createDefaultRoot as I said above (I can post the code tomorrow, when I'm at work again) - it just doesn't feel like the correct way to do it.

I have a JCombobox linked to the JTextPane via a CaretListener, which shows the font family set at the caret position. Even for a non-empty document with text in, say, Times New Roman and Helvetica, the combobox shows the font family Dialog for the beginning and the end of the text unless I overwrite createDefaultRoot. I don't want to allow Dialog as a font family.
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Ilja Preuss:

Thanks Henry. That still looks clumsy to me, but I will take a look at the source code of the action to see wether it gives me new ideas...


Mhh, the action basically calls setCharacterAttributes on the document. I thought we already tried that, but we might have done something wrong. Will try again when I'm back at work again tomorrow.
H Lander
Greenhorn

Joined: Oct 23, 2005
Posts: 15
I agree its a bit clumsy. Although if you define methods to set the Font Size, Family and other attributes, and call these methods from the GUI controls of your text editor it will work quite fine.

Good idea looking at what the Action does.

Regards,
Henry
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by H Lander:
Although if you define methods to set the Font Size, Family and other attributes, and call these methods from the GUI controls of your text editor it will work quite fine.


Yes - in fact I have that already working. It's really only the initial state that I'm struggling with. I currently assume that I was just blind today. Let's see what tomorrow brings (here in germany, tomorrow is only two hours away now... ).
Michael Dunn
Ranch Hand

Joined: Jun 09, 2003
Posts: 4632
setting the font of the JTextPane doesn't give you the initial font you want?
Craig Wood
Ranch Hand

Joined: Jan 14, 2004
Posts: 1535
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Michael Dunn:
setting the font of the JTextPane doesn't give you the initial font you want?


Didn't try it, but it doesn't sound right to me, as the font should be defined by the document, not by the component that shows the document. Might try it if nothing else works, though...
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Craig, setLogicalStyle looks promising. I will have to read about it, and of course try it.
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Ilja Preuss:
Craig, setLogicalStyle looks promising. I will have to read about it, and of course try it.


Now I remember: the problem with setLogicalStyle is that it applies to a whole paragraph.



This shows lucida for all the text, even for the one that is in Times New Roman. I need to show it the actual font of the current character. (In fact I will later need to convert the document to some native format, preserving all the font settings done in the editor.)
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
When I add the following line to caretUpdate, it seems to work!



Now I need to try this in the production code...
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
It looks like it can even be done in the document itself:



Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
I was struggling with some other problems integrating this code into our application, but now I've hit another road block: setting the document on a JTextPane seems to reset the default style or something:



The output of this is

before: Times New Roman
after: Dialog

Problem is, I want to create the document outside the class that is creating the JTextPane.

Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
The BasicTextPaneUI changes the style to the default font... :roll:
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Ilja Preuss:
The BasicTextPaneUI changes the style to the default font... :roll:


No, to the font of the component. So it looks like Michael was right. Sorry for ignoring you, Micheal...

This still looks backward to me, though...
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
So the BasicTextPaneUI changes the default style, which is used as the documents style by default. So if a set a different style, that seems to work:



I'm not sure wether I'm using styles correctly here. For example, is using a NamedStyle the correct way of doing it?

Any hints for simplifying the code would be highly appreciated.

And thanks to anyone who contributed so far - without you, I would have shot myself...
[ October 27, 2005: Message edited by: Ilja Preuss ]
Craig Wood
Ranch Hand

Joined: Jan 14, 2004
Posts: 1535
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Craig, your code would work, but it doesn't allow me to separate concerns in the way I would like. In my design currently the code that creates and configures the document doesn't know about the JTextPane at all, and therefore also doesn't know when it gets added to one.

I guess I could wrap the document into a kind of factory which has a reset method that gets called after the document got added to the JTextPane, but that sounds even more complicated than the code I have now...
Brian Cole
Author
Ranch Hand

Joined: Sep 20, 2005
Posts: 862
Originally posted by Ilja Preuss:
I was struggling with some other problems integrating this code into our application, but now I've hit another road block: setting the document on a JTextPane seems to reset the default style or something:



The output of this is

before: Times New Roman
after: Dialog

Problem is, I want to create the document outside the class that is creating the JTextPane.




It's not pretty, but it will work if you replace
new JTextPane(document) with

Note that StyleContext.getDefaultStyleContext() might not
be appropriate if you're doing something special with your
Documents' StyleContexts.


bitguru blog
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Brian Cole:
It's not pretty, but it will work if you replace
new JTextPane(document) with


Thanks Brian!

I already thought about something like this, but assumed that it would be more complicated...

And you are right - it isn't pretty. I'm not yet sure wether I like it better than the alternatives. Mhh...
Steve Thames
Greenhorn

Joined: Oct 27, 2007
Posts: 1
I first encountered this problem about a year ago and found that it was causing many other people trouble. I recently returned to the problem and found a resolution that I thought I would share in the hopes it will help someone else.

The problem, fundamentally, is that Sun, sometime in the past, implemented a generic UI interface that can be easily changed to fit the target environment--Window, Mac, etc. These Motifs can be globally selected and affect all styles used the in the application/applet. The way they did this, in the case of the JTextPane/JEditorPane, was to modify the default style in the StyleContext object (getAttributeContext()) of the document itself. The pane gets its default settings from the default style context.

This may have made sense to someone, for some reason. Personally, I would have set the defaults in the default StyleContext and not have the UI mess with it at all. But that's just me.

The effect of this was to completly short-circuit the mechanism for using styles the way we want to because the JTextPane/JEditorPane will get its font/color attributes from the StyleContext. Since the UI Motif will resent them no matter what you do, the feature is lost.

My solution turned out to be seems like a hack but actually turns out to be rather elegant because it is encapsulated to one object--StyleContext. I created a subclass of StyleContext and use this to create the default document. This subclass watches the default style and resets it to my values whenever it is changed by something else--such as the UI.

Here is the code. I hope someone finds it useful.
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Steve, thanks for the code!

I didn't yet take a close look, but should I ever need to touch that code again (which might in fact be in the near future), I will consider using it!
 
jQuery in Action, 2nd edition
 
subject: font family of empty DefaultStyledDocument