Как получить объект Java Frame для использования в методе сброса?

Я делаю игру Tic-Tac-Toe на Java. У меня четыре класса: TicTacTester просто вызывает (создает объект) класс TicTacToe. Класс TicTacToe предоставляет графический интерфейс игры (это подкласс JFrame). Он также создает 9 кнопок для отображения в JPanel и для нажатия пользователями. Класс XOButton определяет, что могут делать кнопки, и метод actionPerformed. Наконец, класс GameEnd определяет, что происходит, когда игра заканчивается (создается новый JFrame для отображения счета и предоставления пользователю двух кнопок: выхода и перезапуска).

Проблема в том, что когда я пытаюсь закодировать содержимое того, что происходит, когда пользователь нажимает «перезагрузка». Предполагается вызвать метод resetBoard(), который определен в классе TicTacToe. Проблема в том, что я не знаю имени объекта, созданного из класса TicTacToe (в методе static void main класса тестера я просто набрал «новый TicTacToe», не нужно было определять имя). Я не могу вызвать resetBoard со статической точки зрения (т.е. я не могу сделать TicTacToe.resetBoard(); ), потому что resetBoard должен быть нестатическим.

Что я пробовал: Я попытался включить в конструктор класса GameEnd объект TicTacToe. Если я это сделаю, создатель объекта GameEnd должен перейти в класс TicTacToe, поэтому я могу использовать ключевое слово this. Это не работает, потому что объект GameEnd необходимо создать при выполнении условия WinCondition, которое проверяется при нажатии кнопки в классе XOButton.

Но если я поместил создатель объекта GameEnd в класс XOButton (где он находится сейчас и, якобы, там, где он должен быть), в конструкторе для GameEnd(String s, TicTacToe a), я не могу использовать ключевое слово this для Объект Крестики-нолики.

Это мой класс кнопок. Большая часть кода не актуальна, поэтому она скрыта.


public class XOButton extends JButton implements ActionListener {

//Hidden code
    private void winCheck() {
        for(int j = 0; j < 3; j++) {
            if (board[j][0] == 1 && board[j][1] == 1 && board[j][2] == 1 || board[0][j] == 1 && board[1][j] == 1 && board[2][j] == 1) {
                player1Score++;
                GameEnd end = new GameEnd("X wins this round!");
                finished = true;
                break;
            }
            else if (board[j][0] == 2 && board[j][1] == 2 && board[j][2] == 2 || board[0][j] == 2 && board[1][j] == 2 && board[2][j] == 2) {
                player2Score++;
                GameEnd end = new GameEnd("O wins this round!");
                finished = true;
                break;
            }
        }

        if (board[0][0] == 1 && board[1][1] == 1 && board[2][2] == 1 || board[0][2] == 1 && board[1][1] == 1 && board[2][0] == 1) {
            player1Score++;
            GameEnd end = new GameEnd("X wins this round!");
            finished = true;
        }
        else if (board[0][0] == 2 && board[1][1] == 2 && board[2][2] == 2 || board[0][2] == 2 && board[1][1] == 2 && board[2][0] == 2) {
            player2Score++;
            GameEnd end = new GameEnd("O wins this round!");
            finished = true;
        }
        if (turn == 9 && !finished) {
            GameEnd end = new GameEnd("This round is a Draw");
            finished = true;
        }

    }

    public void resetButton() {
        this.setIcon(null);
        markSpot(0);
        this.clicked = false;
    }

    public static void resetStatics() {
        turn = 0;
        finished = false;
    }

}

Это класс TicTacToe. Большая часть кода не актуальна, поэтому она скрыта.


public class TicTacToe extends JFrame {

//Hidden code

    public void resetBoard() {
        for(int j = 0; j < 3; j++) {
            for(int i = 0; i < 3; i++) {
                buttons[j][i].resetButton();
            }
        }
        XOButton.resetStatics();
    }


}

Это класс GameEnd. Объект этого создается при выполнении условия WinCondition. Большая часть кода не актуальна, поэтому она скрыта.

public class GameEnd extends JFrame implements ActionListener {

//Hidden code

    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == exit) {
            System.exit(0);
        }
        else if (e.getSource() == retry) {
            TicTacToe.resetBoard();
        }

    }

}

//This is the Tester class

public class TicTacTester {
    public static void main(String[] args) {
        new TicTacToe();
    }
}

Я ожидаю, что произойдет перезапуск игрового поля.

1) Чтобы быстрее получить помощь, редактировать добавить минимальный воспроизводимый пример или Короткий, автономный, правильный пример. 2) Одна пустая строка пробела в исходном коде — это все, что нужно для Когда-либо. Пустые строки после { или перед } также обычно избыточны. 3) См. Использование нескольких JFrames, хорошая/плохая практика? 4) Но не расширяйте JFrame или другие компоненты графического интерфейса, если только *специфический не требуется изменить существующее поведение! 5) if (e.getSource() == exit) { System.exit(0); Самый простой способ..

Andrew Thompson 27.05.2019 05:24

.. frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 6) GameEnd Сомневаюсь, что это вообще должен быть класс. Вместо того, чтобы называть это, покажите соответствующий JOptionPane.

Andrew Thompson 27.05.2019 05:24

@AndrewThompson Я немного сбит с толку. Если бы я использовал JOptionPane вместо класса GameEnd, где бы использовался JOptionPane? Буду ли я инициализировать и настраивать/разрабатывать его в классе XOButton, где находится WinCondition, или в классе TicTacToe?

Dhruv Patel 27.05.2019 06:26
"... где можно использовать JOptionPane?" Вы бы вызвали его из любой строки кода, в которой есть new GameEnd(..);
Andrew Thompson 27.05.2019 06:28
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
4
131
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Похоже, вы слишком сильно разбиваете проект. Если у вас есть класс для игры, держите все его методы внутри этого класса. Единственный раз, когда я могу использовать отдельные классы, это если вы пытаетесь создать это с использованием архитектуры Model-View-Controller (MVC) или тому подобного. Это распространенный подход для приложений, использующих графический интерфейс, доступ к данным и контроллеры.

Может быть и в другое время, но это все, что приходит мне в голову.

Из того, что вы показываете, я не думаю, что это применимо.


Я думаю, что это был бы лучший подход:

Крестики-нолики.java

public class TicTacToe extends JFrame {
    private int scorePlayer1;
    private int scorePlayer2;
    private boolean initialized;    // default = false

    // Reset the board
    // Reset the markers, etc.
    public void resetGame() {}

    // Check to see if there is a winner
    // If so, announce the winner and return true
    // Otherwise, return false.
    public boolean winCheck() {}

    // Set up frame, buttons, score, etc.
    public void newGame(){
        // Create however many JPanels you need
        // Add it to a single JFrame

        // When you're ready...
        // and this game has not been initialized for the first time.
        // In this example jframe is an instance of JFrame
        if (!this.initialized)
            jframe.setVisible(true);
    }

    // Play the game
    public void play(){
        // For each round,
        // a player chooses where to put their "X" or "O"
        // add scores, etc.

        // Then at the end of each round
        if (this.winCheck())
            this.resetGame();
    }
}

TicTacToeTester.java:

public class TicTacToeTester {
    public static void main(String[] args){
        TicTacToe game = new TicTacToe();
        game.play();
    }
}

Надеюсь, это поможет!

Дайте знать, если у вас появятся вопросы. :)

Мне все равно нужен класс кнопки, верно? Кроме того, как мне отобразить экран Win без другого JFrame?

Dhruv Patel 27.05.2019 06:35

@DhruvPatel, вы можете создать класс XOButton, если хотите, чтобы он делал определенные вещи ... Я сомневаюсь, что в этом случае это будет необходимо, если он только помещает маркер, а вы используете логику для управления счетом игрока. Если вы решите использовать класс для кнопки, вы можете это сделать. Но проверка выигрышной игры должна оставаться в основном классе TicTacToe, потому что она определяет, есть ли победитель игра, а не кнопка. Это помогает?

Sometowngeek 27.05.2019 06:50

Что касается JFrame, JFrame достаточно для отображения окна. Я обновлю свой ответ.

Sometowngeek 27.05.2019 06:51

@DhruvPatel Я обновил свой ответ ... Дайте мне знать, если это поможет или вам нужна дополнительная помощь :)

Sometowngeek 27.05.2019 07:07

Итак, если бы у меня был метод в TicTacToe для winChecking, как бы я смог его вызвать? Мне нужно запускать «winCheck» каждый раз, когда выполняется ActionPerformed (т.е. каждый раз, когда пользователь выбирает квадрат). Я не могу вызвать метод из класса TicTacToe в методе ActionPerformed, потому что метод actionperformed принадлежит классу Button, а winCheck принадлежит классу TicTacToe.

Dhruv Patel 27.05.2019 16:45

@DhruvPatel Это не сработает ... Как я уже сказал в своем первом комментарии, winCheck должен быть внутри класса Крестики-нолики, а не XOButton. Вот почему я добавил метод play() в класс TicTacToe.

Sometowngeek 27.05.2019 17:57

@DhruvPatel Подожди... Кажется, я вижу способ добавить XOButton. Секунду.

Sometowngeek 27.05.2019 18:25

@DhruvPatel Если вы хотите поместить winCheck() в XOButton, вы действительно можете это сделать. Вот как. gist.github.com/sometowngeek/5f0de509a1c93bb87dffcb3f06918a9‌​5

Sometowngeek 27.05.2019 18:30

Если вы хотите, чтобы я обновил свой ответ этим кодом, дайте мне знать.

Sometowngeek 27.05.2019 18:30

Другие вопросы по теме