--- old/src/macosx/classes/sun/lwawt/LWTextAreaPeer.java 2012-07-20 16:45:51.000000000 +0400 +++ new/src/macosx/classes/sun/lwawt/LWTextAreaPeer.java 2012-07-20 16:45:50.000000000 +0400 @@ -129,16 +129,6 @@ } @Override - public void setText(final String l) { - // Please note that we do not want to post an event - // if TextArea.setText() replaces an empty text by an empty text, - // that is, if component's text remains unchanged. - if (!l.isEmpty() || getTextComponent().getDocument().getLength() != 0) { - super.setText(l); - } - } - - @Override public void replaceRange(final String text, final int start, final int end) { synchronized (getDelegateLock()) { --- old/src/macosx/classes/sun/lwawt/LWTextComponentPeer.java 2012-07-20 16:45:52.000000000 +0400 +++ new/src/macosx/classes/sun/lwawt/LWTextComponentPeer.java 2012-07-20 16:45:51.000000000 +0400 @@ -126,6 +126,12 @@ @Override public void setText(final String l) { synchronized (getDelegateLock()) { + // Please note that we do not want to post an event + // if TextArea.setText() or TextField.setText() replaces an empty text by an empty text, + // that is, if component's text remains unchanged. + if (l.isEmpty() && getTextComponent().getDocument().getLength() == 0) { + return; + } // JTextArea.setText() posts two different events (remove & insert). // Since we make no differences between text events, // the document listener has to be disabled while --- old/src/solaris/classes/sun/awt/X11/XTextFieldPeer.java 2012-07-20 16:45:53.000000000 +0400 +++ new/src/solaris/classes/sun/awt/X11/XTextFieldPeer.java 2012-07-20 16:45:52.000000000 +0400 @@ -222,6 +222,12 @@ protected boolean setXAWTTextField(String txt) { text = txt; if (xtext != null) { + // Please note that we do not want to post an event + // if setText() replaces an empty text by an empty text, + // that is, if component's text remains unchanged. + if (xtext.getDocument().getLength() == 0 && txt.length() == 0) { + return true; + } // JTextField.setText() posts two different events (remove & insert). // Since we make no differences between text events, // the document listener has to be disabled while --- /dev/null 2012-07-20 16:45:54.000000000 +0400 +++ new/test/java/awt/event/TextEvent/TextEventSequenceTest/TextEventSequenceTest.java 2012-07-20 16:45:53.000000000 +0400 @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4028580 + * @summary TextArea does not send TextEvent when setText. Does for insert + * @author kdm@sparc.spb.su: area= awt.TextAvent + * @run main TextEventSequenceTest + */ +import java.awt.*; +import java.awt.event.*; +import sun.awt.SunToolkit; + +public class TextEventSequenceTest { + + private static Frame f; + private static TextField tf; + private static TextArea t; + private static int cntEmptyStrings = 0; + private static int cntNonEmptyStrings = 0; + + public static void main(String[] args) { + + test("non-empty text string"); + test(""); + test(null); + } + + private static void test(String test) { + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + + createAndShowGUI(test); + toolkit.realSync(); + + initCounts(); + t.setText("Hello "); + toolkit.realSync(); + t.append("World! !"); + toolkit.realSync(); + t.insert("from Roger Pham", 13); + toolkit.realSync(); + t.replaceRange("Java Duke", 18, 28); + toolkit.realSync(); + checkCounts(0, 4); + + initCounts(); + t.setText(""); + toolkit.realSync(); + t.setText(""); + toolkit.realSync(); + t.setText(""); + toolkit.realSync(); + checkCounts(1, 0); + + initCounts(); + tf.setText("Hello There!"); + toolkit.realSync(); + checkCounts(0, 1); + + initCounts(); + tf.setText(""); + toolkit.realSync(); + tf.setText(""); + toolkit.realSync(); + tf.setText(""); + toolkit.realSync(); + checkCounts(1, 0); + + f.dispose(); + } + + private static void createAndShowGUI(String text) { + f = new Frame("TextEventSequenceTest"); + f.setLayout(new FlowLayout()); + + TextListener listener = new MyTextListener(); + + tf = new TextField(text); + tf.addTextListener(listener); + f.add(tf); + + t = new TextArea(text, 10, 30); + t.addTextListener(listener); + f.add(t); + + f.pack(); + f.setVisible(true); + } + + static class MyTextListener implements TextListener { + + public synchronized void textValueChanged(TextEvent e) { + TextComponent tc = (TextComponent) e.getSource(); + String text = tc.getText(); + if (text.length() == 0) { + cntEmptyStrings++; + } else { + cntNonEmptyStrings++; + } + } + } + + synchronized static void initCounts() { + cntEmptyStrings = 0; + cntNonEmptyStrings = 0; + } + + synchronized static void checkCounts(int empty, int nonempty) { + if (empty != cntEmptyStrings || nonempty != cntNonEmptyStrings) { + throw new RuntimeException( + String.format("Expected events: empty = %d, nonempty = %d, " + + "actual events: empty = %d, nonempty = %d", + empty, nonempty, cntEmptyStrings, cntNonEmptyStrings)); + } + } +} +