当表单(表单)包含 JFormattedTextField
时,我在使用表单默认按钮时遇到了问题。
在具有此类字段的表单上,如果它恰好具有焦点(并且已更改),则必须按“确定”两次才能“按下”默认按钮。我想我知道为什么会发生这种情况 - 这是因为第一个 Enter 在提交处理中被消耗。
我还能够制定一个解决方法 - 如果您更改 Formatter
以提交每个有效编辑,那么您将获得正确的行为,但这 a) 强制您明确指定格式化程序,并且 b )不可能恢复为“旧”值(例如使用 Escape 或以编程方式)。
下面的代码演示了:当您运行顶部的字段时,每次编辑都会提交并使用单个 Enter(但无法恢复),底部的字段允许恢复,但需要两次 Enter如果已编辑。
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.util.Date;
import javax.swing.JButton;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.text.DateFormatter;
public class ExFrame extends JFrame {
private JPanel contentPane;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
ExFrame frame = new ExFrame();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public ExFrame() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
JFormattedTextField ff_1, ff_2;
//ff_1 has modified behavior of commit on each (valid) edit
DateFormatter f=new DateFormatter();
f.setCommitsOnValidEdit(true);
ff_1 = new JFormattedTextField(f);
ff_1.setValue(new Date());
//ff_2 has default behavior
ff_2 = new JFormattedTextField(new Date());
contentPane.add(ff_1, BorderLayout.NORTH);
contentPane.add(ff_2, BorderLayout.SOUTH);
JButton btnDefault = new JButton("I am default button");
contentPane.add(btnDefault, BorderLayout.CENTER);
getRootPane().setDefaultButton(btnDefault);
}
}
所以问题是:有没有办法让 JFormattedTextField
both 在 Enter 上提交(因此输入被验证,但仅验证一次)<强>如果成功验证,激活默认按钮(按一下)?
最佳答案
基本技巧是让 keyBinding 机制相信 keyStroke 不是由 textField 处理的。为了实现这一点,我们需要子类化 JFormattedTextField 并重写它的 processKeyBindings 以返回 false(意思是:“无法使用”)。
类似于:
JFormattedTextField multiplex = new JFormattedTextField() {
KeyStroke enter = KeyStroke.getKeyStroke("ENTER");
@Override
protected boolean processKeyBinding(KeyStroke ks, KeyEvent e,
int condition, boolean pressed) {
boolean processed = super.processKeyBinding(ks, e, condition,
pressed);
if (processed && condition != JComponent.WHEN_IN_FOCUSED_WINDOW
&& enter.equals(ks)) {
// Returning false will allow further processing
// of the bindings, eg our parent Containers will get a
// crack at them and f.i. route to a default button.
return !isEditValid();
}
return processed;
}
};
multiplex.setValue(new Date());
关于java - 如何使 JFormattedTextField 在具有默认按钮的表单上正常运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9101693/