2009-03-29 7 views
0

Je suis en train de créer une interface utilisateur graphique dans Netbeans 6.1 pour mon projet de conception senior, mais j'ai rencontré un problème gênant. Windows temporaire comme mon identifiant PopUp et d'autres ne disparaîtront pas quand je le dis. J'ai fait des recherches sur la façon de résoudre ce problème pendant environ 2 mois. J'ai même un fil séparé pour mon Pop Up, mais il ne fonctionnera toujours pas .... la seule façon dont il va disparaître si je littéralement ne pas jouer avec l'un des autres composants GUI .... mon code d'exemple devrait aider à décrire mon colère ... ne vous occupez pas du code de l'ombre, il était à des fins de test, ce qui évidemment n'a pas aidé. J'ai également essayé Swing Utilities mais peut-être que je l'ai mal implémenté car c'est la première fois que je les utilise. Il fait essentiellement la même chose que le code ci-dessus sauf la fenêtre se fige quand il fait attendre, que le code ci-dessus ne marche pas faire:Pourquoi mon JFrame ne se cache-t-il pas?

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

S'IL VOUS PLAÎT AIDEZ-MOI !!!

Répondre

1

Règles générales:

  • Ne pas manipuler Les composants de l'interface graphique dans des threads arbitraires; organiser toujours de les manipuler dans le fil des événements
  • Ne jamais attendre ou dormir à l'intérieur du fil des événements (donc, le code jamais à l'intérieur envoyé à invokeLater())

Donc la réponse à la façon dont vous résoudre ce problème est "d'une autre manière" ...

En prenant un peu de recul, qu'est-ce que vous essayez réellement de faire? Si vous voulez juste une boîte de dialogue de connexion pour attendre que l'utilisateur entre son nom d'utilisateur et son mot de passe, y at-il une raison de ne pas utiliser JDialog modal (après tout, c'est là qu'il est ...).

Si vous voulez vraiment un fil arbitraire d'attendre un signal pour fermer la fenêtre/manipuler l'interface graphique, vous besoin de faire l'attente dans l'autre thread, puis faire que SwingUtilities d'appel de fil. invokeLater() avec le code de manipulation de l'interface graphique réelle.

P.S.Il existe en fait certaines méthodes de manipulation de GUI qu'il est possible d'appeler en toute sécurité à partir d'autres threads, par ex. les appels qui "sont en train de définir une étiquette" sont souvent sans danger. Mais quels appels sont sûrs n'est pas très bien défini, il est donc préférable d'éviter le problème dans la pratique.

+0

Je suppose que vous avez raison ... Tout ce que je veux c'est que la fenêtre apparaisse, un utilisateur sélectionne son nom dans une liste, saisit son mot de passe, et dès que le mot de passe est confirmé, je veux que la fenêtre disparaisse. Im changer le cadre à un dialogue en ce moment pour tester ma chance – durrellp

+0

Si ce n'est pas le document thread-safe, il ne l'est pas. En fait, JDK7 supprime une documentation indiquant que les méthodes sont sûres pour les threads car elles ne l'étaient pas (et ne pouvaient pas le faire). –

1

Les composants Swing ne doivent être manipulés que par le fil d'expédition des événements de swing.

classe SwingUtilites propose des méthodes pour soumettre des tâches au thread d'envoi.

+0

Ha - oui, c'est une leçon difficile à apprendre. :) – javamonkey79

+0

je ne comprends pas la réponse, plz relire ce que ive ajouté comme je pense que j'ai utilisé SwingUtilities droite ... – durrellp

+0

votre code semble vraiment bizarre. Je vous conseille de revenir en arrière et lire les tutoriels Swing soleil et recommencer à zéro. – willcodejavaforfood

0

Il est difficile de diagnostiquer votre problème. Je ne suis pas sûr de ce que vous essayez de faire avec les méthodes wait, mais je recommande de laisser wait/notify seul.

Ce code a deux cadres - lorsque vous créez une deuxième image, la première est masquée jusqu'à ce que vous la fermiez.

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

} 

Parce que je ne vois aucune preuve d'entre eux dans votre code, je vais vous suggérer read up on using event listeners plutôt que d'essayer de « attendre » pour terminer le code.

Il est pas tout à fait clair ce que vous essayez d'atteindre, mais vous pourriez être mieux avec une boîte de dialogue modale:

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

Que diriez-vous simplement faire:

//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

Qu'est-ce que vous voulez vraiment être en utilisant est un JDialog modal.

Notez que les bits de ce sont omis. C'est votre devoir/projet.

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

J'ai changé pour Dialogues et pas plus de problèmes de visibilité ... MERCI BEAUCOUP À TOUT LE MONDE POUR TOUT VOTRE ENTRÉE. Je n'ai jamais vraiment vu la différence entre jFrame et jDialog donc j'ai arbitrairement juste utilisé des images. – durrellp

Questions connexes