根据俄罗斯方块游戏创建的数组为JTable单元着色 [英] Coloring JTable cells based on an array created by Tetris game

查看:82
本文介绍了根据俄罗斯方块游戏创建的数组为JTable单元着色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个Tetris GUI.我的朋友写了后端.到目前为止,我们只是将tetris板(或我在代码中引用的网格)打印到控制台窗口.在下面的代码中,我将设置一个JTable来充当Tetris游戏的面板.我想知道如何让我的JTable基于Window类顶部声明的俄罗斯方块游戏"传递的网格来呈现每个网格元素.此网格是2D整数值数组,它引用Pieces类中枚举的颜色.有什么建议?到目前为止,它只打印一种颜色.

I am attempting to create a Tetris GUI. My friend wrote the backend. Up until now, we just had the tetris board (or grid as I refer to it in my code) print to the console window. In the code below I am setting up a JTable to act as the board for the Tetris game. I was wondering how I could get my JTable to render each grid element based on the grid passed from the Tetris 'game' declared in the top of the Window class. This grid is a 2D array of integer value which refer to colors enumerated in the Pieces class. Any suggestions? As of now it only prints one color.

我还为Tetris类发布了一些代码,以便您可以在那里看到可用的方法和参数.

I also posted some code for the Tetris class just so you can see the methods and parameters available there.

这是我的代码(希望在SSCCE = p中):

Here is my code (hopefully in SSCCE =p):

public class Window {
    JPanel cards;
    final static String SPLASHSCREEN = "SplashScreen";
    final static String MAINMENU = "MainMenu";
    final static String TETRIS = "Tetris";
    final static int GRID_ROW_HEIGHT = 30;
    final static int NUM_ROWS = 20;
    final static int NUM_COLS = 10;
    JTable table = new JTable(new MyTableModel());
    Tetris game = new Tetris(); 

    public void addComponentToWindow(Container pane) {
        // Create the "cards"
        .
        .
        .

        // SplashScreen setup
        .
        .
        .

        // MainMenu setup
        .
        .
        .

        // Tetris setup
        final JButton startGame = new JButton("START GAME");
        card3.setLayout(new GridBagLayout());
        GridBagConstraints gbc2 = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.insets = new Insets(2, 2, 2, 2);
        card3.add(startGame, gbc2);
        gbc.gridy = 1;
        startGame.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {                
                table.setDefaultRenderer(Object.class, new MyRenderer());
                table.setRowHeight(GRID_ROW_HEIGHT);
                table.setFocusable(false);
                table.setRowSelectionAllowed(false);
                for (int i = 0; i < game.getNumCols(); i++) {
                    table.getColumnModel().getColumn(i).setPreferredWidth(table.getRowHeight());
                }

                card3.add(table);
                card3.remove(0); //Removes button
                card3.revalidate(); //Redraws graphics
            }
        });

        // Sets up layout
        cards = new JPanel(new CardLayout());
        cards.add(card1, SPLASHSCREEN);
        cards.add(card2, MAINMENU);
        cards.add(card3, TETRIS);

        // Creates the actual window
        pane.add(cards, BorderLayout.CENTER);
    }

    public Color getTableCellBackground(JTable table, int row, int col) {
        TableCellRenderer renderer = table.getCellRenderer(row, col);
        Component component = table.prepareRenderer(renderer, row, col);    
        return component.getBackground();
    }

    class MyRenderer implements TableCellRenderer {
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            JTextField editor = new JTextField();
            if (value != null) {
                editor.setText(value.toString());
            }
            if (game.getCur_color().getKey() == 0) {
                editor.setBackground(Color.WHITE);
            }
            else if (game.getCur_color().getKey() == 1) {
                editor.setBackground(Color.RED);
            }
            else if (game.getCur_color().getKey() == 2) {
                editor.setBackground(Color.GREEN);
            }
            else if (game.getCur_color().getKey() == 3) {
                editor.setBackground(Color.BLUE);
            }
            else if (game.getCur_color().getKey() == 4) {
                editor.setBackground(Color.YELLOW);
            }
            return editor;
        }
    }

    @SuppressWarnings("serial")
    class MyTableModel extends AbstractTableModel {
        public int getColumnCount() {
            return NUM_COLS;
        }
        public int getRowCount() {
            return NUM_ROWS;
        }        
        public Object getValueAt(int row, int col) {
            return null;
        }
    }
}

俄罗斯方块类:

public class Tetris 
{
    int NUM_ROWS = 20;
    int NUM_COLS = 10;

    int grid[][];
    int cur_row;
    int cur_col;
    Pieces cur_color;
    Style cur_style;
    Pieces next_color;
    Style next_style;
    boolean over;

    public Tetris()
    {
        grid = new int[10][20];

        for(int i = 0; i < 10; i ++)
        {
            for(int j = 0; j < 20; j ++)
            {
                grid[i][j] = Pieces.BLANK.getKey();
            }
        }

        next_color = Pieces.createColor();
        next_style = Style.createStyle();
        over = false;

        create_Piece();
    }

    public void createPiece(){...}
    public void setPiece(){...}
    public void removeRow(){...}
}

与所有字段的moveLeft,moveRight,moveDown,rotateLeft,rotateRight,printGame以及getter和setter一起使用. Tetris类中的所有方法均已在控制台中进行了测试,并且可以正常工作.这是我到目前为止的输出.每次颜色都不相同,我很确定我知道为什么,但是我很难考虑如何根据在Tetris类中创建的网格数组为每个单元着色.

Along with the moveLeft, moveRight, moveDown, rotateLeft, rotateRight, printGame, and getters and setters for all fields. All the methods in the Tetris class were tested in the console and work correctly. Here is an output of what I have so far. Each time the color is different and I am pretty sure I know why, but I am having trouble thinking of how to color each cell based on the grid array created in the Tetris class.

推荐答案

这纯粹是概念的证明.

基本上,您已经拥有游戏板的模型.您需要能够将其建模回屏幕.

Basically, you already have a model of the game board. You need to be able to model that back to the screen.

我会将您的电路板模型包装在TableModel中,并与TableCellRenderer一起使用,让两者一起工作.

I would wrap your board model in a TableModel and together with TableCellRenderer, allow the two to work together.

您要做的就是在电路板数据更改时相应地更新表模型.

The all you need to do, is update the table model accordingly when the board data changes.

如果您正确地编写了关系,则边框将通知表格模型,表格模型将通知表格.

If you write your relationships correctly, the border will notify the table model, which will notify the table.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Enumeration;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;

public class TetrisTable {

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

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

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

    public class TestPane extends JPanel {

        private JTable table;
        private TetrisTabelModel model;
        private int currentRow = 0;
        private int blockHeight = 3;
        private int blockWidth = 3;

        public TestPane() {
            model = new TetrisTabelModel();
            table = new JTable(model);
            table.setDefaultRenderer(Integer.class, new TetrisTabelCellRenderer());
            table.setRowHeight(24);
            Enumeration<TableColumn> columns = table.getColumnModel().getColumns();
            while (columns.hasMoreElements()) {
                TableColumn column = columns.nextElement();
                column.setPreferredWidth(24);
                column.setMinWidth(24);
                column.setMaxWidth(24);
                column.setWidth(24);
            }
            setLayout(new GridBagLayout());
            add(table);

            Timer timer = new Timer(500, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {

                    int col = (model.getColumnCount() - blockWidth) / 2;
                    int row = currentRow - blockHeight;
                    if (row + blockHeight >= model.getRowCount()) {
                        ((Timer) e.getSource()).stop();
                    } else {
                        drawShape(row, col, 0);
                        currentRow++;
                        row = currentRow - blockHeight;
                        drawShape(row, col, 3);
                    }

                }

                public void drawShape(int row, int col, int color) {

                    for (int index = 0; index < blockHeight; index++) {

                        if (row >= 0 && row < model.getRowCount()) {

                            switch (index) {
                                case 0:
                                case 1:
                                    model.setValueAt(color, row, col);
                                    break;
                                case 2:
                                    model.setValueAt(color, row, col);
                                    model.setValueAt(color, row, col + 1);
                                    model.setValueAt(color, row, col + 2);
                                    break;
                            }

                        }
                        row++;

                    }
                }
            });
            timer.setRepeats(true);
            timer.setCoalesce(true);
            timer.start();

        }
    }

    public class TetrisTabelModel extends AbstractTableModel {

        private int[][] values;

        public TetrisTabelModel() {
            values = new int[20][10];
        }

        @Override
        public int getRowCount() {
            return values.length;
        }

        @Override
        public int getColumnCount() {
            return values[0].length;
        }

        @Override
        public Class<?> getColumnClass(int columnIndex) {
            return Integer.class;
        }

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            return values[rowIndex][columnIndex];
        }

        @Override
        public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
            values[rowIndex][columnIndex] = (int) aValue;
            fireTableCellUpdated(rowIndex, columnIndex);
        }
    }

    public class TetrisTabelCellRenderer extends DefaultTableCellRenderer {

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            super.getTableCellRendererComponent(table, "", false, false, row, column);
            setOpaque(true);
            if (value != null) {
                if (value == 0) {
                    setBackground(Color.WHITE);
                } else if (value == 1) {
                    setBackground(Color.RED);
                } else if (value == 2) {
                    setBackground(Color.GREEN);
                } else if (value == 3) {
                    setBackground(Color.BLUE);
                } else if (value == 4) {
                    setBackground(Color.YELLOW);
                }
            } else {
                setBackground(Color.DARK_GRAY);
            }
            return this;
        }
    }
}

这篇关于根据俄罗斯方块游戏创建的数组为JTable单元着色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆