2

After applying a MaskFormatter onto a JFormattedTextField, then setting that text field to a column in my JTable, the caret started appearing wherever I click. However I want the caret to appear in the left most position of the cell, no matter where in the cell the user clicks. I tried the setCaretPositionMethod, but it did nothing. My guess would be that there is some sort of table listener, which is forcing the caret to move to where the user clicks, if I knew what this listener was, I could Override the feature.

SSCCE:

public class TableExample extends JFrame {
    public TableExample() {
        add(makeTable());
    }

    private JTable makeTable() {
        Object[][] tableData = {{"","a","b",""}, {"","c","d",""}};
        String[] columns = {"column1", "column2", "column3", "dobColumn"};
        JTable table = new JTable(tableData, columns);

        ////DOB column formats to dd/mm/yy
        TableColumn dobColumn = table.getColumnModel().getColumn(3);
        DateFormat df = new SimpleDateFormat("dd/mm/yy");
        JFormattedTextField tf = new JFormattedTextField(df);
        tf.setColumns(8);
        try {
            MaskFormatter dobMask = new MaskFormatter("##/##/##");
            dobMask.setPlaceholderCharacter('0');
            dobMask.install(tf);
        } catch (ParseException ex) {
             Logger.getLogger(TableExample.class.getName()).log(Level.SEVERE, null, ex);
        }

        ////Does nothing
        tf.setCaretPoisition(0);

        dobColumn.setCellEditor(new DefaultCellEditor(tf));

        return table;
    }

    public static void main(String[] args) {
        JFrame frame = new TableExample();
        frame.setSize( 300, 300 );
        frame.setVisible(true); 
    }
}
user217339
  • 169
  • 1
  • 2
  • 11

1 Answers1

5

If I remember correctly you can add a FocusListener to the formatted text field and then when the component gains focus you can invoke the setCaretPosition(0) method.

However this statement must be wrapped in a SwingUtilities.invokeLater(...) to make sure the code is executed after the default caret positioning of the formatted text field.

The other option is to override the isCellEditable(...) method of the JTable. However this approach will affect all editor in the table.

Here is example code that shows how to "select" the text when the editor is invoked:

public boolean editCellAt(int row, int column, EventObject e)
{
    boolean result = super.editCellAt(row, column, e);
    final Component editor = getEditorComponent();

    if (editor != null && editor instanceof JTextComponent)
    {
        ((JTextComponent)editor).selectAll();

        if (e == null)
        {
            ((JTextComponent)editor).selectAll();
        }
        else if (e instanceof MouseEvent)
        {
            SwingUtilities.invokeLater(new Runnable()
            {
                public void run()
                {
                    ((JTextComponent)editor).selectAll();
                }
            });
        }

    }

    return result;
}
camickr
  • 321,443
  • 19
  • 166
  • 288
  • Thanks, adding the focus listener did exactly what I wanted. Also for some reason applying the mask to a column in the JTable will only apply the mask to the first cell I click on in the column. After that the mask is destroyed, I fixed this problem by recreating the mask and the focus listener inside the tableChanged() method. I posted a question about the problem [here](http://stackoverflow.com/questions/39926784/applying-a-maskformatter-to-a-column-in-my-jtable-but-the-mask-is-only-used-on?noredirect=1#comment67139496_39926784) – user217339 Oct 09 '16 at 22:27