我在想,我所期望的 JFormattedTextField
与默认按钮结合使用是正确的。在编辑 JFormattedTextField
,通常要提交值然后使用它,这通常发生在 focusLost
或者有时候 ActionListener
手动触发。现在,如果这样的文本字段在 JDialog
它有一个 DefaultButton
已定义,使用ctrl+enter触发默认按钮不会导致当前焦点 JFormattedTextField
触发它是 focusLost
事件。
现在,我看到两种解决方案:
手动确保所有inut字段处于comitt(或还原)状态
使用 SwingUtilities.InvokeLater
在 ActionListener
默认按钮的
然而,这两个看起来都很脏,尤其是第一个,因为要扩展所说的对话框而不忘记处理组件是不太容易的。第二种是不受欢迎的,因为 invokeLater
这通常意味着更多的代码更难调试。
有没有更好的办法解决这个问题?
例子:
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class DefaultButton
{
public static void main( String[] args )
{
JFrame frame = new JFrame();
JFormattedTextField field = new JFormattedTextField();
field.setValue( "HELLO" );
JButton defaultButton = new JButton( "Default" );
defaultButton.addActionListener( __ ->
{
JOptionPane.showMessageDialog( frame, "You've chosen: " + field.getValue() );
} );
frame.getRootPane().setDefaultButton( defaultButton );
JPanel panel = new JPanel( new BorderLayout() );
panel.add( field, BorderLayout.NORTH );
panel.add( defaultButton, BorderLayout.SOUTH );
frame.add( panel );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE );
frame.setVisible( true );
}
}
1条答案
按热度按时间z18hc3ub1#
是的,当
JFormattedTextField
有输入焦点,你激活defaultButton
,的JFormattedTextField
不会失去焦点,因此不会提交值。请参阅如何使用格式化文本字段。
这里有一句话:
格式化文本字段的文本及其值是两个不同的属性,并且值通常滞后于文本。
文本属性由
JTextField
班级。此属性始终反映字段显示的内容。值属性,由JFormattedTextField
类,可能不会反映字段中显示的最新文本。用户键入时,text属性会更改,但value属性在提交更改之前不会更改。我看到了两种可能的解决方案(尽管我认为还有更多)。
在
actionPerformed()
方法,或者调用getText()
而不是getValue()
,或呼叫commitEdit()
打电话之前getValue()
,即。或
编辑
我相信这就是你要找的。
专注于方法
actionPerformed()
. 如果JFormattedTextField
当前有焦点,然后强制焦点移动到下一个组件。无论哪个组件具有键盘焦点,都要将JOptionPane
在一个invokeLater()
打电话。