2011-08-29 18 views
7

Oyunum için bir seviye editörü yapıyorum. Seçilen nesneyi özelliklerini değiştirebileceğim bir özellik panelim var. Ayrıca xml düzeyini yazmak için Kaydet Kaydet düğmesi var. editör bileşeni veya girin odağı kaybetti Bir alan düzenleme gönderildiktenJava Swing: Focus issue

(*) basılır. Bu harika çalışıyor, ancak tek sorun eylemlerin bu diziyi varken şudur:

:

  1. düzenleme bir alan
  2. basın ne olur bu Çünkü, düğmeye

tasarruf

  1. ben
  2. düğmesi le kaydetmek basın sahadan
  3. düzenlemek vel alan Gördüğünüz gibi
  4. düzenlemek

gönderilirse odağı kaybetti

  • kaydedilir, bu yanlış düzendir. Tabii ki, alanın odağını kaybetmesini istiyorum, bu da gönderime neden oluyor ve sonra seviyesini koruyor.

    Alanın önce odağı kaybetmesini ve ardından kaydetme düğmesinin eylem dinleyicisini gerçekleştirmesini sağlamak için bir hile, kesmek veya geçici çözüm var mı?

    Şimdiden teşekkürler.

    (* nesne özelliğinde = alana düzenleme de yapılır gönderme)


    EDIT: saha I focusLost ile FocusAdapter kullanıyorum:

    FocusAdapter focusAdapter = new FocusAdapter() 
    { 
    
        @Override 
        public void focusLost(FocusEvent e) 
        { 
         compProperties.setProperty(i, getColor()); 
         record(); // For undo-redo mechanism 
        } 
    }; 
    

    Ve düğme için bir eylem 0 ile ActionListenerPerformed`.

    btnSave.addActionListener(new java.awt.event.ActionListener() { 
        public void actionPerformed(java.awt.event.ActionEvent evt) { 
         // Save the level 
        } 
    }); 
    
  • +1

    Kodun nasıl çalıştığını bilmiyoruz, lütfen buraya bir kod gönderiniz, çünkü burada “DocumentListener” veya “AncesorListener” kullanılarak başka bir seçenek var, ya da sadece “FocucHell” inizi “invokeLater” ile myTextField.setText ile paketleyin. (myTextField.getText); ' – mKorbel

    +0

    @mKorbel: Kaydetme işlemini bir' invokeLater' içine sarmayı denedim, ancak yine de yanlış sırada. –

    +1

    Ayrıca bkz. [Q & A] (http://stackoverflow.com/questions/6803976/focusevent-doesnt-get-the-last-value-of-jformattedtextfield-how-i-can-get-it/6804749#6804749) . – trashgod

    cevap

    3

    Hmm ... yeniden yapamazsınız: On

    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); 
    

    : kayıp aşağıda pasajı her zaman, actionPerfomed önce düğmesini tıklayın veya anımsatıcı kullanma konusunda bağımsız bildirilir içinde Diğer yandan, odaklanmak güvenmek için zor bir özelliktir, sipariş sisteme bağlı olabilir (benimki vista kazanmaktır). Snippet'in size nasıl davrandığını kontrol edin.Sen de benim gibi aynı diziyi görürseniz

    • , sorun başka bir yerde olduğunu
    • kayıp önce kaydetmek alırsanız, sonunda koyar invokeLater (içine kaydetmek eylemi sarmak için deneyin EventQueue ait, bu yüzden sizin hile yapmak gerekir bir SwingUtilities.invokeLater() içine kodu kaydetmek sarma,) tüm bekleyen olaylardan sonra

      Action save = new AbstractAction("save") { 
      
          @Override 
          public void actionPerformed(ActionEvent e) { 
           SwingUtilities.invokeLater(new Runnable() { 
            public void run() { 
             LOG.info("save: " + field.getText()); 
            } 
           }); 
          } 
      }; 
      
    +0

    '' problemi başka bir yerde var OP tarafından 'I/O akışlarını ekledim 1) Odak & ActionListener'ı javax.swing.Action İçinde Çıkarma 2) I/O Akışlarını Runnable # iş parçacığına yönlendirmek, 3) tüm bitmiş sonra Focus & ActionListener'ı geri ekleyin, 4) iki adımda iki invokeLater(), 5) ActionListener'den dealyed Olayları javax.swi kullanarak geciktirirse çalışır ng.Timer & javax.swing.Action, 6) Action, ActionListener 7 gibi hareketin biraz farklı olduğunu görüyoruz. Tüm hareketler JButton'dan JTexfield'a odaklanmak invokeLater() +1'e sarıldı – mKorbel

    0

    Normalde yürütüldüğünde. Daha önce de belirttiğiniz gibi, bu işe yaramıyor mu?

    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();    
         } 
        } 
    }; 
    

    ve düğme için: Bu deneyin

    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(); 
         } 
        } 
    }); 
    

    ve sonra senin kaydetmek yöntemi:

    private void save(){ 
        // do your saving work 
        saveRequested = false; 
    } 
    

    sizin focusLost sizin düğmenin eyleminden sonra çağrılan Bu yalnızca çalışır. Birdenbire sipariş doğruysa, bu kod iki kere kaydedilir().

    Ancak yine de, kaydetme kodunun tüm olayları işledikten sonra yürütüldüğünden, save() kodunuzu orijinal yaklaşımınıza sarmanız gerekir. Düğme tıklama ve focusLost olaylarınızı işledikten sonra budur. FocusLost kodunuz hemen yürütüldüğü için (invokeLater() 'da değil), focusLost kodu her zaman kaydetme kodunuzdan önce gerçekleştirilmelidir. Bu, olay sırasının doğru olacağı anlamına gelmez! Ancak olaylarla ilgili kod doğru sırada yürütülecektir.