JPanels中的JButtons带有GridLayout JFrame

时间:2012-04-29 05:37:55

标签: java swing user-interface layout

Java / Eclipse IDE。

我有一个JFrame设置为大小为NxN的GridLayout。用户将N作为程序开头的命令行给出。 NxN模式的JButtons被添加到JPanels的窗口中,由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一起使用。

邀请任何有关更好解决方案的建议。

谢谢!

3 个答案:

答案 0 :(得分:12)

这里尝试这个代码示例:

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

输出:

Start After Click

答案 1 :(得分:7)

  

每个JButton都需要自己的JPanel来使用GridLayout吗?

没有。在JFrame上添加和setLayout不会执行它们显示的内容。 JFrame是顶级容器,最好在JPanels中组织您的内容。

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

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

答案 2 :(得分:4)

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