[英]Java Swing: Focus issue
我正在为我的游戏制作关卡编辑器。 我有一个属性面板,我可以在其中修改所选对象的属性。 我还有一个Save按钮来编写级别xml。
当编辑器组件失去焦点或按下Enter时,将提交字段编辑(*)。 这很有效,但唯一的问题是,当我有这一系列动作时:
因为,会发生什么:
如您所见,这是错误的顺序。 当然我希望该字段失去焦点,这会导致提交然后保存级别。
是否有技巧,黑客或解决方法使字段首先失去焦点,然后执行保存按钮的动作侦听器?
提前致谢。
(* submit =字段的编辑也在对象属性中进行)
编辑 :对于我正在使用FocusAdost的focusLost
:
FocusAdapter focusAdapter = new FocusAdapter()
{
@Override
public void focusLost(FocusEvent e)
{
compProperties.setProperty(i, getColor());
record(); // For undo-redo mechanism
}
};
对于按钮,一个简单的ActionListener
与actionPerformed`。
btnSave.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
// Save the level
}
});
嗯...无法重现:在下面的片段中,丢失的内容总是在actionPerfomed之前得到通知,独立于我是否单击按钮或使用助记符:
final JTextField field = new JTextField("some text to change");
FocusAdapter focus = new FocusAdapter() {
@Override
public void focusLost(FocusEvent e) {
LOG.info("lost: " + field.getText());
}
};
field.addFocusListener(focus);
Action save = new AbstractAction("save") {
@Override
public void actionPerformed(ActionEvent e) {
LOG.info("save: " + field.getText());
}
};
save.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_S);
JButton button = new JButton(save);
JComponent box = Box.createHorizontalBox();
box.add(field);
box.add(button);
另一方面,焦点是一个难以依赖的属性,排序可能是系统依赖的(我的是胜利视野)。 检查代码段在您的代码上的行为方式。
如果你在丢失之前得到了保存,请尝试将save动作包装到invokeLater(它将它放在EventQueue的末尾,因此它在所有挂起的事件之后执行)
Action save = new AbstractAction("save") { @Override public void actionPerformed(ActionEvent e) { SwingUtilities.invokeLater(new Runnable() { public void run() { LOG.info("save: " + field.getText()); } }); } };
通常,将保存代码包装到SwingUtilities.invokeLater()
应该可以解决问题。 正如您已经提到的,这不起作用? 尝试这个:
private boolean editFocus = false;
FocusAdapter focusAdapter = new FocusAdapter()
{
@Override
public void focusGained(FocusEvent e){
editFocus = true;
}
@Override
public void focusLost(FocusEvent e){
compProperties.setProperty(i, getColor());
record(); // For undo-redo mechanism
editFocus = false;
if (saveRequested){
save();
}
}
};
并为您的按钮:
private boolean saveRequested = false;
btnSave.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
if (editFocus){
saveRequested = true;
return;
} else {
save();
}
}
});
然后你的保存方法:
private void save(){
// do your saving work
saveRequested = false;
}
这仅适用于在按钮操作后调用focusLost时。 如果突然顺序正确,则此代码将调用save()两次。
但同样,在原始方法中包装save()代码应该有效,因为保存代码将在处理完所有事件后执行。 这是在处理按钮单击和focusLost事件之后。 因为你的focusLost代码立即执行(它没有包装在invokeLater()中),所以应该始终在保存代码之前执行focusLost代码。 这并不意味着事件顺序是正确的! 但是与事件关联的代码将按正确的顺序执行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.