如何在循环中创建 JPanel 并将它们插入 JPanel 数组 [] []

How to Create JPanels in a Loop and insert them in JPanel Array [] []

大家好,我正在使用 Eclipse,我正在尝试创建一个 Connect4 Game Grid ,它是一个 JPanel gridArray [6] [7]。我稍后将按钮和网格的不同面板添加到主面板中,并将其添加到我的框架中。

我的问题: 我想用空字段(白色)的图片填充 gridArray JPanel,但首先我想创建一个新面板并通过循环将其插入到我的 gridArray 中,直到 gridArray 中包含所有 42 个面板并完全填充。我的代码在下面,但不知何故它不起作用,尽管我的逻辑应该没问题。

我尝试使用辅助函数来创建一个新的 JPanel 并为 fillGrid() 中的每个循环调用该函数;基本上调用了 42 次,但它仍然不起作用...

我很乐意提供帮助!

package connect4;

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

public class GridTest extends JFrame {

    JFrame mainWindow;
    JPanel buttonPanel, mainPanel;
    JPanel gridPanel;
    JPanel emptyPanel;
    JPanel panel1;
    ImageIcon emptyBox;
    JPanel[][] gridArray;

    JLabel emptyLabel;

    JButton arrow1,arrow2,arrow3,arrow4,arrow5,arrow6,arrow7;

    public GridTest() {
        createGameGrid();
        fillGrid();
    }

    public void createGameGrid() {

        //creating window and mainpanel
        mainWindow = new JFrame("Connect 4");
        mainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        mainPanel = new JPanel();
        mainPanel.setLayout(new BorderLayout());

        //defining top panel with 7 buttons;
        buttonPanel = new JPanel();
        buttonPanel.setLayout(new GridLayout(1, 7));

        arrow1 = new JButton("V");
        arrow2 = new JButton("V");
        arrow3 = new JButton("V");
        arrow4 = new JButton("V");
        arrow5 = new JButton("V");
        arrow6 = new JButton("V");
        arrow7 = new JButton("V");

        buttonPanel.add(arrow1);
        buttonPanel.add(arrow2);
        buttonPanel.add(arrow3);
        buttonPanel.add(arrow4);
        buttonPanel.add(arrow5);
        buttonPanel.add(arrow6);
        buttonPanel.add(arrow7);

        //create Grind Panel
        gridPanel = new JPanel();
        gridPanel.setLayout(new GridLayout(6,7));

        mainPanel.add(buttonPanel, BorderLayout.NORTH);
        mainPanel.add(gridPanel, BorderLayout.SOUTH);
        mainWindow.add(mainPanel);
        mainWindow.pack();
        mainWindow.setLocationRelativeTo(null);
        mainWindow.setVisible(true);
    }

    private JPanel greateOnePanel(){
      //here we need to insert the icon which is in empty box into a newly created panel   
      //ifirst wanted to insert black panels do ensure it works as intended but it doesnt
        JPanel panel = new JPanel();
        panel.setBackground(Color.BLACK);
        panel.setSize(50,50);

        return panel;
    }

    //here we need to fill the grid with the panels created above from left to right...
    public void fillGrid() {
       for(int j = 0; j < 6; j++) {
          for (int k = 0; k < 7; k++) {
            gridPanel.add(greateOnePanel());

          }
       }
    }

   public static void main(String[] args) {
     new GridTest();
   }
}

我尝试使用 gridArray 的这种方法,但它会抛出 NullPointer Exeptions 并且不会用简单的文本标签填充网格 "Hallo"(仅用于测试目的)

public void fillGrid() {
        for(int j = 0; j < 6; j++) {
          for (int k = 0; k < 7; k++) {

             JLabel label = new JLabel("Hallo"); 

            gridArray[j][k] = new JPanel();
            gridArray[j][k].setSize(50, 50);
            gridArray[j][k].setBackground(Color.RED);
            gridArray[j][k].add(label);
            gridPanel.add(gridArray[j][k]);


          }
        }
    }

问题是你没有初始化网格数组。 否则会抛出空指针异常。

JPanel[][] gridArray = new JPanel[6][8];

同时设置主面板的首选大小以使网格可见。

mainPanel.setPreferredSize(new Dimension(400, 200));

这是我 运行 您的代码经过此处提到的修改后所看到的。

另外请使用以下代码从 main 执行它。

   public static void main(String[] args) {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new GridTest();
            }
        });    

   }

这是一个简短的自包含代码,应该可以帮助完成任务的各个方面。

不需要在每个单元格中都有一个面板。它唯一有帮助的是设置 BG 颜色。只要背景设置为不透明,就可以在标签中完成。

此代码定义了一个 SquareLabel,它覆盖 getPreferredSize() 到 return 首选宽度和高度的最大值作为两者的值(通常是宽度)。

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

public class SquareLabelGrid {

    int rows = 6;
    int cols = 7;
    JLabel[][] labelArray = new JLabel[cols][rows];
    Font bigFont = new Font(Font.SANS_SERIF, Font.BOLD, 30);
    Insets labelInsets;

    SquareLabelGrid() {
        JPanel gameBoard = new JPanel(new GridLayout(rows, cols));
        // a border to make the cell boundaries more clear and add 
        // some space around the text
        Border border = new CompoundBorder(
                new LineBorder(Color.BLACK),new EmptyBorder(4,4,4,4));
        for (int yy = 0; yy < rows; yy++) {
            for (int xx = 0; xx < cols; xx++) {
                JLabel l = getColoredSquareLabel(xx, yy);
                labelArray[xx][yy] = l;
                gameBoard.add(l);
                l.setBorder(border);
            }
        }
        JOptionPane.showMessageDialog(null, gameBoard);
    }

    private JLabel getColoredSquareLabel(int x, int y) {
        SquareLabel label = new SquareLabel(
                String.format("%1s,%1s", (x+1), (y+1)));
        label.setFont(bigFont);
        label.setOpaque(true); // so we can see the BG color
        label.setBackground(Color.ORANGE); // I prefer orange!
        // make the GUI less 'crowded'
        label.setBorder(new EmptyBorder(4,4,4,4)); 

        return label;
    }

    public static void main(String[] args) {
        Runnable r = () -> {
            new SquareLabelGrid();
        };
        SwingUtilities.invokeLater(r);
    }
}

class SquareLabel extends JLabel {

    SquareLabel(String label) {
        super(label);
    }

    /* This will create a square component that accounts for the 
     size of the String / Icon it contains. No guesswork! */
    @Override
    public Dimension getPreferredSize() {
        Dimension d = super.getPreferredSize();
        int w = d.width;
        int h = d.height;
        int sz = w > h ? w : h;

        return new Dimension(sz, sz);
    }
}