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 agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.