2012-01-07 2 views
16

У меня есть 2 JPanel в рамке. Первая панель содержит элементы java, такие как кнопки и т. Д. Две кнопки, которые я добавил, появляются, но JSpinner появляется сразу после изменения размера окна. Я предполагаю, что это произойдет и с другими элементами, которые я добавлю. Как я могу решить эту проблему?Элементы Java появляются только после изменения размера окна

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

ответ

29

Вы добавление компонентов GUI после вызывающего setVisible(true) на JFrame, и это в обратном направлении, так как вы рендеринг GUI, прежде чем что-то было добавлено, и поэтому имеет смысл, что вещи добавлены позже выиграли» t отображается до тех пор, пока все не будут перекрашены.

Вместо этого сначала добавьте все компоненты и только , затем визуализируйте GUI, позвонив по телефону setVisible(true) на JFrame.

Редактировать
Кроме того, вы хотите, чтобы избежать вызова setSize(...) на что-либо, но вместо того, чтобы позволить компоненты размер сами, используя свои preferredSizes и по телефону pack() на JFrame ранее для его отображения с setVisible(true).

Edit 2
Например:

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

И вы хотите обернуть весь свой код в свой основной метод в вызове 'EventQueue.invokeLater()' для соблюдения [политики потоков Swing] (http://docs.oracle.com/javase/7/docs/ api/javax/swing/package-summary.html # threading) – Robin

+0

Я должен переместить весь свой код из основного метода в методе run, а в main mathod я должен добавить этот $ SwingUtilities.invokeLater (new StartingPoint()); ? – Alex

+0

@Alex: вы избавитесь от * всего * статического кода выше, создайте свой guanan gui в самом классе, затем в своем основном создайте Runnable, который инициализирует ваш класс, добавляет JPanel класса в JFrame, а затем отображает JFrame. Например, см. ** Редактировать 2 ** выше. –

4

Добавить setVisible(true) в конце, и это работает.

Смежные вопросы