-
Bug
-
Resolution: Duplicate
-
P4
-
None
-
1.3.0
-
generic
-
generic
Name: bsC130419 Date: 06/29/2001
C:\>java -version
java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)
Due to the way in which DefaultCaret attempts to scroll itself into view, there
are some unusual behaviors that occur when updating viewports that contain
multi-line text components (such as JTextArea). The protected method
adjustVisibility(Rectangle nloc) is called when the text area is modified,
which causes the scroll pane to scroll to each text area in the viewport. This
behavior is especially noticeable when information in the text area changes
asynchronously or programmatically.
The following code illustrates this behavior:
------------------------------8<-------------------------------
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
public class ScrollTest extends JFrame implements ChangeListener
{
JTextArea area1 = new JTextArea("1", 8, 20);
JTextArea area2 = new JTextArea("2", 8, 20);
JTextArea area3 = new JTextArea("3", 8, 20);
JScrollPane scrollPane = new JScrollPane();
public ScrollTest()
{
this.setLocation(100, 100);
this.setSize(300, 300);
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = GridBagConstraints.RELATIVE;
panel.add(area1, gbc);
panel.add(area2, gbc);
panel.add(area3, gbc);
scrollPane.setViewportView(panel);
scrollPane.getVerticalScrollBar().getModel().addChangeListener(this);
this.getContentPane().add(scrollPane, BorderLayout.CENTER);
JButton button = new JButton("update");
this.getContentPane().add(button, BorderLayout.SOUTH);
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
area1.setText("1\n\n\n\n\n\n\n\n\n\n\n\nWahhoooo!");
area2.setText("2\n\n\n\n\n\n\n\n\n\n\n\nWahhoooo!");
area3.setText("3\n\n\n\n\n\n\n\n\n\n\n\nWahhoooo!");
}
});
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void stateChanged(ChangeEvent event)
{
System.out.println(scrollPane.getVerticalScrollBar().getModel());
}
public static void main(String[] args)
{
new ScrollTest().setVisible(true);
}
}
------------------------------8<-------------------------------
Clicking the button will cause the viewport to scroll such that the last line
of the bottom-most text area is visible. Note that the individual JTextArea
components are NOT in JScrollPane containers.
The output from the console is this:
javax.swing.DefaultBoundedRangeModel[value=0, extent=243, min=0, max=408,
adj=false]
javax.swing.DefaultBoundedRangeModel[value=0, extent=243, min=0, max=663,
adj=false]
javax.swing.DefaultBoundedRangeModel[value=199, extent=243, min=0, max=663,
adj=false]
javax.swing.DefaultBoundedRangeModel[value=420, extent=243, min=0, max=663,
adj=false]
This shows the problem in its essence. The last three model changes are caused
by the DefaultCaret class when it detects a change in the text component and
attempts to scroll the viewport so the changed component is visible. This
wreaks havoc since it will cause the viewport to scroll even if someone is
doing data entry in another field. The adjustments are asynchronous and
controlled by inaccessible methods in DefaultCaret.
I have come up with two workarounds. Simplest is to enclose all of the
JTextAreas in a JScrollPane. This seemed a little draconian, so I tried
another route. By extending DefaultCaret, I was able to skirt the problem
sufficiently:
------------------------------8<-------------------------------
area1.setCaret(new NoScrollCaret());
area2.setCaret(new NoScrollCaret());
area3.setCaret(new NoScrollCaret());
.
.
class NoScrollCaret extends DefaultCaret
{
protected void adjustVisibility(Rectangle rect)
{
JTextComponent component = this.getComponent();
if (component.getParent().getClass() == JViewport.class)
super.adjustVisibility(rect);
}
}
------------------------------8<-------------------------------
In this manner, if the immediate parent of a text component is not a viewport,
the adjustment is not made.
(Review ID: 127325)
======================================================================
- duplicates
-
JDK-4201999 JTextArea's don't automatically scroll when appending() to them.
-
- Resolved
-
- relates to
-
JDK-4846173 TEST_BUG: Regression test javax/swing/text/DefaultCaret/4476714/bug4476714.java
-
- Closed
-