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组件焦点的问题(我猜可能是焦点的问题) 高分求全面
java:限制swing中的JTextField只能输入中文,字母,数字。