Pergunta

Eu estou no processo de criar uma GUI no NetBeans 6.1 para o meu projeto de design sênior, mas eu correr em um obstáculo irritante. Temporária do Windows como meu PopUp login e outros não vão desaparecer quando eu digo isso. Estive pesquisando como resolver isso por cerca de 2 meses em off. Eu mesmo louco um segmento separado para o meu Pop Up mas ainda não vai funcionar .... a única maneira ele vai desaparecer se eu mexer, literalmente, não faça com qualquer um dos outros componentes GUI .... meu código de exemplo deve ajudar a descrever a minha raiva ... mente não faça o código de sombra, que era para fins de teste, o que obviamente não precisava de ajuda.

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

Eu também tentei Utilities balanço, mas talvez eu implementado errado, pois é a minha primeira vez de usá-los. Ele faz essencialmente a mesma coisa que o código acima, exceto os congelamentos janela quando chega a esperar, que o doesnt código acima fazer:

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

Por favor me ajude !!!

Foi útil?

Solução

Regras de ouro:

  • Não manipular componentes GUI em tópicos arbitrárias; sempre arranjar para manipulá-los no segmento de eventos
  • Nunca espere ou dormir dentro do segmento de eventos (assim, o código nunca dentro enviado para invokeLater ())

Portanto, a resposta à forma como você resolver este problema é "outra maneira" ...

que estão de volta a partir do problema um pouco, o que é que você está realmente tentando fazer? Se você quer apenas um diálogo de login que esperar para que o usuário digite o nome de usuário e senha, há uma razão para não usar apenas um JDialog modal (afinal de contas, é isso que ele está lá para ...).

Se você realmente quer alguma linha arbitrária de esperar por um sinal para fechar a janela / manipular o GUI, então você necessidade de fazer a espera na outra linha , e em seguida, fazer que SwingUtilities.invokeLater chamada thread () com o código de manipulação de GUI real.

P.S. Na verdade, existem alguns métodos de manipulação de GUI que é seguro para chamar de outros tópicos, por exemplo, chamadas que são "apenas a criação de um rótulo" são muitas vezes segura. Mas qual as chamadas são seguros não é muito bem definida, por isso é melhor apenas para evitar o problema na prática.

Outras dicas

Os componentes Swing só deve ser manipulado pelo segmento de eventos balanço expedição.

SwingUtilites classe tem métodos para enviar tarefas para o segmento de despacho.

É difícil diagnosticar o problema. Eu não tenho certeza o que você está tentando fazer com o métodos de espera , mas eu recomendo deixando espera / notificar sozinho.

Este código tem dois quadros -. Quando você cria um segundo quadro, o primeiro está escondido até você fechá-lo

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

}

Porque eu não vejo nenhuma evidência de-los em seu código, eu vou sugerir que você ler sobre usando ouvintes de eventos ao invés de tentar 'espera' para o código ao fim.

Não é totalmente claro o que você está tentando alcançar, mas você pode ser melhor fora com um diálogo modal:

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

}

Que tal fazer simplesmente:

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

O que você realmente quer estar usando é um JDialog modal.

Note, bits deste são deixados de fora. É o seu dever de casa / projeto.

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
       }
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top