2

I'm trying to create a program that runs a game of Go. I want one screen that asks you the size of the Go board in question, one that actually plays the game, and one that lets you decide to play again or not. What is the most effective way to do this using Swing? I saw people talk about using CardLayout on other questions but my understanding is that the user can switch between those screens on demand, which isn't what I want.

I am also using Eclipse if the native GUI builder in Eclipse would work better but I've never figured out how to make it work.

Sig
  • 91
  • 2
  • 12
  • 2
    [How to Use CardLayout](http://docs.oracle.com/javase/tutorial/uiswing/layout/card.html) – MadProgrammer Apr 19 '16 at 07:51
  • 2
    *'CardLayout on other questions but my understanding is that the user can switch between those screens on demand"* - The user can't do anything you don't allow them to do. With `CardLayout`, you control when a view is switched – MadProgrammer Apr 19 '16 at 07:52
  • That was actually the example I was looking at, I didn't notice it declaring the combobox, thought it was automatic. I might try working with it again. – Sig Apr 19 '16 at 21:27

2 Answers2

2

A slightly less modal approach would allow the user to select and play one of several common games. Using this button based memory game as an example,

  • Enumerate the supported game features.

  • Add instances of the enum values to a JComboBox.

  • Handle changes using remove(), validate() and repaint() to update the game board.

In this example, a JLabel serves as a placeholder for the game. Alternatively, leave your game view in place, update your observable game model, as described here, and arrange for the listening view to respond as required.

image

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

/**
 * @see https://stackoverflow.com/a/36714997/230513
 */
public class Go {

    private Game game = Game.Easy;
    private final JComboBox gameCombo = new JComboBox();

    enum Game {

        Easy(9), Fast(13), Classic(17), Full(19);
        private int size;
        private String name;

        private Game(int size) {
            this.size = size;
            this.name = this.name() + ": " + size + "\u00d7" + size;
        }

        public int size() {
            return this.size;
        }

        @Override
        public String toString() {
            return this.name;
        }
    }

    private void display() {
        JFrame f = new JFrame("Test");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel board = new JPanel() {
            @Override
            public Color getBackground() {
                return Color.cyan.darker();
            }

            @Override
            public Dimension getPreferredSize() {
                return new Dimension(320, 240);
            }
        };
        board.add(new JLabel(game.toString()));
        f.add(board);
        JPanel p = new JPanel();
        for (Game g : Game.values()) {
            gameCombo.addItem(g);
        }
        gameCombo.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                game = (Game) gameCombo.getSelectedItem();
                board.removeAll();
                board.add(new JLabel(game.toString()));
                board.validate();
                board.repaint();
            }
        });
        p.add(new JButton("Start"));
        p.add(gameCombo, BorderLayout.SOUTH);
        f.add(p, BorderLayout.SOUTH);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Go()::display);
    }
}
Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • I thought about using this method but I wanted to see if there was a simpler method I could use. Thank you though. – Sig Apr 19 '16 at 21:28
  • @Sig: I've proposed an alternative above; it's not especially simpler but it _is_ more scalable as your game model evolves. – trashgod Apr 19 '16 at 22:16
1

Different options:

Different JFrames

One JFrame for each "scene" you use. When you pass from one to other, you just set that one visible and the last non-visible.

But this is actually weird and not my recommendation.

Different JPanels

The same that above, but instead of switching to visible/non-visible; you change the panel you have in the JFrame (and repaint it, of course).

Also, this is a bad choice, but I wanted you to know different ways you can do this (in case you want to do something different later and one of this becomes a better option).

JOptionPane

This is the good one for your game. You can prompt a JOptionPane (with input text or something like that) that asks you the size of the board, then get its response and pass it to a constructor for the JFrame, and when the game is over, use another JOptionPane (Yes/No) to ask the > Play Again? <

Here a few examples.

dquijada
  • 1,697
  • 3
  • 14
  • 19
  • Why would the second one be a bad choice? It seems like it'd be a reasonably intuitive way of doing things. – Sig Apr 19 '16 at 21:29
  • A bad choice for what you need. With JOptionPane the question you need pops, and it's easy to retrieve the value introduced. – dquijada Apr 21 '16 at 08:11