简体   繁体   English

Java中的KeyAdapter输入无法正常工作

[英]KeyAdapter input in java not working

I just wrote some code to make my player move in my little maze game, but nothing happens. 我只是编写了一些代码来使我的玩家在我的小迷宫游戏中移动,但没有任何反应。 Also my maze is not drawn correct as in the matrix input. 另外,我的迷宫没有像矩阵输入中那样正确绘制。 I don't figure out why is wrong this code...any help is well appeciated. 我不知道为什么这个代码是错误的...任何帮助都是值得赞赏的。 Thank you! 谢谢!

import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import javax.swing.*;

public class Main extends JPanel {
    private static Image white;
    private static Image black;
    private static Image finish;
    private static Image player;
    private static int x = 1;
    private static int y = 1;
    private String matrix[][];

    public Main() {
        addKeyListener(new Keys());
        setFocusable(true);
    }

    public static String[][] load(String input) {
        List<String[]> rows = new ArrayList<>();
        try (Scanner scanner = new Scanner(input)) {
            while (scanner.hasNextLine()) {
                String line = scanner.nextLine();
                String[] cols = new String[line.length()];
                for (int i = 0; i < cols.length; i++) {
                    cols[i] = line.substring(i, i + 1);
                }
                rows.add(cols);
            }
        }
        return rows.toArray(new String[rows.size()][]);
    }

    public static JFrame buildFrame() {
        JFrame frame = new JFrame("Labyrinth Game");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(900, 950);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        return frame;
    }

    public void moveUp() {
        x += 0;
        y += -1;
    }

    public void moveLeft() {
        x += -1;
        y += 0;
    }

    public void moveDown() {
        x += 0;
        y += 1;
    }

    public void moveRight() {
        x += 1;
        y += 0;
    }

    public class Keys extends KeyAdapter {
        @Override
        public void keyPressed(KeyEvent e) {
            int keycode = e.getKeyCode();
            // repaint();
            if (keycode == KeyEvent.VK_W) {
                if (!matrix[getX()][getY() - 1].equals("1")) {
                    moveUp();
                }
            }
            if (keycode == KeyEvent.VK_A) {
                if (!matrix[getX() - 1][getY()].equals("1")) {
                    moveLeft();
                }
            }
            if (keycode == KeyEvent.VK_S) {
                if (!matrix[getX()][getY() + 1].equals("1")) {
                    moveDown();
                }
            }
            if (keycode == KeyEvent.VK_D) {
                if (!matrix[getX() + 1][getY()].equals("1")) {
                    moveRight();
                }
            }
        }

        @Override
        public void keyReleased(KeyEvent event) {
        }
    }

    public static void main(String[] args) {
        String input = "1111111111111111111111111111111111111111111\n"
                + "1000000010001000001000000010000000100000001\n"
                + "1010111010101010101111101011111010111111101\n"
                + "1010001010100010100000001010000010000010001\n"
                + "1011101010111110101111111010111111111010111\n"
                + "1000101010100000101000001000100010000010001\n"
                + "1011101011101011111011101111111010111110101\n"
                + "1010001000001010000010100000001010000010101\n"
                + "1010111111111010111110111111101011111011101\n"
                + "1010100000100010100000000000101000000000101\n"
                + "1110101111101110111110111011101011111110101\n"
                + "1000100000000010000010100010001000100010001\n"
                + "1011111111111111111011101010111111101011101\n"
                + "1000000000000000100010001010000000001010001\n"
                + "1011111111111011101110111011111111111010111\n"
                + "1000100010001000001010001000100000001010101\n"
                + "1110101011101111111010101110111110111010101\n"
                + "1000101010001000100000101000100000100010001\n"
                + "1011101010111010101111101011101110101111111\n"
                + "1000001010000010000000101000001000100010001\n"
                + "1111111011111110111111101111111011111010101\n"
                + "1000001010000010100010001000000010000010101\n"
                + "1011111010111011101010111011111110101110101\n"
                + "1010000010001010001010001000100000101010101\n"
                + "1010111111101010111011101111101111101011101\n"
                + "1000100000001010101010001000100010101000101\n"
                + "1011111011111010101010111010111010101011101\n"
                + "1010000010001000101010000010001010001000001\n"
                + "1010101110101111101011101111101011111010101\n"
                + "1010101000101000001000101000001000000010101\n"
                + "1011101011111010111110111011101111111110111\n"
                + "1000001000000010000000000010000000000010021\n"
                + "1111111111111111111111111111111111111111111\n";

        String[][] matrix = load(input);

        JFrame frame = buildFrame();
        ImageIcon img = new ImageIcon("C:/Users/Desktop/black20.png");
        black = img.getImage();
        img = new ImageIcon("C:/Users/Desktop/gri20.png");
        white = img.getImage();
        img = new ImageIcon("C:/Users/Desktop/finish20.png");
        finish = img.getImage();
        img = new ImageIcon("C:/Users/Desktop/smiley20.png");
        player = img.getImage();
        // frame.add(new Player());
        JPanel pane = new JPanel() {
            @Override
            public void paint(Graphics g) {
                super.paint(g);
                for (int i = 0; i < matrix.length; i++) {
                    for (int j = 0; j < matrix[0].length; j++) {
                        if (matrix[i][j].equals("1")) {
                            g.drawImage(black, i * 20, j * 20, null);
                        }
                        if (matrix[i][j].equals("0")) {
                            g.drawImage(white, i * 20, j * 20, null);
                        }
                        if (matrix[i][j].equals("2")) {
                            g.drawImage(finish, i * 20, j * 20, null);
                        }
                    }
                }
                g.drawImage(player, x * 20, y * 20, null);
            }
        };
        frame.add(pane);
        frame.add(new Main());
    }
}

It should look like: 它应该看起来像:

在此处输入图片说明

Problems/Suggestions: 问题/建议:

  • You're adding more than one component to the JFrame in a default fashion. 您正在以默认方式向JFrame添加多个组件。 Since the JFrame's contentPane uses BorderLayout, only one component will display, the last one added, and the other will be completely covered and will remain invisible. 由于JFrame的contentPane使用BorderLayout,因此仅显示一个组件,添加的最后一个组件将被完全覆盖,并且将保持不可见。
  • Your Main JPanel is not being used as a true JPanel. 您的主JPanel未被用作真正的JPanel。 Nothing is being added to it, and in fact it looks like it should be a logical class and not a component class. 没有添加任何东西,实际上看起来它应该是逻辑类而不是组件类。
  • Rather than using KeyListeners, which are very fidgety when it comes to focus problems, use Key Bindings which will allow you to get around focus issues in a clean and higher level way. 与其使用KeyListeners(在解决焦点问题时非常烦躁),不如使用Key Bindings(键绑定) ,它可以让您以更清晰,更高级的方式解决焦点问题。
  • Don't override the JPanel's paint method but rather its paintComponent method as this will give you several advantages, including default use of double buffering for your animation. 不要重写JPanel的paint方法,而要覆盖它的paintComponent方法,因为这将为您带来许多好处,包括默认为动画使用双缓冲。
  • Don't give component classes a public int getX() and public int getY() method without care since these override key methods that place the component within its container. 不要不小心为组件类提供public int getX()public int getY()方法,因为它们会覆盖将组件放置在其容器中的键方法。 Since the Main class shouldn't even extend JPanel, this will end up to be a non-issue for your code, but in the future, it would mess your program up. 由于Main类甚至不应该扩展JPanel,因此这最终对于您的代码来说不是问题,但是在将来,它将使您的程序混乱。
  • When you run into similar problems, such as a KeyListener not working, remove the issue from your big program and try to reproduce it in a small separate program. 当您遇到类似的问题(例如KeyListener不起作用)时,请从大型程序中删除该问题,然后尝试在一个单独的小型程序中重现该问题。 This will give you a much cleaner environment for helping you to isolate and understand your problem and thereby help you fix it. 这将为您提供一个更清洁的环境,以帮助您隔离和理解问题,从而帮助您解决问题。
  • Your program is mis-using the static modifier. 您的程序滥用了static修饰符。 Your x and y fields should not be static and should not be accessed in a static way. 您的x和y字段不应为静态,并且不应以静态方式进行访问。
  • You've got way too much code within your main method, which is one of the reasons why you likely made x and y static, because you were forced to do so since you're trying to access them within main. 您的main方法中有太多代码,这就是您可能将x和y设为静态的原因之一,因为您试图在main中访问它们而被迫这样做。 The solution is not to make the fields static but to get all that code out of the static world and into the instance world. 解决方案不是使字段成为静态,而是使所有代码脱离静态世界并进入实例世界。

Edit 编辑

For some reason the question intrigued me, and so I decided to try to MVC or Model-View-Controller it if possible and see what I could come up with. 由于某种原因,这个问题引起了我的兴趣,因此,我决定尝试使用MVC或Model-View-Controller,如果可能的话,看看我能想到什么。 So here goes a bunch of classes that sort of work, beginning with a text file that holds the data. 因此,这里有许多类的工作,从保存数据的文本文件开始。

The GUI looks like: GUI如下所示:

在此处输入图片说明

It must be in the same location as the class files since it is obtained as a resource and must have the file name "input.txt" 它必须与类文件位于同一位置,因为它是作为资源获得的,并且必须具有文件名"input.txt"

1111111111111111111111111111111111111111111
1000000010001000001000000010000000100000001
1010111010101010101111101011111010111111101
1010001010100010100000001010000010000010001
1011101010111110101111111010111111111010111
1000101010100000101000001000100010000010001
1011101011101011111011101111111010111110101
1010001000001010000010100000001010000010101
1010111111111010111110111111101011111011101
1010100000100010100000000000101000000000101
1110101111101110111110111011101011111110101
1000100000000010000010100010001000100010001
1011111111111111111011101010111111101011101
1000000000000000100010001010000000001010001
1011111111111011101110111011111111111010111
1000100010001000001010001000100000001010101
1110101011101111111010101110111110111010101
1000101010001000100000101000100000100010001
1011101010111010101111101011101110101111111
1000001010000010000000101000001000100010001
1111111011111110111111101111111011111010101
1000001010000010100010001000000010000010101
1011111010111011101010111011111110101110101
1010000010001010001010001000100000101010101
1010111111101010111011101111101111101011101
1000100000001010101010001000100010101000101
1011111011111010101010111010111010101011101
1010000010001000101010000010001010001000001
1010101110101111101011101111101011111010101
1010101000101000001000101000001000000010101
1011101011111010111110111011101111111110111
1000001000000010000000000010000000000010021
1111111111111111111111111111111111111111111

Next the main program, the one that creates the model, the view, and the controller, hooks them all together, and then displays the GUI: 接下来,主程序即创建模型,视图和控制器的主程序,将它们全部钩在一起,然后显示GUI:

import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

/**
 * link: http://stackoverflow.com/a/41418250/522444
 * 
 * @author Pete
 *
 */
@SuppressWarnings("serial")
public class Main2 extends JPanel {
    private View mainPanel;

    public Main2(MatrixModel matrixModel) {
        mainPanel = new View(matrixModel);
        new Controller(matrixModel, mainPanel);

        setLayout(new BorderLayout());
        add(mainPanel, BorderLayout.CENTER);
    }

    private static void createAndShowGui(MatrixModel model) {
        Main2 mainPanel = new Main2(model);

        JFrame frame = new JFrame("Main2");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        final MatrixModel model = MatrixUtil.getInput(MatrixUtil.PATH_TO_RSC);

        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGui(model);
            }
        });
    }
}

Next a utility class with static methods for reading in the text file as a resource and converting it into a Model object: 接下来是一个带有静态方法的实用程序类,用于将文本文件作为资源读取并将其转换为Model对象:

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class MatrixUtil {
    // again this text file must be in the jar file or the code base 
    // at the same location as the class / java files
    public static final String PATH_TO_RSC = "input.txt";

    public static MatrixModel getInput(String resourcePath) {
        InputStream is = MatrixUtil.class.getResourceAsStream(resourcePath);
        if (is == null) {
            String text = "resourcePath is not found and not loading text: " + resourcePath;
            throw new IllegalArgumentException(text);
        }
        return getInput(is);
    }

    public static MatrixModel getInput(InputStream is) {
        MatrixModel model = null;
        try (Scanner scan = new Scanner(is)) {
            List<List<MatrixPosition>> listOfLists = new ArrayList<>();
            while (scan.hasNextLine()) {
                String line = scan.nextLine();
                if (line.trim().isEmpty()) {
                    continue;
                }
                List<MatrixPosition> list = new ArrayList<>();
                for (char c : line.toCharArray()) {
                    list.add(MatrixPosition.getMatrixPosition(String.valueOf(c)));
                }
                listOfLists.add(list);
            }
            MatrixPosition[][] grid = new MatrixPosition[listOfLists.size()][];
            for (int i = 0; i < grid.length; i++) {
                List<MatrixPosition> list = listOfLists.get(i);
                grid[i] = list.toArray(new MatrixPosition[] {});
            }
            model = new MatrixModel(grid, new SpritePosition(1, 1));
        }

        return model;
    }

}

Basic enum to represent direction: 基本枚举代表方向:

public enum Direction {
    UP, DOWN, LEFT, RIGHT
}

Another enum to represent a location point in the grid, and whether it is a wall, a coridor or the end as well as static methods to convert from number to MatrixPosition: 另一个表示网格中的位置点的枚举,它是墙,走廊还是终点,以及将数字转换为MatrixPosition的静态方法:

public enum MatrixPosition {
    WALL(1), CORRIDOR(0), END(2);

    private int value;

    private MatrixPosition(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public static MatrixPosition getMatrixPosition(int value) {
        for (MatrixPosition position : MatrixPosition.values()) {
            if (value == position.getValue()) {
                return position;
            }
        }
        String text = "value of " + value;
        throw new IllegalArgumentException(text);
    }

    public static MatrixPosition getMatrixPosition(String strValue) {
        int value = -1;
        try {
            value = Integer.parseInt(strValue);
        } catch (NumberFormatException e) {
            String text = "NumberFormatException for strValue " + strValue;
            throw new IllegalAccessError(text);
        }
        return getMatrixPosition(value);
    }
}    

A class to represent a position of our sprite, similar to the java.awt.Point class but with row and column fields instead of x and y: 表示我们精灵的位置的类,类似于java.awt.Point类,但具有行和列字段,而不是x和y:

public class SpritePosition {
    int row;
    int column;

    public SpritePosition(int row, int column) {
        this.row = row;
        this.column = column;
    }

    public int getRow() {
        return row;
    }

    public void setRow(int row) {
        this.row = row;
    }

    public int getColumn() {
        return column;
    }

    public void setColumn(int column) {
        this.column = column;
    }

    public void setRowColumn(int row, int column) {
        this.row = row;
        this.column = column;
    }

}    

The model has property change support code so that it can notify any classes listening to it of any changes in its state. 该模型具有属性更改支持代码,因此它可以将其状态的任何更改通知给所有侦听该类的类。 The controller will be the class listening to the model 控制器将是听模型的班级

import java.beans.PropertyChangeListener;
import javax.swing.event.SwingPropertyChangeSupport;

public class MatrixModel {
    public static final String SPRITE_POINT = "sprite point";
    private SwingPropertyChangeSupport pcSupport = new SwingPropertyChangeSupport(this);
    private MatrixPosition[][] grid;
    private SpritePosition spritePosition;

    public MatrixModel(MatrixPosition[][] grid, SpritePosition spritePosition) {
        this.grid = grid;
        this.spritePosition = spritePosition;
    }

    public int getRows() {
        return grid.length;
    }

    public int getColumns() {
        return grid[0].length;
    }

    public MatrixPosition getPosition(SpritePosition p) {
        return getPosition(p.row, p.column);
    }

    public MatrixPosition getPosition(int row, int col) {
        return grid[row][col];
    }

    public void setSpritePoint(SpritePosition spritePosition) {
        SpritePosition oldValue = this.spritePosition;
        SpritePosition newValue = spritePosition;
        this.spritePosition = spritePosition;
        pcSupport.firePropertyChange(SPRITE_POINT, oldValue, newValue);
    }

    public boolean isPointValid(SpritePosition p) {
        if (p.column < 0 || p.row < 0) {
            return false;
        }
        if (p.column >= grid[0].length || p.row >= grid.length) {
            return false;
        }
        return grid[p.row][p.column] == MatrixPosition.CORRIDOR;
    }

    public boolean isMoveValid(Direction direction) {
        int row = spritePosition.row;
        int column = spritePosition.column;
        switch (direction) {
        case UP:
            return isPointValid(new SpritePosition(row - 1, column));
        case DOWN:
            return isPointValid(new SpritePosition(row + 1, column));
        case LEFT:
            return isPointValid(new SpritePosition(row, column - 1));
        case RIGHT:
            return isPointValid(new SpritePosition(row, column + 1));
        default:
            return false;
        }
    }

    public void move(Direction direction) {
        if (!isMoveValid(direction)) {
            String text = "For move to " + direction + "spritePosition: " + spritePosition;
            throw new IllegalArgumentException(text);
        }
        int row = spritePosition.row;
        int column = spritePosition.column;
        switch (direction) {
        case UP:
            setSpritePoint(new SpritePosition(row - 1, column));
            break;
        case DOWN:
            setSpritePoint(new SpritePosition(row + 1, column));
            break;
        case LEFT:
            setSpritePoint(new SpritePosition(row, column - 1));
            break;
        case RIGHT:
            setSpritePoint(new SpritePosition(row, column + 1));
            break;

        default:
            break;
        }
    }

    public SpritePosition getSpritePosition() {
        return spritePosition;
    }

    public void addPropertyChangeListener(PropertyChangeListener listener) {
        pcSupport.addPropertyChangeListener(listener);
    }

    public void removePropertyChangeListener(PropertyChangeListener listener) {
        pcSupport.removePropertyChangeListener(listener);
    }

    public void addPropertyChangeListener(String name, PropertyChangeListener listener) {
        pcSupport.addPropertyChangeListener(name, listener);
    }

    public void removePropertyChangeListener(String name, PropertyChangeListener listener) {
        pcSupport.removePropertyChangeListener(name, listener);
    }
}    

Controller class, one that sets up key bindings on the view so that it can listen for key presses, checks if they represent a valid move, and if so then tells the model to make the move. 控制器类,该类在视图上设置按键绑定,以便它可以侦听按键,检查它们是否代表有效的移动,如果是,则告诉模型进行移动。 It also adds a listener to the model so that when its state changes, it will tell the view to move the sprite 它还向模型添加了一个侦听器,以便当其状态更改时,它将告诉视图移动精灵

import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.EnumMap;
import java.util.Map;

import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.KeyStroke;

public class Controller {
    private MatrixModel model;
    private View view;
    private Map<Direction, KeyStroke> dirKeyMap = new EnumMap<>(Direction.class);

    public Controller(MatrixModel model, View view) {
        this.model = model;
        this.view = view;

        dirKeyMap.put(Direction.DOWN, KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0));
        dirKeyMap.put(Direction.UP, KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0));
        dirKeyMap.put(Direction.LEFT, KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0));
        dirKeyMap.put(Direction.RIGHT, KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0));

        model.addPropertyChangeListener(new ModelListener());
        setUpKeyBindings(view);
    }

    private void setUpKeyBindings(View view) {
        int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
        InputMap inputMap = view.getInputMap(condition);
        ActionMap actionMap = view.getActionMap();
        for (Direction dir : Direction.values()) {
            KeyStroke keyStroke = dirKeyMap.get(dir);
            hookUp(inputMap, actionMap, dir, keyStroke);
        }
    }

    private void hookUp(InputMap inputMap, ActionMap actionMap, Direction dir, KeyStroke key) {
        inputMap.put(key, key.toString());
        actionMap.put(key.toString(), new MoveAction(dir, model));
    }

    public MatrixModel getModel() {
        return model;
    }

    public View getView() {
        return view;
    }

    class ModelListener implements PropertyChangeListener {
        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            if (MatrixModel.SPRITE_POINT.equals(evt.getPropertyName())) {
                SpritePosition p = model.getSpritePosition();
                view.setSpritePoint(p);
            }
        }
    }

}

@SuppressWarnings("serial")
class MoveAction extends AbstractAction {
    private Direction dir;
    private MatrixModel model;

    public MoveAction(Direction dir, MatrixModel model) {
        super(dir.toString());
        this.dir = dir;
        this.model = model;
    }

    public void actionPerformed(ActionEvent e) {
        if (model.isMoveValid(dir)) {
            model.move(dir);
        }
    }
}

Finally the View class, that extends JPanel, that displays the maze and the sprite: 最后,扩展JPanel的View类显示迷宫和精灵:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class View extends JPanel {
    private static final int CELL_WIDTH = 20;
    private static final Color CORRIDOR_COLOR = Color.LIGHT_GRAY;
    private static final Color WALL_COLOR = Color.DARK_GRAY;
    private static final Color END_COLOR = Color.ORANGE;
    private static final Color SPRITE_COLOR = Color.RED;
    private static final int GAP = 1;
    private BufferedImage gridImg = null;
    private SpritePosition spritePosition;
    private JPanel mainPanel = new JPanel();

    public View(MatrixModel matrixModel) {
        gridImg = createImg(matrixModel);
        spritePosition = matrixModel.getSpritePosition();
    }

    public JPanel getMainPanel() {
        return mainPanel;
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet() || gridImg == null) {
            return super.getPreferredSize();
        }
        int prefW = gridImg.getWidth();
        int prefH = gridImg.getHeight();
        return new Dimension(prefW, prefH);
    }

    public void setSpritePoint(SpritePosition spritePosition) {
        this.spritePosition = spritePosition;
        repaint();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (gridImg != null) {
            g.drawImage(gridImg, 0, 0, this);
        }
        g.setColor(SPRITE_COLOR);
        int y = spritePosition.row * CELL_WIDTH + GAP;
        int x = spritePosition.column * CELL_WIDTH + GAP;
        g.fillRect(x, y, CELL_WIDTH - 2 * GAP, CELL_WIDTH - 2 * GAP);
    }

    private BufferedImage createImg(MatrixModel matrixModel) {
        BufferedImage img = null;
        if (matrixModel != null && matrixModel.getRows() > 0) {
            int w = matrixModel.getColumns() * CELL_WIDTH;
            int h = matrixModel.getRows() * CELL_WIDTH;
            img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2 = img.createGraphics();
            for (int row = 0; row < matrixModel.getRows(); row++) {
                for (int col = 0; col < matrixModel.getColumns(); col++) {
                    MatrixPosition position = matrixModel.getPosition(row, col);
                    Color c = null;
                    switch (position) {
                    case CORRIDOR:
                        c = CORRIDOR_COLOR;
                        break;
                    case WALL:
                        c = WALL_COLOR;
                        break;
                    case END:
                        c = END_COLOR;
                        break;
                    }
                    g2.setColor(c);
                    int x = col * CELL_WIDTH;
                    int y = row * CELL_WIDTH;
                    g2.fillRect(x, y, CELL_WIDTH, CELL_WIDTH);
                }
            }
            g2.dispose();
        }
        return img;
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM