按下后如何更改正方形的颜色?

How do I change the color of a square once pressed on?

现在我有代码可以在 25x25 的棋盘上随机化彩色方块。我想要做的是能够让这些彩色方块在按下后变成白色,一旦变成白色,就无法反转。我正在考虑使用 Listeners,但不确定如何开始。

这是我必须创建的随机方块。

import java.awt.*;
import javax.swing.*;
import java.util.ArrayList;
import java.util.List;

public class ColoredBoxes {
   //Selected Colors
   private Color[] availableColors = new Color[] {Color.YELLOW, Color.RED, Color.BLUE, Color.GREEN};
   public static void main(String[] args) {
        new ColoredBoxes();
   }

    public ColoredBoxes() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Collapse");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {
        //Size of the board
        protected static final int ROWS = 25;
        protected static final int COLS = 25;
        protected static final int BOX_SIZE = 25;

        private List<Color> colors;
        
        //RandomColors across the given board size.
        public TestPane() {
            int length = ROWS * COLS;
            colors = new ArrayList<Color>();
            for (int index = 0; index < length; index++) {
                int randomColor = (int) (Math.random() * availableColors.length);
                colors.add(availableColors[randomColor]);
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(COLS * BOX_SIZE, ROWS * BOX_SIZE);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();

            int xOffset = (getWidth() - (COLS * BOX_SIZE)) / 2;
            int yOffset = (getHeight() - (ROWS * BOX_SIZE)) / 2;

            System.out.println("...");
            for (int row = 0; row < ROWS; row++) {
                for (int col = 0; col < COLS; col++) {
                    int index = (row * COLS) + col;
                    g2d.setColor(colors.get(index));
                    g2d.fillRect(xOffset + (col * BOX_SIZE), yOffset + (row * BOX_SIZE), BOX_SIZE, BOX_SIZE);
                }
            }
            g2d.dispose();
        }
    }
}

非常感谢任何帮助。

要在点击时更改颜色,您只需要一个 MouseListener,在 mouseClicked() 方法中,您必须将点击坐标转换为颜色网格的行和列,更改该颜色,然后要求组件重新绘制。

这里的实现,我只是用二维颜色数组替换了你的一维颜色列表,因为它简化了表示和从 x,y 到 row,col 的转换。

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class ColoredBoxes {
   //Selected Colors
   private Color[] availableColors = new Color[] {Color.YELLOW, Color.RED, Color.BLUE, Color.GREEN};
   

   //This is the color that will be set when a cell is clicked
   private static final Color CLICKED_COLOR = Color.white;
   
   public static void main(String[] args) {
        new ColoredBoxes();
   }

    public ColoredBoxes() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Collapse");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {
        //Size of the board
        protected static final int ROWS = 25;
        protected static final int COLS = 25;
        protected static final int BOX_SIZE = 25;

        //Since you have a ROWSxCOLS color grid better use a 2-dimension array
        private Color[][] cells;
        
        //RandomColors across the given board size.
        public TestPane() {
            cells=new Color[ROWS][COLS];
            for (int i=0;i<cells.length;i++) {
                for (int j=0;j<cells[i].length;j++) {
                    int randomColor = (int) (Math.random() * availableColors.length);
                    cells[i][j]=availableColors[randomColor];
                }
            }
            
            //Here the mouse listener, we only need to manage click events
            //so I use a MouseAdapter to not implement the complete MouseListener interface
            addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    onClick(e);
                }
            });
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(COLS * BOX_SIZE, ROWS * BOX_SIZE);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();

            int xOffset = (getWidth() - (COLS * BOX_SIZE)) / 2;
            int yOffset = (getHeight() - (ROWS * BOX_SIZE)) / 2;

            System.out.println("...");
            for (int row = 0; row < ROWS; row++) {
                for (int col = 0; col < COLS; col++) {
                    g2d.setColor(cells[row][col]);
                    g2d.fillRect(xOffset + (col * BOX_SIZE), yOffset + (row * BOX_SIZE), BOX_SIZE, BOX_SIZE);
                }
            }
            g2d.dispose();
        }
        
        //Finally the click handler
        protected void onClick(MouseEvent e) {
            //Convert mouse x,y (that are relative to the panel) to row and col
            int xOffset = (getWidth() - (COLS * BOX_SIZE)) / 2;
            int yOffset = (getHeight() - (ROWS * BOX_SIZE)) / 2;
            
            int row=(e.getY()-yOffset)/BOX_SIZE;
            int col=(e.getX()-xOffset)/BOX_SIZE;

            //Check that we are in the grid
            if (row>=0&&row<ROWS&&col>=0&&col<COLS) {
                //Set new color
                cells[row][col]=Color.white;
                //Repaint, only the changed region
                repaint(xOffset + (col * BOX_SIZE), yOffset + (row * BOX_SIZE), BOX_SIZE, BOX_SIZE);
            }
        }
        
    }
}

您可以使用带有自定义 class 的 GridPane 布局来表示正方形

如果你想检查,我这里有一个工作示例

所有方块自己处理自己的画

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.List;

public class ColoredBoxes {

    //Selected Colors
    private Color[] availableColors = new Color[]{Color.YELLOW, Color.RED, Color.BLUE, Color.GREEN};

    public ColoredBoxes() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                }
                catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Collapse");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

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

    public class TestPane extends JPanel {

        //Size of the board
        protected static final int ROWS     = 25;
        protected static final int COLS     = 25;
        protected static final int BOX_SIZE = 25;

        private List<Square> colors; // List of the representation of the Squares

        //RandomColors across the given board size.
        public TestPane() {
            int        length     = ROWS * COLS;
            GridLayout gridLayout = new GridLayout(ROWS, HEIGHT, 0, 0);
            this.setLayout(gridLayout);
            colors = new ArrayList<>();
            for (int row = 0; row < ROWS; row++) {
                for (int col = 0; col < COLS; col++) {
                    int    randomColor = (int) (Math.random() * availableColors.length);
                    Square temp        = new Square(availableColors[randomColor], row, col);
                    colors.add(temp);
                    this.add(temp);
                }
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(COLS * BOX_SIZE, ROWS * BOX_SIZE);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();

            int xOffset = (getWidth() - (COLS * BOX_SIZE)) / 2;
            int yOffset = (getHeight() - (ROWS * BOX_SIZE)) / 2;

            System.out.println("...");
            for (int row = 0; row < ROWS; row++) {
                for (int col = 0; col < COLS; col++) {
                    int index = (row * COLS) + col;
                    g2d.setColor(colors.get(index).getColor());
                    g2d.fillRect(xOffset + (col * BOX_SIZE), yOffset + (row * BOX_SIZE), BOX_SIZE, BOX_SIZE);
                }
            }
            g2d.dispose();
        }
    }

    public class Square extends JPanel {

        private Color   color;
        private boolean clicked = false;
        private int     row;
        private int     col;

        public Square(Color color, int row, int col) {
            this.row = row;
            this.col = col;
            this.color = color;
            this.addMouseListener(new MouseListener() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    if (!clicked) {
                        //do stuff
                        Square source = (Square) e.getSource();
                        source.setColor(Color.white);
                        repaint();//Dont forget the repaint method
                        clicked = true;
                    }
                }

                @Override
                public void mousePressed(MouseEvent e) {
                    if (!clicked) {
                        //do stuff
                        Square source = (Square) e.getSource();
                        source.setColor(Color.white);
                        repaint();//Dont forget the repaint method
                        clicked = true;
                    }
                }

                @Override
                public void mouseReleased(MouseEvent e) {

                }

                @Override
                public void mouseEntered(MouseEvent e) {

                }

                @Override
                public void mouseExited(MouseEvent e) {

                }
            });
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(color);
            g.fillRect(0, 0, getWidth(), getHeight());
        }

        public Color getColor() {
            return color;
        }

        public void setColor(Color color) {
            this.color = color;
        }
    }
}