简体   繁体   English

带有 GridLayout JFrame 的 JPanels 内的 JButtons

[英]JButtons inside JPanels with a GridLayout JFrame

I have one JFrame that is set to a GridLayout of size NxN.我有一个 JFrame 设置为大小为 NxN 的 GridLayout。 N is given by the user as a command line at the start of the program. N 由用户在程序开始时作为命令行给出。 JButtons in an NxN pattern are added to the window in JPanels, set in location by GridLayout (I think). NxN 模式中的 JButton 被添加到 JPanels 的窗口中,由 GridLayout 设置在位置(我认为)。

Does each JButton need its own JPanel to use GridLayout?每个 JButton 是否需要自己的 JPanel 才能使用 GridLayout? I'm under the impression that you can set up just one JPanel for all the buttons and set the JPanel to a GridLayout for the JButtons.我的印象是,您可以为所有按钮只设置一个 JPanel,并将 JPanel 设置为 JButton 的 GridLayout。 I want to add another JPanel to the left of the button array to display button clicks (JLabel) and a reset button within that same left JPanel.我想在按钮数组的左侧添加另一个 JPanel,以在同一个左侧 JPanel 中显示按钮点击 (JLabel) 和重置按钮。

Here is (a little of) my code, where N is given by the user, system is my background processes class, and ButtonEvent is the class for ActionListener/actionPerformed:这是(一小部分)我的代码,其中 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);

And this is what I have (N=4):这就是我所拥有的(N = 4):

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

Here is (approximately) what I am looking for (N=4):这是(大约)我正在寻找的内容(N = 4):

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

All I need/want is two (or more) JPanels that are set up roughly like above, and all the layout managers I've tried don't play nice with the GridLayout layout JFrame.我需要/想要的是两个(或更多)JPanels,它们的设置大致如上,并且我尝试过的所有布局管理器都不能很好地与 GridLayout 布局 JFrame 配合使用。

Here try this code example:在这里试试这个代码示例:

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 :输出 :

开始点击后

Does each JButton need its own JPanel to use GridLayout?每个 JButton 是否需要自己的 JPanel 才能使用 GridLayout?

No. Add and setLayout on JFrame don't do what they appear to.不。 JFrame 上的 Add 和 setLayout 不会做它们看起来的那样。 JFrame is Top-Level Containers and it is better to organise your content in JPanels. JFrame 是顶级容器,最好在 JPanel 中组织您的内容。

You should organize your panels in that form:您应该以这种形式组织面板:

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

Then add JPanel to the JFrame.然后将 JPanel 添加到 JFrame。 Also put panels in seperate classes:还将面板放在单独的类中:

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

One advantage to giving each button (or group of buttons) its own panel is that the nested panel can have a different layout.为每个按钮(或一组按钮)提供自己的面板的一个优点是嵌套面板可以具有不同的布局。 In this example , each nested ButtonPanel has the default FlowLayout , so the button's size remains constant as the enclosing container is resized.在这个例子中,每个嵌套的ButtonPanel都有默认的FlowLayout ,所以当封闭容器的大小被调整时,按钮的大小保持不变。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM