为什么它不把每个标签都变成红色? [Java]

Why doesn't it turn every label to red? [Java]

我是编码新手,我一直在尝试将我所有的 JLabel 都变成红色,但出于某种原因,它就是行不通。一些方块仍然保持相同的颜色。这是我的代码的样子:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.util.Random;
import java.util.Scanner;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.Border;

public class Build {
    JPanel[][] rod = new JPanel[11][11];
    JLabel[][] label = new JLabel[11][11];
    Border border = BorderFactory.createLineBorder(Color.BLACK);
    JLabel[][] store = new JLabel[11][11];
    JFrame frame = new JFrame("Start");
    
    public static void main(String[] args) {
        new Build();
    }

    public Build() {

        frame.getContentPane();
        frame.setSize(330, 330);
        frame.setLayout(new GridLayout(11, 11));
        Random rand = new Random();
        Dimension dimension = new Dimension(30, 30);
        for (int row = 0; row < label.length; row++) {
            for (int col = 0; col < label[row].length; col++) {
                JLabel myLabel = new JLabel();
                myLabel = new JLabel();
                myLabel.setOpaque(true);
                myLabel.setBackground(Color.WHITE);
                if (row % 2 == 0) {

                    myLabel.setBackground(Color.BLACK);
                }

                myLabel.setPreferredSize(dimension);
                myLabel.setBorder(border);
                frame.add(myLabel);
                label[row][col] = myLabel;

            }
            int ran = rand.nextInt(11);
            label[row][ran].setBackground(Color.WHITE);

            store = label.clone();
        }

        frame.setVisible(true);

        Scanner scan = new Scanner(System.in);
        int e = scan.nextInt();
        if (e == 1) {
            store();
        }

    }

    public void store() {
        for (int i = 10; i > 0; i--) {

            for (int j = 0; j < label[i].length; j++) {
                while (label[i][j] == null) {
                    System.out.println("wow");

                }

                label[i][j].setBackground(Color.RED);

                label[i][j].setOpaque(true);
            }
        }
    }
}

我的意图是从前一行复制 1-10 的每一行(比如第 0 行变成第 1 行),这就是我设置存储数组的原因,但我正在努力了解为什么此代码不会将 1-10 的每个方块变为红色。

数据: (在 运行 store() 之前): Works normal.

(在 运行 store() 之后): The first row hasn't changed, so that's good, but it's not working well for the rest.

我修改了您的代码以说明一些基本的 Swing 原则。

这是我想出的 GUI。我将随机单元格设为蓝色而不是白色,这样您就可以看到我确实让每一行中的一个单元格具有不同的颜色。我将单元格分开 2 个像素,这样您可以更清楚地看到每个白色单元格。

这是左键单击按钮后的 GUI。

如您所见,所有单元格现在都是红色的。

我删除了 Scanner 控制台代码并将其替换为 GUI JButton

Oracle 有一个有用的教程,Creating a GUI With Swing。跳过 Netbeans 部分。

您在 main 方法中做的第一件事是调用 SwingUtilities invokeLater 方法。此方法确保您在 Event Dispatch Thread.

上创建和执行 Swing 组件

我创建了一个 JFrame 和两个 JPanels。一个 JPanel 保存单元格,而另一个 JPanel 保存 JButton。是的,您可以直接将 Swing 组件添加到 JFrame,但这样做并不明智。始终创建一个 JPanel 来容纳您的 Swing 组件并将 JPanel 放在 JFrame.

JFrame 有一个默认值 BorderLayout

我将 JFrame 和两个 JPanels 的创建分成不同的方法。这使代码更易于阅读和理解。

我为 JButton 创建了一个 ActionListener。这就是在 Swing 中等待用户操作的方式。

此代码应该是您要完成的工作的更好基础。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.Border;

public class Build implements Runnable {
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Build());
    }
    
    private JLabel[][] label;
    
    private Random random;
    
    public Build() {
        this.random = new Random();
        this.label = new JLabel[11][11];
    }
    
    @Override
    public void run() {
        JFrame frame = new JFrame("Start");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        frame.add(createMainPanel(), BorderLayout.CENTER);
        frame.add(createButtonPanel(), BorderLayout.SOUTH);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }
    
    private JPanel createMainPanel() {
        JPanel panel = new JPanel(new GridLayout(0, 11, 2, 2));
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        
        Dimension dimension = new Dimension(30, 30);
        Border border = BorderFactory.createLineBorder(Color.BLACK);
        for (int row = 0; row < label.length; row++) {
            for (int col = 0; col < label[row].length; col++) {
                label[row][col] = new JLabel();
                label[row][col].setBorder(border);
                label[row][col].setOpaque(true);
                label[row][col].setPreferredSize(dimension);
                
                if (row % 2 == 0) {
                    label[row][col].setBackground(Color.BLACK);
                } else {
                    label[row][col].setBackground(Color.WHITE);
                }

                panel.add(label[row][col]);
            }
            
            int ran = random.nextInt(label[row].length);
            label[row][ran].setBackground(Color.BLUE);
        }
        
        return panel;
    }
    
    private JPanel createButtonPanel() {
        JPanel panel = new JPanel(new FlowLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        
        JButton button = new JButton("Click me");
        button.addActionListener(new ButtonListener());
        panel.add(button);
        
        return panel;
    }
    
    public class ButtonListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent event) {
            for (int i = label.length - 1; i >= 0; i--) {
                for (int j = 0; j < label[i].length; j++) {
                    label[i][j].setBackground(Color.RED);
                }
            }
        }
        
    }

}