-
Bug
-
Resolution: Unresolved
-
P4
-
None
-
6
-
x86
-
generic
We have noticed a problem that can arise when using an AWT text field and the input method editor and running in a Japanese environment. The problem is reproduced in the attached sample program. We want the text field to hold not more than a certain number of bytes (9 in the sample program), a check we need to make due to the way certain data is subsequently stored in a database.
In using this program, our most easily explained test runs uses double wide ASCII characters in the Japanese Windows environment. The problem reported by the customer involves Japanese characters, but to make it easier for us to observe and report our results, we use double width ASCII characters.
Suppose we have the text field "essentially full", having input 4 double-width ASCII characters (e.g., "abcd"). If you place the cursor between the second and third characters (between b and c), and try to enter a single character with the input method editor (e.g, "e"), when you press Enter to commit the change to the text field, the field will revert to "abcd" because there is no room for the new, double-wide character. Things will behave similarly if you try to enter a pair of double-wide characters (e.g., "ef"). If you try to enter a longer string, however, problems arise. If you try to enter 3 double-width ASCII characters (e.g., "efg"), when you press Enter to commit the change, the field will change to "aaeb". This behavior is incorrect, and gets even more unusual with longer input strings and larger field sizes. We have seen no way to deal with this unusual interaction between Java and the Input Method Editor.
DESCRIPTIONEND
TESTCASEBEGIN
//
// Class : TestAwt
// Test for AWT input check
//
// Created 2002.2.13 by Takeo Kobayashi
//
import java.awt.*;
import java.awt.event.*;
public class TestAwt extends Frame {
TextField tf;
// for debug
static int evNo = 0;
static TextArea ta;
static int getByteLength( String text ) {
try {
return text.getBytes( "EUC-JP" ).length;
}
catch ( java.io.UnsupportedEncodingException ex ) {
ex.printStackTrace();
}
return -1;
}
static String acceptableText( String text, int caret, int maxBytes ) {
StringBuffer str = new StringBuffer( text.substring( 0, caret ) );
String tail = text.substring( caret );
int len = str.length();
int headMax = maxBytes - getByteLength( tail );
while( getByteLength( str.toString() ) > headMax ) {
str.deleteCharAt( --len );
}
return str.toString() + tail;
}
static class TextLengthListener implements TextListener {
private int textMax;
TextLengthListener( int max ) {
textMax = max;
}
public void textValueChanged( TextEvent e ) {
Object source = e.getSource();
if ( ! (source instanceof TextComponent) ) return;
TextComponent tc = (TextComponent)source;
String newText = tc.getText();
int caret = tc.getCaretPosition();
// for debug
ta.append( " " + (++evNo) + " : " + e.paramString() + " " +
+ caret + " -> " + newText + "\n" );
int byteLen = getByteLength( newText );
if ( textMax < byteLen ) {
int caretPosFromEnd = newText.length() - caret;
newText = acceptableText( newText, caret, textMax );
tc.setText( newText );
tc.setCaretPosition( newText.length() - caretPosFromEnd );
Toolkit.getDefaultToolkit().beep();
}
}
}
public TestAwt() {
super( "Test input check with AWT" );
setSize( 500, 300 );
setLayout( new FlowLayout() );
addWindowListener( new WindowAdapter() {
public void windowClosing( WindowEvent e ) {
System.exit( 0 );
}
} );
int textMax = 9;
add( new Label( "Input test (max. " + textMax + " bytes)" ) );
tf = new TextField( "Test", 10 );
tf.addTextListener( new TextLengthListener( textMax ) );
add( tf );
// for debug
ta = new TextArea( "From test event :\n" );
add( ta );
}
public static void main( String[] args ) {
new TestAwt().show();
}
}
TESTCASEEND
In using this program, our most easily explained test runs uses double wide ASCII characters in the Japanese Windows environment. The problem reported by the customer involves Japanese characters, but to make it easier for us to observe and report our results, we use double width ASCII characters.
Suppose we have the text field "essentially full", having input 4 double-width ASCII characters (e.g., "abcd"). If you place the cursor between the second and third characters (between b and c), and try to enter a single character with the input method editor (e.g, "e"), when you press Enter to commit the change to the text field, the field will revert to "abcd" because there is no room for the new, double-wide character. Things will behave similarly if you try to enter a pair of double-wide characters (e.g., "ef"). If you try to enter a longer string, however, problems arise. If you try to enter 3 double-width ASCII characters (e.g., "efg"), when you press Enter to commit the change, the field will change to "aaeb". This behavior is incorrect, and gets even more unusual with longer input strings and larger field sizes. We have seen no way to deal with this unusual interaction between Java and the Input Method Editor.
DESCRIPTIONEND
TESTCASEBEGIN
//
// Class : TestAwt
// Test for AWT input check
//
// Created 2002.2.13 by Takeo Kobayashi
//
import java.awt.*;
import java.awt.event.*;
public class TestAwt extends Frame {
TextField tf;
// for debug
static int evNo = 0;
static TextArea ta;
static int getByteLength( String text ) {
try {
return text.getBytes( "EUC-JP" ).length;
}
catch ( java.io.UnsupportedEncodingException ex ) {
ex.printStackTrace();
}
return -1;
}
static String acceptableText( String text, int caret, int maxBytes ) {
StringBuffer str = new StringBuffer( text.substring( 0, caret ) );
String tail = text.substring( caret );
int len = str.length();
int headMax = maxBytes - getByteLength( tail );
while( getByteLength( str.toString() ) > headMax ) {
str.deleteCharAt( --len );
}
return str.toString() + tail;
}
static class TextLengthListener implements TextListener {
private int textMax;
TextLengthListener( int max ) {
textMax = max;
}
public void textValueChanged( TextEvent e ) {
Object source = e.getSource();
if ( ! (source instanceof TextComponent) ) return;
TextComponent tc = (TextComponent)source;
String newText = tc.getText();
int caret = tc.getCaretPosition();
// for debug
ta.append( " " + (++evNo) + " : " + e.paramString() + " " +
+ caret + " -> " + newText + "\n" );
int byteLen = getByteLength( newText );
if ( textMax < byteLen ) {
int caretPosFromEnd = newText.length() - caret;
newText = acceptableText( newText, caret, textMax );
tc.setText( newText );
tc.setCaretPosition( newText.length() - caretPosFromEnd );
Toolkit.getDefaultToolkit().beep();
}
}
}
public TestAwt() {
super( "Test input check with AWT" );
setSize( 500, 300 );
setLayout( new FlowLayout() );
addWindowListener( new WindowAdapter() {
public void windowClosing( WindowEvent e ) {
System.exit( 0 );
}
} );
int textMax = 9;
add( new Label( "Input test (max. " + textMax + " bytes)" ) );
tf = new TextField( "Test", 10 );
tf.addTextListener( new TextLengthListener( textMax ) );
add( tf );
// for debug
ta = new TextArea( "From test event :\n" );
add( ta );
}
public static void main( String[] args ) {
new TestAwt().show();
}
}
TESTCASEEND