1

JTableセルの色付けに問題があります。テトリスゲームを作っています。ゲームのすべての機能が機能します。ボタンを押す、ピースを移動するためのキーボード操作、完全な行の削除など。現在発生する出力は、単にテーブルの整数値を出力することです(スクリーンショットを参照)。これらの整数値は色を参照します。以下のMyRendererクラスの整数値に基づいてセルの色を変更するコードがありますが、色付けは行われません。見つけられない「レンダリング」メソッドがあるのか​​、それとも呼び出すために独自のペイントメソッドを作成する必要があるのか​​疑問に思いました。

助言がありますか?

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

テトリスのスクリーンショット

4

1 に答える 1

3

レンダラーのに新しいコンポーネントを割り当てないでくださいgetTableCellRendererComponent()JTableすべてのセルに対して単一のレンダラーを再利用します。あなたの場合、すべてのセルに新しいコンポーネントを何度も割り当てます。詳細については、「テーブルの使用方法」チュートリアルの「概念:エディターとレンダラー」を参照してください。この拡張を検討してください(これはの拡張であることに注意してください):DefaultTableCellRendererDefaultTableCellRendererJLabel

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.Class両方の場所またはInteger.Class

もう1つのポイントは、キーリスナーとしてキーバインディングを使用する方法を調べてください。これは低レベルのインターフェイスです。

于 2013-03-25T00:38:55.163 に答える