[snow-cvs] r75 - trunk/src/java/snow/swing
Alessio Stalla
astalla at common-lisp.net
Thu Apr 15 20:50:45 UTC 2010
Author: astalla
Date: Thu Apr 15 16:50:45 2010
New Revision: 75
Log:
ConsoleDocument should now be thread-safe: the user input buffer is always kept at the end
of the document, so multiple threads cannot accidentally cause the buffer position to be miscalculated.
Modified:
trunk/src/java/snow/swing/ConsoleDocument.java
Modified: trunk/src/java/snow/swing/ConsoleDocument.java
==============================================================================
--- trunk/src/java/snow/swing/ConsoleDocument.java (original)
+++ trunk/src/java/snow/swing/ConsoleDocument.java Thu Apr 15 16:50:45 2010
@@ -59,32 +59,28 @@
public class ConsoleDocument extends DefaultStyledDocument {
- private int lastEditableOffset = 0;
- private StringBuffer inputBuffer = new StringBuffer();
+ private StringBuffer inputBuffer = new StringBuffer();
- private Reader reader = new Reader() {
+ private Reader reader = new Reader() {
- @Override
- public void close() throws IOException {
- }
+ @Override
+ public void close() throws IOException {}
- @Override
- public synchronized int read(char[] cbuf, int off, int len) throws IOException {
- try {
- int length = Math.min(inputBuffer.length(), len);
- while(length <= 0) {
- wait();
- length = Math.min(inputBuffer.length(), len);
- }
- inputBuffer.getChars(0, length, cbuf, off);
- inputBuffer.delete(0, length);
- lastEditableOffset += length;
- return length;
- } catch (InterruptedException e) {
- throw new IOException(e);
- }
-
+ @Override
+ public synchronized int read(char[] cbuf, int off, int len) throws IOException {
+ try {
+ int length = Math.min(inputBuffer.length(), len);
+ while(length <= 0) {
+ wait();
+ length = Math.min(inputBuffer.length(), len);
+ }
+ inputBuffer.getChars(0, length, cbuf, off);
+ inputBuffer.delete(0, length);
+ return length;
+ } catch (InterruptedException e) {
+ throw new IOException(e);
}
+ }
};
private Writer writer = new Writer() {
@@ -97,27 +93,32 @@
@Override
public void write(final char[] cbuf, final int off, final int len) throws IOException {
- synchronized(reader) {
- try {
+ try {
+ final int insertOffs;
+ synchronized(reader) {
if(inputBuffer.toString().trim().isEmpty()) {
int length = inputBuffer.length();
inputBuffer.delete(0, length);
- lastEditableOffset -= length;
}
- SwingUtilities.invokeAndWait(new Runnable() {
- public void run() {
+ insertOffs = getLength() - inputBuffer.length();
+ reader.notifyAll();
+ }
+ Runnable r = new Runnable() {
+ public void run() {
+ synchronized(reader) {
try {
- superInsertString(getLength(), new String(cbuf, off, len), null);
+ superInsertString(insertOffs,
+ new String(cbuf, off, len),
+ null);
} catch(Exception e) {
assert(false); //BadLocationException should not happen here
}
}
- });
- lastEditableOffset = getLength();
- reader.notifyAll();
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
+ }
+ };
+ SwingUtilities.invokeAndWait(r);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
}
}
};
@@ -139,26 +140,27 @@
};
replThread.start();
}
-
- @Override
- public void insertString(int offs, String str, AttributeSet a)
- throws BadLocationException {
- if(offs < lastEditableOffset) {
- throw new BadLocationException("Can only insert after " + lastEditableOffset, offs);
- }
- synchronized(reader) {
- superInsertString(offs, str, a);
- inputBuffer.insert(offs - lastEditableOffset, str);
- if(processInputP(inputBuffer, str)) {
- reader.notifyAll();
- }
- }
+
+ @Override
+ public void insertString(int offs, String str, AttributeSet a)
+ throws BadLocationException {
+ synchronized(reader) {
+ int bufferStart = getLength() - inputBuffer.length();
+ if(offs < bufferStart) {
+ throw new BadLocationException("Can only insert after " + bufferStart, offs);
+ }
+ superInsertString(offs, str, a);
+ inputBuffer.insert(offs - bufferStart, str);
+ if(processInputP(inputBuffer, str)) {
+ reader.notifyAll();
+ }
}
+ }
- protected void superInsertString(int offs, String str, AttributeSet a)
+ protected void superInsertString(int offs, String str, AttributeSet a)
throws BadLocationException {
- super.insertString(offs, str, a);
- }
+ super.insertString(offs, str, a);
+ }
/**
* Guaranteed to run with exclusive access to the buffer.
@@ -185,16 +187,17 @@
return parenCount <= 0;
}
- @Override
- public void remove(int offs, int len) throws BadLocationException {
- if(offs < lastEditableOffset) {
- throw new BadLocationException("Can only remove after " + lastEditableOffset, offs);
- }
- super.remove(offs, len);
- synchronized(reader) {
- inputBuffer.delete(offs - lastEditableOffset, offs - lastEditableOffset + len);
- }
+ @Override
+ public void remove(int offs, int len) throws BadLocationException {
+ synchronized(reader) {
+ int bufferStart = getLength() - inputBuffer.length();
+ if(offs < bufferStart) {
+ throw new BadLocationException("Can only remove after " + bufferStart, offs);
+ }
+ super.remove(offs, len);
+ inputBuffer.delete(offs - bufferStart, offs - bufferStart + len);
}
+ }
public Reader getReader() {
return reader;
More information about the snow-cvs
mailing list