3

I have frame with JFormattedTextField(s). My simplified code can look like:

JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(100,100);
frame.setLayout(new GridLayout(2,2));

JFormattedTextField field1 = new JFormattedTextField(NumberFormat.getInstance());
field1.setValue(0.4);
frame.add(new JLabel("value A"));
frame.add(field1);

JFormattedTextField field2 = new JFormattedTextField(NumberFormat.getInstance());
field2.setValue(0.8);
frame.add(new JLabel("value B"));
frame.add(field2);

frame.setVisible(true);

which generates:

enter image description here

Goal

When I click/focus on any of JFormattedTextField I would like it to automatically place caret at the end

enter image description here enter image description here

Problem

I tried using following solutions before calling frame.setVisible(true); but none of them seems to work

Community
  • 1
  • 1
user5327287
  • 410
  • 4
  • 18
  • What is the content of JTextField? Where do you want to set caret, and *when* should it happen? – Pshemo Mar 16 '19 at 23:09
  • which problem? "isn't working any more" does not help much - it is working for me (assuming `ratioField` instead of `JTextField` in first code sample) – user85421 Mar 16 '19 at 23:13
  • 3
    Please [edit] your question to include a [mcve], which can be compiled and tested by others, that shows that the caret is not set at the specific position. – Progman Mar 16 '19 at 23:18
  • I edited the post – user5327287 Mar 17 '19 at 16:16
  • You claimed that it is `JTextField` but your code uses `JFormattedTextField`. Details may matter. – Pshemo Mar 17 '19 at 19:03
  • It doesn't matter because it extends JTextField – user5327287 Mar 17 '19 at 21:01
  • Extending JTextField doesn't guarantee same behavior (which is main idea behind overriding methods in subclasses). I am not sure if that is what you want to achieve but if I understand you correctly you want cursor to be set after value *from the start* (from when frame is shown). Code you shown above works for that scenario with `JTextField` but not with `JFormattedTextField`. So *class* of instance does matter for that scenario, but it may not matter if it isn't what you wanted to achieve (if your goal is different which is why I asked earlier *when* setting cursor should happen). – Pshemo Mar 17 '19 at 21:38
  • But the JFormattedTextField class didn't override this method and if it does override so the oracle docs had mention it which they don't – user5327287 Mar 17 '19 at 21:58
  • It doesn't need to override it. That method only describes *where* to set cursor, but not *when* to set it (when it should be called - this decision seems to be made in different place which probably is overridden). – Pshemo Mar 17 '19 at 22:00
  • So where do you think the problem is? – user5327287 Mar 17 '19 at 22:16
  • I don't know, I am not swing guru like MadProgrammer (and few others here), but at least now it is clear what you wanted to achieve so maybe they will figure it out. – Pshemo Mar 17 '19 at 22:24
  • @user5327287 I tried to simplify your question. Let me know if I overdid it and you prefer your [earlier version] - in which case feel free to roll-it-back my edit (or if you don't know how to do it let me know about it, I will do it for you). – Pshemo Mar 19 '19 at 17:04
  • Yes seems good to me. Thank you, I just changed from the word 'cursor' to 'caret' – user5327287 Mar 20 '19 at 07:12

1 Answers1

5

Works without issue for me....

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

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

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;

            JTextField textField = new JTextField("This is a test");
            add(textField, gbc);

            JButton button = new JButton("This is a button");
            add(button, gbc);
            button.setFocusable(false);
            button.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (textField.getCaretPosition() != 0) {
                        textField.setCaretPosition(0);
                    } else {
                        textField.setCaretPosition(textField.getText().length());
                    }
                    textField.requestFocusInWindow();
                }
            });
        }

    }

}

Provide a runnable example which doesn't work if you still have issues

Update with JFormattedTextField....

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

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

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;

            JFormattedTextField textField = new JFormattedTextField("This is a test");
            textField.setValue(0.8d);
            add(textField, gbc);

            JButton button = new JButton("This is a button");
            add(button, gbc);
            button.setFocusable(false);
            button.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (textField.getCaretPosition() != 0) {
                        textField.setCaretPosition(0);
                    } else {
                        textField.setCaretPosition(textField.getText().length());
                    }
                    textField.requestFocusInWindow();
                }
            });
        }

    }

}

Updated with "set at beginning"

Okay, I just want to point out that I have personally dislike of JFormattedTextField, it does a lot of "things" at times which don't always make sense.

An "old" trick I've used, when implementing a "auto select all on focus gain", is to offload the request to the end of the Event Dispatching Thread, this places the request AFTER all the "funky stuff" that the JFormattedTextField does when the field becomes focused...

JFormattedTextField textField = new JFormattedTextField("This is a test");
textField.setValue(0.8d);
add(textField, gbc);
textField.addFocusListener(new FocusAdapter() {
    @Override
    public void focusGained(FocusEvent arg0) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                textField.setCaretPosition(textField.getText().length());
            }
        });
    }
});

Yes, I'm serious ...

Community
  • 1
  • 1
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • Based on OP update it seems (s)he is using JFormattedTextField, not JTextField (despite what question title suggests, EDIT: now it changed). – Pshemo Mar 17 '19 at 19:26
  • It doesn't matter because it extends JTextField – user5327287 Mar 17 '19 at 21:02
  • @Pshemo and @user5327287 which extends from `JTextComponent` from which the `setCaretPosition` is defined – MadProgrammer Mar 17 '19 at 21:12
  • @MadProgrammer I am just wondering if OP wants cursor to be after value *from the start* (from when frame is shown). It can be easily done with JTextField but JFormattedTextField seems to be "resetting" (I am not really sure what is really happening here so don't know which word would be correct) at start, even if we explicitly call `textField.setCaretPosition(textField.getText().length());` after `textField.setValue(0.8d);`. – Pshemo Mar 17 '19 at 21:51
  • But I don't want a button to execute this code when clicked. I did tried to use OnMouseClick but it doesn't work too – user5327287 Mar 17 '19 at 21:53
  • @user5327287 Then please *edit* your question and explain what you *do* want to achieve. *When* and *what* you want to happen? – Pshemo Mar 17 '19 at 21:54
  • @user5327287 Can you see the difference between your "example" and mine? This is what we mean by a [minimal, complete, verifiable example](https://stackoverflow.com/help/mcve) – MadProgrammer Mar 17 '19 at 22:17
  • I did tried this trick of `addFocusListener` and it didn't worked for me. When I print the caret position it does return the end of the text index but in the `JPanel` its still showing it at the start of the line – user5327287 Mar 17 '19 at 22:36
  • 1
    Wait never mind now I noticed that you had the `EventQueue.invokeLater` which I missed. Now it works thx :) – user5327287 Mar 17 '19 at 22:40
  • Yes, the EventQueue.invokeLater is the secret ! Thank you ! – Dacian Mar 28 '22 at 11:43