簡體   English   中英

Java Swing:焦點問題

[英]Java Swing: Focus issue

我正在為我的游戲制作關卡編輯器。 我有一個屬性面板,我可以在其中修改所選對象的屬性。 我還有一個Save按鈕來編寫級別xml。

當編輯器組件失去焦點按下Enter時,將提交字段編輯(*)。 這很有效,但唯一的問題是,當我有這一系列動作時:

  1. 編輯一個字段
  2. 按保存按鈕

因為,會發生什么:

  1. 我編輯該字段
  2. 我按下保存按鈕
  3. 級別已保存
  4. 該領域失去了焦點
  5. 編輯已提交

如您所見,這是錯誤的順序。 當然我希望該字段失去焦點,這會導致提交然后保存級別。

是否有技巧,黑客或解決方法使字段首先失去焦點,然后執行保存按鈕的動作偵聽器?

提前致謝。

(* 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM