Thursday, May 6, 2010

DefaultStyledDocument.styleChanged(Style style) may not run in a timely manner

Programmer Question


I'm experiencing an intermittent problem with a class that extends javax.swing.text.DefaultStyledDocument. This document is being sent to a printer. Most of the time the formatting of the document looks correct, but once in a while it doesn't. It looks like some of the changes in the formatting have not been applied.



I took a look at the DefaultStyledDocument.styleChanged(Style style) code:



/**
* Called when any of this document's styles have changed.
* Subclasses may wish to be intelligent about what gets damaged.
*
* @param style The Style that has changed.
*/
protected void styleChanged(Style style) {
// Only propagate change updated if have content
if (getLength() != 0) {
// lazily create a ChangeUpdateRunnable
if (updateRunnable == null) {
updateRunnable = new ChangeUpdateRunnable();
}

// We may get a whole batch of these at once, so only
// queue the runnable if it is not already pending
synchronized(updateRunnable) {
if (!updateRunnable.isPending) {
SwingUtilities.invokeLater(updateRunnable);
updateRunnable.isPending = true;
}
}
}
}

/**
* When run this creates a change event for the complete document
* and fires it.
*/
class ChangeUpdateRunnable implements Runnable {
boolean isPending = false;

public void run() {
synchronized(this) {
isPending = false;
}

try {
writeLock();
DefaultDocumentEvent dde = new DefaultDocumentEvent(0,
getLength(),
DocumentEvent.EventType.CHANGE);
dde.end();
fireChangedUpdate(dde);
} finally {
writeUnlock();
}
}
}


Does the fact that SwingUtilities.invokeLater(updateRunnable) is called, rather than invokeAndWait(updateRunnable), mean that I can't count on my formatting changes appearing in the document before it is rendered?



If that is the case, is there a way to ensure that I don't proceed with rendering until the updates have occurred?





Find the answer here

No comments:

Post a Comment

LinkWithin

Related Posts with Thumbnails