我无法为我的JTable单元着色。我正在做一个俄罗斯方块游戏。游戏的所有功能都有效;按下按钮,键盘交互以移动片段,删除完整的行等。现在发生的输出只是打印出的表格整数值(参见屏幕截图)。这些整数值指的是颜色。我有代码根据下面的MyRenderer类中的所述整数值更改单元格的颜色,但不会发生着色。我想知道是否有一些“rerender”方法,我只是没有找到或者我是否需要构建自己的绘制方法来调用?
有什么建议吗?
startGame.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
card3.remove(0); // Removes button
model = new MyTableModel();
table = new JTable(model);
table.setDefaultRenderer(int.class, new MyRenderer());
table.setRowHeight(GRID_ROW_HEIGHT);
table.setFocusable(false);
table.setRowSelectionAllowed(true);
for (int i = 0; i < NUM_COLS; i++) {
table.getColumnModel().getColumn(i)
.setPreferredWidth(table.getRowHeight());
}
card3.add(table);
JButton pauseButton = new JButton("Pause");
card3.add(pauseButton);
pauseButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
game.pause();
}
});
card3.setFocusable(true);
card3.requestFocusInWindow();
KeyListener kl = new KeyListener() {
public void keyTyped(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyChar() == 'a' || e.getKeyChar() == 'A') {
game.move_Left();
draw_grid_first_time();
card3.revalidate();
} else if (e.getKeyChar() == 'd'
|| e.getKeyChar() == 'D') {
game.move_Right();
draw_grid_first_time();
card3.revalidate();
} else if (e.getKeyChar() == 'q'
|| e.getKeyChar() == 'Q') {
game.rotate_left();
draw_grid_first_time();
card3.revalidate();
} else if (e.getKeyChar() == 'e'
|| e.getKeyChar() == 'E') {
game.rotate_right();
draw_grid_first_time();
card3.revalidate();
} else if (e.getKeyChar() == ' ') {
game.pause();
}
}
};
card3.addKeyListener(kl);
draw_grid_first_time();
card3.revalidate(); // Redraws graphics
Timer timer = new Timer(500, new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
if (!game.getPause()) {
game.move_Down();
draw_grid();
card3.revalidate(); // Redraws graphics
}
}
public void draw_grid() {
for (int i = 0; i < game.getNumRows(); i++) {
for (int j = 0; j < game.getNumCols(); j++) {
int[][] grid = game.getGrid();
model.setValueAt(grid[j][i], i, j);
}
}
}
});
timer.setRepeats(true);
timer.setCoalesce(true);
timer.start();
if (game.isOver()) {
timer.stop();
}
}
});
// 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 void draw_grid_first_time() {
for (int i = 0; i < game.getNumRows(); i++) {
for (int j = 0; j < game.getNumCols(); j++) {
int[][] grid = game.getGrid();
model.setValueAt(grid[j][i], i, j);
}
}
}
// Render each cell as a background color dependent on grid from tetris game
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 ((Integer) table.getValueAt(row, column) == 0) {
editor.setBackground(Color.DARK_GRAY);
} else if ((Integer) table.getValueAt(row, column) == 1) {
editor.setBackground(Color.RED);
} else if ((Integer) table.getValueAt(row, column) == 2) {
editor.setBackground(Color.GREEN);
} else if ((Integer) table.getValueAt(row, column) == 3) {
editor.setBackground(Color.BLUE);
} else if ((Integer) table.getValueAt(row, column) == 4) {
editor.setBackground(Color.YELLOW);
}
return editor;
}
}
// Overwrite the Table Model to be what I want color wise
@SuppressWarnings("serial")
class MyTableModel extends AbstractTableModel {
private int[][] values = new int[NUM_COLS][NUM_ROWS];
public int getColumnCount() {
return NUM_COLS;
}
public int getRowCount() {
return NUM_ROWS;
}
public Object getValueAt(int row, int col) {
return values[col][row];
}
public void setValueAt(Object val, int row, int col) {
values[col][19 - row] = (Integer) val;
fireTableCellUpdated(row, col);
}
}
答案 0 :(得分:3)
您不应在渲染器getTableCellRendererComponent()
中分配新组件。 JTable
为所有单元格重用单个渲染器。在您的情况下,您可以多次为每个单元格分配新组件。有关详细信息,请参阅如何使用表教程中的Concepts: Editors and Renderers。考虑DefaultTableCellRenderer
的此扩展(请注意DefaultTableCellRenderer
是JLabel
的扩展名):
class MyRenderer extends DefaultTableCellRenderer {
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row,
int column) {
Component c = super.getTableCellRendererComponent(table,
value, isSelected, hasFocus, row, column);
c.setBackground(getColor((Integer) value));
return c;
}
private Color getColor(int value) {
switch(value){
case 1: return Color.RED;
case 2: return Color.GREEN;
//TODO the rest of colors
}
return Color.DARK_GRAY;
}
}
另请注意,由于您要为整数列设置渲染器,因此请确保您的模型在其getColumnClass()
实现中实际返回一个有效的类。否则,将不使用渲染器。例如,DefaultTableModel.getColumnClass()
会为所有列返回Object.class
。
getColumnClass()
返回描述存储在指定列中的数据对象的类。 JTable
使用它来为该列分配默认渲染器和编辑器。在您的情况下,如果您在模型中存储整数,则getColumnClass()
应返回Integer.class
。但请注意,Integer.class
和int.class
不同。因此setDefaultRenderer
应该与getColumnClass
返回的类相对应。在您的情况下,两个地方int.Class
或Integer.Class
。
另一点,查看How to Use Key Bindings作为关键侦听器是一个较低级别的接口