JDK-4253904 : TextField.select() leaves caretPosition in different states depending on OS
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 1.1.8
  • Priority: P4
  • Status: Closed
  • Resolution: Cannot Reproduce
  • OS: windows_nt
  • CPU: x86
  • Submitted: 1999-07-14
  • Updated: 2020-11-06
  • Resolved: 2020-11-06
Related Reports
Relates :  
Description
After TextField.select() is called, a TextField is left in a different state on Win32 than it is on Solaris.  

On Solaris after TextField.select() is called, getCaretPosition() returns the index of the end of the selection.  

However on Win32, after TextField.select() is called, getCaretPosition() returns the index of the beginning of the selection.  This is in direct contradiction to what is seen on the screen; the insert cursor can be seen flashing at the end of the selection rather than the beginning.  

Using Swing components, the behavior seems to be resolved - it is identical on Win32 and Solaris.  After JTextField.select() is called, getCaretPosition() returns the index of the end of the selection, which is correct behavior since that's the same index as the visible flashing cursor.

Run the test case TFBehavior.java under Win32 and Solaris to see the behavior difference.  To duplicate the bug, simply click on the "Select(10,...)" button and then on the "Print Values" button and observe the caret position that is printed.  A second test case JTFBehavior.java can also be found below, to demonstrate that there is no behavior difference for Swing components.


//-----------------------TFBehavior.java----------------------------
import java.awt.*;
import java.awt.event.*;

public class TFBehavior
{
    Frame f;
    TextField tf;
    TextField tf2;
    Button b1, b2, b3, b4, b5;

    public static void main(String[] args) {
        new TFBehavior();
    }

    public TFBehavior() {
        f = new Frame("TextField Behavior Test");
        f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        tf = new TextField("Check textfield behavior");

        b1 = new Button("Select(0,0)");
        b1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                tf.select(0,0);
                tf.requestFocus();
            }
        });
        b2 = new Button("Select(10,...)");
        b2.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                tf.select(10,tf.getText().length());
                tf.requestFocus();
            }
        });
        b3 = new Button("Cursor=0");
        b3.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                tf.setCaretPosition(0);
                tf.requestFocus();
            }
        });
        b4 = new Button("Cursor=10");
        b4.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                tf.setCaretPosition(10);
                tf.requestFocus();
            }
        });
        b5 = new Button("Print Values");
        b5.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.out.println("Caret=" + tf.getCaretPosition() +
                        ", Selection=" + tf.getSelectionStart() +
                        "," + tf.getSelectionEnd());
            }
        });

        tf2 = new TextField("Change text here and hit <return>");
        tf2.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                tf.setText(tf2.getText());
                tf.requestFocus();
            }
        });

        Panel p1 = new Panel();
        p1.setLayout(new GridLayout(1,5));
        p1.add(b1);
        p1.add(b2);
        p1.add(b3);
        p1.add(b4);
        p1.add(b5);

        f.setLayout(new GridLayout(3,1));
        f.add(tf);
        f.add(p1);
        f.add(tf2);

        f.pack();
        f.setVisible(true);
    }
}



//----------------------------JTFBehavior.java-----------------------------
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class JTFBehavior
{
    JFrame f;
    JTextField tf;
    JTextField tf2;
    JButton b1, b2, b3, b4, b5;

    public static void main(String[] args) {
        new JTFBehavior();
    }

    public JTFBehavior() {
        f = new JFrame("TextField Behavior Test");
        f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        tf = new JTextField("Check textfield behavior");

        b1 = new JButton("Select(0,0)");
        b1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                tf.select(0,0);
                tf.requestFocus();
            }
        });
        b2 = new JButton("Select(10,...)");
        b2.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                tf.select(10,tf.getText().length());
                tf.requestFocus();
            }
        });
        b3 = new JButton("Cursor=0");
        b3.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                tf.setCaretPosition(0);
                tf.requestFocus();
            }
        });
        b4 = new JButton("Cursor=10");
        b4.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                tf.setCaretPosition(10);
                tf.requestFocus();
            }
        });
        b5 = new JButton("Print Values");
        b5.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.out.println("Caret=" + tf.getCaretPosition() +
                        ", Selection=" + tf.getSelectionStart() +
                        "," + tf.getSelectionEnd());
            }
        });

        tf2 = new JTextField("Change text here and hit <return>");
        tf2.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                tf.setText(tf2.getText());
                tf.requestFocus();
            }
        });

        JPanel p1 = new JPanel();
        p1.setLayout(new GridLayout(1,5));
        p1.add(b1);
        p1.add(b2);
        p1.add(b3);
        p1.add(b4);
        p1.add(b5);

        Container pane = f.getContentPane();
        pane.setLayout(new GridLayout(3,1));
        pane.add(tf);
        pane.add(p1);
        pane.add(tf2);

        f.pack();
        f.setVisible(true);
    }
}

Comments
After migration of TextField to the RICHEDIT from the EDIT by the JDK-7092551 cursor is not visible during selection, and we can return any value: start/end of the selection.
06-11-2020

SUGGESTED FIX In file src/win32/sun/sun/awt/windows/WTextComponentPeer.java change the implementation of getCaretPosition from this: public int getCaretPosition() { return getSelectionStart(); }; To this: public int getCaretPosition() { return getSelectionEnd(); };
17-09-2004

EVALUATION Needs to be fixed. mike.bronson@eng 1999-08-02 Reproducible on build 1.4.0-beta_refresh-b71 on Win2K. mike.bronson@eng 2001-07-16
02-08-1999