Problema con setVisible (true)
-
18-09-2019 - |
Domanda
I due esempi riportati di seguito sono uguali. Entrambi sono supposti per produrre stesso risultato ad esempio generare le coordinate di immagini visualizzate sullo JPanel. Esempio 1, funziona perfettamente (stampare le coordinate di immagini), tuttavia Esempio 2 restituendo 0 per la coordinata.
Mi chiedevo perché, perché, ho messo il setVisible (vero) dopo l'aggiunta del pannello, in entrambi gli esempi. L'unica differenza è che l'esempio 1 usato extends JPanel
e l'esempio 2 extends JFrame
ESEMPIO 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);
}
}
Esempio 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();
}
}
Soluzione
Il problema è che nel secondo esempio, si sta cercando di stampare i limiti di un componente prima che il componente è stato aggiunto al suo contenitore (chiamando add()
) e prima contenuto del frame sono state stabilite (chiamando pack()
).
Ecco il mio tentativo di riprodurre esempio 1. ...
Ecco il mio tentativo di riprodurre Esempio 2. Ho aggiunto la chiamata SwingUtilities
per mettere le cose nel thread giusto, e ho compilato il contenuto del costruttore GetCoordiates
con l'aiuto di vostri commenti:
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();
}
});
}
}
Proprio come hai descritto, esso stampa una dimensione pari a zero:
Coordinate: java.awt.Rectangle [x = 0, y = 0, = 0 width, height = 0]
Tuttavia, se si stampa la dimensione dopo che il componente è stato aggiunto e il telaio è stato confezionato, dovrebbe funzionare. Ecco una versione modificata del mio esempio 2, in cui ho aggiunto un metodo GetCoordinate.printBounds()
e chiamare quel metodo tutto è stato aggiunto e disposto:
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();
}
});
}
}
Con queste modifiche, ottengo il seguente output della console, tra cui una dimensione diversa da zero per i miei contenuti:
Coordinate: java.awt.Rectangle [x = 5, y = 5, larghezza = 23, altezza = 16]
Altri suggerimenti
Una causa comune di tali anomalie non riesce a inizio il EDT . In questo caso, non posso dire dal codice ciò che è diverso:., In particolare, non è chiaro dove il secondo esempio stampe
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);
}
}