Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 4652358
Votes 1
Synopsis Using value of "line.separator" for line separator in TextArea fails.
Category java:classes_awt
Reported Against merlin-rc1
Release Fixed 1.4.2(mantis)
State 10-Fix Delivered, bug
Priority: 4-Low
Related Bugs 4666876 , 4697796
Submit Date 13-MAR-2002
Description




FULL PRODUCT VERSION :
java version "1.4.0-rc"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-rc-b91)
Java HotSpot(TM) Client VM (build 1.4.0-rc-b91, mixed mode)


FULL OPERATING SYSTEM VERSION :
Microsoft Windows 2000 [Version 5.00.2195]

A DESCRIPTION OF THE PROBLEM :
Using the value of the "line.separator" system property to
separate lines when appending to a TextArea causes the lines
to get all jumbled with the Java 1.4 appletviewer and with
the Java 1.4 Plug-in.  The problem does not occur when using
the appletviewer of Java 1.0.2, Java 1.1.8_008, Java
1.2.2_010, nor Java 1.3.1_02-b02.


REGRESSION.  Last worked in version 1.3.1

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Run the sample program below using the appletviewer.
2. Enter multiple lines of text into the text field, each
followed by the Enter key.
3. Look at the corresponding lines in the text area.


EXPECTED VERSUS ACTUAL BEHAVIOR :
If you typed:
  line1
  line2
  line3
you should see the following in the text area:
  line1
  line2
  line3

With Java 1.4, you instead see:
  lin
  lin
  line3e2e1

Note that the first line printed in the text area is the hex
value of the "line.separator" system property.


ERROR MESSAGES/STACK TRACES THAT OCCUR :
None.


This bug can be reproduced always.

---------- BEGIN SOURCE ----------
HTML for appletviewer:
----------------------
<html>
<head>
<title>TextArea Test</title>
</head>
<body>
<h1>TextArea Test</h1>
<applet code="Append.class" width="300" height="300">
</applet>
</body>
</html>

Java 1.0.2 source code:
-----------------------
import java.applet.*;
import java.awt.*;

public class Append extends Applet {
    private static final String LINE_SEPARATOR =
        System.getProperty("line.separator", "\n");
    private static final char[] DIGITS =
        {'0', '1', '2', '3', '4', '5', '6', '7',
         '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
    private static final Font FONT = new Font("Courier", Font.PLAIN, 13);

    private static final int NEW_LINE   = '\n';
    private static final int RETURN     = '\r';
    private static final int ESCAPE_KEY =   27;

    private TextArea  area;
    private TextField field;

    private static String hexEncode(byte[] bytes) {
        StringBuffer buffer = new StringBuffer(bytes.length * 2);
        for (int i = 0; i < bytes.length; i++) {
            byte b = bytes[i];
            buffer.append(DIGITS[(b & 0xF0) >> 4]);
            buffer.append(DIGITS[b & 0x0F]);
        }
        return buffer.toString();
    }

    public void init() {
        area  = new TextArea();
        field = new TextField();
        area.setFont(FONT);
        field.setFont(FONT);
        setLayout(new BorderLayout());
        add("Center", area);
        add("South", field);
        byte[] bytes = new byte[LINE_SEPARATOR.length()];
        LINE_SEPARATOR.getBytes(0, bytes.length, bytes, 0);
        area.appendText(hexEncode(bytes));
    }

    public void start() {
        field.requestFocus();
    }

    public boolean keyDown(Event event, int key) {
        boolean handled = false;
        if (event.target == field) {
            String text = field.getText();
            switch (key) {
                case NEW_LINE: case RETURN:
                    // area.appendText("\n" + text);
                    area.appendText(LINE_SEPARATOR + text);
                    field.setText("");
                    handled = true;
                    break;
                case ESCAPE_KEY:
                    field.setText("");
                    handled = true;
                    break;
            }
        }
        return handled;
    }
}

---------- END SOURCE ----------

CUSTOMER WORKAROUND :
Use "\n" for the line separator character, regardless of the
platform.
(Review ID: 139621) 
======================================================================
Work Around
N/A
Evaluation
I ran this with JDK1.4 FCS on Windows NT4 using appletviewer, and was not 
able to reproduce it.  

Here is the source code for /src/share/classes/java/awt/TextArea.appendText() 
It hasn't changed in almost four years.  

    /**
     * @deprecated As of JDK version 1.1,
     * replaced by <code>append(String)</code>.
     */
    public synchronized void appendText(String str) {
        if (peer != null) {
            insertText(str, getText().length());
        } else {
            text = text + str;
        }
    }

The peers of the textfield and textarea are not null according to some printlns 
I added to the test case.  AWT TextArea widgets are just standard win32 Rich 
Edit controls.  

Note: the line.separator value printed is 0D0A = \r\n.  

I tried changing the value of LINE_SEPARATOR to "\r\n" and that worked 
fine as well.  

 xxxxx@xxxxx  2002-03-13

I tried this on Win2K, and reproduced the failure.  Sigh.  

 xxxxx@xxxxx  2002-03-13

I added some printlns to the test case, and found that the length and caret 
position are different on win2k vs. winnt.  

These results are for typing 
line1 
line2 
line3

        if (event.target == field) {
            String text = field.getText();
            switch (key) {
                case NEW_LINE: case RETURN:
                    // area.appendText("\n" + text);
                    System.err.println("before length = " + area.getText().length());
                    System.err.println("before caret = " + area.getCaretPosition());
                    area.appendText(LINE_SEPARATOR + text);
                    System.err.println("after length = " + area.getText().length());
                    System.err.println("after caret = " + area.getCaretPosition());
                    field.setText("");
                    handled = true;
                    break;

Windows_NT
before length = 4
before caret = 4
after length = 11
after caret = 11
before length = 11
before caret = 11
after length = 18
after caret = 18
before length = 18
before caret = 18
after length = 25
after caret = 25
before length = 25
before caret = 25

Windows_2000
before length = 4
before caret = 4
after length = 10
after caret = 11
before length = 10
before caret = 11
after length = 16
after caret = 17
before length = 16
before caret = 17
after length = 22
after caret = 23
before length = 22
before caret = 23

I wonder if win2k handles the crlf like win9x does, rather than like winnt? 
I assume the problem is specific to the rich edit control we are using in 1.4, 
since it apparently doesn't happen with the common edit control we used in 
1.3.1.  

 xxxxx@xxxxx  2002-03-13

Tested Windows XP with 1.4.1 build 5.  It behaves the same as NT, not 2000.  
So the problem is on Win2K only.  

 xxxxx@xxxxx  2002-03-14





I think the problem is in the AwtTextCompoentn::AddCR method in
awt_TextComponent.cpp. If we look at the buffer before AddCR and after
AddCR we will see:

let's say we add "\r\nline1" then we will see:
\r    \n    l     i     n     e     1     \0
0D 00 0A 00 6C 00 69 00 6E 00 65 00 31 00 00 00

after AddCR we see:
\r    \r    \n    l     i     n     e     1     \0
0D 00 0D 00 0A 00 6C 00 69 00 6E 00 65 00 31 00 00 00

so, it adds one additional \r. The code in AddCR looks only for
presense of \n when it decides whether or not it is line
separator. But it doesn't ensure that it is already correctly (in
Win32 terms) formatted line separator. From one side, it is ok - line
separator for strings inside of java is unicode '\n' so we could
expect that we will receive text only with '\n's. But it will be
convenient to allow user to use '\r\n' as line separator as well. I
suggest this as the fix for this bug, see Suggested fix section for
diffs.
 xxxxx@xxxxx  2002-04-17

======================================================================




Please see an evaluation for 4701398.

 xxxxx@xxxxx  2002-08-01

======================================================================
Comments
  
  Include a link with my name & email   


PLEASE NOTE: JDK6 is formerly known as Project Mustang