synopsis: NullPointerException occurs in getCommittedTextLength method description: While the switch of Input Method Editor (IME) is ON, when some key is pressed, NullPointerException occurs each time. It occurs on J2SE 5.0_04, but it does not occur on J2SE 1.4.2. - STEPS TO FOLLOW TO REPRODUCE THE PROBLEM: E:\xiaojun\support\JTextField>java TextFieldTest ----- Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException at javax.swing.text.JTextComponent$InputMethodRequestsHandler.getCommittedTextLength(Unknown Source) at CustomTextField.isCommittedText(TextFieldTest.java:46) at CustomTextField.access$0(TextFieldTest.java:44) at CustomTextField$CustomDocumentAdapter.insertUpdate(TextFieldTest.java:54) at javax.swing.text.AbstractDocument.fireInsertUpdate(Unknown Source) at javax.swing.text.AbstractDocument.handleInsertString(Unknown Source) at javax.swing.text.AbstractDocument.insertString(Unknown Source) at javax.swing.text.PlainDocument.insertString(Unknown Source) at javax.swing.text.JTextComponent.replaceInputMethodText(Unknown Source) at javax.swing.text.JTextComponent.processInputMethodEvent(Unknown Source) at java.awt.Component.processEvent(Unknown Source) at java.awt.Container.processEvent(Unknown Source) at java.awt.Component.dispatchEventImpl(Unknown Source) at java.awt.Container.dispatchEventImpl(Unknown Source) at java.awt.Component.dispatchEvent(Unknown Source) at java.awt.EventQueue.dispatchEvent(Unknown Source) at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.run(Unknown Source) ----- I guess that getCommittedTextLength method has been modified in relation to BugID.5004088. As indicated by the last of [Evaluation] of this bug report, the idea of 'Position for the end of composedText' has been introduced from tiger-beta2 for BugID.5004088. And so, I guess that the implementation of getCommittedTextLength method has been changed according to the position. [BugID:5004088 REGRESSION: Delete composed text caused insertion of erroneous text] http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5004088 As the present inner implementation of JTextComponent, the position of ComposedText is determined after the event which notifies that the character has been inserted to the document is issued. ------JTextComponent SOURCE-------------------------- 3579 doc.insertString(caret.getDot(), composedTextContent, 3580 composedTextAttribute); 3581 composedTextStart = doc.createPosition(caret.getDot() - 3582 composedTextContent.length()); 3583 composedTextEnd = doc.createPosition(caret.getDot()); ----------------------------------------------------- When DocumentListener#insertUpdate was call-backed by the event, the position of ComposedText has not been determined yet. Consequently, when getCommittedTextLength method is invoked in DocumentListener#insertUpdate, I guess that NullPointerException occurs in the process of using the position of ComposedText in getCommittedTextLength method. - EXPECTED VERSUS ACTUAL BEHAVIOR: NullPoiterException does not occur like J2SE 1.4.2. - REPRODUCIBILITY: The following source code issues always NullPointerException when some key is pressed, while the switch of IME is ON. ---------- BEGIN SOURCE ---------- import java.awt.im.InputMethodRequests; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.SwingUtilities; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; public class TextFieldTest extends JFrame { public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { new TextFieldTest(); } }); } public TextFieldTest() { this.init(); this.setSize(150, 60); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); } private void init() { CustomTextField textField = new CustomTextField(); textField.setColumns(10); JPanel panel = new JPanel(); panel.add(textField); this.getContentPane().add(panel); } } class CustomTextField extends JTextField { public CustomTextField() { getDocument().addDocumentListener(new CustomDocumentAdapter()); } private boolean isCommittedText() { InputMethodRequests imr = getInputMethodRequests(); int committedTextLength = imr.getCommittedTextLength(); int textLength = getText().length(); return committedTextLength == textLength; } private class CustomDocumentAdapter implements DocumentListener { public void insertUpdate(DocumentEvent e) { System.out.println("insert"); isCommittedText(); } public void removeUpdate(DocumentEvent e) { System.out.println("remove"); isCommittedText(); } public void changedUpdate(DocumentEvent e) { System.out.println("change"); isCommittedText(); } } }
|