Java Swing:焦点问题
我正在为我的游戏制作一个关卡编辑器。我有一个属性面板,可以在其中修改所选对象的属性。我还有一个保存按钮来编写关卡 xml。
当编辑器组件失去焦点或Enter被按下时,字段编辑被提交(*)。这很好用,但唯一的问题是,当我执行以下操作序列时:
- 编辑字段
- 按保存按钮
因为,发生的情况是这样的:
- 我编辑字段
- 我按保存按钮
- 关卡已保存
- 该字段丢失了focus
- 编辑已提交
如您所见,这是错误的顺序。当然,我希望该字段失去焦点,这会导致提交并然后保存关卡。
是否有技巧、黑客或解决方法可以使字段首先失去焦点,然后执行保存按钮的操作侦听器?
提前致谢。
(*提交=对字段的编辑也在对象属性中进行)
编辑:对于字段,我使用带有focusLost
的FocusAdapter:
FocusAdapter focusAdapter = new FocusAdapter()
{
@Override
public void focusLost(FocusEvent e)
{
compProperties.setProperty(i, getColor());
record(); // For undo-redo mechanism
}
};
对于按钮a简单的 ActionListener
和 actionPerformed`。
btnSave.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
// Save the level
}
});
I'm making a level editor for my game. I have a property panel where I can modify the selected object its properties. I also have a Save button to write the level xml.
A field-edit is submitted(*) when the editor component lost the focus or Enter is pressed. This is working great, but the only problem is that when I have this sequence of actions:
- Edit a field
- Press the save button
Because, what happens is this:
- I edit the field
- I press the save button
- The level is saved
- The field lost the focus
- The edit is submitted
As you can see, this is the wrong order. Of course I want the field to lose its focus, which causes the submit and then save the level.
Is there a trick, hack or workaround to make the field first lose the focus and then perform the action listener of the save button?
Thanks in advance.
(* submit = the edit to the field is also made in the object property)
EDIT: For the field I'm using a FocusAdapter with focusLost
:
FocusAdapter focusAdapter = new FocusAdapter()
{
@Override
public void focusLost(FocusEvent e)
{
compProperties.setProperty(i, getColor());
record(); // For undo-redo mechanism
}
};
And for the button a simple ActionListener
with actionPerformed`.
btnSave.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
// Save the level
}
});
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
嗯...无法重现:在下面的代码片段中,丢失总是在 actionPerfomed 之前通知,与我是否单击按钮或使用助记符无关:
另一方面,焦点是一个需要依赖的棘手属性,排序可能与系统相关(我的是win vista)。检查该代码片段在您的代码片段上的表现如何。
如果您在丢失之前获得了保存,请尝试将保存操作包装到invokeLater中(这会将其放在EventQueue的末尾,因此它会被执行)在所有待处理事件之后)
Hmm ... can't reproduce: in the snippet below the lost is always notified before the actionPerfomed, independent on whether I click the button or use the mnemonic:
On the other hand, focus is a tricky property to rely on, the ordering might be system-dependent (mine is win vista). Check how the snippet behave on yours.
if you get the save before the lost, try to wrap the the save action into invokeLater (which puts it at the end of the EventQueue, so it's executed after all pending events)
通常,将保存代码包装到
SwingUtilities.invokeLater()
中应该可以解决问题。正如您已经提到的,这不起作用?试试这个:对于你的按钮:
然后你的保存方法:
这只在按钮操作后调用 focusLost 时才有效。如果顺序突然正确,则此代码将调用 save() 两次。
但同样,将 save() 代码包装在原始方法中应该可行,因为保存代码将在处理所有事件后执行。那是在处理按钮单击和 focusLost 事件之后。因为您的 focusLost 代码会立即执行(它没有包装在 invokeLater() 中),所以 focusLost 代码应始终在保存代码之前执行。这并不意味着事件顺序是正确的!但与事件关联的代码将以正确的顺序执行。
Normally, wrapping your save code into an
SwingUtilities.invokeLater()
should do the trick. As you already mentioned, this doesn't work? Try this:and for your button:
and then your save method:
This only works when your focusLost gets called after your button's action. If suddenly the order is correct, this code will get save() called twice.
But again, wrapping your save() code in your original approach should work, because the save code will execute after processing all events. That is after processing your button click and your focusLost events. Because your focusLost code executes immediately (it's not wrapped in an invokeLater()), the focusLost code should be executed always before your save code. This does not mean that the event order will be correct! But the code associated to the events will executed in the right order.