-
Bug
-
Resolution: Unresolved
-
P3
-
None
-
6
-
generic
-
generic
All Swing listeners must be notified on Event Dispatch Thread
please see http://java.sun.com/products/jfc/tsc/articles/threads/threads3.html
"Swing components will generally not comply with the single-thread rule unless all their events are sent and received on the event-dispatch thread. For example, property-change events should be sent on the event-dispatch thread, and model-change events should be received on the event-dispatch thread."
But following example shows that document listener notifications clearly break this rule
(don't forget to set proxy settings properly)
Current behaviour:
DocumentListener notifications are sent from the wrong thread
Expected behaviour:
DocumentListener notifications must be sent from Event Dispatch Thread only
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.Document;
import javax.swing.text.html.HTMLEditorKit;
import java.awt.*;
import java.io.IOException;
import java.net.URL;
import java.util.Properties;
/** @author JohnM */
public class EditorPaneEDTViolation extends JFrame{
static JEditorPane msgArea;
public EditorPaneEDTViolation() {
setTitle("EDT Violations R Us");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
msgArea = new JEditorPane();
JPanel p = new JPanel();
p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
p.add(msgArea);
add(p, BorderLayout.CENTER);
setBounds(100, 100, 800, 600);
}
public static void main(String[] args) {
Properties systemproperties = System.getProperties();
systemproperties.put("proxyHost",
"yourcache");// http proxy server
systemproperties.put("proxyPort",
"80"); // http port #
systemproperties.put("proxySet","true");
System.setProperties(systemproperties);
EventQueue.invokeLater(new Runnable(){
public void run(){
final EditorPaneEDTViolation epv = new EditorPaneEDTViolation();
epv.setVisible(true);
try {
msgArea.setEditorKit(new HTMLEditorKit() {
public Document createDefaultDocument() {
Document doc = super.createDefaultDocument();
doc.addDocumentListener(new DocumentListener() {
public void insertUpdate(DocumentEvent e) {
if (!SwingUtilities.isEventDispatchThread()) {
System.out.println("Error !!!");
}
}
public void removeUpdate(DocumentEvent e) {
if (!SwingUtilities.isEventDispatchThread()) {
System.out.println("Error !!!");
}
}
public void changedUpdate(DocumentEvent e) {
if (!SwingUtilities.isEventDispatchThread()) {
System.out.println("Error !!!");
}
}
});
return doc;
}
});
msgArea.setPage(new URL("http://www.google.com"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
}
}
please see http://java.sun.com/products/jfc/tsc/articles/threads/threads3.html
"Swing components will generally not comply with the single-thread rule unless all their events are sent and received on the event-dispatch thread. For example, property-change events should be sent on the event-dispatch thread, and model-change events should be received on the event-dispatch thread."
But following example shows that document listener notifications clearly break this rule
(don't forget to set proxy settings properly)
Current behaviour:
DocumentListener notifications are sent from the wrong thread
Expected behaviour:
DocumentListener notifications must be sent from Event Dispatch Thread only
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.Document;
import javax.swing.text.html.HTMLEditorKit;
import java.awt.*;
import java.io.IOException;
import java.net.URL;
import java.util.Properties;
/** @author JohnM */
public class EditorPaneEDTViolation extends JFrame{
static JEditorPane msgArea;
public EditorPaneEDTViolation() {
setTitle("EDT Violations R Us");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
msgArea = new JEditorPane();
JPanel p = new JPanel();
p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
p.add(msgArea);
add(p, BorderLayout.CENTER);
setBounds(100, 100, 800, 600);
}
public static void main(String[] args) {
Properties systemproperties = System.getProperties();
systemproperties.put("proxyHost",
"yourcache");// http proxy server
systemproperties.put("proxyPort",
"80"); // http port #
systemproperties.put("proxySet","true");
System.setProperties(systemproperties);
EventQueue.invokeLater(new Runnable(){
public void run(){
final EditorPaneEDTViolation epv = new EditorPaneEDTViolation();
epv.setVisible(true);
try {
msgArea.setEditorKit(new HTMLEditorKit() {
public Document createDefaultDocument() {
Document doc = super.createDefaultDocument();
doc.addDocumentListener(new DocumentListener() {
public void insertUpdate(DocumentEvent e) {
if (!SwingUtilities.isEventDispatchThread()) {
System.out.println("Error !!!");
}
}
public void removeUpdate(DocumentEvent e) {
if (!SwingUtilities.isEventDispatchThread()) {
System.out.println("Error !!!");
}
}
public void changedUpdate(DocumentEvent e) {
if (!SwingUtilities.isEventDispatchThread()) {
System.out.println("Error !!!");
}
}
});
return doc;
}
});
msgArea.setPage(new URL("http://www.google.com"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
}
}