2

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

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

4

2 回答 2

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() {
    }
}
于 2012-05-28T12:54:09.683 回答
0

我这样固定:

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

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

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

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

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

 getComponent().isFocusOwner()
于 2012-05-28T20:51:30.527 回答