Почему моя таблица не видна, когда она находится в JScrollPane?

Я пытался часами, разными вещами и везде искал решение, но я не могу отобразить свою таблицу в addScoreCardUpper(). Я получаю горизонтальную полосу прокрутки, но без содержимого, всего 2 пикселя границы.

import java.awt.BorderLayout;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;

public class YahtzeeGUI extends JFrame{
    /**
     * 
     */
    private static final long serialVersionUID = 3255683022699487295L;
    private JFrame frame;
    private JPanel panel;
    private JPanel dicePanel;
    private JScrollPane scrollPane;
    private JButton btnRoll;
    private JButton[] btnDice = new JButton[5];
    private JTable table;

    private Yahtzee y = new Yahtzee();

    public YahtzeeGUI(){
        createWindow();
        addButtonRoll();
        addButtonDice();
        addScoreCardUpper();
        //addScoreCardLower();


        frame.add(panel);
        frame.setVisible(true);
    }

    public void createWindow(){
        frame = new JFrame();
        frame.setTitle("Yahtzee");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(1000,700);
        frame.setVisible(true);
        panel = new JPanel(new BorderLayout());
        dicePanel = new JPanel();
        scrollPane = new JScrollPane(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
    }

    public void addButtonRoll(){
        btnRoll = new JButton ("Roll the Dice");
        btnRoll.addActionListener(new RollHandler());

        dicePanel.add (btnRoll);
        panel.add(dicePanel, BorderLayout.SOUTH);
    }

    public void addButtonDice(){

        for (int i = 0; i < btnDice.length; i++){
            btnDice[i] = new JButton(String.valueOf(y.dice[i].getFaceValue()));
            btnDice[i].addActionListener(new HoldHandler());
            dicePanel.add (btnDice[i]);
        }
        panel.add(dicePanel, BorderLayout.SOUTH);
    }

    public void addScoreCardUpper(){
        String tableHeader[] = {"Upper Section", "How to score", "Score" };
        String tableValues[][] = {
                {"ONES", "Total of all Ones",""},
                {"TWOS", "Total of all Twos",""},
                {"THREES", "Total of all Threes",""},
                {"FOURS", "Total of all Fours",""},
                {"FIVES", "Total of all Fives",""},
                {"SIXES", "Total of all Sixes",""},
                {"TOTAL SCORE", "",""},
                {"BONUS", "",""},
                {"TOTAL + BONUS", "",""}
        };

        table = new JTable(tableValues, tableHeader);
        table.setEnabled(false);
        setColumnWidths();
        scrollPane.add(table); // Here is the offender
        panel.add(scrollPane, BorderLayout.EAST);
    }

    /*public void addScoreCardLower(){
        String tableHeader[] = {"Lower S", "How to score", "Score" };
        String tableValues[][] = {
                {"ONES", "Total of all Ones",""},
                {"TWOS", "Total of all Twos",""},
                {"THREES", "Total of all Threes",""},
                {"FOURS", "Total of all Fours",""},
                {"FIVES", "Total of all Fives",""},
                {"SIXES", "Total of all Sixes",""},
                {"TOTAL SCORE", "",""},
                {"BONUS", "",""},
                {"TOTAL + BONUS", "",""}
        };

        table = new JTable(tableValues, tableHeader);
        table.setEnabled(false);
        setColumnWidths();
        scoreSubPanel.add(table);
        panel.add(scoreSubPanel, BorderLayout.WEST);
    }*/

    public void setColumnWidths(){

        TableColumn a = table.getColumnModel().getColumn(0);
        TableColumn b = table.getColumnModel().getColumn(1);
        a.setPreferredWidth(100);
        b.setPreferredWidth(100);

    }

    class RollHandler implements ActionListener {

        public void actionPerformed(ActionEvent event) {

            for(int i = 0; i < y.dice.length; i++){
                if (y.dice[i].getHoldState() != true){
                    y.dice[i].roll();
                    btnDice[i].setText(String.valueOf(y.dice[i].getFaceValue()));
                }
            }
        }
    }

    class HoldHandler implements ActionListener {

        public void actionPerformed(ActionEvent event) {
            for (int i = 0; i < btnDice.length; i++){
                if (event.getSource()== btnDice[i]){ // Picks the pressed button after running through them all.
                    if (y.dice[i].getHoldState() == false){
                        y.dice[i].setHoldState(true);
                    } else if (y.dice[i].getHoldState() == true){
                        y.dice[i].setHoldState(false);
                    }
                }
            }
        }
    }

}

person bkrpage    schedule 23.03.2014    source источник
comment
Я заметил две, вероятно, несвязанные вещи: у вас есть два JFrames, переменная кадра экземпляра и YahtzeeGUI, который расширяет JFrame. Вы также вызываете setVisible(true) дважды, в конструкторе и в createWindow, вы, вероятно, захотите вызвать setVisible(true) только один раз там, где он существует прямо сейчас в конструкторе.   -  person NESPowerGlove    schedule 23.03.2014


Ответы (2)


Это ваша проблема:

scrollPane.add(table);

Это не добавляет JTable в область просмотра JScrollPane, где вы хотите, а полностью заменяет область просмотра JScrollPane на JTable, делая JScrollPane полностью нефункциональным. Вместо этого установите таблицу в качестве окна просмотра JScrollPane:

scrollPane.setViewportView(table);

Сделайте либо это, либо передайте таблицу в конструктор JScrollPane, который делает почти то же самое:

JScrollPane scrollPane = new JScrollPane(table,
          ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
          ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);

Все это хорошо объяснено в JScrollPane API. , и вам захочется взглянуть на важные детали.


Изменить
Ваш код также вызывает setVisible(true) в JFrame перед добавлением всех компонентов, что может привести к проблемам. Вы захотите избежать этого.

person Hovercraft Full Of Eels    schedule 23.03.2014
comment
Спасибо! В конце использовал scrollPane.setViewportView(table). Кроме того, спасибо за примечание setVisible(true), я совсем забыл об этом. - person bkrpage; 23.03.2014

Попробуйте любой

scrollPane = new JScrollPane(table);

or

scrollPane = new JScrollPane(table,ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);

or

scrollPane.getViewport().add(table);
person Braj    schedule 23.03.2014
comment
Попробовал средний, все получилось, спасибо. Однако я выбрал scrollPane.setViewportView(table), так как мне будет легче вернуться к нему позже и понять. Спасибо еще раз - person bkrpage; 23.03.2014