着色JTable细胞

我无法为我的JTable单元着色。 我正在做一个俄罗斯方块游戏。 游戏的所有function都有效; 按下按钮,键盘交互以移动片段,删除完整的行等。现在出现的输出只是打印出的表格整数值(参见屏幕截图)。 这些整数值指的是颜色。 我有代码根据下面的MyRenderer类中的所述整数值更改单元格的颜色,但不会发生着色。 我想知道是否有一些“rerender”方法我只是没有找到或者我是否需要构建自己的paint方法来调用?

有什么建议?

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); } } 

俄罗斯方块截图

您不应在渲染器的getTableCellRendererComponent()分配新组件。 JTable为所有单元重用单个渲染器。 在您的情况下,您为每个单元格分配新组件很多次。 有关详细信息,请参阅概念: 如何使用表中的 编辑器和渲染器教程。 考虑DefaultTableCellRenderer这个扩展(注意DefaultTableCellRendererJLabel的扩展):

 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.classint.class是不同的。 因此setDefaultRenderer应该对应于getColumnClass返回的类。 在您的情况下,两个地方都是int.ClassInteger.Class

另一点,看看如何使用键绑定作为键侦听器是一个较低级别的接口