Java 如何使JTable单元格中的插入符号在应用MaskFormatter后显示在左侧

Java 如何使JTable单元格中的插入符号在应用MaskFormatter后显示在左侧,java,swing,jtable,caret,jformattedtextfield,Java,Swing,Jtable,Caret,Jformattedtextfield,将MaskFormatter应用于JFormattedTextField,然后将该文本字段设置为JTable中的一列后,插入符号开始出现在我单击的任何位置。但是,我希望插入符号显示在单元格的最左侧位置,无论用户单击单元格中的哪个位置。我尝试了setCaretPositionMethod,但没有任何效果。我的猜测是,存在某种表侦听器,它迫使插入符号移动到用户单击的位置,如果我知道这个侦听器是什么,我可以覆盖该功能 SSCCE: public class TableExample extends J

将MaskFormatter应用于JFormattedTextField,然后将该文本字段设置为JTable中的一列后,插入符号开始出现在我单击的任何位置。但是,我希望插入符号显示在单元格的最左侧位置,无论用户单击单元格中的哪个位置。我尝试了setCaretPositionMethod,但没有任何效果。我的猜测是,存在某种表侦听器,它迫使插入符号移动到用户单击的位置,如果我知道这个侦听器是什么,我可以覆盖该功能

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); 
    }
}

如果我没记错,您可以向格式化文本字段添加
FocusListener
,然后当组件获得焦点时,您可以调用
setCaretPosition(0)
方法

但是,必须将此语句包装在
SwingUtilities.invokeLater(…)
中,以确保在格式化文本字段的默认插入符号定位之后执行代码

另一个选项是重写JTable的
isCellEditable(…)
方法。但是,此方法将影响表中的所有编辑器

下面的示例代码显示了在调用编辑器时如何“选择”文本:

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;
}

如果我没记错,您可以向格式化文本字段添加
FocusListener
,然后当组件获得焦点时,您可以调用
setCaretPosition(0)
方法

但是,必须将此语句包装在
SwingUtilities.invokeLater(…)
中,以确保在格式化文本字段的默认插入符号定位之后执行代码

另一个选项是重写JTable的
isCellEditable(…)
方法。但是,此方法将影响表中的所有编辑器

下面的示例代码显示了在调用编辑器时如何“选择”文本:

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;
}

谢谢,添加focus listener正是我想要的。此外,由于某些原因,将掩码应用于JTable中的列只会将掩码应用于我在列中单击的第一个单元格。在销毁掩码之后,我通过在tableChanged()方法中重新创建掩码和焦点侦听器修复了这个问题。我发布了一个关于这个问题的问题,谢谢,并补充说焦点听众做了我想做的事情。此外,由于某些原因,将掩码应用于JTable中的列只会将掩码应用于我在列中单击的第一个单元格。在销毁掩码之后,我通过在tableChanged()方法中重新创建掩码和焦点侦听器修复了这个问题。我发布了一个关于这个问题的问题