Frage

Ich bin im Begriff, eine GUI in Netbeans 6.1 für meinen Senioren Design-Projekt zu schaffen, aber ich habe in eine lästige snag laufen. Temporäre Windows-wie mein Login PopUp und andere werde nicht verschwinden, wenn ich es sage. Ich habe untersucht, wie dies auf einem elfenbein für ca. 2 Monate zu lösen. Ich habe sogar wütend einen separaten Thread für meinen Pop Up aber es wird nicht noch Arbeit .... den einzigen Weg, es wird verschwinden, wenn ich buchstäblich Chaos mit einer der anderen GUI-Komponenten nicht .... mein Beispielcode beschreiben helfen soll meine Ärger ... nicht den Schatten Code nichts, es war zu Testzwecken, die offensichtlich half nicht.

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

Ich habe auch Swing-Dienstprogramme versucht, aber vielleicht implementiert ich es falsch, wie es ist mein erstes Mal mit ihnen. Es tut im Wesentlichen dasselbe wie der Code oben, außer dem Fenster friert ein, wenn es warten wird, die die oben genannte Code tut tun:

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

Bitte helfen Sie mir !!!

War es hilfreich?

Lösung

Faustregeln:

  • Sie manipulieren nicht GUI-Komponenten in beliebigen Threads; immer ordnen sie im Falle Thread zu manipulieren
  • Nie innerhalb des Ereignis-Thread warten oder zu schlafen (so, nie in Code zu invokeLater gesendet ())

So ist die Antwort darauf, wie Sie dieses Problem lösen ist „eine andere Art und Weise“ ...

Stehendes von dem Problem ein wenig zurück, was ist es Sie tatsächlich versuchen zu tun? Wenn Sie nur ein Login-Dialog wollen für den Benutzer warten Benutzernamen und ein Passwort einzugeben, gibt es ein Grund, nicht nur auf eine modale JDialog zu verwenden (nachdem alle, das ist, was es es ist für ...).

Wenn Sie wirklich etwas beliebigen Thread wollen für ein Signal zu warten, bis das Fenster / manipulieren, um die GUI zu schließen, dann Sie müssen die Warten in dem anderen Thread tun , und dann machen dass Thread Aufruf SwingUtilities.invokeLater () mit dem tatsächlichen GUI Manipulation Code.

P. S. Es gibt tatsächlich einige GUI Manipulationsmethoden, dass es sicher ist, von anderen Threads zu nennen, z.B. Anrufe, die „nur Setzen einer Marke“ sind oft sicher sind. Aber die Anrufe sicher sind, ist nicht sehr gut definiert, so ist es am besten nur das Problem in der Praxis zu vermeiden.

Andere Tipps

Die Swing-Komponenten dürfen nur von dem Swing Event Dispatch Thread manipuliert werden.

Klasse SwingUtilites hat Methoden Aufgaben an den Dispatch Thread senden.

Es ist schwierig, Ihr Problem zu diagnostizieren. Ich bin nicht sicher, was Sie versuchen, mit dem Methoden warten, aber ich empfehle verlassen warten / benachrichtigen allein.

Dieser Code hat zwei Frames - wenn Sie einen zweiten Rahmen zu erstellen, wird die erste ausgeblendet, bis Sie es schließen

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

}

Weil ich sehe keine Anzeichen von ihnen in Ihrem Code, ich werde Sie

Wie wäre es tut einfach:

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

Was wollen Sie wirklich zu verwenden ist ein modaler JDialog.

Beachten Sie, Bits hierfür sind weggelassen. Es ist Ihre Hausaufgaben / Projekt.

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