setContentPane() 和 getContentPane().add() 都不起作用

Neither setContentPane() nor getContentPane().add() works

如果这有助于解决问题,我可以提供我的所有代码,但我相信因为这只会影响一个 class 真的,它可以在这里解决,以简化问题。

我有一个单人纸牌项目(注意 package/class 名称,它是反复试验的,我没有删除旧项目)拒绝接受我拥有的 GameArea class,它扩展 JPanel。 GameArea 在其自己的单独实例中运行良好,其中测试器 class 运行 仅使用 JFrame 上的 JPanel。该测试人员 class 使用 setContentPane(newGame) 将其添加到 JFrame。

在下面的 class 中,getContentPane().add(newGame) 和 setContentPane(newGame) 均未成功将游戏添加到框架中。 class 设置一个主菜单,有两个按钮。第一个将其带入“开始新游戏”屏幕,然后应该开始游戏的按钮将是:

1) 如果使用 getContentPane().add(newGame) 则只显示绿屏

2) 显示按下的“开始新游戏”,如果使用 setContentPane(newGame),则在“开始新游戏”屏幕上冻结。这令人沮丧,因为在此之前调用了 getContentPane().removeAll()...但是,使用菜单,我可以 return 到主菜单,并且仍然 运行 在冻结和修复的无限循环中.

我怀疑是因为我对 swing classes 了解不够,所以我遗漏了一些东西。非常感谢任何帮助,因为我需要在 2 天内完成这项工作。

package guitestersolitairenew;
/**
 *
 * @author Josh
 * @version 1.00 2015/3/28
 */
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import static javax.swing.Action.MNEMONIC_KEY;
import static javax.swing.Action.SHORT_DESCRIPTION;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.GroupLayout;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
public class GUITesterSolitaireNew extends JFrame 
{

    public GUITesterSolitaireNew() 
    {
        initComponents();
        setMainMenu();
    }

    private void initComponents() 
    {
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setBackground(new java.awt.Color(80, 135, 40));
        setTitle("Klondike Solitaire");
        getContentPane().setBackground(new java.awt.Color(85,130,40));
        setSize(1200,700);
        setLocationRelativeTo(null);
        setResizable(false);

        JMenuBar menubar = new JMenuBar();
        menubar.add(new JMenu("File"));

        class MainMenu extends AbstractAction
        {
            public MainMenu(String text, ImageIcon icon, String desc, Integer mnemonic)
            {
                super(text,icon);
                putValue(SHORT_DESCRIPTION, desc);
                putValue(MNEMONIC_KEY, mnemonic);
            }

            @Override
            public void actionPerformed(ActionEvent e)
            {
                setMainMenu();
            }
        }
        menubar.getMenu(0).add(new JMenuItem(new MainMenu("Main Menu", null, "Return to the main menu.", KeyEvent.VK_M)));

    class NewGame extends AbstractAction
    {
        public NewGame(String text, ImageIcon icon, String desc, Integer mnemonic)
        {
            super(text,icon);
            putValue(SHORT_DESCRIPTION, desc);
                    putValue(MNEMONIC_KEY, mnemonic);
        }

        @Override
        public void actionPerformed(ActionEvent e)
        {
                    newGame(e);
        }
    }
        menubar.getMenu(0).add(new JMenuItem(new NewGame("New Game", null, "Start a new game.", KeyEvent.VK_N)));

    class RestartGame extends AbstractAction
    {
        public RestartGame(String text, ImageIcon icon, String desc, Integer mnemonic)
        {
            super(text,icon);
            putValue(SHORT_DESCRIPTION, desc);
                    putValue(MNEMONIC_KEY, mnemonic);
        }

        @Override
        public void actionPerformed(ActionEvent e)
        {
            //Fix to restart game.
        }
    }
        menubar.getMenu(0)
                .add(new JMenuItem(new RestartGame("Restart Game", null, "Restart the current game.", KeyEvent.VK_R)));

    class LoadGame extends AbstractAction
    {
        public LoadGame(String text, ImageIcon icon, String desc, Integer mnemonic)
        {
            super(text,icon);
            putValue(SHORT_DESCRIPTION, desc);
                    putValue(MNEMONIC_KEY, mnemonic);
        }

        @Override
        public void actionPerformed(ActionEvent e)
        {
            //Fix to load game.
        }
    }
        menubar.getMenu(0).add(new JMenuItem(new LoadGame("Load Game", null, "Load a saved game.", KeyEvent.VK_L)));

        class SaveGame extends AbstractAction
        {
            public SaveGame(String text, ImageIcon icon, String desc, Integer mnemonic)
            {
                super(text,icon);
                putValue(SHORT_DESCRIPTION, desc);
                putValue(MNEMONIC_KEY, mnemonic);
            }

            @Override
            public void actionPerformed(ActionEvent e)
            {
                //Fix to save game
            }
        }
        menubar.getMenu(0).add(new JMenuItem(new SaveGame("Save Game", null, "Create a save file.", KeyEvent.VK_S)));

        class ExitAction extends AbstractAction
        {
        public ExitAction (String text, ImageIcon icon, String desc, Integer mnemonic)
        {
                super(text, icon);
                putValue(SHORT_DESCRIPTION, desc);
                putValue(MNEMONIC_KEY, mnemonic);
            }

            @Override
            public void actionPerformed(ActionEvent e) 
            {
                System.exit(0);
            }
        }
        menubar.getMenu(0).add(new JMenuItem(new ExitAction("Exit", null, "Exit from the program.", KeyEvent.VK_E)));


        menubar.add(new JMenu("Help"));

        class Rules extends AbstractAction
        {
        public Rules (String text, ImageIcon icon, String desc, Integer mnemonic)
        {
                super(text, icon);
                putValue(SHORT_DESCRIPTION, desc);
                putValue(MNEMONIC_KEY, mnemonic);
            }

            @Override
            public void actionPerformed(ActionEvent e) 
            {
                JFrame rules = new JFrame("Klondike Solitaire Rules");
                rules.setSize(400,430);
                rules.setLocationRelativeTo(null);
                rules.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

                JTextArea jta = new JTextArea();
                jta.setEditable(false);
                Component add = rules.add(jta);
                JScrollPane jsp = new JScrollPane();
        jsp.setViewportView(jta); 
        rules.getContentPane().add(jsp, java.awt.BorderLayout.CENTER); 
        jta.setCaretPosition(jta.getText().length());

                jta.append("Klondike Solitaire Rules:\n\n");
                jta.setCaretPosition(jta.getText().length());

                jta.append("The game starts with a standard 52 card deck.\n");
                jta.setCaretPosition(jta.getText().length());
                jta.append("The cards are first dealt into 7 'tableaus' where the cards\n");
                jta.setCaretPosition(jta.getText().length());
                jta.append("are all turned face down and one card laid onto each tableau.\n");
                jta.setCaretPosition(jta.getText().length());
                jta.append("The left one is turned up, and the process is repeated for the\n");
                jta.setCaretPosition(jta.getText().length());
                jta.append("2nd to 7th tableaus. The 2nd card in the 2nd tableau is turned up.\n");
                jta.setCaretPosition(jta.getText().length());
                jta.append("Each tableau receives as many cards as the column position. The\n");
                jta.setCaretPosition(jta.getText().length());
                jta.append("last card in each tableau will be face up. The deck is placed\n");
                jta.setCaretPosition(jta.getText().length());
                jta.append("off to the side.\n\n");
                jta.setCaretPosition(jta.getText().length());

                jta.append("The cards are drawn one at a time from deck. Valid moves are: \n");
                jta.setCaretPosition(jta.getText().length());
                jta.append("-Move card from deck to tableau\n");
                jta.setCaretPosition(jta.getText().length());
                jta.append("-Move card from deck to foundation <stacks by suit>\n");
                jta.setCaretPosition(jta.getText().length());
                jta.append("-Click deck again for another card.\n");
                jta.setCaretPosition(jta.getText().length());
                jta.append("The deck is cycled if cards are remaining. The cards, after\n");
                jta.setCaretPosition(jta.getText().length());
                jta.append("being face up, will sort in descent of value and opposing\n");
                jta.setCaretPosition(jta.getText().length());
                jta.append("face color: i.e. a black 6 can only go on top of a red 7.\n\n");
                jta.setCaretPosition(jta.getText().length());

                jta.append("The player wins by moving all cards from the deck and tableaus\n");
                jta.setCaretPosition(jta.getText().length());
                jta.append("to the 4 foundations. The foundations sort by suit in ascending\n");
                jta.setCaretPosition(jta.getText().length());
                jta.append("order of value, starting with the ace. All aces are low.");

                rules.setResizable(false);
        rules.setVisible(true);
            }
        }
        menubar.getMenu(1)
                .add(new JMenuItem(new Rules("Rules", null, "Show a popup aid for the rules of the game.", KeyEvent.VK_R)));

    class Info extends AbstractAction
        {
        public Info (String text, ImageIcon icon, String desc, Integer mnemonic)
        {
                super(text, icon);
                putValue(SHORT_DESCRIPTION, desc);
                putValue(MNEMONIC_KEY, mnemonic);
            }

            @Override
            public void actionPerformed(ActionEvent e) 
            {
                JFrame info = new JFrame("Development Info");
        info.setSize(450,225);
                info.setLocationRelativeTo(null); //sends it to center of screen
        info.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); //does not close application, but actually kills the window when closed
        JTextArea jta = new JTextArea();
                jta.setEditable(false); //The user can't type on the text box.
            Component add = info.add(jta); //abstraction that adds the component jta to window info
            JScrollPane jsp = new JScrollPane();

        jsp.setViewportView(jta); //puts the text area in the scroll pane
        info.getContentPane().add(jsp, java.awt.BorderLayout.CENTER); //centers the text area and scroll pane to be the main subject of the frame
        jta.setCaretPosition(jta.getText().length()); //sets the cursor to the end of the text typed so far

        //edited out

                info.setResizable(false);
        info.setVisible(true);
            }
        }
        menubar.getMenu(1)
                .add(new JMenuItem(new Info("Info", null, "Information about Klondike Solitaire.", KeyEvent.VK_I)));
        setJMenuBar(menubar);

    }                        

    private void newGame(java.awt.event.ActionEvent evt) 
    {                                         
        getContentPane().removeAll();
        getContentPane().repaint();
        setBackground(new java.awt.Color(80, 135, 40));

        JLabel jLabel1 = new JLabel();
        JButton jButton1 = new JButton();

        jLabel1.setBackground(new java.awt.Color(80, 135, 40));
        jLabel1.setFont(new java.awt.Font("Kunstler Script", 1, 120)); // NOI18N
        jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel1.setText("Klondike Solitaire");
        jLabel1.setVerticalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel1.setMaximumSize(new java.awt.Dimension(800, 100));
        jLabel1.setMinimumSize(new java.awt.Dimension(800, 100));
        jLabel1.setPreferredSize(new java.awt.Dimension(800, 100));
        jLabel1.setRequestFocusEnabled(true);

        jButton1.setText("Start New Game");
        jButton1.setFont(new java.awt.Font("Times New Roman", 1, 20));
        jButton1.setMaximumSize(new java.awt.Dimension(200, 50));
        jButton1.setMinimumSize(new java.awt.Dimension(200, 50));
        jButton1.setPreferredSize(new java.awt.Dimension(200, 50));
        jButton1.addActionListener(new java.awt.event.ActionListener() 
        {
            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) 
            {
                startNewGame();
            }
        });

        JLabel replay = new JLabel("Replay game from seed:");
        replay.setBackground(new java.awt.Color(80,135,40));
        replay.setFont(new java.awt.Font("Times New Roman", 1, 20));
        replay.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        replay.setVerticalAlignment(javax.swing.SwingConstants.CENTER);
        replay.setMaximumSize(new java.awt.Dimension(220, 50));
        replay.setMinimumSize(new java.awt.Dimension(220, 50));
        replay.setPreferredSize(new java.awt.Dimension(220, 50));

        JTextField getSeed = new JTextField();
        getSeed.setCaretPosition(getSeed.getText().length());
        getSeed.setFont(new java.awt.Font("Times New Roman", 1, 18));
        getSeed.setMaximumSize(new java.awt.Dimension(150, 24));
        getSeed.setMinimumSize(new java.awt.Dimension(150, 24));
        getSeed.setPreferredSize(new java.awt.Dimension(150, 24));

        JButton startSeed = new JButton("Start Game");
        startSeed.setFont(new java.awt.Font("Times New Roman", 1, 20));
        startSeed.setMaximumSize(new java.awt.Dimension(130, 30));
        startSeed.setMinimumSize(new java.awt.Dimension(130, 30));
        startSeed.setPreferredSize(new java.awt.Dimension(130, 30));
        startSeed.addActionListener(new java.awt.event.ActionListener()
        {
            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt)
            {
                startNewGame(Integer.parseInt(getSeed.getText()));
            }
        });

        JButton back = new JButton("Back to Main Menu");
        back.setFont(new java.awt.Font("Times New Roman", 1, 20));
        back.setMaximumSize(new java.awt.Dimension(200, 50));
        back.setMinimumSize(new java.awt.Dimension(200, 50));
        back.setPreferredSize(new java.awt.Dimension(200, 50));
        back.addActionListener(new java.awt.event.ActionListener()
        {
            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt)
            {
                setMainMenu();
            }
        });

        GroupLayout layout = new GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(GroupLayout.Alignment.CENTER)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(200, 200, 200)
                        .addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER, false)
                            .addComponent(back, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(replay, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addComponent(getSeed, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addComponent(startSeed, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                            .addComponent(jButton1, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                        .addGroup(layout.createSequentialGroup()
                        .addGap(200, 200, 200)
                        .addComponent(jLabel1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)))
                .addContainerGap(90, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(150, 150, 150)
                .addComponent(jLabel1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                .addGap(10, 10, 10)
                .addComponent(jButton1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                .addGap(35, 35, 35)
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER)
                    .addComponent(replay, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addComponent(getSeed, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addComponent(startSeed, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                .addGap(180, 180, 180)
                .addComponent(back, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
        );

    } 

    private void startNewGame() 
    {
        getContentPane().removeAll();
        getContentPane().repaint();

        newGame.newGame();
        Container pane = getContentPane();
        pane.add(newGame);
        setContentPane(pane);
        getContentPane().revalidate();
        getContentPane().repaint();
    }

    public void startNewGame(int seed)
    {
        getContentPane().removeAll();
        getContentPane().repaint();

        newGame.newGame();
        add(newGame);
    }

    private void setMainMenu()
    {
        getContentPane().removeAll();
        getContentPane().repaint();
        setBackground(new java.awt.Color(80, 135, 40));

        JLabel jLabel1 = new javax.swing.JLabel();
        JButton jButton1 = new javax.swing.JButton();
        JButton jButton2 = new javax.swing.JButton();

        jLabel1.setBackground(new java.awt.Color(80, 135, 40));
        jLabel1.setFont(new java.awt.Font("Kunstler Script", 1, 120)); // NOI18N
        jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel1.setText("Klondike Solitaire");
        jLabel1.setVerticalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel1.setMaximumSize(new java.awt.Dimension(800, 100));
        jLabel1.setMinimumSize(new java.awt.Dimension(800, 100));
        jLabel1.setPreferredSize(new java.awt.Dimension(800, 100));
        jLabel1.setRequestFocusEnabled(true);

        jButton1.setText("New Game");
        jButton1.setFont(new java.awt.Font("Times New Roman", 1, 20));
        jButton1.setMaximumSize(new java.awt.Dimension(200, 50));
        jButton1.setMinimumSize(new java.awt.Dimension(200, 50));
        jButton1.setPreferredSize(new java.awt.Dimension(200, 50));
        jButton1.addActionListener(new java.awt.event.ActionListener() 
        {
            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) 
            {
                newGame(evt);
            }
        });

        jButton2.setText("Load Game");
        jButton2.setFont(new java.awt.Font("Times New Roman", 1, 20));
        jButton2.setMaximumSize(new java.awt.Dimension(200, 50));
        jButton2.setMinimumSize(new java.awt.Dimension(200, 50));
        jButton2.setPreferredSize(new java.awt.Dimension(200, 50));

        GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(GroupLayout.Alignment.CENTER)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(200, 200, 200)
                        .addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER, false)
                            .addComponent(jButton2, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(jButton1, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(200, 200, 200)
                        .addComponent(jLabel1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)))
                .addContainerGap(90, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(150, 150, 150)
                .addComponent(jLabel1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                .addGap(10, 10, 10)
                .addComponent(jButton1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                .addGap(5, 5, 5)
                .addComponent(jButton2)
                .addContainerGap(120, Short.MAX_VALUE))
        );
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) 
    {
        /* Set the Nimbus look and feel */
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try 
        {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) 
            {
                System.out.println("Main.main(): 492");
                if ("Nimbus".equals(info.getName())) 
                {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } 
        catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) 
        {
            java.util.logging.Logger.getLogger(GUITesterSolitaireNew.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() 
        {
            @Override
            public void run() 
            {
                new GUITesterSolitaireNew().setVisible(true);
            }
        });
    }

    private javax.swing.JInternalFrame jInternalFrame1;
    private GameArea newGame = new GameArea();
}

不要使用 setContentPane 切换视图,使用 CardLayout,这就是它的设计目的。有关详细信息,请参阅 How to Use CardLayout

此外,这样做没有什么意义...

setContentPane(pane);
getContentPane().revalidate();
getContentPane().repaint();

在这种情况下,需要重新验证的不是 contentPane,而是 contentPane 的父...