0

I can provide all of my code if that would aid in the problem, but I believe since this only affects one class really, it can be solved here, to simplify the issue.

I have a solitaire project (mind the package/class name, it was trial and error and I didn't delete the old projects) that refuses to accept the GameArea class I have, which extends JPanel. The GameArea works fine in its own separate instance where the tester class runs with only the JPanel on the JFrame. That tester class uses setContentPane(newGame) to add it to the JFrame.

In the class below, neither getContentPane().add(newGame) nor setContentPane(newGame) successfully adds the game to the frame. This class sets up a main menu, with two buttons. The first one takes it into the Start New Game screen, and then the button which is supposed to start the game will either:

1) show only a green screen if getContentPane().add(newGame) is used

2) show a pressed Start New Game, and then freeze on the Start New Game screen if setContentPane(newGame) is used. This is frustrating because getContentPane().removeAll() is called before this...However, using the menu, I can return to the main menu and still run in that infinite loop of freeze and fix.

I suspect because I don't know enough about swing classes yet that I'm missing something. Any help is greatly appreciated, since I need to have this done in 2 days.

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();
}
  • Please learn how to make an [MCVE](http://stackoverflow.com/help/mcve) (Minimal Complete Verifiable Example) rather than give us a 'code dump' of over 500 lines of code! – Andrew Thompson Mar 30 '15 at 05:52

1 Answers1

2

Don't use setContentPane to switch views, use a CardLayout, that's what it's designed for. See How to Use CardLayout for more details

Also, there's little point to doing this...

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

In this instance, it's not the contentPane that needs to be revalidated, it's the contentPanes parent...

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • I appreciate the guiding hand, thank you. CardLayout is tough to learn though. Is there not a way to work with what I already have set? I still don't understand why I can't add my JPanel to this class that has a menu already set up. Is it the GroupLayout that's already in place? –  Mar 31 '15 at 03:34
  • `set/getContentPane` isn't the right method to use to do switching. `add`/`remove` are going to give you issues as well. The simplest solution remains `CardLayout` – MadProgrammer Mar 31 '15 at 03:42
  • Alright, that will have to be another day I read up on it. Thanks for letting me know so I didn't waste any more time trying to fix something that wouldn't work. –  Mar 31 '15 at 04:19
  • Thank you so much, I got this working in a CardLayout. What I did is I kept the GroupLayout, but I created panels with a GroupLayout, and added the panels to a single panel with a CardLayout. When the buttons are clicked, it switches the panels in the CardLayout. This is exactly what I was aiming for, so thank you for guiding me in that direction! –  Apr 02 '15 at 20:41
  • Glad you were able to figure it out – MadProgrammer Apr 02 '15 at 20:47