2009-03-29 11 views
0

저는 수석 디자인 프로젝트를 위해 Netbeans 6.1에서 GUI를 만드는 중이지만 성가신 걸림돌을 겪었습니다. 내 로그인 PopUp과 같은 다른 임시 윈도우는 내가 말할 때 사라집니다. 나는 약 2 개월 동안 이것을 해결하는 방법을 연구 해왔다. 나도 내 팝업에 대한 별도의 스레드를 화나게했지만 여전히 작동하지 않을 것이다 .... 내가 말 그대로 다른 GUI 구성 요소 중 하나를 엉망으로하지 않으면 사라질 유일한 방법 .... 내 샘플 코드는 내 설명을 도와야한다 내 분노 ... 그림자 코드에 신경 쓰지 마라. 테스트 목적이었다. 분명히 도움이되지 않았다.왜 내 JFrame은 숨기지 않습니까?

//This method is called once a user presses the "first" login button on the main GUI 
public synchronized void loginPopUpThread() { 
    doHelloWorld = new Thread(){ 
     @Override 
     public synchronized void run() 
     { 
      try 
      { 
        loginPopUpFrame.pack(); 
        loginPopUpFrame.setVisible(true); 
        System.out.println("waitin"); 
        doHelloWorld.wait(); 
        System.out.println("Not Sleepin.."); 
        loginPopUpFrame.pack(); 
        loginPopUpFrame.setVisible(false); 
      } 
      catch (InterruptedException e) 
      { 
      } 
     } 
    }; 
    doHelloWorld.start(); 

//This is called when the "second" loginB is pressed and the password is correct... 
public synchronized void notifyPopUp() { 
    synchronized(doHelloWorld) { 

     doHelloWorld.notifyAll(); 
     System.out.println("Notified"); 
    } 
} 

스윙 유틸리티를 사용해 보았지만 어쩌면 처음 사용했을 때 잘못 구현했습니다. 그것은 본질적으로 위의 코드 나던 할 코드가 기다려야 얻을 때 창이 정지 제외하고는 상기와 같은 일, 수행합니다

javax.swing.SwingUtilities.invokeLater(new Runnable() { 
     public synchronized void run() { 
      try 
      { 
        loginPopUpFrame.pack(); 
        loginPopUpFrame.setVisible(true); 
        System.out.println("waitin"); 
        wait(); 
         System.out.println("Not Sleepin."); 
         loginPopUpFrame.pack(); 
         loginPopUpFrame.setVisible(false); 
      } 
      catch (InterruptedException e) 
      { 
      } 
     } 
    }); 

이 좀 도와주세요!

답변

1

규칙 :

  • 가 조작하지 마십시오 임의 스레드의 GUI 구성 요소. 항상 기다려야하거나 이벤트 thread (그래서, invokeLater로 전송 결코 내부 코드())

그래서 당신이 해결 방법에 대한 답이 문제가 내부에 잠

  • 절대로 이벤트 스레드를 조작 할 준비 "다른 방법"...

    문제가 조금 돌아 서서, 실제로 무엇을하려고합니까? 사용자가 사용자 이름과 암호를 입력 할 때까지 기다리기위한 로그인 대화 상자를 원한다면 모달 JDialog를 사용하지 않는 이유가 무엇인지 (결국 그 이유는 무엇인지 ...).

    당신이 정말로 어떤 임의의 스레드가/창을 닫으 GUI를 조작, 다음 필요가 다른 스레드에서 대기 할 다음 스레드 호출 SwingUtilities의를 만들기 위해 신호를 기다리고 싶지 않는 경우. 실제 GUI 조작 코드로 invokeLater()를 호출하십시오.

    P.실제로는 다른 스레드에서 호출하는 것이 안전 한 GUI 조작 방법이 있습니다. "레이블을 설정하는 것"인 호출은 종종 안전합니다. 하지만 어떤 호출이 안전한지는 잘 정의되어 있지 않으므로 실제로 문제를 피하는 것이 가장 좋습니다.

  • +0

    나는 너희들이 맞을 것 같아 ... 내가 원하는 모든 것은 나타나는 창이있다. 사용자가 목록에서 그의 이름을 선택하고, 암호를 입력하고, 암호가 확인 되 자마자 나는 창을 그냥 사라지기를 원했다. 내 행운을 시험하기 위해 지금 프레임을 대화 상자로 바꾸는 것 – durrellp

    +0

    문서 스레드로부터 안전하지 않다면 그렇지 않다. 사실 JDK7은 메서드가 thread-safe 인 일부 문서를 제거합니다. –

    1

    스윙 구성 요소는 스윙 이벤트 발송 스레드에서만 조작해야합니다.

    클래스 SwingUtilites에는 작업을 발송 스레드에 제출하는 메서드가 있습니다.

    +0

    하 - 예, 학습은 어렵습니다. :) – javamonkey79

    +0

    나는 대답을 이해하지 못한다. plz는 내가 SwingUtilities를 올바르게 사용한 것으로 생각해서 추가 된 것을 읽었다. – durrellp

    +0

    코드가 정말로 이상하게 보인다. 나는 당신이 돌아가서 태양 스윙 튜토리얼을 읽고 처음부터 다시 시작할 것을 조언 할 것이다. – willcodejavaforfood

    0

    문제를 진단하기가 어렵습니다. wait 방법으로 무엇을 하려는지 확실하지 않지만 wait/notify 만 남겨 두는 것이 좋습니다.

    이 코드에는 두 개의 프레임이 있습니다. 두 번째 프레임을 만들면 첫 번째 프레임을 닫을 때까지 첫 번째 프레임이 숨겨집니다.

    public class SwapFrames { 
    
        private JFrame frame; 
    
        private JFrame createMainFrame() { 
        JButton openOtherFrameButton = new JButton(
         "Show other frame"); 
    
        frame = new JFrame(); 
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        Container contentPane = frame.getContentPane(); 
        contentPane.setLayout(new FlowLayout()); 
        contentPane.add(openOtherFrameButton); 
        frame.pack(); 
    
        openOtherFrameButton 
         .addActionListener(new ActionListener() { 
          @Override 
          public void actionPerformed(ActionEvent e) { 
          onClickOpenOtherFrame(); 
          } 
         }); 
    
        return frame; 
        } 
    
        private void onClickOpenOtherFrame() { 
        frame.setVisible(false); 
    
        JFrame otherFrame = new JFrame(); 
        otherFrame 
         .setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
        otherFrame.setContentPane(new JLabel(
         "Close this to make other frame reappear.")); 
        otherFrame.pack(); 
        otherFrame.setVisible(true); 
        otherFrame.addWindowListener(new WindowAdapter() { 
         @Override 
         public void windowClosed(WindowEvent e) { 
         frame.setVisible(true); 
         } 
        }); 
        } 
    
        public static void main(String[] args) { 
        JFrame frame = new SwapFrames().createMainFrame(); 
        frame.setVisible(true); 
        } 
    
    } 
    

    난 당신의 코드에서의 증거가 표시되지 않기 때문에

    , 난 당신을 제안 read up on using event listeners 오히려 코드가 끝날 때까지 "대기"하는 것보다거야.

    당신이 달성하려고하는지 완전히 명확하지 않다, 그러나 당신이 모달 대화에 더 좋을 수도 있습니다 : 엄지 손가락의

    public class DialogDemo { 
    
        public JFrame createApplicationFrame() { 
        JButton openDialogButton = new JButton("Open Dialog"); 
    
        final JFrame frame = new JFrame(); 
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        Container container = frame.getContentPane(); 
        container.setLayout(new FlowLayout()); 
        container.add(openDialogButton); 
        frame.pack(); 
    
        openDialogButton 
         .addActionListener(new ActionListener() { 
          @Override 
          public void actionPerformed(ActionEvent e) { 
          onOpenDialog(frame); 
          } 
         }); 
    
        return frame; 
        } 
    
        private void onOpenDialog(JFrame frame) { 
        JDialog dialog = createDialog(frame); 
        dialog.setVisible(true); 
        } 
    
        private JDialog createDialog(JFrame parent) { 
        JButton closeDialogButton = new JButton("Close"); 
    
        boolean modal = true; 
        final JDialog dialog = new JDialog(parent, modal); 
        dialog 
         .setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); 
        Container container = dialog.getContentPane(); 
        container.add(closeDialogButton); 
        dialog.pack(); 
        dialog.setLocationRelativeTo(parent); 
    
        closeDialogButton 
         .addActionListener(new ActionListener() { 
          @Override 
          public void actionPerformed(ActionEvent e) { 
          dialog.setVisible(false); 
          } 
         }); 
    
        return dialog; 
        } 
    
        public static void main(String[] args) { 
        new DialogDemo().createApplicationFrame().setVisible(
         true); 
        } 
    
    } 
    
    0

    방법은 간단하고 약 :

    //This method is called once a user presses the "first" login button on the main GUI 
    public void loginPopUpThread() { 
        SwingUtilities.invokeLater(new Runnable() { 
         public void run() { 
          loginPopUpFrame.pack(); 
          loginPopUpFrame.setVisible(true); 
         } 
        }; 
    } 
    
    //This is called when the "second" loginB is pressed and the password is correct... 
    public void notifyPopUp() { 
        SwingUtilities.invokeLater(new Runnable() { 
         public void run() { 
          loginPopUpFrame.setVisible(false); 
         } 
        }; 
    } 
    
    0

    은 무엇 당신이 정말로 사용하고 싶은 것은 모달 JDialog를합니다.

    참고로이 비트는 제외되었습니다. 숙제/프로젝트입니다.

    public void actionPerformed(ActionEvent e) 
    { 
        // User clicked the login button 
        SwingUtilities.invokeLater(new Runnable() 
        { 
         public void run() 
         { 
         LoginDialog ld = new LoginDialog(); 
         // Will block 
         ld.setVisible(true); 
         } 
        }); 
    } 
    
    public class LoginDialog extends JDialog 
    { 
        public LoginDialog() 
        { 
         super((Frame)null, "Login Dialog", true); 
    
         // create buttons/labels/components, add listeners, etc 
        } 
    
        public void actionPerformed(ActionEvent e) 
        { 
         // user probably clicked login 
         // valid their info 
         if(validUser) 
         { 
          // This will release the modality of the JDialog and free up the rest of the app 
          setVisible(false); 
          dispose(); 
         } 
         else 
         { 
          // bad user ! scold them angrily, a frowny face will do 
         } 
        } 
    } 
    
    +0

    대화 상자로 바뀌었고 더 이상 가시성 문제가 없었습니다 ... 모든 입력에 대해 모두에게 감사드립니다. 절대로 jFrame과 jDialog의 차이를 본적이 없으므로 프레임을 임의로 사용했습니다. – durrellp