rzvika2
asked on
word wrap in DefaultStyledDocument
Hi!
I'm using DefaultStyledDocument (new DefaultStyledDocument(new StyleContext());)
I want that the text will be word wrapped.
Can you tell me how to do it?
Thanks!
I'm using DefaultStyledDocument (new DefaultStyledDocument(new StyleContext());)
I want that the text will be word wrapped.
Can you tell me how to do it?
Thanks!
ASKER
I'm using JTextPane.
I want to insert strings with colors (that's why)
I want to insert strings with colors (that's why)
Errr....this does wordWrapping:
-------------------------- ---------- --------
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.text.* ;
public class WordWrap extends Frame
{
BorderLayout borderLayout1 = new BorderLayout();
JScrollPane scroll = new JScrollPane();
JTextPane textPane = new JTextPane();
public WordWrap()
{
try
{
jbInit();
}
catch(Exception e)
{
e.printStackTrace();
}
}
private void jbInit() throws Exception
{
this.setLayout(borderLayou t1);
textPane.setDocument( new DefaultStyledDocument( new StyleContext() ) );
textPane.setText("This is a quick and dirty test to see if we can do word wrapping on a JTextPane");
this.addWindowListener(new java.awt.event.WindowAdapt er()
{
public void windowClosing(WindowEvent e)
{
this_windowClosing(e);
}
});
this.add(scroll, BorderLayout.CENTER);
scroll.getViewport().add( textPane, null );
scroll.setPreferredSize( new Dimension( 300, 300 ) );
}
void this_windowClosing(WindowE vent e)
{
System.exit( 0 ) ;
}
public static void main(String[] args)
{
WordWrap wordWrap = new WordWrap();
wordWrap.pack() ;
wordWrap.show();
}
}
--------------------------
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.text.* ;
public class WordWrap extends Frame
{
BorderLayout borderLayout1 = new BorderLayout();
JScrollPane scroll = new JScrollPane();
JTextPane textPane = new JTextPane();
public WordWrap()
{
try
{
jbInit();
}
catch(Exception e)
{
e.printStackTrace();
}
}
private void jbInit() throws Exception
{
this.setLayout(borderLayou
textPane.setDocument( new DefaultStyledDocument( new StyleContext() ) );
textPane.setText("This is a quick and dirty test to see if we can do word wrapping on a JTextPane");
this.addWindowListener(new
{
public void windowClosing(WindowEvent e)
{
this_windowClosing(e);
}
});
this.add(scroll, BorderLayout.CENTER);
scroll.getViewport().add( textPane, null );
scroll.setPreferredSize( new Dimension( 300, 300 ) );
}
void this_windowClosing(WindowE
{
System.exit( 0 ) ;
}
public static void main(String[] args)
{
WordWrap wordWrap = new WordWrap();
wordWrap.pack() ;
wordWrap.show();
}
}
ASKER
****.
This is the opposit that I've wanted.
by default it is word wrapped, but I don't want it to be like this.
I'm so sorry, you will get the points.
Can you tell me how to make the word not wrapped?
Thanks!
This is the opposit that I've wanted.
by default it is word wrapped, but I don't want it to be like this.
I'm so sorry, you will get the points.
Can you tell me how to make the word not wrapped?
Thanks!
Ahhhhh! ;-)
hehehehe
Yeah, extend JTextPane
JTextPane extends JEditorPane which implements Scrollable
So what you need to do, is override the part of the Scrollable interface that checks if the JTextPane should fix itself to the width of the ScrollPane...
Hope you see what I mean...anyway...here's the code ;-)
Tim
--------------------------
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.text.* ;
import java.util.* ;
public class WordWrap extends Frame
{
class MyTextPane extends JTextPane
{
public boolean getScrollableTracksViewpor tWidth()
{
return false ;
}
}
BorderLayout borderLayout1 = new BorderLayout();
JScrollPane scroll = new JScrollPane();
MyTextPane textPane = new MyTextPane();
public WordWrap()
{
try
{
jbInit();
}
catch(Exception e)
{
e.printStackTrace();
}
}
private void jbInit() throws Exception
{
this.setLayout(borderLayou t1);
StyleContext sc = new StyleContext() ;
DefaultStyledDocument dsd = new DefaultStyledDocument( sc ) ;
textPane.setStyledDocument ( dsd );
Style s = sc.getStyle( "default" ) ;
Enumeration e = s.getAttributeNames() ;
while( e.hasMoreElements() )
{
System.out.println( e.nextElement() ) ;
}
textPane.setText("This is a quick and dirty test to see if we can do word wrapping on a JTextPane");
this.addWindowListener(new java.awt.event.WindowAdapt er()
{
public void windowClosing(WindowEvent e)
{
this_windowClosing(e);
}
});
this.add(scroll, BorderLayout.CENTER);
scroll.getViewport().add( textPane, null );
scroll.setPreferredSize( new Dimension( 300, 300 ) );
}
void this_windowClosing(WindowE vent e)
{
System.exit( 0 ) ;
}
public static void main(String[] args)
{
WordWrap wordWrap = new WordWrap();
wordWrap.pack() ;
wordWrap.show();
}
}
hehehehe
Yeah, extend JTextPane
JTextPane extends JEditorPane which implements Scrollable
So what you need to do, is override the part of the Scrollable interface that checks if the JTextPane should fix itself to the width of the ScrollPane...
Hope you see what I mean...anyway...here's the code ;-)
Tim
--------------------------
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.text.* ;
import java.util.* ;
public class WordWrap extends Frame
{
class MyTextPane extends JTextPane
{
public boolean getScrollableTracksViewpor
{
return false ;
}
}
BorderLayout borderLayout1 = new BorderLayout();
JScrollPane scroll = new JScrollPane();
MyTextPane textPane = new MyTextPane();
public WordWrap()
{
try
{
jbInit();
}
catch(Exception e)
{
e.printStackTrace();
}
}
private void jbInit() throws Exception
{
this.setLayout(borderLayou
StyleContext sc = new StyleContext() ;
DefaultStyledDocument dsd = new DefaultStyledDocument( sc ) ;
textPane.setStyledDocument
Style s = sc.getStyle( "default" ) ;
Enumeration e = s.getAttributeNames() ;
while( e.hasMoreElements() )
{
System.out.println( e.nextElement() ) ;
}
textPane.setText("This is a quick and dirty test to see if we can do word wrapping on a JTextPane");
this.addWindowListener(new
{
public void windowClosing(WindowEvent e)
{
this_windowClosing(e);
}
});
this.add(scroll, BorderLayout.CENTER);
scroll.getViewport().add( textPane, null );
scroll.setPreferredSize( new Dimension( 300, 300 ) );
}
void this_windowClosing(WindowE
{
System.exit( 0 ) ;
}
public static void main(String[] args)
{
WordWrap wordWrap = new WordWrap();
wordWrap.pack() ;
wordWrap.show();
}
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Simply returning false in getScrollableTracksViewpor tWidth() did not work for me. For cases where the JTextPane's preferred size is less than that of the JScrollPane's viewport, I would get only a partially filled viewport.
My getScrollableTracksViewpor tWidth() in my extension of JTextPane looks like this:
public boolean getScrollableTracksViewpor tWidth()
{
if (getParent() instanceof JViewport)
{
if (getParent().getWidth() > document.getLongestLineWid th())
return true;
}
return false;
}
In the above code, document is a reference to a class that extends DefaultStyledDocument and implements the method getLongestLineWidth(). My implementation of that method is below. (It includes things that are not relevant to this issue, like the PropertyChangeListener and the modified flag. My appologies for this.)
import java.awt.Component;
import java.awt.Font;
import java.beans.PropertyChangeL istener;
import java.beans.PropertyChangeS upport;
import java.util.ArrayList;
import javax.swing.JPanel;
import javax.swing.text.Attribute Set;
import javax.swing.text.BadLocati onExceptio n;
import javax.swing.text.DefaultSt yledDocume nt;
import javax.swing.text.Style;
import javax.swing.text.StyleCons tants;
import javax.swing.text.StyleCont ext;
import org.apache.log4j.Logger;
/**
* This Document for the text editor's text area handles highlighting.
* @see javax.swing.text.PlainDocu ment
*/
public class TextEditorDocument extends DefaultStyledDocument implements LineNumberedDocument
{
private static final Logger logger = Logger.getLogger(TextEdito rDocument. class);
public static final String FONT_NAME = "Monospaced";
public static final int FONT_SIZE = 12;
public static final String MODIFIED_PROPNAME = "modified";
public static final char NEW_LINE_CHAR = '\n';
public static final String NEW_LINE_STRING = "\n";
private static final Component metricsComponent = new JPanel();
private Style regularStyle = null;
private boolean modified = false;
/** An array of Integer objects that correspond to the offset for the start of each line */
protected ArrayList offsets = new ArrayList();
private PropertyChangeSupport changeSupport = null;
public TextEditorDocument()
{
Style _default = StyleContext.getDefaultSty leContext( ).getStyle (StyleCont ext.DEFAUL T_STYLE);
StyleConstants.setFontFami ly(_defaul t, FONT_NAME);
StyleConstants.setFontSize (_default, FONT_SIZE);
regularStyle = this.addStyle("regular", _default);
this.setLogicalStyle(0, regularStyle);
}
/**
* Updates the offsets of each line affected and then updates the syntax
* highlighting of those lines
* @see javax.swing.text.Document# insertStri ng(int, java.lang.String, javax.swing.text.Attribute Set)
*/
public void insertString(int offs, String str, AttributeSet a) throws BadLocationException
{
if (str == null || str.length() == 0)
return;
int numLines = getNumLines();
super.insertString(offs, str, a);
setModified(true);
int startLineIndex = getLineIndex(offs);
int endLineIndex = updateOffsetsAfterInsert(o ffs, str);
if (numLines != getNumLines())
firePropertyChange(NUM_LIN ES_PROPNAM E, new Integer(numLines), new Integer(getNumLines()));
}
/**
* @see javax.swing.text.Document# remove(int , int)
*/
public void remove(int offs, int len) throws BadLocationException
{
if (len <= 0)
return;
int numLines = getNumLines();
String removedText = this.getText(offs, len);
super.remove(offs, len);
setModified(true);
updateOffsetsAfterRemove(o ffs, removedText);
if (numLines != getNumLines())
firePropertyChange(NUM_LIN ES_PROPNAM E, new Integer(numLines), new Integer(getNumLines()));
}
/**
* Returns the index of the line in <code>lines</code> that corresponds
* to the specified offset in the document.
*/
protected int getLineIndex(int offset)
{
if (offsets.size() <= 1)
return 0;
int lineIndex = 0;
for (int i = 0; i < offsets.size(); i++)
{
if (i == offsets.size()-1)
return i;
int nextLineOffset = ((Integer)offsets.get(i+1) ).intValue ();
if (offset < nextLineOffset)
return i;
}
throw new RuntimeException("shouldn' t get here in getLineIndex(" + offset + ")");
}
/**
* Gets the text of the line at the specified index
* @param lineIndex the index of the line to return
*/
public String getLine(int lineIndex)
{
if (lineIndex < 0 || lineIndex >= offsets.size())
throw new IndexOutOfBoundsException( "Index: " + lineIndex + ", Size: " + offsets.size());
int lineOffset = ((Integer)offsets.get(line Index)).in tValue();
int lineLength = 0;
if (offsets.size() == lineIndex + 1)
lineLength = this.getLength() - lineOffset;
else
lineLength = ((Integer)offsets.get(line Index + 1)).intValue() - lineOffset;
try
{
return this.getText(lineOffset, lineLength);
}
catch (BadLocationException e)
{
logger.error("lineOffset=" + lineOffset + " lineLength=" + lineLength +
" offsets.size()=" + offsets.size() + " lineIndex=" + lineIndex, e);
// since this method is only used internally, any error here is a
// coding error
throw new RuntimeException(e);
}
}
/**
* Returns the line number that corresponds to the specified offset. This
* is the same as the line index + 1.
* @param offset the location in the document
* @see #getLineIndex(int)
*/
public int getLineNumber(int offset)
{
return 1 + getLineIndex(offset);
}
/**
* Returns the character position relative to the line that corresponds
* to the specified offset.
* @param offset the location in the document
*/
public int getCharacterPosition(int offset)
{
int lineIndex = getLineIndex(offset);
int lineOffset = ((Integer)offsets.get(line Index)).in tValue();
return 1 + offset - lineOffset;
}
/**
* Returns the number of lines of text in this document.
*/
public int getNumLines()
{
return offsets.size();
}
/**
* Returns the number of newline characters ('\n') that are found in the
* specified string.
*/
protected int countNewLines(String text)
{
int count = 0;
for (int i = 0; i < text.length(); i++)
{
if (text.charAt(i) == NEW_LINE_CHAR)
count++;
}
return count;
}
/**
* Updates <code>offsets</code> after a remove.
* @param offset the offset where the text was removed
* @param insertedText the removed text
*/
private void updateOffsetsAfterRemove(i nt offset, String removedText)
{
int interruptedLineIndex = getLineIndex(offset);
// remove offsets for newlines that were deleted
for (int i = countNewLines(removedText) ; i > 0; i--)
{
offsets.remove(interrupted LineIndex + 1);
}
for (int i = interruptedLineIndex + 1; i < offsets.size(); i++)
{
int curOffset = ((Integer)offsets.get(i)). intValue() ;
offsets.set(i, new Integer(curOffset - removedText.length()));
}
}
/**
* Updates <code>offsets</code> after an insert.
* @param offset the offset where the text was inserted
* @param insertedText the inserted text
* @return the index of the last line that was modified by the insert
*/
private int updateOffsetsAfterInsert(i nt offset, String insertedText)
{
if (offsets.size() == 0)
offsets.add(new Integer(0));
int interruptedLineIndex = getLineIndex(offset);
int startingOffset = ((Integer)offsets.get(inte rruptedLin eIndex)).i ntValue();
// increase the value of all the following offsets by the length
// of the inserted text
for (int i = interruptedLineIndex + 1; i < offsets.size(); i++)
{
int curOffset = ((Integer)offsets.get(i)). intValue() ;
offsets.set(i, new Integer(curOffset + insertedText.length()));
}
// add new offsets for the inserted text
int lineIndex = interruptedLineIndex + 1;
for (int indexOfNewLine = -1; indexOfNewLine + 1 < insertedText.length(); lineIndex++)
{
indexOfNewLine = insertedText.indexOf(NEW_L INE_CHAR, indexOfNewLine+1);
if (indexOfNewLine == -1)
break;
offsets.add(lineIndex, new Integer(offset + indexOfNewLine + 1));
}
return lineIndex - 1;
}
/**
* Returns true if this document has been modified.
* @return the <code>modified</code> flag
*/
public boolean isModified()
{
return modified;
}
/**
* Sets the <code>modified</code> flag to the specified value.
*/
void setModified(boolean modified)
{
if (this.modified == modified)
return;
this.modified = modified;
firePropertyChange(TextEdi torDocumen t.MODIFIED _PROPNAME, new Boolean(!modified), new Boolean(modified));
}
/**
* Support for reporting bound property changes for Object properties.
* This method can be called when a bound property has changed and it will
* send the appropriate PropertyChangeEvent to any registered
* PropertyChangeListeners.
*
* @param propertyName the property whose value has changed
* @param oldValue the property's previous value
* @param newValue the property's new value
*/
protected void firePropertyChange(String propertyName, Object oldValue, Object newValue)
{
if (changeSupport == null)
return;
changeSupport.fireProperty Change(pro pertyName, oldValue, newValue);
}
/**
* Adds a PropertyChangeListener to the listener list. The listener is
* registered for all bound properties of this class.
* If listener is null, no exception is thrown and no action is performed.
* @param propertyName the name of the property to listen on
* @param listener the PropertyChangeListener to be added
* @see #removePropertyChangeListe ner
*/
public synchronized void addPropertyChangeListener( String propertyName, PropertyChangeListener listener)
{
if (listener == null)
return;
if (changeSupport == null)
changeSupport = new PropertyChangeSupport(this );
changeSupport.addPropertyC hangeListe ner(proper tyName, listener);
}
/**
* Removes a PropertyChangeListener from the listener list. This method
* should be used to remove PropertyChangeListeners that were registered
* for all bound properties of this class.
* <p>
* If listener is null, no exception is thrown and no action is performed.
* @param propertyName the name of the property to listen on
* @param listener the PropertyChangeListener to be removed
* @see #addPropertyChangeListener
*/
public synchronized void removePropertyChangeListen er(String propertyName, PropertyChangeListener listener)
{
if (listener == null || changeSupport == null)
return;
changeSupport.removeProper tyChangeLi stener(pro pertyName, listener);
}
/**
* @see com.realvue.tools.textedit or.LineNum beredDocum ent#getNum CharsInLon gestLine()
*/
public int getLongestLineWidth()
{
int max = 0;
Font font = StyleContext.getDefaultSty leContext( ).getFont( regularSty le);
int numLines = getNumLines();
for (int i = 0; i < numLines; i++)
{
char[] line = getLine(i).toCharArray();
int lineWidth = metricsComponent.getFontMe trics(font ).charsWid th(line, 0, line.length);
if (lineWidth > max)
max = lineWidth;
}
return max;
}
}
The implementation of getLongestLineWidth() above will not be sufficient for everyone. I only use a single (monospaced) font of a single size. If this is not the case for you, you will need to sum up the character width of each character on the line using the font metrics of that character's font.
I hope this helps... somebody... somewhere.
My getScrollableTracksViewpor
public boolean getScrollableTracksViewpor
{
if (getParent() instanceof JViewport)
{
if (getParent().getWidth() > document.getLongestLineWid
return true;
}
return false;
}
In the above code, document is a reference to a class that extends DefaultStyledDocument and implements the method getLongestLineWidth(). My implementation of that method is below. (It includes things that are not relevant to this issue, like the PropertyChangeListener and the modified flag. My appologies for this.)
import java.awt.Component;
import java.awt.Font;
import java.beans.PropertyChangeL
import java.beans.PropertyChangeS
import java.util.ArrayList;
import javax.swing.JPanel;
import javax.swing.text.Attribute
import javax.swing.text.BadLocati
import javax.swing.text.DefaultSt
import javax.swing.text.Style;
import javax.swing.text.StyleCons
import javax.swing.text.StyleCont
import org.apache.log4j.Logger;
/**
* This Document for the text editor's text area handles highlighting.
* @see javax.swing.text.PlainDocu
*/
public class TextEditorDocument extends DefaultStyledDocument implements LineNumberedDocument
{
private static final Logger logger = Logger.getLogger(TextEdito
public static final String FONT_NAME = "Monospaced";
public static final int FONT_SIZE = 12;
public static final String MODIFIED_PROPNAME = "modified";
public static final char NEW_LINE_CHAR = '\n';
public static final String NEW_LINE_STRING = "\n";
private static final Component metricsComponent = new JPanel();
private Style regularStyle = null;
private boolean modified = false;
/** An array of Integer objects that correspond to the offset for the start of each line */
protected ArrayList offsets = new ArrayList();
private PropertyChangeSupport changeSupport = null;
public TextEditorDocument()
{
Style _default = StyleContext.getDefaultSty
StyleConstants.setFontFami
StyleConstants.setFontSize
regularStyle = this.addStyle("regular", _default);
this.setLogicalStyle(0, regularStyle);
}
/**
* Updates the offsets of each line affected and then updates the syntax
* highlighting of those lines
* @see javax.swing.text.Document#
*/
public void insertString(int offs, String str, AttributeSet a) throws BadLocationException
{
if (str == null || str.length() == 0)
return;
int numLines = getNumLines();
super.insertString(offs, str, a);
setModified(true);
int startLineIndex = getLineIndex(offs);
int endLineIndex = updateOffsetsAfterInsert(o
if (numLines != getNumLines())
firePropertyChange(NUM_LIN
}
/**
* @see javax.swing.text.Document#
*/
public void remove(int offs, int len) throws BadLocationException
{
if (len <= 0)
return;
int numLines = getNumLines();
String removedText = this.getText(offs, len);
super.remove(offs, len);
setModified(true);
updateOffsetsAfterRemove(o
if (numLines != getNumLines())
firePropertyChange(NUM_LIN
}
/**
* Returns the index of the line in <code>lines</code> that corresponds
* to the specified offset in the document.
*/
protected int getLineIndex(int offset)
{
if (offsets.size() <= 1)
return 0;
int lineIndex = 0;
for (int i = 0; i < offsets.size(); i++)
{
if (i == offsets.size()-1)
return i;
int nextLineOffset = ((Integer)offsets.get(i+1)
if (offset < nextLineOffset)
return i;
}
throw new RuntimeException("shouldn'
}
/**
* Gets the text of the line at the specified index
* @param lineIndex the index of the line to return
*/
public String getLine(int lineIndex)
{
if (lineIndex < 0 || lineIndex >= offsets.size())
throw new IndexOutOfBoundsException(
int lineOffset = ((Integer)offsets.get(line
int lineLength = 0;
if (offsets.size() == lineIndex + 1)
lineLength = this.getLength() - lineOffset;
else
lineLength = ((Integer)offsets.get(line
try
{
return this.getText(lineOffset, lineLength);
}
catch (BadLocationException e)
{
logger.error("lineOffset="
" offsets.size()=" + offsets.size() + " lineIndex=" + lineIndex, e);
// since this method is only used internally, any error here is a
// coding error
throw new RuntimeException(e);
}
}
/**
* Returns the line number that corresponds to the specified offset. This
* is the same as the line index + 1.
* @param offset the location in the document
* @see #getLineIndex(int)
*/
public int getLineNumber(int offset)
{
return 1 + getLineIndex(offset);
}
/**
* Returns the character position relative to the line that corresponds
* to the specified offset.
* @param offset the location in the document
*/
public int getCharacterPosition(int offset)
{
int lineIndex = getLineIndex(offset);
int lineOffset = ((Integer)offsets.get(line
return 1 + offset - lineOffset;
}
/**
* Returns the number of lines of text in this document.
*/
public int getNumLines()
{
return offsets.size();
}
/**
* Returns the number of newline characters ('\n') that are found in the
* specified string.
*/
protected int countNewLines(String text)
{
int count = 0;
for (int i = 0; i < text.length(); i++)
{
if (text.charAt(i) == NEW_LINE_CHAR)
count++;
}
return count;
}
/**
* Updates <code>offsets</code> after a remove.
* @param offset the offset where the text was removed
* @param insertedText the removed text
*/
private void updateOffsetsAfterRemove(i
{
int interruptedLineIndex = getLineIndex(offset);
// remove offsets for newlines that were deleted
for (int i = countNewLines(removedText)
{
offsets.remove(interrupted
}
for (int i = interruptedLineIndex + 1; i < offsets.size(); i++)
{
int curOffset = ((Integer)offsets.get(i)).
offsets.set(i, new Integer(curOffset - removedText.length()));
}
}
/**
* Updates <code>offsets</code> after an insert.
* @param offset the offset where the text was inserted
* @param insertedText the inserted text
* @return the index of the last line that was modified by the insert
*/
private int updateOffsetsAfterInsert(i
{
if (offsets.size() == 0)
offsets.add(new Integer(0));
int interruptedLineIndex = getLineIndex(offset);
int startingOffset = ((Integer)offsets.get(inte
// increase the value of all the following offsets by the length
// of the inserted text
for (int i = interruptedLineIndex + 1; i < offsets.size(); i++)
{
int curOffset = ((Integer)offsets.get(i)).
offsets.set(i, new Integer(curOffset + insertedText.length()));
}
// add new offsets for the inserted text
int lineIndex = interruptedLineIndex + 1;
for (int indexOfNewLine = -1; indexOfNewLine + 1 < insertedText.length(); lineIndex++)
{
indexOfNewLine = insertedText.indexOf(NEW_L
if (indexOfNewLine == -1)
break;
offsets.add(lineIndex, new Integer(offset + indexOfNewLine + 1));
}
return lineIndex - 1;
}
/**
* Returns true if this document has been modified.
* @return the <code>modified</code> flag
*/
public boolean isModified()
{
return modified;
}
/**
* Sets the <code>modified</code> flag to the specified value.
*/
void setModified(boolean modified)
{
if (this.modified == modified)
return;
this.modified = modified;
firePropertyChange(TextEdi
}
/**
* Support for reporting bound property changes for Object properties.
* This method can be called when a bound property has changed and it will
* send the appropriate PropertyChangeEvent to any registered
* PropertyChangeListeners.
*
* @param propertyName the property whose value has changed
* @param oldValue the property's previous value
* @param newValue the property's new value
*/
protected void firePropertyChange(String propertyName, Object oldValue, Object newValue)
{
if (changeSupport == null)
return;
changeSupport.fireProperty
}
/**
* Adds a PropertyChangeListener to the listener list. The listener is
* registered for all bound properties of this class.
* If listener is null, no exception is thrown and no action is performed.
* @param propertyName the name of the property to listen on
* @param listener the PropertyChangeListener to be added
* @see #removePropertyChangeListe
*/
public synchronized void addPropertyChangeListener(
{
if (listener == null)
return;
if (changeSupport == null)
changeSupport = new PropertyChangeSupport(this
changeSupport.addPropertyC
}
/**
* Removes a PropertyChangeListener from the listener list. This method
* should be used to remove PropertyChangeListeners that were registered
* for all bound properties of this class.
* <p>
* If listener is null, no exception is thrown and no action is performed.
* @param propertyName the name of the property to listen on
* @param listener the PropertyChangeListener to be removed
* @see #addPropertyChangeListener
*/
public synchronized void removePropertyChangeListen
{
if (listener == null || changeSupport == null)
return;
changeSupport.removeProper
}
/**
* @see com.realvue.tools.textedit
*/
public int getLongestLineWidth()
{
int max = 0;
Font font = StyleContext.getDefaultSty
int numLines = getNumLines();
for (int i = 0; i < numLines; i++)
{
char[] line = getLine(i).toCharArray();
int lineWidth = metricsComponent.getFontMe
if (lineWidth > max)
max = lineWidth;
}
return max;
}
}
The implementation of getLongestLineWidth() above will not be sufficient for everyone. I only use a single (monospaced) font of a single size. If this is not the case for you, you will need to sum up the character width of each character on the line using the font metrics of that character's font.
I hope this helps... somebody... somewhere.
jTextArea.setWrapStyleWord
should do it...