2009-03-29 8 views
0

私はシニアデザインプロジェクトのためにNetbeans 6.1でGUIを作成していますが、迷惑をかけてしまいました。私のログインポップアップのような一時的なWindowsおよび他の人は私がそれを言うとき消えません。私は約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"); 
    } 
} 

私はSwing Utilitiesも試してみましたが、初めて使ったので間違って実装したことがあります。それは本質的に、それは上記のコードのdoesntが行うどの、待機するようになったときに、ウィンドウを除き、上記のコードと同じことがフリーズします:

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

MEを助けてください!

答えて

1

ルール:

  • 操作しないでください任意のスレッド内のGUIコンポーネント常にイベントスレッド
  • でそれらを操作するために手配ですから、この問題を解決する方法の答えがある

(そう、決してinvokeLater(に送信されたコード内))イベントスレッド内待たないまたはスリープありません"他の方法" ...

問題から少し立って、実際に何をしようとしていますか?ユーザーがユーザー名とパスワードを入力するのを待つためのログインダイアログを表示したい場合は、モーダルJDialogを使用しないようにする理由があります(結局のところ、そこにあるものです...)。

あなたは本当にあなたがして、GUIを操作する/ウィンドウを閉じるには、信号を待つために、いくつかの任意のスレッドをしたいならば他のスレッドで待機を行い、その後、そのスレッドのコールSwingUtilitiesを作成する必要があります。実際のGUI操作コードでinvokeLater()を呼び出します。

P.S.実際には、他のスレッドから安全に呼び出すことができるいくつかのGUI操作メソッドがあります。 「ラベルを設定するだけの」呼び出しはしばしば安全です。しかし、安全な呼び出しはきわめて明確に定義されているわけではないので、実際には問題を避けるのが最善です。単にことについて

+0

私は皆さんが正しいと思います...私が望むのは、ウィンドウが表示され、ユーザーがリストから自分の名前を選択し、パスワードを入力し、パスワードが確認されるとただちにウィンドウが消えたかったということです。私の運をテストするために今フレームをダイアログに変えよう – durrellp

+0

文書のスレッドセーフではない場合、それはそうではありません。実際、JDK7では、メソッドがスレッドセーフでないため、メソッドがスレッドセーフではない(およびできなかった)ため、いくつかのドキュメントが削除されています。 –

1

スイングコンポーネントは、スイングイベントディスパッチスレッドによってのみ操作される必要があります。

クラスSwingUtilitesには、ディスパッチスレッドにタスクを送信するメソッドがあります。

+0

ハ - はい、それは勉強困難です。 :) – javamonkey79

+0

私は答えを理解していない、PLZは私がSwingUtilitiesを正しく使ったと思ったので追加されたiveを読み返した。 – durrellp

+0

あなたのコードは本当に奇妙に見える。私はあなたに戻って太陽のスイングチュートリアルを読んで最初からやり直すようアドバイスします。 – willcodejavaforfood

0

問題を診断することは困難です。 waitメソッドで何をしようとしているのかよく分かりませんが、wait/notifyのままにすることをおすすめします。

このコードには2つのフレームがあります。つまり、2番目のフレームを作成すると、最初のフレームは閉じられるまで非表示になります。

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

関連する問題