Java Swing:JTextField不会像预期的那样失去焦点

时间:2012-05-28 12:42:11

标签: java swing focus jtable jtextfield

我有一个有两列的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)。

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

2 个答案:

答案 0 :(得分:4)

您可以覆盖stopEditing()

中的TableCellEditor

或直接写

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() {
    }
}

答案 1 :(得分:0)

我修好了这个:

1)将焦点放在新的JTextField上:

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

2)表自动检测丢失的焦点:

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

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

 getComponent().isFocusOwner()