2012-01-07 16 views
16

Ho 2 JPanel in una cornice. Il primo pannello contiene elementi java come pulsanti, ecc. I due pulsanti che ho aggiunto appaiono ma JSpinner appare subito dopo aver ridimensionato la finestra. Immagino che questo accadrà anche con altri elementi che aggiungerò. Come potrei risolvere questo problema?Gli elementi Java compaiono solo dopo il ridimensionamento della finestra

import java.awt.BorderLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.WindowAdapter; 
import java.util.ArrayList; 
import java.util.List; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JSpinner; 
import javax.swing.SpinnerListModel; 
import javax.swing.SpinnerNumberModel; 

public class StartingPoint { 

static JFrame window; 
static DrawingArea draw; 
static JButton b1, b2; 
static JPanel userInt; 
static JSpinner gravitySpinner; 

public static void main(String[] args) { 
    window = new JFrame("Ball"); 
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    window.setSize(600, 400); 
    window.setLayout(new BorderLayout()); 
    window.setVisible(true); 

    draw = new DrawingArea(); 
    window.add(draw, BorderLayout.CENTER); 

    userInt = new JPanel(); 
    window.add(userInt, BorderLayout.NORTH); 

    b1 = new JButton("Start"); 
    b2 = new JButton("aaa"); 
    b1.addActionListener(new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      draw.setUp(); 
     } 
    }); 
    userInt.add(b1); 
    userInt.add(b2); 


    SpinnerNumberModel gravityModel = new SpinnerNumberModel(.9, .1, 2, .1); 
    gravitySpinner = new JSpinner(gravityModel); 
    userInt.add(gravitySpinner); 
} 
} 

risposta

29

Stai l'aggiunta di componenti per l'interfaccia grafica dopo chiamando setVisible(true) sul JFrame e che è a ritroso dal momento che si sta rendendo il GUI prima è stato aggiunto nulla, e quindi ha senso che le cose aggiunti in seguito ha vinto' t essere visualizzato fino a quando tutto è ridipinto.

Invece, prima aggiungere tutti i componenti, e solo quindi eseguire il rendering della GUI chiamando setVisible(true) sulla JFrame.

Modifica
Inoltre, ti consigliamo di evitare di chiamare setSize(...) su qualsiasi cosa, ma invece far dimensionare componenti stessi utilizzando le loro preferredSizes e chiamando pack() sul JFrame prima di visualizzare con setVisible(true).

Edit 2
Ad esempio:

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JSpinner; 
import javax.swing.SpinnerNumberModel; 
import javax.swing.SwingUtilities; 

public class StartingPoint { 

    private DrawingArea draw; 
    private JButton b1, b2; 
    private JPanel userInt; 
    private JSpinner gravitySpinner; 

    private JPanel mainPanel = new JPanel(); 

    public StartingPoint() { 
     mainPanel.setLayout(new BorderLayout()); 
     draw = new DrawingArea(); 
     mainPanel.add(draw, BorderLayout.CENTER); 

     userInt = new JPanel(); 
     mainPanel.add(userInt, BorderLayout.NORTH); 

     b1 = new JButton("Start"); 
     b2 = new JButton("aaa"); 
     b1.addActionListener(new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      draw.setUp(); 
     } 
     }); 
     userInt.add(b1); 
     userInt.add(b2); 

     SpinnerNumberModel gravityModel = new SpinnerNumberModel(.9, .1, 2, .1); 
     gravitySpinner = new JSpinner(gravityModel); 
     userInt.add(gravitySpinner); 
    } 

    public JPanel getMainPanel() { 
     return mainPanel; 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      JFrame window = new JFrame("Ball"); 
      window.add(new StartingPoint().getMainPanel()); 
      window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

      window.pack(); 
      window.setLocationRelativeTo(null); 
      window.setVisible(true); 
     } 
     }); 
    } 
} 

class DrawingArea extends JPanel { 

    private static final int PREF_W = 600; 
    private static final int PREF_H = 400; 

    public void setUp() { 
     // TODO finish 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     return new Dimension(PREF_W, PREF_H); 
    } 

} 
+2

E si desidera avvolgere tutto il codice nel metodo principale in una chiamata 'EventQueue.invokeLater()' per rispettare la [politica di thread Swing] (http://docs.oracle.com/javase/7/docs/ api/javax/swing/package-summary.html # threading) – Robin

+0

Dovrei spostare tutto il mio codice dal metodo principale nel metodo run e nel mathod principale devo aggiungere questo $ SwingUtilities.invokeLater (new StartingPoint()); ? – Alex

+0

@Alex: elimineresti * tutto * statico nel codice qui sopra, crea il tuo JPanel gui nella classe stessa, quindi nel tuo principale crea un Runnable che inizializza la tua classe, aggiunge il JPanel della classe a una JFrame e poi visualizza il JFrame. Ad esempio, vedi ** Modifica 2 ** sopra. –

4

Aggiungere setVisible(true) alla fine e funziona.

Problemi correlati