如何根据单元格中的值为 JTable 的各个单元格着色?
How do I color individual cells of a JTable based on the value in the cell?
我正在尝试制作俄罗斯方块克隆版。游戏使用 JTable
作为棋盘的表示。该板是一个二维整数数组。
我正在尝试这样做,当某个单元格具有某个值时,该单元格将变为某种颜色。我以为我让它工作正常,但它不工作。非常感谢您的帮助。
谢谢。
这是我的代码:
董事会:
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();
}
}
初始化JTable:
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.
}
}
您需要创建自定义 table 单元格渲染器。 Here's a good place to start
data/model 和 view/table 之间存在关系。模型维护"what",视图控制"how".
JTable
提供了一种方法,您可以通过使用 TableCellRenderers
来实现 "how" 的行为(呈现内容),这些方法负责确定单元格应该如何处理"painted" 基于模型 "what" 的值。
先看看 How to Use Tables and Using Custom Renderers
现在,此示例使用 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<TableColumn> 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];
}
}
}
我本来打算提供一张 "sad" 脸,你可以在两者之间切换,但我女儿想让我和她一起画画,抱歉 ;)
我正在尝试制作俄罗斯方块克隆版。游戏使用 JTable
作为棋盘的表示。该板是一个二维整数数组。
我正在尝试这样做,当某个单元格具有某个值时,该单元格将变为某种颜色。我以为我让它工作正常,但它不工作。非常感谢您的帮助。
谢谢。
这是我的代码:
董事会:
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();
}
}
初始化JTable:
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.
}
}
您需要创建自定义 table 单元格渲染器。 Here's a good place to start
data/model 和 view/table 之间存在关系。模型维护"what",视图控制"how".
JTable
提供了一种方法,您可以通过使用 TableCellRenderers
来实现 "how" 的行为(呈现内容),这些方法负责确定单元格应该如何处理"painted" 基于模型 "what" 的值。
先看看 How to Use Tables and Using Custom Renderers
现在,此示例使用 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<TableColumn> 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];
}
}
}
我本来打算提供一张 "sad" 脸,你可以在两者之间切换,但我女儿想让我和她一起画画,抱歉 ;)