2009-03-29 21 views
0

Ich bin gerade dabei, eine GUI in Netbeans 6.1 für mein Senior-Design-Projekt zu erstellen, aber ich habe einen nervigen Haken gefunden. Temporäre Windows wie mein Login PopUp und andere verschwinden nicht, wenn ich es erzähle. Ich habe erforscht, wie man das für ungefähr 2 Monate auf einem weg löst. Ich habe sogar einen separaten Thread für mein Pop Up gemacht, aber es wird immer noch nicht funktionieren .... die einzige Art und Weise, wie es verschwinden wird, wenn ich mich buchstäblich mit keiner der anderen GUI-Komponenten anlege .... mein Beispielcode sollte helfen, meine zu beschreiben Wut ... achtet nicht auf den Schattencode, es war zu Testzwecken, was offensichtlich nicht geholfen hat.Warum wird mein JFrame nicht versteckt?

Ich habe auch Swing Utilities versucht, aber vielleicht habe ich es falsch implementiert, da es das erste Mal ist, dass ich sie benutze. Es tut im Wesentlichen dasselbe wie der Code oben, mit Ausnahme der Fenster frieren 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 MICH !!!

Antwort

1

Faustregeln:

  • nicht manipulieren Sie GUI-Komponenten in beliebigen Threads; immer ordnen sie im Fall Faden
  • nie in dem Ereignis-Thread (so, nie in Code zu invokeLater() gesendet)

die Antwort auf Also warten oder Schlaf zu manipulieren, wie Sie lösen dieses Problem "etwas anderes" ...

Etwas zurückstehen von dem Problem, Was ist es eigentlich, was du versuchst zu tun? Wenn Sie nur wollen, dass ein Login-Dialog darauf wartet, dass der Benutzer Benutzernamen und Passwort eingibt, gibt es einen Grund, nicht nur einen modalen JDialog zu verwenden (schließlich ist es das, wofür er da ist ...).

Wenn Sie wirklich etwas willkürlich Thread wollen für ein Signal zu warten, bis das Fenster/manipulieren, um die GUI zu schließen, Sie dann Notwendigkeit, die Warte in dem anderen Thread, zu tun und dann dass Thread Anruf SwingUtilities machen. invokeLater() mit dem eigentlichen GUI-Manipulationscode.

P.S.Es gibt tatsächlich einige GUI-Manipulationsmethoden, die von anderen Threads, z. Anrufe, die "nur ein Label setzen" sind oft sicher. Aber welche Anrufe sicher sind, ist nicht besonders gut definiert, daher ist es am besten, das Problem in der Praxis zu vermeiden.

+0

Ich denke ihr habt recht ... Alles was ich will ist das Fenster um zu erscheinen, ein Benutzer wählt seinen Namen aus einer Liste aus, tippt sein Passwort und sobald das Passwort bestätigt ist, wollte ich das Fenster einfach verschwinden lassen. Ich ändere jetzt den Rahmen in einen Dialog, um mein Glück zu testen – durrellp

+0

Wenn es nicht threadsicheres Dokument ist, ist es nicht. Tatsächlich entfernt JDK7 einige Dokumentationen, dass Methoden Thread-sicher sind, weil sie nicht waren (und konnten). –

1

Die Swing-Komponenten sollten nur vom Thread des Swing-Ereignisversands manipuliert werden.

Klasse SwingUtilites verfügt über Methoden zum Senden von Aufgaben an den Versandthread.

+0

Ha - ja, das ist eine Lektion hart gelernt. :) – javamonkey79

+0

ich verstehe nicht die Antwort, PLZ wieder lesen, was ive hinzugefügt, wie ich denke, dass ich SwingUtilities richtig ... – durrellp

+0

Ihr Code sieht wirklich komisch aus. Ich würde dir raten, zurück zu gehen und die Sun Swing Tutorials zu lesen und wieder von vorne anzufangen. – willcodejavaforfood

0

Es ist schwierig, Ihr Problem zu diagnostizieren. Ich bin mir nicht sicher, was Sie mit den Methoden wait zu tun versuchen, aber ich empfehle wait/notify allein zu verlassen.

Dieser Code hat zwei Frames - wenn Sie einen zweiten Frame erstellen, wird der erste verborgen, bis Sie ihn 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 Sie keine Beweise für sie in Ihrem Code sehen, werde ich vorschlagen, read up on using event listeners anstatt zu versuchen, zu „warten“ für Code zu beenden.

Es ist nicht ganz klar, was Sie erreichen wollen, aber Sie könnten mit einem modalen Dialog besser dran:

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

Wie wäre es einfach tun:

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

Was Sie wirklich verwenden wollen ein modaler JDialog ist.

Hinweis, Bits davon sind weggelassen. Es ist deine Hausaufgabe/dein 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 
     } 
    } 
} 
+0

Ich habe auf Dialoge gewechselt und keine Sichtbarkeitsprobleme mehr ... DANKE ALLE FÜR ALLE IHREN EINGANG. Ich habe den Unterschied zwischen jFrame und jDialog nie wirklich gesehen, also habe ich willkürlich nur Frames verwendet. – durrellp

Verwandte Themen