1
\$\begingroup\$

Based on this article, I wrote a small "Guess my number" game in Hexagonal architecture which interacts with a Java Swing GUI adapter.

Any feedback is appreciated.

Main.java

package piovezan.hexaguessnumber;

public class Main 
{
    public static void main(String[] args) {
        int numberToGuess = 5;
        GuiGuesser guesser = new GuiGuesser();
        guesser.execute();
        HexagonalGuessMyNumber game = new HexagonalGuessMyNumber(numberToGuess, guesser, guesser);
        game.play();
    }
}

Guesser.java

package piovezan.hexaguessnumber;

public interface Guesser {
    public int guess();
}

Display.java

package piovezan.hexaguessnumber;

public interface Display {
    public void show(String text);
}

HexagonalGuessMyNumber.java

package piovezan.hexaguessnumber;

import java.util.Objects;

public class HexagonalGuessMyNumber {

    private final int numberToGuess;
    private final Display display;
    private final Guesser guesser;

    public HexagonalGuessMyNumber(int numberToGuess, Display display, Guesser guesser) {
        this.numberToGuess = numberToGuess;
        this.display = Objects.requireNonNull(display);
        this.guesser = Objects.requireNonNull(guesser);
    }

    public boolean play() {
        display.show("Guess the number I'm thinking in up to five attempts.");
        for (int attempt = 1; attempt <= 5; attempt++) {
            int guess = guesser.guess();
            display.show("Attempt #" + attempt + ": " + guess + ".");
            if (guess == numberToGuess) {
                display.show("Congratulations, you guessed correctly! The number is " + numberToGuess + "!");
                return true;
            }
        }

        display.show("You weren't able to guess. Better luck next time.");
        return false;
    }
}

GuiGuesser.java

package piovezan.hexaguessnumber;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public final class GuiGuesser implements Guesser, Display {

    private final JTextField textField;
    private final JButton button;
    private final JPanel panel;
    private final JLabel label;

    private final BlockingQueue<Integer> queue = new LinkedBlockingQueue<>();


    public GuiGuesser() {
        this.textField = new JTextField();
        this.button = new JButton("Guess");
        this.panel = new JPanel();
        this.label = new JLabel();
    }


    /**
     * Create the GUI and show it.  For thread safety,
     * this method should be invoked from the
     * event-dispatching thread.
     */
    public void execute() {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JFrame("GUI Guesser");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                initTextField();
                initButton();
                initPanel();
                initLabel();
                frame.getContentPane().add(panel);

                frame.pack();
                frame.setVisible(true);
            }
        });
    }

    private void initTextField() {
        textField.setColumns(10);
    }

    private void initButton() {
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    queue.add(Integer.parseInt(textField.getText()));
                } catch (NumberFormatException ex) {
                    // Do nothing.
                }
            }
        });
    }

    private void initPanel() {
        panel.add(textField);
        panel.add(button);
        panel.add(label);
    }

    private void initLabel() {
        label.setPreferredSize(new Dimension(600, 600));
    }

    @Override
    public int guess() {
        try {
            return queue.take();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }


    @Override
    public void show(String text) {
        label.setText(text);
    }
}

I've ommitted KeyboardGuesser (Scanner-based keyboard input), ConsoleDisplay and UnitTestGuesser from the review, as they are unrelated and quite simple. The first two can be seen in the linked article.

\$\endgroup\$

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Browse other questions tagged or ask your own question.