Por que não vai o meu JFrame esconder?
-
22-08-2019 - |
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 !!!
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
}
}
}