2012-04-29 25 views
7

Java/Eclipse IDE tại đây.JButtons bên trong JPanels với một GridLayout JFrame

Tôi có một JFrame được đặt thành GridLayout có kích thước NxN. N được người dùng đưa ra như một dòng lệnh ở đầu chương trình. JButtons trong một mẫu NxN được thêm vào cửa sổ trong JPanels, được đặt trong vị trí bởi GridLayout (tôi nghĩ).

Mỗi JButton có cần JPanel riêng của mình để sử dụng GridLayout không? Tôi theo ấn tượng rằng bạn có thể thiết lập chỉ một JPanel cho tất cả các nút và thiết lập JPanel thành GridLayout cho JButtons. Tôi muốn thêm một JPanel khác ở bên trái của mảng nút để hiển thị các nút bấm (JLabel) và nút reset trong cùng một JPanel bên trái.

Dưới đây là (một chút) mã của tôi, trong đó N được đưa ra bởi người sử dụng, hệ thống là nền tảng của tôi xử lý lớp, và ButtonEvent là lớp cho ActionListener/actionPerformed:

JFrame window = new JFrame(""); 
GridLayout layout = new GridLayout(N,N); 
window.setLayout(layout); 

for (int row = 0; row < N; row++){ 
    for (int col = 0; col < N; col++){ 
     JPanel panel = new JPanel(); 
     JButton b = new JButton ("("+row+","+col+")"); 
     window.add(b).setLocation(row, col); 
     panel.add(b); 
     b.addActionListener(new ButtonEvent(b, system, row, col)); 
     window.add(panel); 
    } 
} 

window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
window.pack(); 
window.setVisible(true); 

Và đây là những gì tôi có (N = 4):

http://i.imgur.com/nbQoM.png

Dưới đây là (ước tính) những gì tôi đang tìm kiếm (N = 4):

http://i.imgur.com/SiVWO.png

Tất cả những gì tôi cần/muốn là hai (hoặc nhiều hơn) JPanels được thiết lập gần như trên, và tất cả các trình quản lý bố cục mà tôi đã cố gắng không chơi tốt với JFrame bố cục GridLayout.

Mọi đề xuất về giải pháp tốt hơn đều được mời.

Cảm ơn!

Trả lời

11

đây thử mã ví dụ này:

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 

public class LayoutExample extends JFrame 
{ 
    private static final String INITIAL_TEXT = "Nothing Pressed"; 
    private static final String ADDED_TEXT = " was Pressed"; 
    private JLabel positionLabel; 
    private JButton resetButton; 
    private static int gridSize = 4; 

    public LayoutExample() 
    { 
     super("Layout Example"); 
    } 

    private void createAndDisplayGUI() 
    {  
     setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 

     JPanel contentPane = new JPanel(); 
     contentPane.setLayout(new FlowLayout(FlowLayout.LEFT, 20, 20)); 
     contentPane.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 2)); 

     JPanel leftPanel = new JPanel(); 
     leftPanel.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 2)); 
     leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.Y_AXIS));  
     JPanel labelPanel = new JPanel(); 
     positionLabel = new JLabel(INITIAL_TEXT, JLabel.CENTER); 
     JPanel buttonLeftPanel = new JPanel(); 
     resetButton = new JButton("Reset"); 
     resetButton.addActionListener(new ActionListener() 
     { 
      public void actionPerformed(ActionEvent ae) 
      { 
       positionLabel.setText(INITIAL_TEXT); 
      } 
     }); 
     labelPanel.add(positionLabel); 
     buttonLeftPanel.add(resetButton); 
     leftPanel.add(labelPanel); 
     leftPanel.add(buttonLeftPanel); 

     contentPane.add(leftPanel); 

     JPanel buttonPanel = new JPanel(); 
     buttonPanel.setLayout(new GridLayout(gridSize, gridSize, 10, 10)); 
     for (int i = 0; i < gridSize; i++) 
     { 
      for (int j = 0; j < gridSize; j++) 
      { 
       JButton button = new JButton("(" + i + ", " + j + ")"); 
       button.setActionCommand("(" + i + ", " + j + ")"); 
       button.addActionListener(new ActionListener() 
       { 
        public void actionPerformed(ActionEvent ae) 
        { 
         JButton but = (JButton) ae.getSource(); 
         positionLabel.setText(
          but.getActionCommand() + ADDED_TEXT);       
        } 
       }); 
       buttonPanel.add(button); 
      } 
     } 
     contentPane.add(buttonPanel); 

     setContentPane(contentPane); 
     pack(); 
     setLocationByPlatform(true); 
     setVisible(true); 
    } 

    public static void main(String[] args) 
    { 
     if (args.length > 0) 
     { 
      gridSize = Integer.parseInt(args[0]); 
     } 
     SwingUtilities.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       new LayoutExample().createAndDisplayGUI(); 
      } 
     }); 
    } 
} 

OUTPUT:

Start After Click

+1

+1 Xem thêm [ví dụ] có liên quan này (http://stackoverflow.com/a/7706684/230513). – trashgod

+1

@trashgod: Cảm ơn bạn đã xóa lỗi lớn đó, vì bây giờ ít nhất nó sẽ chạy, ngay cả khi không cung cấp bất kỳ đối số nào :-). Kiểm tra của tôi trước đây là vô ích, LOL. –

+0

Rất tuyệt! Tôi thích cách này kích thước lại (hoặc, thực sự, không thay đổi kích thước). Bài đăng của trashgod dưới đây giải thích chính xác lý do tại sao chức năng này như vậy. Cảm ơn! – Avertheus

7

Mỗi JButton có cần JPanel riêng của mình để sử dụng GridLayout không?

No. Thêm và thiết lậpLời hết trên JFrame không làm những gì chúng xuất hiện. JFrame là các Container cấp cao nhất và tốt hơn là tổ chức nội dung của bạn trong JPanels.

Bạn nên sắp xếp các tấm của bạn theo hình thức đó:

----JPanel----------------------------| 
| ---LeftPanel--- ---ButtonsPanel--- | 
| |    | |    | | 
| |    | |    | | 
| |    | | GridLayout(N,N)| | 
| |    | |    | | 
| |    | |    | | 
| --------------- ------------------ | 
--------------------------------------- 

Sau đó thêm JPanel vào JFrame. Cũng đặt tấm pin trong các lớp riêng biệt:

class BPanel extends JPanel { 
    public BPanel() { 
     GridLayout layout = new GridLayout(N,N, hgap, vgap); 
     setLayout(layout); 
     for (int row = 0; row < N; row++){ 
      for (int col = 0; col < N; col++){ 
       JButton b = new JButton ("("+row+","+col+")"); 
       add(b).setLocation(row, col); 
       b.addActionListener(new ButtonEvent(b, system, row, col)); 
      } 
     } 
    } 
} 
class LeftPanel extends JPanel { 
.... 
} 

class MainFrame extends JFrame { 
    public MainFrame() { 
     JPanel p = new JPanel(); 
     p.add(new LeftPanel()); 
     p.add(newButtonsPanel()); 
     add(p); 
    } 
} 
+1

Câu trả lời hay. Nghệ thuật tuyệt vời ASCII! Xem thêm [Ví dụ về bố cục lồng nhau] (http://stackoverflow.com/a/5630271/418556). –

+0

Vâng, điều này dường như đã làm việc cho tôi. Tôi có tất cả các JPanels của tôi trong các lớp khác nhau, và một JPanel cho GridLayout. Cảm ơn lời giải thích! – Avertheus

3

Một lợi thế để cho mỗi nút (hoặc nhóm các nút) bảng điều khiển riêng của nó là bảng điều khiển lồng nhau có thể có bố cục khác nhau. Trong số này example, mỗi lồng nhau ButtonPanel có mặc định FlowLayout, do đó kích thước của nút vẫn không đổi khi vùng chứa được thay đổi kích thước.

+0

Thật thú vị, thực sự, đó là những gì tôi nhận ra, khi tôi đọc câu trả lời đầu tiên cho chủ đề này bởi @ixos, Vì vậy, để vui, tôi ngồi xuống để làm những gì OP muốn, và tôi nhận ra điều này 'kích thước khía cạnh' gây ra vấn đề trên 'Left Panel', đó là lý do tại sao hai' JPanel 'riêng biệt cho' JButton' và 'JLabel ', nhưng những gì bạn đề nghị rằng đối với mỗi' JButton' một 'JPanel', tôi thích điều này :-) –

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