9

我有一个设置为 NxN 大小的 GridLayout 的 JFrame。N 由用户在程序开始时作为命令行给出。NxN 模式中的 JButton 被添加到 JPanel 的窗口中,由 GridLayout 设置(我认为)。

每个 JButton 是否需要自己的 JPanel 才能使用 GridLayout?我的印象是,您可以为所有按钮设置一个 JPanel,并将 JPanel 设置为 JButtons 的 GridLayout。我想在按钮数组的左侧添加另一个 JPanel 以显示按钮单击(JLabel)和同一左侧 JPanel 中的重置按钮。

这是(一点)我的代码,其中 N 由用户给出,system 是我的后台进程类,ButtonEvent 是 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);

这就是我所拥有的(N = 4):

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

这是(大约)我正在寻找的(N = 4):

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

我需要/想要的只是两个(或更多)JPanels,它们的设置大致类似于上面,而且我尝试过的所有布局管理器都不能很好地与 GridLayout 布局 JFrame 配合使用。

4

3 回答 3

15

这里试试这个代码示例:

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

输出 :

开始 点击后

于 2012-04-29T12:07:33.193 回答
8

每个 JButton 是否需要自己的 JPanel 才能使用 GridLayout?

不。 JFrame 上的 Add 和 setLayout 不会像它们看起来那样做。JFrame 是顶级容器,最好在 JPanel 中组织您的内容。

您应该以这种形式组织您的面板:

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

然后将 JPanel 添加到 JFrame。还将面板放在单独的类中:

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);
    }
}
于 2012-04-29T06:27:59.253 回答
4

为每个按钮(或按钮组)提供自己的面板的一个优点是嵌套面板可以具有不同的布局。在此示例中,每个嵌套ButtonPanel都有默认值FlowLayout,因此按钮的大小在调整封闭容器的大小时保持不变。

于 2012-04-29T17:03:44.777 回答