2014-08-28 3 views
0

여러 프레임으로 작업 할 때 숨겨진 구성 요소가 제대로 처리되지 않는 문제가 있습니다.프레임이 보이지 않을 때 자바가 대화를 처리하지 않음

간단히 말해 부모가 숨겨진 프레임 인 모달 대화 상자를 처리 할 수 ​​없습니다. 예를 들어

:

  1. 는 "전환 프레임 가시성"버튼을 클릭

    import java.awt.*; 
    import java.awt.event.*; 
    import javax.swing.*; 
    import java.util.*; 
    
    public class MultipleFrameTest { 
        public static void main(String[] args) { 
         TestFrame test = new TestFrame(); 
         FrameTester tester = new FrameTester(test); 
    
         tester.setVisible(true); 
        } 
    
        private static class TestFrame extends JFrame { 
         JDialog dialog; 
         java.util.Timer timer; 
    
         public TestFrame() { 
          super("Test Frame"); 
    
          this.dialog = null; 
          this.timer = new java.util.Timer("Frame Timer"); 
    
          fillFrame(); 
          pack(); 
         } 
    
         private void fillFrame() { 
          JButton dialogButton = new JButton("Launch Model Dialog"); 
          dialogButton.addActionListener(new ActionListener() { 
           public void actionPerformed(ActionEvent event) { 
            JOptionPane pane = new JOptionPane("Wait for 2 seconds", 
             JOptionPane.QUESTION_MESSAGE, 
             JOptionPane.OK_CANCEL_OPTION); 
            dialog = pane.createDialog(TestFrame.this, "Question"); 
    
            timer.schedule(new TimerTask() { 
             public void run() { 
              SwingUtilities.invokeLater(new Runnable() { 
               public void run() { 
                TestFrame.this.setVisible(false); 
    
                if (dialog != null) { 
                 dialog.setVisible(false); 
                 dialog.dispose(); 
                 dialog = null; 
                } 
               } 
              }); 
             } 
            }, 2 * 1000); 
    
            dialog.setVisible(true); 
           } 
          }); 
    
          JPanel panel = new JPanel(); 
          panel.add(dialogButton); 
    
          add(panel); 
         } 
        }  
    
        private static class FrameTester extends JFrame { 
         JFrame frame; 
    
         public FrameTester(JFrame frame) { 
          super("Frame Tester"); 
    
          this.frame = frame; 
    
          fillFrame(); 
          pack(); 
         } 
    
         private void fillFrame() { 
          JButton toggleButton = new JButton("Toggle Frame Visibility"); 
          toggleButton.addActionListener(new ActionListener() { 
           public void actionPerformed(ActionEvent event) { 
            frame.setVisible(!frame.isVisible()); 
           } 
          }); 
    
          JPanel panel = new JPanel(); 
          panel.add(toggleButton); 
    
          add(panel); 
         } 
        } 
    } 
    

    이 예제를 실행하려면. 그러면 TestFrame이 표시됩니다.

  2. "모달 대화 상자 시작"버튼을 클릭하십시오. 그러면 JOptionPane이 표시됩니다.
  3. TimerTaskTestFramedispose()JOptionPane을 숨길 때까지 2 초 정도 기다리십시오.
  4. "Toggle Frame Visibility Button"을 클릭하십시오. TestFrame이 표시되고 JOptionPane이 첨부됩니다.

나는 내가 TestFrame를 숨기기 전에 JOptionPane를 배치함으로써이 문제를 해결할 수 있다는 사실을 알고 : 왜 이런 일

- TestFrame.this.setVisible(false); 

    if (dialog != null) { 
    dialog.setVisible(false); 
    dialog.dispose(); 
    dialog = null; 
    } 

+ TestFrame.this.setVisible(false); 

는 사람은 알고 있나요? 버려지고있는 동안 숨겨진 경우에도 모달 대화 상자가 사라질 것으로 예상됩니다.

+3

[* 여러 JFrames 사용, 좋음/나쁨 연습 * *] (http://stackoverflow.com/q/9554636/230513)도 참조하십시오. – trashgod

답변

3

실제로 trashgod의 덧글은 The Use of Multiple JFrames, Good/Bad Practice?이라고 생각하지만, 여기에 왜이 동작이 나타나는 지에 대한 설명이 나와 있습니다.

이 문제는 대화 전에 대화창 소유를 숨기기 때문에 발생합니다. 그런 일을 할 때, 소유 된 대화 상자는 showWithParent으로 표시되고 프레임에서 setVisible(true)에 대한 다음 호출은 해당 플래그로 인해 소유 대화 상자의 표시를 자동으로 트리거합니다. 귀하의 질문에 명시된 바와 같이 그것을 방지하는 유일한 방법은 먼저 소유 대화 상자를 숨긴 다음 소유 창을 숨기는 것입니다.

synchronized(ownedWindowList) { 
     for (int i = 0; i < ownedWindowList.size(); i++) { 
      Window child = ownedWindowList.elementAt(i).get(); 
      if ((child != null) && child.visible) { 
       child.hide(); 
       child.showWithParent = true; // See here the flag set to true 
      } 
     } 
    } 

그리고 여기 Window.show()있어서의 대응 추출물 : Btw는

 for (int i = 0; i < ownedWindowList.size(); i++) { 
      Window child = ownedWindowList.elementAt(i).get(); 
      if ((child != null) && child.showWithParent) { // Here theh flag is checked 
       child.show(); 
       child.showWithParent = false; // flag is then reset 
      }  // endif 
     } 

대신 복잡한 타이머/TimerTask를/invokeLater 구조를 사용하여 다음

는 상기 Window.hide() 방법 추출물 그냥 javax.swing.Timer ( setRepeats(false))을 사용할 수 있습니다. Swing 타이머는 항상 Event Dispatching Thread에서 실행됩니다.

+0

정보를 제공해 주셔서 감사합니다! –

관련 문제