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: 4834399
Votes 0
Synopsis invokeLater causes JScrollPane to scroll to bottom at creation
Category java:classes_swing
Reported Against 1.4.1
Release Fixed
State 11-Closed, duplicate of 4201999, bug
Priority: 4-Low
Related Bugs 4201999 , 4302560 , 4424708
Submit Date 19-MAR-2003
Description




FULL PRODUCT VERSION :
See System Info

Version = Sun ONE Studio 4u1 CE

EXTRA RELEVANT SYSTEM CONFIGURATION :
Product version SUN ONE Studio 4 update 1,
CE, Build 020923
IDE versioning IDE/1 spec=1.43.3.1 impl =
020923
OS Windows 2000 version 5.0 running on x86
Java 1.4.1
VM Java HotSpot Client VM 1.4.1-b21
System Locale: en_GB (f4j_ce)


A DESCRIPTION OF THE PROBLEM :
I have a problem that seems to be an invokeLater
bug. My intention is to have a simple dialog with
a scrollable textarea, where the scrollbar is at
the top when the dialog is opened. Because I
want a non-blocking modal dialog I am trying to
show the dialog using SwingUtilities.invokeLater.
The problem is, for some reason this causes the
scrollbar to start at the bottom of the textarea; if I
show the dialog without using invokeLater, the
scrollbar does start at the top. I have isolated
this behavior in the attached program code.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Execute the attached program with "if (true)"
in the main to experience the expected behavior
2. Execute the attached program with "if (false)"
in the main to experience the actual faulty
behavior

EXPECTED VERSUS ACTUAL BEHAVIOR :
Expected: scrollbar at the top
Actual: scrollbar at the bottom

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
/*
 * MessageDialog2.java
 *
 * Created on 16 December 2002, 16:22
 */

import java.awt.Frame;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

/**
 *
 * @author  smakmanc
 */
public class MessageDialog2 extends JDialog {
    
    /** Creates new form MessageDialog2 */
    public MessageDialog2() {
        super(new JFrame(), true);
        initComponents();
        detailsTextArea.setText
("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nn\n");
    }
    
    /** This method is called from within the
constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The
content of this method is
     * always regenerated by the Form Editor.
     */
    private void initComponents() {
        java.awt.GridBagConstraints
gridBagConstraints;

        mainPanel = new javax.swing.JPanel();
        messagePanel = new javax.swing.JPanel();
        detailsScrollPane = new
javax.swing.JScrollPane();
        detailsTextArea = new
javax.swing.JTextArea();

        addWindowListener(new
java.awt.event.WindowAdapter() {
            public void windowClosing
(java.awt.event.WindowEvent evt) {
                closeDialog(evt);
            }
        });

        mainPanel.setLayout(new
java.awt.BorderLayout());

        messagePanel.setLayout(new
java.awt.GridBagLayout());

        detailsScrollPane.setMaximumSize(new
java.awt.Dimension(80, 80));
        detailsScrollPane.setMinimumSize(new
java.awt.Dimension(0, 16));
        detailsScrollPane.setPreferredSize(new
java.awt.Dimension(80, 80));
        detailsScrollPane.setViewportView
(detailsTextArea);

        gridBagConstraints = new
java.awt.GridBagConstraints();
        gridBagConstraints.fill =
java.awt.GridBagConstraints.BOTH;
        messagePanel.add(detailsScrollPane,
gridBagConstraints);

        mainPanel.add(messagePanel,
java.awt.BorderLayout.CENTER);

        getContentPane().add(mainPanel,
java.awt.BorderLayout.CENTER);

        pack();
    }
    
    /** Closes the dialog */
    private void closeDialog
(java.awt.event.WindowEvent evt) {
        setVisible(false);
        dispose();
    }
    
    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        if (false) {
            new MessageDialog2().show();
        }
        else {
            SwingUtilities.invokeLater(new Runnable
() {
                public void run() {
                    new MessageDialog2().show();
                    System.exit(0);
                }
            });
        }
    }
    
    // Variables declaration - do not modify
    private javax.swing.JPanel messagePanel;
    private javax.swing.JTextArea detailsTextArea;
    private javax.swing.JScrollPane
detailsScrollPane;
    private javax.swing.JPanel mainPanel;
    // End of variables declaration
    
}

---------- END SOURCE ----------
(Review ID: 179166) 
======================================================================
Work Around
N/A
Evaluation




        The reason of such behavior is javax.swing.text.DefaultCaret.async
property. When JTextArea.setText() is invoked in DispatchThread the
caret updates its position due to DefaultCaret.UpdateHandler.insertUpdate()
and the text area scrolls to bottom. But when the setText() is invoked
from other thread the condition 
     if (async || SwingUtilities.isEventDispatchThread())
(in DefaultCaret.UpdateHandler.insertUpdate() method)
fails, the caret doesn't updates its position and thus remains on its
initial position (0).
    Think the 'async' property should be removed from DefaultCaret
since JTextComponent.setText() method is declared as 'thread safe'.
There should be another mechanism to enable/disable caret position
updates.



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




    Currently the new 'updatePolicy' property is added to the
DefaultCaret class (see the bug #4201999). It may control the
behavior of the caret (and therefore text component scrolling)
when the document mutates. The default caret behavior remains
the same because of compatibility reasons, but you may change
it by setting the 'updatePolicy' property.
    In the test case submitted you may position the caret
of the text area to the beginning of the text :
      detailsTextArea.setText("\n\n\n\n\n\n\n\n\n\n\n\n\n\");
      detailsTextArea.setCaretPosition(0);
or turn off caret updates
      ((DefaultCaret)detailsTextArea.getCaret()).setUpdatePolicy
             (DefaultCaret.NEVER_UPDATE);
      detailsTextArea.setText("\n\n\n\n\n\n\n\n\n\n\n\n\n\");
to avoid text area to scroll to the last line.
   Close this bug as duplicate.


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


PLEASE NOTE: JDK6 is formerly known as Project Mustang