使用 GridLayout 5x5 更新 JPanel 中的 JLabel 数组

Update Array of JLabels within a JPanel with GridLayout 5x5

基本上我得到了一个带有 GridLayout 5x5 的 JPanel,每个 "square" 作为一个带有数字和不同背景颜色的 JLabel,具体取决于它的数字。

我每次单击其中一个按钮(菜单一除外)时都需要更新面板,因为它会更改整数数组,这是我从中获取数字以放入标签的数组。

我的问题是如何更新每个 JLabel(包括颜色) JFrame Layout

public static JPanel painel(){
    novo_jogo();
    // Painel Grelha
    JPanel grelha = new JPanel();
    GridLayout grid_grelha = new GridLayout(linhas, colunas, 3, 3);
    grelha.setLayout(grid_grelha);
    grelha.setOpaque(true);
    grelha.setSize(janela_x - 140, janela_y-140);
    grelha.setLocation(70, 20);
    grelha.setBackground(Color.GREEN);
    // criar JLabels
    for (int num = 0; num < linhas; num++){
        for (int num2 = 0; num2 < colunas; num2++){
            JLabel label = new JLabel();
            label.setText(String.valueOf(tabuleiro[num][num2]));
            label.setOpaque(true);
            label.setBackground(select_cor(tabuleiro[num][num2]));
            label.setHorizontalAlignment(SwingConstants.CENTER);
            grelha.add(label);
        }
    }
    return grelha;

这是在适当的网格等中创建整个面板的函数... (这也是在从主

延伸出来的不同 class 中制作的
public class Board extends Game{....}

我的想法是使用 repaint() 函数只更新带有网格的面板JPanel grelha = Board.painel();,然后 frame.getContentPane().add(grelha); 后来我的想法是只更新网格 (grelha) 面板,但是当我这样做时:

/* Main */
public static void main(String[] args){
    frame.setTitle("Jogo 2048 em Java"); // Titulo da janela
    frame.setSize(janela_x, janela_y); // Define o tamanho da janela
    frame.setLocationRelativeTo(null); // Centraliza a janela no ecrã
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    frame.setBackground(Color.WHITE);
    frame.setResizable(false); // Não deixa a janela ser aumentada
    // Painel Fundo
    JPanel fundo = new JPanel();
    fundo.setBackground(Color.WHITE);
    // Painel Botões
    JPanel botoes = new JPanel();
    GridLayout grid_botoes = new GridLayout(1, 5, 5, 5);
    botoes.setLayout(grid_botoes);
    botoes.setOpaque(true);
    botoes.setSize(360, 50);
    botoes.setLocation(70, 390);
    botoes.setBackground(Color.WHITE);
    JPanel grelha = Board.painel();
    // Botões e colocar no painel
    JButton init = new JButton("Init");
    JButton left = new JButton("Left");
    JButton down = new JButton("Down");
    JButton right = new JButton("Right");
    JButton menu = new JButton("Menu");
    botoes.add(init);
    botoes.add(left);
    botoes.add(down);
    botoes.add(right);
    botoes.add(menu);
    // Adicionar Panels à janela
    frame.getContentPane().add(botoes);
    frame.getContentPane().add(grelha);
    frame.getContentPane().add(fundo);
    frame.setVisible(true);
    // ActionListener dos botões
    ActionListener accao_botoes = new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            int n = -1;
            if (e.getSource().equals(init)) n = 0;
            else if (e.getSource().equals(left)) n = 1;
            else if (e.getSource().equals(down)) n = 2;
            else if (e.getSource().equals(right)) n = 3;
            else n = 4;
            switch (n){
                case 0:
                    Board.novo_jogo();
                    Board.print();
                    break;
                case 1:
                    Board.esquerda();
                    Board.print();
                    break;
                case 2:
                    Board.baixo();
                    Board.print();
                    break;
                case 3:
                    Board.direita();
                    Board.print();
                    break;
                case 4:
                    janela_menu();
                    break;
                }
        }
    };
    init.addActionListener(accao_botoes);
    left.addActionListener(accao_botoes);
    down.addActionListener(accao_botoes);
    right.addActionListener(accao_botoes);
    menu.addActionListener(accao_botoes);
    while(true){
        frame.repaint();
        try{
            Thread.sleep(10);
        }catch(Exception e){}
    }
}

它不更新面板,事实上它不更新任何东西:( 我尝试了 grelha.validate()、grelha.repaint() 但似乎没有任何效果,我是否遗漏了什么?

谁能帮帮我?

  1. 创建 Board 实例并保留对此对象的引用 Board board=Board.painel();

  2. 对该实例进行操作 board.direita(); board.print();

  3. 在 class 中实现 direita 应该更改 JLabel 属性

  4. 删除 while(true) 循环。美国东部时间将更新 swing 小部件。

示例direita(其他移动方式类似)

public void direita() {
    if (currentX+1 < colunas) ++currentX;
    JLabel label = labels[currentY][currentX];
    label.setBackground(Color.YELLOW);
}

painel

的例子
public static Board painel(){
    // Painel Grelha
    return new Board();
}

Board构造函数

public Board() {
    GridLayout grid_grelha = new GridLayout(linhas, colunas, 3, 3);
    setLayout(grid_grelha);
    setOpaque(true);
    setSize(janela_x - 140, janela_y-140);
    setLocation(70, 20);
    setBackground(Color.GREEN);
    // criar JLabels
    for (int num = 0; num < linhas; num++){
        for (int num2 = 0; num2 < colunas; num2++){
            JLabel label = new JLabel();
            //label.setText(String.format("%d,%d",num,num2));
            label.setOpaque(true);
            label.setBackground(select_cor(num,num2));
            label.setHorizontalAlignment(SwingConstants.CENTER);
            add(label);
            labels[num][num2]=label;
        }
    }
}