【问题标题】:JButtons inside JPanels with a GridLayout JFrame带有 GridLayout JFrame 的 JPanel 内的 JButton
【发布时间】:2012-05-09 08:15:16
【问题描述】:

我有一个设置为大小为 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

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

【问题讨论】:

    标签: java eclipse swing user-interface layout


    【解决方案1】:

    这里试试这个代码示例:

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

    输出:

    【讨论】:

      【解决方案2】:

      是否每个 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);
          }
      }
      

      【讨论】:

      • 是的,这似乎对我有用。我现在将所有 JPanel 放在不同的类中,而 GridLayout 有一个 JPanel。谢谢你的解释!
      【解决方案3】:

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

      【讨论】:

      • 这很有趣,实际上,这就是我意识到的,当我阅读@ixos 对这个线程的第一个答案时,为了好玩,我坐下来做 OP 想要做的事情,我意识到这一点@ 987654324@ 的东西在 Left Panel 上造成了问题,这就是为什么 JButtonJLabel 的这两个单独的 JPanels 的原因,但是你建议对于每个 JButtonJPanel,我喜欢这个: -)
      猜你喜欢
      • 1970-01-01
      • 2020-08-03
      • 2012-09-06
      • 1970-01-01
      • 2018-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-10
      相关资源
      最近更新 更多