2

I have a JPanel component with a JTable inside of it. When I run the code as it's written below, the table renders and updates correctly. As soon as I try to use the scrollPane approach, the table does not render at all. Can anyone explain to me why this is?

    private static class GameHistoryPanel extends JPanel {

        private DataModel model;
        private JTable table;
        private int currentRow;
        private int currentColumn;
        private final Dimension HISTORY_PANEL_DIMENSION = new Dimension(190,460);


        public GameHistoryPanel() {
            this.setLayout(new BorderLayout());
            this.model = new DataModel();
            this.table = new JTable(model);
            this.add(table.getTableHeader(), BorderLayout.NORTH);
            this.add(table, BorderLayout.CENTER);
//            JScrollPane scrollPane = new JScrollPane();
//            scrollPane.setViewportView(table);
//            this.add(scrollPane);
            setPreferredSize(HISTORY_PANEL_DIMENSION);
            this.currentRow = 0;
            this.currentColumn = 0;
        }

        public void increment(Board board, Move move) {
            model.setValueAt(move, currentRow, currentColumn);
            if(board.currentPlayer().getAlliance() == Alliance.WHITE) {
                currentColumn++;
            } else if (board.currentPlayer().getAlliance() == Alliance.BLACK) {
                currentRow++;
                currentColumn = 0;
            }
            validate();
            repaint();
        }
    }
Jonathan
  • 20,053
  • 6
  • 63
  • 70
Amir Afghani
  • 37,814
  • 16
  • 84
  • 124
  • I think that answered by (@trashgod), everything important bases on your question and code are there, – mKorbel Dec 13 '12 at 16:51

3 Answers3

2

It appears that you are using a JTable as view of a TableModel in which each cell exists in one of two states. Visible changes to a cell should result only from a change to the model, which may be examined in preparing the cell's renderer. In particular, invoking the methods validate() and repaint() should not be required. Their presence suggests that you are altering the view without the model's knowledge, which could explain the anomaly seen.

trashgod
  • 203,806
  • 29
  • 246
  • 1,045
1

Try

JScrollPane scrollPane = new JScrollPane(table);
this.add(scrollPane);
Nikolay Kuznetsov
  • 9,467
  • 12
  • 55
  • 101
  • @AmirAfghani, try to setPreferredSize on JScrollPane – Nikolay Kuznetsov Dec 13 '12 at 14:06
  • 1
    @Amir Afghani then post an [SSCCE](http://sscce.org/), exaclty demonstrated your issue, short, runnable, compilable, just about JFrame, JSCrollPane and JTable – mKorbel Dec 13 '12 at 14:07
  • @Nikolay Kuznetsov too fast suggestion, everything without SSCCE are shots to the dark :-) – mKorbel Dec 13 '12 at 14:08
  • Extracting this into an SSCCE is going to be hard - I'll see what I can do. The strange thing is that the whole panel containing the table is grey. When it works, the table renders white. – Amir Afghani Dec 13 '12 at 14:10
  • @Amir Afghani then your personal issue hidden in the rest of your code, everything without SSCCE are shots to the dark, – mKorbel Dec 13 '12 at 14:11
  • @mKorbel I understand - I thought I might have overlooked something easy to see in that section of code that would be easy to spot. – Amir Afghani Dec 13 '12 at 14:12
  • `panel containing the table is grey` this is about `Background` of `JScrollPane`, required more details – mKorbel Dec 13 '12 at 14:12
  • by default JTable with JScrollPane haven't any issues, something strange, nor bugs – mKorbel Dec 13 '12 at 14:14
  • 1
    Using `getPreferredScrollableViewportSize()` is a (marginally) better alternative is a `JScrollPane`. See also [Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing](http://stackoverflow.com/q/7229226/230513)? – trashgod Dec 13 '12 at 15:46
1

This may be stating the obvious, but remember that you can only add a JComponent to a container once.

After

this.setLayout(new BorderLayout());
this.model = new DataModel();
this.table = new JTable(model);

either you

this.add(table, BorderLayout.CENTER);
// note that table-headers should not be added explicitly
// commented out: this.add(table.getTableHeader(), BorderLayout.NORTH);

or you

JScrollPane scrollPane = new JScrollPane(table);
this.add(scrollPane);

but trying to do both will result in problems.

I recommend using Swingx's JXTable, if at all possible. Much more flexible, and out-of-the-box column sorting and hiding/reordering.

tucuxi
  • 17,561
  • 2
  • 43
  • 74
  • Thanks for the answer - but indeed this is obvious. The former works, the latter does not. Why shouldn't the table headers be added explicitly? – Amir Afghani Dec 13 '12 at 14:36