Java Swing dispose() vs setVisible(false)
J'ai une application Java autonome qui récupère les données d'une base de données et l'affiche dans une JTable. Au démarrage de l'application, l'utilisateur est invité à entrer un nom d'utilisateur/mot de passe dans un JDialog. Une fois les informations d'identification correctes sont entrés, le principal JFrame contenant les données à afficher. Sur les principaux JFrame j'ai un bouton de déconnexion que lorsque l'on clique dessus, doit fermer le JFrame et de réafficher la connexion JDialog. Tout ce qui est la plupart du temps de travail sauf que j'ai trouvé que le principal JFrame ne disparaissent pas lorsque le bouton de déconnexion est cliqué. Ci-dessous un petit exemple de mon code:
Main.java:
import javax.swing.SwingUtilities;
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new MainFrame();
}
});
}
}
MainFrame.java:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
public class MainFrame extends JFrame implements ActionListener {
private JButton button;
private MyDialog dialog;
public MainFrame() {
super("this is the JFrame");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
dialog = new MyDialog(this);
button = new JButton("click me to hide this JFrame and display JDialog");
button.addActionListener(this);
add(button);
pack();
setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
setVisible(false); //works when changed to dispose();
dialog.setVisible(true);
}
}
MyDialog.java:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
public class MyDialog extends JDialog implements ActionListener {
private JFrame parentFrame;
private JButton button;
public MyDialog(JFrame parentFrame) {
super(parentFrame, "this is the JDialog", true);
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
this.parentFrame = parentFrame;
button = new JButton("click me to hide JDialog and show JFrame");
button.addActionListener(this);
add(button);
pack();
setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
setVisible(false);
parentFrame.setVisible(true);
}
}
Dans MainFrame.java si je change la ligne qui dit setVisible(false)
à dispose()
puis la JFrame s'en va quand je clique sur le bouton. Ma question est, pourquoi est-ce de travailler avec dispose()
et pas avec setVisible(false)
? Est-il un meilleur moyen pour moi d'organiser mon code? Je suis nouveau sur le Swing, donc je m'excuse si c'est une question de base. Merci.
ÉDITÉ 2011-10-19 10:26 PDT
Merci à vous tous pour votre aide. J'ai changé le JDialog avoir une valeur null parent et maintenant tout fonctionne comme je le voulais.
OriginalL'auteur user1002119 | 2011-10-18
Vous devez vous connecter pour publier un commentaire.
Voir la ligne où vous lancez le JDialog:
De la configuration de la même image que le parent qu'un cadre de la boîte de dialogue se trouve sur. Vous voyez, une boîte de dialogue apparaît pas sur son propre, il doit s'asseoir sur le dessus d'un parent cadre.
Donc, dans votre code, lorsque vous écrivez:
Dans la première ligne, vous dites le cadre de disparaître, puis vous dites à la boîte de dialogue apparaît, qui raconte vraiment de la boîte de dialogue qui apparaîtra sur son bloc parent. Depuis le parent cadre est le même, on dirait qu'il reste visible pour vous. Si vous supprimez la seconde ligne, je suis sûr que l'image disparaît. Mais quand vous dites le cadre de disposer, à ce qu'il disparaisse totalement, car vous lui avez dit de ne pas juste pour perdre de la visibilité, mais aussi supprimer de la mémoire.
Puis, quand vous dites à la boîte de dialogue paraître, elle recherche son JFrame (qui a été éliminé), re-initialise et ouvre.
La façon de résoudre votre problème, c'est de faire une nouvelle JFrame pour le JDialog. Ensuite, ne pas utiliser de disposer et d'utiliser seulement la setVisible commande.
-Asaf
MyDialog()
aller:super(null, "this is the JDialog", false);
. Si la trame principale est caché de ne pas recevoir des commentaires utiles de toute façon, donc il n'y a pas de raison de faire de la boîte de dialogue modale.Vous avez raison, c'est aussi une option. J'ai oublié que le booléen il est pour la modalité. Aussi, je suis assez certain que le booléen modalité a été désapprouvée et la ModalityType méthode est maintenant préféré.
Pas vraiment obsolète, du moins pas officiellement. Il est précisé à quelle valeur booléenne correspondant à la modalité de type, de sorte qu'il est probablement juste une question de style que celle que vous préférez.
Intéressant, parce que si vous essayez d'utiliser setModal(boolean modal) dans eclipse, il est marqué comme obsolète.
Dans la version de Java qui est fourni avec OS X, il n'est pas marqué dans la doc (ni avec
@Deprecated
, ou le correspondant balise javadoc), et je n'ai pas l'avertissement du compilateur lors de la construction avec javac à partir de l'Ide, donc j'aurais de la craie que jusqu'à l'Éclipse d'avoir sa propre opinion de ce. Les docs mentionsetModal()
est "obsolète", de façon à ce que pourrait être la motivation. (Ils ne disent pas que sur les constructeurs.)OriginalL'auteur Asaf
Je vais simplement donner le code est correct, dans mon propre style. Il n'est certainement pas le seul ou même prouvé meilleure solution.
setVisible(false) sur le cadre principal doit invoquer l'opération de fermeture, logiquement pour un cadre principal EXIT_ON_CLOSE. Si le dialogue est un enfant de la trame principale, puis l'application se ferme.
J'ai donc pris une boîte de dialogue modale une deuxième fenêtre du haut, qui a une (JFrame)null en tant que parent. Par conséquent, vous avez une application avec deux top windows. Et les boîtes de dialogue modales sont à chaque fois éliminés.
J'ai fait la boîte de dialogue modale DO_NOTHING_ON_CLOSE, comme vous ne voulez pas l'icône de fermeture de la fonction.
D'où le dispose() dans le actionPerformed.
(Si vous avez, à tout moment, un parent, vous pouvez utiliser getOwner() au lieu de copier le parent d'un champ.)
OriginalL'auteur Joop Eggen