Question

Je suis en train de créer une interface graphique dans Netbeans 6.1 pour mon projet de conception supérieure, mais j'ai rencontré un accroc ennuyeux. Fenêtres temporaires comme mon login PopUp et d'autres wont disparaissent quand je le dis. J'ai fait des recherches sur la façon de résoudre ce pendant environ 2 mois sur un arrêt. J'ai même fou un thread séparé pour mon pop-up, mais il ne sera pas encore du travail .... la seule façon il disparaîtra si je ne plaisante pas avec littéralement l'un des autres composants de l'interface graphique .... mon exemple de code devrait aider à décrire mon la colère ... ne vous dérange pas le code de l'ombre, il était à des fins de test, qui, évidemment, cela n'a pas aidé.

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

J'ai aussi essayé swing Utilities mais peut-être que je mis en œuvre mal car il est ma première fois de les utiliser. 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:

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 HELP ME !!!

Était-ce utile?

La solution

Règles de base:

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

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

en retrait du problème un peu, c'est-ce que vous êtes en train d'essayer de le faire? Si vous voulez juste une boîte de dialogue de connexion pour attendre l'utilisateur d'entrer le nom d'utilisateur et mot de passe, est-il une raison de ne pas simplement utiliser un JDialog modal (après tout, c'est ce qu'il est là pour ...).

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 le fil appel SwingUtilities.invokeLater () avec le code de manipulation de l'interface graphique réelle.

P.S. Il y a en fait des méthodes de manipulation de l'interface qu'il est sûr d'appeler d'autres fils, par exemple les appels qui sont « juste une étiquette de réglage » sont souvent en toute sécurité. Mais qui sont les appels en toute sécurité est pas très bien défini, il est donc préférable d'éviter tout le problème dans la pratique.

Autres conseils

Les composants Swing ne doivent être manipulés par le fil de la distribution d'événements swing.

classe SwingUtilites a des méthodes pour soumettre des tâches au fil d'expédition.

Il est difficile de diagnostiquer votre problème. Je ne sais pas ce que vous essayez de faire avec le attendre des méthodes , mais je recommande de laisser attendre / notifier seul.

Ce code a deux cadres - lorsque vous créez un second cadre, le premier est caché jusqu'à ce que vous 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

Que diriez-vous de faire simplement:

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

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

Note, les bits de ce sont laissés de côté. Il est votre travail / 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
       }
    }
}
scroll top