如何根据单元格中的值为JTable的单个单元着色?

我正在尝试制作俄罗斯方块克隆。 游戏使用JTable作为棋盘的代表。 该板是2D整数数组。

我试图这样做,当某个单元格具有一定的值时,单元格将变为某种颜色。 我以为我的工作正常,但它无法正常工作。 我真的很感激一些帮助。

谢谢。

这是我的代码:

板:

 import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import javax.swing.Timer; import javax.swing.table.*; /** * @author _______________ * * Board.java * * The Board class gives information to the InitializeJTable class regarding * the data-type of the JTable elements, how many rows/columns are in the JTable, etc; * * I extended Board with AbstractTableModel, a class that allows me to display any data-type * inside the elements of the JTable. * * This class also has method declarations that are required by AbstractTableModel, these methods are: * - getRowCount() * - getColumnCount() * - getValueAt(int, int) * */ @SuppressWarnings("serial") public class Board extends AbstractTableModel { TableColorSetter TCS; boolean lost = false; InitializeGUI iGUI; InitializeJTable iJT; public int SPEED = 1000; L l = new L(); public Block currentBlock = l; public int[][] boxes;//A 2D Array of booleans that defines the status of the Tetris board. Used by InitializeJTable and InitializePreviewJTable /* * boardType is an integer that works with the constructor. * * If boardType is equal to 0, the constructor generates a 22x10 array (This is used with the main board) * However, if boardType is equal to 1, the constructor generates a 4x4 array (This is used with the preview/hold board, a smaller board on the side) */ public Board(int boardType) { if(boardType == 0) { boxes = new int[22][10]; loop(); } else if(boardType == 1) boxes = new int[4][4]; } /* * getRowCount() * * getRowCount is a required declaration by the AbstractTableModel class. * @return the amount of rows in the boxes boolean */ @Override public int getRowCount() { return boxes.length; } public int getTetrisType(Block block) { return block.getTetrisType(); } public void letPieceDown(int origA, int origB, int tetrisType) { boxes[origA][origB] = 0; boxes[origA + 1][origB] = tetrisType; } /* * getColumnCount() * * getColumnCount() is a required declaration by the AbstractTableModel class. * @return the amount of columns in the boxes boolean */ @Override public int getColumnCount() { return boxes[0].length; } @Override public void setValueAt(Object aValue, int rowIndex, int columnIndex) { boxes[rowIndex][columnIndex] = (int)aValue; fireTableCellUpdated(rowIndex, columnIndex); } /* * getValueAt() * * getValueAt() is a required declaration by the AbstractTableModel class. * returns the amount of columns in the boxes boolean * * @param int rowIndex The row index of the boolean that you want to return. * int columnIndex The column index of the boolean that you want to return. * * @return the value of the boolean at the specified location in the boolean array. */ @Override public Object getValueAt(int rowIndex, int columnIndex) { return boxes[rowIndex][columnIndex]; } public int getVal(int row, int col) { return boxes[row][col]; } /** * * loop(); * * The loop() method is a very rough draft in regards to placing Tetris objects on the board and having them move, and stack. * * TODO: */ public void loop() { Timer timer = new Timer(SPEED, new ActionListener() { int x = 0; int y = 0; @Override public void actionPerformed(ActionEvent e) { while(lost = false) { for(int a = 0; a < getColumnCount(); a++) { for(int b = 0; b < getRowCount(); b++) { TCS.getTableCellRendererComponent(iJT.getTable(), "", false, false, b, a); } } } if(x == getRowCount() - 1) { x = 0; } else if(boxes[x + 1][y] != 0 && x == 0) { boxes[x][y] = getTetrisType(currentBlock); fireTableDataChanged(); //System.out.println("GAME OVER!"); //y++; //Just for testing. PlaySound sound = new PlaySound(); sound.setSoundType(1); sound.start(); ((Timer)e.getSource()).stop(); } else if(boxes[x + 1][y] != 0) { x = 0; } else { //System.out.println("Pos: " + x + ", 0. Row count: " + getRowCount() + " -- " + x); letPieceDown(x, y, getTetrisType(currentBlock)); fireTableDataChanged(); x++; } } }); timer.start(); } } 

InitializeJTable:

 import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumnModel; import java.awt.Color; import java.awt.Component; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTable; /** * @author _________________ * * InitializeJTable.java * * The InitializeJTable class sets up the JTable to look like a Tetris board. * * @TODO: Add more commenting */ @SuppressWarnings("serial") public class InitializeJTable extends JPanel { private int COLS = 10; private int HEIGHT = 30; Color white = Color.WHITE; Color black = Color.BLACK; Board tetrisBoard; JTable table; public Board returnBoard() { return tetrisBoard; } public JTable getTable() { return table; } public InitializeJTable() { //The InitializeJTable constructor tetrisBoard = new Board(0); //Create a new board of 22x10 booleans, with a boardType of 0. table = new JTable(tetrisBoard); //Apply the information from the Board constructor to the JTable. (Information like, how many rows/cols in the JTable, what data-type the JTable elements are, etc) //setLayout(new GridBagLayout()); //Sets the Layout of the JTable to a GridBagLayout. This means, it makes the JTable look like a grid. table.setCellSelectionEnabled(false); //Disables dragging/selection of columns on the JTable with the mouse. We won't be needing that. TableColumnModel columns = table.getColumnModel(); //Gets information about the columns of the JTable. I need this to set the length of the columns (to make them square) table.setRowHeight(HEIGHT); //Sets the height of the JTable rows to HEIGHT int, currently set to 30. Can be easily changed. //table.setForeground(white); //Use this to make all blocks white. Still need to make it work correctly. /* * Sadly, there isn't a -- table.setColumnHeight(int) -- method in the JTable API. (to set the length of the columns to the specified integer) * * So I have to manually set the width of each column. This is why I declared the TableColumnModel above */ for(int a = 0; a < COLS; a++) { columns.getColumn(a).setPreferredWidth(HEIGHT); //Sets the height of the JTable columns to HEIGHT int, currently set to 30. Can be changed easily. } add(table);//The table's all set up correctly, add it. } } 

数据/模型与视图/表之间存在关系。 该模型维持“什么”,视图控制“如何”。

JTable提供了一种方法,通过使用TableCellRenderers ,您可以通过这种方式来处理“如何”(填充内容),这些方法负责确定如何根据来自“what”的值来“绘制”单元格。模型。

首先看一下如何使用表和使用自定义渲染器

现在,此示例使用double值来确定单元格值为1的距离,该值表示应绘制单元格的颜色(黑色= 0;白色= 1)。 为此,它使用自定义TableCellRenderer将模型中的值(“what”)转换为颜色(或“how”)

 public class PaintTableCellRenderer extends DefaultTableCellRenderer { @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { super.getTableCellRendererComponent(table, "", isSelected, hasFocus, row, column); if (value instanceof Double) { double distance = (double) value; int part = (int) (255 * distance); Color color = new Color(part, part, part); setBackground(color); } else { setBackground(Color.WHITE); } return this; } } 

微笑

它还演示了您可能需要了解的有关JTable的其他一些事项。

 import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.EventQueue; import java.util.Enumeration; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; 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 Smile { public static void main(String[] args) { new Smile(); } public Smile() { 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("Testing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(new TestPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class TestPane extends JPanel { private double[][] smily = { {1, 1, 1, 1, 1, 0.996, 1, 0.843, 0.784, 0.788, 0.773, 0.769, 0.765, 0.765, 0.788, 0.784, 0.847, 1, 0.996, 1, 1, 1, 1, 0.996}, {1, 1, 1, 1, 1, 0.871, 0.733, 0.761, 0.847, 0.941, 0.941, 0.941, 0.941, 0.941, 0.933, 0.843, 0.761, 0.733, 0.871, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 0.784, 0.733, 0.902, 0.941, 0.941, 0.941, 0.945, 0.941, 0.941, 0.941, 0.941, 0.941, 0.941, 0.898, 0.733, 0.784, 1, 1, 1, 1}, {1, 1, 1, 0.765, 0.773, 0.945, 0.945, 0.941, 0.929, 0.937, 0.941, 0.941, 0.945, 0.941, 0.957, 0.91, 0.941, 0.941, 0.941, 0.78, 0.761, 1, 1, 1}, {1, 1, 0.808, 0.773, 0.941, 0.941, 0.941, 0.941, 0.294, 0.447, 0.941, 0.941, 0.941, 0.941, 0.702, 0.239, 0.886, 0.941, 0.945, 0.941, 0.78, 0.8, 1, 1}, {1, 0.89, 0.725, 0.945, 0.941, 0.941, 0.945, 0.843, 0, 0, 0.922, 0.945, 0.941, 0.941, 0.408, 0, 0.663, 0.941, 0.941, 0.945, 0.941, 0.725, 0.89, 1}, {0.992, 0.753, 0.902, 0.941, 0.945, 0.945, 0.941, 0.725, 0.051, 0, 0.808, 0.941, 0.941, 0.945, 0.294, 0.051, 0.553, 0.941, 0.941, 0.941, 0.941, 0.91, 0.741, 0.984}, {0.871, 0.78, 0.941, 0.941, 0.945, 0.945, 0.941, 0.694, 0.051, 0, 0.784, 0.945, 0.941, 0.941, 0.278, 0, 0.518, 0.941, 0.941, 0.945, 0.941, 0.941, 0.78, 0.878}, {0.816, 0.855, 0.941, 0.945, 0.945, 0.945, 0.941, 0.737, 0, 0.051, 0.82, 0.941, 0.941, 0.941, 0.302, 0.051, 0.565, 0.941, 0.949, 0.945, 0.941, 0.941, 0.863, 0.804}, {0.8, 0.945, 0.941, 0.945, 0.945, 0.941, 0.941, 0.875, 0, 0, 0.937, 0.941, 0.941, 0.941, 0.443, 0, 0.694, 0.945, 0.945, 0.945, 0.945, 0.949, 0.941, 0.765}, {0.769, 0.941, 0.945, 0.957, 0.961, 0.941, 0.945, 0.941, 0.443, 0.565, 0.945, 0.941, 0.941, 0.941, 0.769, 0.388, 0.918, 0.941, 0.941, 0.941, 0.945, 0.941, 0.941, 0.78}, {0.753, 0.941, 0.941, 0.941, 0.941, 0.941, 0.941, 0.953, 0.941, 0.941, 0.941, 0.941, 0.945, 0.941, 0.941, 0.941, 0.941, 0.941, 0.941, 0.941, 0.941, 0.941, 0.941, 0.788}, {0.741, 0.945, 0.839, 0.427, 0.624, 0.941, 0.941, 0.945, 0.941, 0.941, 0.941, 0.949, 0.945, 0.945, 0.941, 0.941, 0.941, 0.941, 0.941, 0.6, 0.376, 0.941, 0.945, 0.784}, {0.749, 0.941, 0.914, 0.345, 0.647, 0.941, 0.945, 0.949, 0.945, 0.945, 0.941, 0.941, 0.945, 0.941, 0.945, 0.945, 0.945, 0.945, 0.941, 0.702, 0.384, 0.941, 0.941, 0.78}, {0.796, 0.945, 0.941, 0.627, 0.592, 0.941, 0.941, 0.941, 0.945, 0.945, 0.945, 0.941, 0.949, 0.945, 0.941, 0.945, 0.945, 0.937, 0.945, 0.58, 0.631, 0.941, 0.937, 0.776}, {0.812, 0.859, 0.941, 0.855, 0.384, 0.957, 0.941, 0.945, 0.945, 0.945, 0.941, 0.953, 0.941, 0.945, 0.945, 0.945, 0.941, 0.941, 0.941, 0.384, 0.941, 0.941, 0.867, 0.812}, {0.871, 0.788, 0.941, 0.941, 0.533, 0.51, 0.941, 0.941, 0.941, 0.945, 0.949, 0.945, 0.945, 0.945, 0.941, 0.937, 0.941, 0.945, 0.522, 0.522, 0.941, 0.941, 0.792, 0.886}, {0.992, 0.761, 0.914, 0.941, 0.941, 0.325, 0.612, 0.941, 0.941, 0.941, 0.941, 0.941, 0.941, 0.941, 0.941, 0.941, 0.941, 0.624, 0.318, 0.941, 0.945, 0.91, 0.765, 0.988}, {1, 0.882, 0.741, 0.941, 0.941, 0.922, 0.337, 0.475, 0.894, 0.941, 0.941, 0.941, 0.941, 0.941, 0.945, 0.894, 0.49, 0.325, 0.925, 0.941, 0.941, 0.753, 0.894, 1}, {1, 1, 0.796, 0.78, 0.941, 0.941, 0.941, 0.592, 0.447, 0.565, 0.667, 0.737, 0.737, 0.667, 0.565, 0.451, 0.588, 0.941, 0.941, 0.941, 0.796, 0.808, 1, 1}, {1, 1, 0.996, 0.753, 0.788, 0.941, 0.941, 0.941, 0.941, 0.702, 0.584, 0.557, 0.553, 0.592, 0.698, 0.906, 0.941, 0.945, 0.941, 0.796, 0.769, 0.996, 1, 1}, {1, 1, 1, 1, 0.769, 0.745, 0.922, 0.941, 0.941, 0.941, 0.941, 0.941, 0.941, 0.941, 0.941, 0.941, 0.941, 0.918, 0.741, 0.776, 1, 1, 0.996, 1}, {1, 0.996, 1, 1, 1, 0.851, 0.733, 0.773, 0.867, 0.945, 0.941, 0.941, 0.941, 0.941, 0.945, 0.867, 0.769, 0.725, 0.851, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 0.984, 0.843, 0.78, 0.761, 0.78, 0.796, 0.796, 0.784, 0.765, 0.78, 0.835, 0.984, 1, 1, 1, 1, 1, 1} }; public TestPane() { AsciiTableModel model = new AsciiTableModel(); model.setData(smily); JTable table = new JTable(model); table.setRowHeight(24); Enumeration columns = table.getColumnModel().getColumns(); while (columns.hasMoreElements()) { TableColumn col = columns.nextElement(); col.setWidth(24); col.setPreferredWidth(24); col.setMinWidth(24); col.setMaxWidth(24); } table.setRowHeight(24); table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); table.setDefaultRenderer(Object.class, new PaintTableCellRenderer()); setLayout(new BorderLayout()); add(new JScrollPane(table)); } @Override public Dimension getPreferredSize() { return new Dimension(200, 200); } } public class PaintTableCellRenderer extends DefaultTableCellRenderer { @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { super.getTableCellRendererComponent(table, "", isSelected, hasFocus, row, column); if (value instanceof Double) { double distance = (double) value; int part = (int) (255 * distance); Color color = new Color(part, part, part); setBackground(color); } else { setBackground(Color.WHITE); } return this; } } public class AsciiTableModel extends AbstractTableModel { private double[][] data; public AsciiTableModel() { data = new double[24][24]; } public void setData(double[][] value) { data = value; fireTableDataChanged(); } @Override public int getRowCount() { return 24; } @Override public int getColumnCount() { return 24; } @Override public Object getValueAt(int rowIndex, int columnIndex) { return data[rowIndex][columnIndex]; } } } 

我打算提供一个你可以切换的“悲伤”的脸,但我的女儿想让我和她一起画画,对不起;)

您需要创建自定义表格单元格渲染器。 这是一个很好的起点