2011-08-29 7 views
7

내 게임의 레벨 편집기를 만들고 있습니다. 선택한 개체의 속성을 수정할 수있는 속성 패널이 있습니다. 나는 또한 버튼을 저장하여 레벨 xml을 작성합니다. 에디터 컴퍼넌트 또는 를 입력 포커스를 잃은 필드 편집이 제출자바 스윙 : 포커스 문제

(*)는을 누르면. 이것은 큰 노력하고 있지만, 유일한 문제는 내가 작업이 순서 때이다 :

:

  1. 편집 필드
  2. 눌러 무슨 일하는 것은 이것이다, 때문에 버튼을

을 저장

  1. 본인은
  2. 버튼 르 저장 눌러 필드를
  3. 을 편집 VEL이 필드는 당신이 볼 수 있듯이
  4. 편집이

제출 초점을 잃은

  • 저장이 잘못된 순서입니다. 물론 필드가 그 초점을 잃고 싶습니다. 그러면 제출이 발생하고 다음 레벨을 저장합니다.

    필드가 먼저 포커스를 잃고 저장 버튼의 동작 수신기를 수행하는 트릭, 해킹 또는 해결 방법이 있습니까?

    미리 감사드립니다.

    (* 객체 속성에 = 분야에 편집도 만들어 제출)


    편집 : 필드의 내가 focusLost와 FocusAdapter을 사용하고 있습니다 :

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

    버튼의 경우 actionPerformed`가 포함 된 간단한 ActionListener을 사용하십시오.

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

    'DocumentListener'를 사용하거나'AncesorListener'를 사용하거나'myTextField.setText와 함께'invokeLater'에'FocucHell'을 래핑하는 것으로 다른 옵션이 있기 때문에, (myTextField.getText);' – mKorbel

    +0

    @mKorbel : 저장 프로세스를'invokeLater'에 래핑하려고 했는데도 여전히 잘못된 순서로되어 있습니다. –

    +1

    참고 사항 [Q ​​& A] (http://stackoverflow.com/questions/6803976/focusevent-doesnt-get-the-last-value-of-jformattedtextfield-how-i-get-it/6804749#6804749) . – trashgod

    답변

    3

    흠 ... 재현 할 수 없습니다 : 온

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

    : 잃어버린 아래의 조각은 항상 각 actionPerfomed 전에 버튼을 클릭하거나 니모닉을 사용하는지 여부에 대한 독립적 인 통보에 반면에 초점은 의존 할 수있는 까다로운 속성이며, 순서는 시스템에 따라 다를 수 있습니다 (내 시각은 승리 전망 임). 스 니펫이 어떻게 동작하는지 확인하십시오.내가 당신이 동일한 순서를 참조하면

    • 이 문제는 다른 곳이다
    • 당신이이 손실되기 전에 저장 얻는 경우에, 마지막에 넣는다 invokeLater (에 저장 작업을 마무리하려고 가 EventQueue의, 그래서 그것은 당신의 트릭을 할해야 SwingUtilities.invokeLater()에 코드를 저장 포장,) 모든 보류중인 이벤트 후

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

    OP가 I/O 스트림을 추가함으로써 문제가 어딘가에 있습니다. 1) javax.swing.Action에서 Focus & ActionListener를 제거하십시오. 2) I/O 스트림을 Runnable # thread로 리디렉션합니다. 3) 모든 작업을 수행 한 다음 Focus 및 ActionListener를 다시 추가합니다. 4) 두 개의 invokeLater()로 각각 두 단계를 지연하면 동일한 방식으로 작동합니다. 5) javax.swi를 사용하여 ActionListener의 이벤트를 처리합니다. ng.Timer & javax.swing.Action, 6) Action이 ActionListener처럼 조금 다르게 보입니다. 7) 모두 JBoss에서 JTexfield로 포커스가 invokeLater() +1에 래핑되었습니다. – mKorbel

    0

    일반적으로 실행합니다. 이미 언급했듯이, 이것은 효과가 없습니까?

    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 코드는 항상 저장 코드보다 먼저 실행되어야합니다. 이것은 이벤트 순서가 정확하다는 것을 의미하지 않습니다! 그러나 이벤트와 관련된 코드는 올바른 순서로 실행됩니다.