Problema com setvisible (true)
-
18-09-2019 - |
Pergunta
Os dois exemplos mostrados abaixo são os mesmos. Ambos devem produzir o mesmo resultado, por exemplo, gerar as coordenadas das imagens exibidas no JPanel. Exemplo 1, funciona perfeitamente (imprima as coordenadas das imagens), no entanto, o Exemplo 2 retornando 0 para a coordenada.
Fiquei me perguntando por que, porque eu coloquei o setVisible (verdadeiro) depois de adicionar o painel, nos dois exemplos. A única diferença é que o exemplo 1 usado extends JPanel
e Exemplo 2 extends JFrame
EXEMPLO 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);
}
}
Exemplo 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();
}
}
Solução
O problema é que, no segundo exemplo, você está tentando imprimir os limites de um componente antes que o componente seja adicionado ao seu contêiner (chamando add()
) e antes que o conteúdo do quadro seja apresentado (ligando pack()
).
Aqui está minha tentativa de reproduzir o Exemplo 1. ...
Aqui está minha tentativa de reproduzir o exemplo 2. Eu adicionei o SwingUtilities
Ligue para colocar as coisas no tópico certo, e eu preenchi o conteúdo do GetCoordiates
Construtor com a ajuda de seus comentários:
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();
}
});
}
}
Assim como você descreveu, ele imprime um tamanho de zero:
Coordenada: java.awt.rectangle [x = 0, y = 0, largura = 0, altura = 0
No entanto, se você imprimir o tamanho após o componente ter sido adicionado e o quadro foi embalado, ele deve funcionar. Aqui está uma versão modificada do meu exemplo 2, onde adicionei um método GetCoordinate.printBounds()
e chame esse método de tudo foi adicionado e estabelecido:
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();
}
});
}
}
Com essas mudanças, recebo a seguinte saída do console, incluindo um tamanho diferente de zero para o meu conteúdo:
Coordenada: java.awt.rectangle [x = 5, y = 5, largura = 23, altura = 16
Outras dicas
Uma causa comum de tais anomalias está deixando de começar no EDT. Nesse caso, não sei dizer pelo seu código o que é diferente: em particular, não está claro onde o segundo exemplo imprime.
Contoh
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);
}
}