2012-01-07 20 views
16

Tengo 2 JPanels en un marco. El primer panel contiene elementos de Java, como botones, etc. Aparecen los dos botones que agregué pero el JSpinner aparece justo después de cambiar el tamaño de la ventana. Supongo que esto sucederá también con otros artículos que agregaré. ¿Cómo podría resolver este problema?Los elementos de Java aparecen solo después de cambiar el tamaño de la ventana

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); 
} 
} 

Respuesta

29

Has añadido componentes de la interfaz gráfica de usuario después de llamar a setVisible(true) en el JFrame y eso es al revés ya que estás haciendo que la interfaz gráfica de usuario antes de que algo se ha añadido, y así que tiene sentido que las cosas añadieron más tarde ganó' t se mostrará hasta que todo esté repintado.

En su lugar, primero agregue todos sus componentes, y solo luego represente la GUI llamando al setVisible(true) en el JFrame.

Editar
También, usted querrá evitar llamar setSize(...) en otra cosa que en cambio dejar componentes de tamaño sí mismos con sus preferredSizes y llamando pack() en el JFrame antes de mostrar con setVisible(true).

Editar 2
Por ejemplo:

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

Y desea ajustar todo su código en su método principal en una llamada 'EventQueue.invokeLater()' para respetar la [política de enhebrado de Swing] (http://docs.oracle.com/javase/7/docs/ api/javax/swing/package-summary.html # threading) – Robin

+0

Debería mover todo mi código desde el método principal en el método run y en mathod principal tengo que agregar este $ SwingUtilities.invokeLater (new StartingPoint()); ? – Alex

+0

@Alex: Usted se desharía de * todo * estático en el código anterior, cree su GUI de JPanel en la clase misma, luego en su principal cree un Runnable que inicialice su clase, agregue el JPanel de la clase a un JFrame y luego muestre el JFrame. Por ejemplo, vea ** Editar 2 ** arriba. –

4

Añadir setVisible(true) al final y funciona.

Cuestiones relacionadas