[英]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.