Re: Why replaceSelection in JTextPane is not behaving safely?
 
lenyado wrote:
The problem is that it seems to work perfectly
right but then it hangs. I have no idea what goes wrong, as when I
debug it in the Eclipse, all the thread are still in running status.
-- Class TextConsole.java --
For future reference, don't indent code examples for Usenet with TAB 
characters.  Use a maximum of four spaces for indentation.
import ...
imports and comments elided for brevity.
class TextConsole extends JTextPane {
It's usually a good idea, especially when first learning Java, to declare 
classes 'public'.
    
private static final long serialVersionUID = -5329149879890129297L;
    private static final int DEFAULT_FONT_SIZE = 20;
    private static final String DEFAULT_FONT_NAME = "Courier New";
    private static final int DEFAULT_WIDTH_CHARS = 80;
    private static final int DEFAULT_HEIGHT_CHARS = 25;
    private static final Color DEFAULT_BACKGROUND_COLOR = Color.BLACK;
    private static final Color DEFAULT_FOREGROUND_COLOR = Color.WHITE;
    private Font font = null;
It isn't necessary to initialize member variables to 'null'; it only makes the 
same initialization happen twice.
    
private int lastSubmitKey = -1;
    private StringBuffer clearBuffer;
    private String blankLine = null;
    private int[] submitKeys = new int[0];
    private Color backgroundColor, foregroundColor;
    private volatile boolean finished = false;
It isn't necessary to initialize member variables to 'false'; it only makes 
the same initialization happen twice.
    
MutableAttributeSet attrs = getInputAttributes();
It is necessary to declare 'getInputAttributes()'.
    
int widthChars = DEFAULT_WIDTH_CHARS;
    int heightChars = DEFAULT_HEIGHT_CHARS;
    /**
     * Maximum number of characters that will hold
     * in the console window == width * height
     */
    int maxLength = pointToInt(widthChars, heightChars);
Bear in mind that this method call will use the default values for 
'widthChars' and 'heightChars', that is, 'DEFAULT_WIDTH_CHARS' and 
'DEFAULT_HEIGHT_CHARS', respectively.  It will not use the values that are set 
later by the constructor.  One wonders why you set this value twice, once here 
and another time in the explicit constructor.
... 
    public TextConsole(int width, int height, int fontSize, String
fontName, Color backgroundColor, Color foregroundColor) {
        this.font = new Font(fontName, Font.PLAIN, fontSize);
        this.widthChars = width;
        this.heightChars = height;
        this.backgroundColor = backgroundColor;
        this.foregroundColor = foregroundColor;
        this.maxLength = pointToInt(widthChars, heightChars);
        setFont(font);
        FontRenderContext fontRenderContext = new FontRenderContext(null,
false, true);
        Rectangle2D stringBounds = font.getStringBounds(new char[] { 'W' },
0, 1, fontRenderContext);
        setPreferredSize(new Dimension(
                (int) (5+ (widthChars + 1) * stringBounds.getWidth()),
                (int) (5+ (heightChars + 1) * stringBounds.getHeight())));
        setForeground(this.foregroundColor);
        setBackground(this.backgroundColor);
        setCaretColor(this.foregroundColor);
        clearBuffer = new StringBuffer();
        for (int j = 0; j < heightChars; j++) {
            for (int i = 0; i < widthChars; i++) {
                clearBuffer.append(" ");
            }
            if (j < heightChars - 1) {
                clearBuffer.append("\n");
            }
        }
        fill();
    }
    private void fill() {
        setText(clearBuffer.toString());
        StyleConstants.setBackground(attrs, backgroundColor);
        StyleConstants.setForeground(attrs, foregroundColor);
        StyleConstants.setUnderline(attrs, false);
        getStyledDocument().setCharacterAttributes(0, maxLength, attrs,
true);
    }
    private int pointToInt(int i, int j) {
        if (i < 0 || i > widthChars || j < 0 || j > heightChars)
            return 0;
Aside from the fact that you should have braces around the body part of the 
'if', if the width x length were zero then you'd be returning an illegal 
location in your int, because the position (0) is >= the length (0).  Hmm, 
your error message says that the problem is an 
"ArrayIndexOutOfBoundsException: 0 >= 0".  Coincidence?
        
int ret = ((j -1 ) * (widthChars + 1)) + (i - 1);
        return ret;
    }
...
John B. Matthews already pointed out that you need to do all GUI work on the 
EDT, and where to learn what that means.  As to your concern that "there seems 
  [sic] no tools that I can used [sic] to debug the program (such as dump the 
JVM status)", Eclipse has those tools.  It certainly has, as John said, 
"useful displays of the JVM's threads and the call stack in each."
-- 
Lew