2012-01-07 25 views
16

Tôi có 2 JPanels trong một khung. Bảng điều khiển đầu tiên chứa các mục java giống như các nút vv. Hai nút tôi đã thêm sẽ xuất hiện nhưng JSpinner xuất hiện ngay sau khi tôi thay đổi kích thước cửa sổ. Tôi đoán điều này cũng sẽ xảy ra với các mục khác mà tôi sẽ thêm vào. Làm thế nào tôi có thể giải quyết vấn đề này?Các mục Java chỉ xuất hiện sau khi cửa sổ đổi kích thước

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

Trả lời

29

Bạn đang thêm các thành phần để GUI sau gọi setVisible(true) trên JFrame và đó là ngược vì bạn đang render GUI trước bất cứ điều gì đã được thêm vào, và vì vậy nó có ý nghĩa rằng mọi thứ thêm vào sau chiến thắng' t được hiển thị cho đến khi tất cả được sơn lại.

Thay vào đó, trước tiên hãy thêm tất cả các thành phần của bạn và chỉ sau đó hiển thị GUI bằng cách gọi setVisible(true) trên JFrame.

Sửa
Ngoài ra, bạn sẽ muốn tránh gọi setSize(...) về bất cứ điều gì mà thay vào đó hãy để các thành phần kích thước mình bằng cách sử preferredSizes của họ và bằng cách gọi pack() trên JFrame trước khi hiển thị nó với setVisible(true).

Chỉnh sửa 2
Ví dụ:

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

Và bạn muốn bọc tất cả mã của mình trong phương thức chính trong lời gọi 'EventQueue.invokeLater()' để tôn trọng [Chính sách truyền luồng xoay] (http://docs.oracle.com/javase/7/docs/ api/javax/swing/package-summary.html # luồng) – Robin

+0

Tôi nên di chuyển tất cả mã của mình từ phương thức chính trong phương thức chạy và trong toán học chính tôi phải thêm $ SwingUtilities.invokeLater này (new StartingPoint()); ? – Alex

+0

@Alex: Bạn sẽ loại bỏ mọi thứ * tĩnh trong đoạn mã trên, tạo JPanel gui của bạn trong lớp, sau đó tạo chính Runnable để khởi tạo lớp, thêm JPanel của lớp vào JFrame và sau đó hiển thị JFrame. Ví dụ: xem ** Chỉnh sửa 2 ** ở trên. –

4

Thêm setVisible(true) ở cuối và nó hoạt động.

Các vấn đề liên quan