Java Swing:JTextField 没有按预期失去焦点

Posted

技术标签:

【中文标题】Java Swing:JTextField 没有按预期失去焦点【英文标题】:Java Swing: JTextField doesn't lose focus as expected 【发布时间】:2012-06-02 20:01:10 【问题描述】:

我有一个有 2 列的 JTable。其中一列由 JTextField 表示,另一列由单选按钮表示。

以这种方式填充模型:

   model.addRow(new Object[]radioButton, "");

与 JTextField 相关联的单元格编辑器是这样的:

class MyCellEditor extends DefaultCellEditor 

  MyCellEditor(JTextField textField) 
    super(textField);
    textField.addFocusListener(new FocusListener() 

        public void focusLost(FocusEvent e) 
            // do something if focus is lost
        

        @Override
        public void focusGained(FocusEvent e) 
        
    );

当我单击 JTextField 单元格时,我会按预期得到一个“闪烁”光标,因此我可以输入我的文本。无论如何,如果我单击主窗口中的其他任何位置,我希望使用“focusLost(...)”方法已被调用,但只有当我在窗口中“播放”一下时才会发生这种情况(比如几次点击进出 jtextfield)。

为什么组件在第一次点击另一个外部组件后没有失去焦点?

【问题讨论】:

【参考方案1】:

我是这样解决的:

1) 将焦点放在新的 JTextField:

 if (editCellAt(getRowCount()-1, 1)) getEditorComponent().requestFocus();

2) 表格自动检测失去焦点:

 table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);

3) 在 "MyCellEditor class --> @Override public boolean stopCellEditing()" 中只检查组件是否有焦点:

 getComponent().isFocusOwner()

【讨论】:

【参考方案2】:

您可以在TableCellEditor 中覆盖stopEditing()

或者直接写

table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);

更复杂的(JFormattedTextField)例子

import java.awt.Component;
import java.awt.EventQueue;
import java.text.DecimalFormat;
import java.text.ParseException;
import javax.swing.*;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumnModel;

public class EditorAsRendererTableTest 

    public static void main(String[] args) 
        EventQueue.invokeLater(new Runnable() 

            @Override
            public void run() 
                JTable table = new JTable(3, 2);
                TableColumnModel colModel = table.getColumnModel();
                MyCellEditor both = new MyCellEditor();
                colModel.getColumn(0).setCellEditor(both);
                colModel.getColumn(0).setCellRenderer(both);
                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                frame.getContentPane().add(new JScrollPane(table));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            
        );
    

    private static class MyCellEditor extends AbstractCellEditor implements TableCellEditor, TableCellRenderer 

        private static final long serialVersionUID = 1L;
        private JFormattedTextField renderer = new JFormattedTextField(DecimalFormat.getInstance());
        private JFormattedTextField editor;

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) 
            renderer.setValue(value);
            return renderer;
        

        @Override
        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) 
            editor = new JFormattedTextField(DecimalFormat.getInstance());
            editor.setValue(value);
            return editor;
        

        @Override
        public boolean stopCellEditing() 
            try 
                editor.commitEdit();
             catch (ParseException e) 
                return false;
            
            return super.stopCellEditing();
        

        @Override
        public Object getCellEditorValue() 
            return editor.getValue();
        
    

    private EditorAsRendererTableTest() 
    

【讨论】:

我过去已经尝试过这两种方法,但它们都不起作用(无论如何我认为使用 stopEditing() 你指的是:public boolean stopCellEditing())。就我而言,stopCellEditing() 仅在按下“enter”键时调用。 @Randomize 请在此处查看我的编辑,不要忘记也覆盖 cancelCellEditing() 感谢您的帮助。我运行您的演示代码,看起来在我单击文本字段后我无法单击其他任何地方。是否意味着“最佳实践”,以便文本字段在输入值之前不会失去焦点? @Randomize Focus 不是 JTable 的正确监听器,不要忘记覆盖 cancelCellEditing(),这是真正 CellEditor 的后半部分 当焦点移开时我看不到差异。如果我单击其他地方,则不会调用 stopCellEditing 和 cancelCellEditing。

以上是关于Java Swing:JTextField 没有按预期失去焦点的主要内容,如果未能解决你的问题,请参考以下文章

Java Swing JtextField 插图

如何在 Java Swing 中控制 JTextField 的宽度?

关于Java swing组件焦点的问题(我猜可能是焦点的问题) 高分求全面

java:限制swing中的JTextField只能输入中文,字母,数字。

java.swing JtextField 中怎么限制只能输入数字

java swing JTextField设置PlaceHolder [重复]