Problème avec setvisible (vrai)
-
18-09-2019 - |
Question
Les deux exemples illustrés ci-dessous sont les mêmes. Les deux sont censés produire le même résultat, par exemple, génèrez les coordonnées des images affichées sur JPanel. L'exemple 1, fonctionne parfaitement (imprimez les coordonnées des images), mais l'exemple 2 renvoyant 0 pour la coordonnée.
Je me demandais pourquoi parce que j'ai mis le setvisible (vrai) après avoir ajouté le panneau, dans les deux exemples. La seule différence est que l'exemple 1 utilisé extends JPanel
et exemple 2 extends JFrame
EXEMPLE 1:
public class Grid extends JPanel{
public static void main(String[] args){
JFrame jf=new JFrame();
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final Grid grid = new Grid();
jf.add(grid);
jf.pack();
Component[] components = grid.getComponents();
for (Component component : components) {
System.out.println("Coordinate: "+ component.getBounds());
}
jf.setVisible(true);
}
}
Exemple 2:
public class Grid extends JFrame {
public Grid () {
setLayout(new GridBagLayout());
GridBagLayout m = new GridBagLayout();
Container c = getContentPane();
c.setLayout (m);
GridBagConstraints con = new GridBagConstraints();
//construct the JPanel
pDraw = new JPanel();
...
m.setConstraints(pDraw, con);
pDraw.add (new GetCoordinate ()); // call new class to generate the coordinate
c.add(pDraw);
pack();
setVisible(true);
}
public static void main(String[] args) {
new Grid();
}
}
La solution
Le problème est que dans le deuxième exemple, vous essayez d'imprimer les limites d'un composant avant que le composant ne soit ajouté à son conteneur (en appelant add()
) Et avant que le contenu du cadre n'ait été présenté (en appelant pack()
).
Voici ma tentative de reproduction de l'exemple 1. ...
Voici ma tentative de reproduction de l'exemple 2. J'ai ajouté le SwingUtilities
Appelez pour mettre des choses dans le bon fil, et j'ai rempli le contenu du GetCoordiates
Constructeur avec l'aide de vos commentaires:
class GetCoordinate extends JLabel {
public GetCoordinate() {
setText("Foo!");
System.out.println("Coordinate: " + this.getBounds());
}
}
public class Grid extends JFrame {
public Grid() {
setLayout(new GridBagLayout());
GridBagLayout m = new GridBagLayout();
Container c = getContentPane();
c.setLayout(m);
GridBagConstraints con = new GridBagConstraints();
// construct the JPanel
final JPanel pDraw = new JPanel();
m.setConstraints(pDraw, con);
pDraw.add(new GetCoordinate()); // call new class to generate the
// coordinate
c.add(pDraw);
pack();
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Grid();
}
});
}
}
Tout comme vous l'avez décrit, il imprime une taille de zéro:
Coordonnée: java.awt.rectangle [x = 0, y = 0, largeur = 0, hauteur = 0
Cependant, si vous imprimez la taille après l'ajout du composant et que le cadre a été emballé, cela devrait fonctionner. Voici une version modifiée de mon exemple 2, où j'ai ajouté une méthode GetCoordinate.printBounds()
Et appelez cette méthode que tout a été ajouté et présenté:
class GetCoordinate extends JLabel {
public GetCoordinate() {
setText("Foo!");
// Let's not try to do this here anymore...
// System.out.println("Coordinate: " + this.getBounds());
}
public void printBounds() // <-- Added this method
{
System.out.println("Coordinate: " + this.getBounds());
}
}
public class Grid extends JFrame {
public Grid() {
setLayout(new GridBagLayout());
GridBagLayout m = new GridBagLayout();
Container c = getContentPane();
c.setLayout(m);
GridBagConstraints con = new GridBagConstraints();
// construct the JPanel
final JPanel pDraw = new JPanel();
m.setConstraints(pDraw, con);
final GetCoordinate content = new GetCoordinate();
pDraw.add(content);
c.add(pDraw);
pack();
setVisible(true);
content.printBounds(); // <-- Added this
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Grid();
}
});
}
}
Avec ces modifications, j'obtiens la sortie de la console suivante, y compris une taille non nulle pour mon contenu:
Coordonnées: java.awt.rectangle [x = 5, y = 5, largeur = 23, hauteur = 16
Autres conseils
Une cause commune de telles anomalies ne parvient pas à commencer EDT. Dans ce cas, je ne peux pas dire à partir de votre code ce qui est différent: en particulier, il n'est pas clair où le deuxième exemple imprime.
controh
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author LENOVO G40
*/
public class Main {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
new FrmMenuUTama().setVisible(true);
}
}