Skip to content

Commit

Permalink
Merge pull request SKCraft#82 from seebs/master
Browse files Browse the repository at this point in the history
Avoid pathological failure mode when trimming lines.
  • Loading branch information
sk89q committed Aug 3, 2015
2 parents 454aa32 + 2a50a19 commit 40555cc
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 28 deletions.
26 changes: 17 additions & 9 deletions launcher/src/main/java/com/skcraft/launcher/swing/MessageLog.java
Original file line number Diff line number Diff line change
Expand Up @@ -111,21 +111,29 @@ public void clear() {
* @param line line
* @param attributes attribute set, or null for none
*/
public void log(String line, AttributeSet attributes) {
public void log(final String line, AttributeSet attributes) {
final Document d = document;
final JTextComponent t = textComponent;
if (colorEnabled) {
if (line.startsWith("(!!)")) {
attributes = highlightedAttributes;
}
}
final AttributeSet a = attributes;

try {
int offset = document.getLength();
document.insertString(offset, line,
(attributes != null && colorEnabled) ? attributes : defaultAttributes);
textComponent.setCaretPosition(document.getLength());
} catch (BadLocationException ble) {

}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
int offset = d.getLength();
d.insertString(offset, line,
(a != null && colorEnabled) ? a : defaultAttributes);
t.setCaretPosition(d.getLength());
} catch (BadLocationException ble) {

}
}
});
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
public class LimitLinesDocumentListener implements DocumentListener {
private int maximumLines;
private boolean isRemoveFromStart;
private volatile boolean isRemoving;

/**
* Specify the number of lines to be stored in the Document. Extra lines
Expand All @@ -34,6 +35,7 @@ public LimitLinesDocumentListener(int maximumLines,
boolean isRemoveFromStart) {
setLimitLines(maximumLines);
this.isRemoveFromStart = isRemoveFromStart;
this.isRemoving = false;
}

/**
Expand All @@ -54,12 +56,15 @@ public void insertUpdate(final DocumentEvent e) {
// Changes to the Document can not be done within the listener
// so we need to add the processing to the end of the EDT

SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
removeLines(e);
}
});
if (!this.isRemoving) {
this.isRemoving = true;
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
removeLines(e);
}
});
}
}

@Override
Expand All @@ -74,20 +79,25 @@ private void removeLines(DocumentEvent e) {
// The root Element of the Document will tell us the total number
// of line in the Document.

Document document = e.getDocument();
Element root = document.getDefaultRootElement();

while (root.getElementCount() > maximumLines) {
if (isRemoveFromStart) {
removeFromStart(document, root);
} else {
removeFromEnd(document, root);
try {
Document document = e.getDocument();
Element root = document.getDefaultRootElement();
int excess = root.getElementCount() - maximumLines;

if (excess > 0) {
if (isRemoveFromStart) {
removeFromStart(document, root, excess);
} else {
removeFromEnd(document, root);
}
}
} finally {
this.isRemoving = false;
}
}

private void removeFromStart(Document document, Element root) {
Element line = root.getElement(0);
private void removeFromStart(Document document, Element root, int excess) {
Element line = root.getElement(excess - 1);
int end = line.getEndOffset();

try {
Expand All @@ -101,14 +111,14 @@ private void removeFromEnd(Document document, Element root) {
// We use start minus 1 to make sure we remove the newline
// character of the previous line

Element line = root.getElement(root.getElementCount() - 1);
Element line = root.getElement(maximumLines);
int start = line.getStartOffset();
int end = line.getEndOffset();
int end = root.getEndOffset();

try {
document.remove(start - 1, end - start);
} catch (BadLocationException ble) {
System.out.println(ble);
}
}
}
}

0 comments on commit 40555cc

Please sign in to comment.