Что не так с этим кодом Java - JLabel не отображается в JPanel (JFrames)? - PullRequest
0 голосов
/ 16 июля 2010

Соответствующие части этого кода, вызывающие проблему, находятся между ------------ тире ....

import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import javax.swing.JLabel;
import java.awt.Color;
import java.awt.GridLayout;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.*;

public class Game3 extends JFrame implements ActionListener {

    private int[][] winCombinations = new int[][]{
            {0, 1, 2}, {3, 4, 5}, {6, 7, 8},  //horizontal wins
            {0, 3, 6}, {1, 4, 7}, {2, 5, 8},  //virticle wins
            {0, 4, 8}, {2, 4, 6}   //diagonal wins
    };

    private JFrame gameWindow = new JFrame("TIC-TAC-TOE");
    private JButton buttons[] = new JButton[9];
    private JPanel biggerPanel;
    private JPanel winnerPanel;
    private int count = 0;
    private String letter = ""; //The player X or O is initialized to empty string
    private boolean win = false;
    public static final int WIDTH = 400;
    public static final int HEIGHT = 300;
    private JLabel winnerLabel = new JLabel("");

    public Game3() {

        gameWindow.setSize(WIDTH, HEIGHT);
        gameWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        gameWindow.setLayout(new BorderLayout());
        JPanel winnerPanel = new JPanel();
        winnerPanel.setBackground(Color.MAGENTA);
        winnerPanel.setLayout(new FlowLayout());
// -----------------------------------------------------------
        win = winBool();
        if (win == true) {
            JLabel winnerLabel = new JLabel(letter + " WINS!");
            winnerPanel.add(winnerLabel);
            gameWindow.add(winnerPanel, BorderLayout.NORTH);
        } else if (count == 9 && win == false) {
            JLabel winnerLabel1 = new JLabel("Tie Game!");
            winnerPanel.add(winnerLabel1);
            gameWindow.add(winnerPanel, BorderLayout.NORTH);
        }
// -----------------------------------------------------------

        JPanel biggerPanel = new JPanel();
        biggerPanel.setLayout(new GridLayout(3, 3));
        gameWindow.add(biggerPanel, BorderLayout.CENTER);
        for (int i = 0; i <= 8; i++) {
            buttons[i] = new JButton();
            buttons[i].setBackground(Color.WHITE);
            biggerPanel.add(buttons[i]);
            buttons[i].addActionListener(this);
        }
        gameWindow.setVisible(true);
    }

    public void actionPerformed(ActionEvent e) {
        count++;
        if (count == 1 || count == 3 || count == 5 || count == 7 || count == 9) {
            letter = "X";
        } else if (count == 2 || count == 4 || count == 6 || count == 8 || count == 10) {
            letter = "O";
        }

        JButton pressedButton = (JButton) e.getSource();
        pressedButton.setText(letter);
        pressedButton.setEnabled(false);

        for (int i = 0; i <= 7; i++) {
            if (buttons[winCombinations[i][0]].getText().equals(buttons[winCombinations[i][1]].getText())
                    && buttons[winCombinations[i][1]].getText().equals(buttons[winCombinations[i][2]].getText())
                    && buttons[winCombinations[i][0]].getText() != "") {
                win = true;
            }
        }
    }

    // -------------------------------------------------------------------------------------
    public boolean winBool() {
        return win;
    }

    // ----------------------------------------------------------------------------------------
    public static void main(String[] args) {
        Game3 game3 = new Game3();
    }
}

Ответы [ 4 ]

2 голосов
/ 16 июля 2010

Похоже, код, который добавляет объекты JLabel, находится в конструкторе и поэтому будет вызываться только один раз.Условия, которые заставят его добавлять метки, не выполняются при вызове конструктора, и поэтому никакие метки не добавляются.

Возможно, вы захотите извлечь добавление объектов JLabel в отдельную функцию и вызвать еес actionPerformed каждый раз, когда появляется обновление.

Кроме того, подумайте, нужен ли вам gameWindow, учитывая, что класс Game3 расширяется JFrame

0 голосов
/ 16 июля 2010
public class Test extends JFrame implements ActionListener {

private int[][] winCombinations = new int[][]{
        {0, 1, 2}, {3, 4, 5}, {6, 7, 8},  //horizontal wins
        {0, 3, 6}, {1, 4, 7}, {2, 5, 8},  //virticle wins
        {0, 4, 8}, {2, 4, 6}   //diagonal wins
};

private JFrame gameWindow = new JFrame("TIC-TAC-TOE");
private JButton buttons[] = new JButton[9];
private JPanel biggerPanel;
private JPanel winnerPanel;
private int count = 0;
private String letter = ""; //The player X or O is initialized to empty string
private boolean win = false;
public static final int WIDTH = 400;
public static final int HEIGHT = 300;
private JLabel winnerLabel = new JLabel("");

public Test() {

    gameWindow.setSize(WIDTH, HEIGHT);
    gameWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    gameWindow.setLayout(new BorderLayout());

    JPanel biggerPanel = new JPanel();
    biggerPanel.setLayout(new GridLayout(3, 3));
    gameWindow.add(biggerPanel, BorderLayout.CENTER);
    for (int i = 0; i <= 8; i++) {
        buttons[i] = new JButton();
        buttons[i].setBackground(Color.WHITE);
        biggerPanel.add(buttons[i]);
        buttons[i].addActionListener(this);
    }
    gameWindow.setVisible(true);
}

private void publishResult() {
    JPanel winnerPanel = new JPanel();
    winnerPanel.setBackground(Color.MAGENTA);
    winnerPanel.setLayout(new FlowLayout());

    win = winBool();
    if (win == true) {
        JLabel winnerLabel = new JLabel(letter + " WINS!");
        winnerPanel.add(winnerLabel);
        gameWindow.add(winnerPanel, BorderLayout.NORTH);
    } else if (count == 9 && win == false) {
        JLabel winnerLabel1 = new JLabel("Tie Game!");
        winnerPanel.add(winnerLabel1);
        gameWindow.add(winnerPanel, BorderLayout.NORTH);
    }
    gameWindow.repaint();
}

public void actionPerformed(ActionEvent e) {
    count++;
    if (count == 1 || count == 3 || count == 5 || count == 7 || count == 9) {
        letter = "X";
    } else if (count == 2 || count == 4 || count == 6 || count == 8 || count == 10) {
        letter = "O";
    }

    JButton pressedButton = (JButton) e.getSource();
    pressedButton.setText(letter);
    pressedButton.setEnabled(false);

    for (int i = 0; i <= 7; i++) {
        if (buttons[winCombinations[i][0]].getText().equals(buttons[winCombinations[i][1]].getText())
                && buttons[winCombinations[i][1]].getText().equals(buttons[winCombinations[i][2]].getText())
                && buttons[winCombinations[i][0]].getText() != "") {
            win = true;
            publishResult();
        }
    }
}

public boolean winBool() {
    return win;
}

public static void main(String[] args) {
    Test game3 = new Test();
}  }

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

Неправильно: Часть кода, написанная для добавления JLabel (с логикой if / else-if), не должна быть в этом месте, так как конструкторбудет вызываться только один раз при инициализации объекта (в нашем случае, фрейма).

Решение: Я полагаю, что JLabel следует добавлять всякий раз, когда выигрывает какой-либо выигрыш, и тот сценарий, который вы захватили в actionPerformed (где вы устанавливаете win = true).Поэтому я извлек вашу логику добавления JLabel в отдельный метод и вызываю ее, когда происходит победа.

Совет: Вы можете отладить сценарий, чтобы лучше понять, что происходит!:)

0 голосов
/ 16 июля 2010

В конструкторе у вас есть

if(win == true) {
    JLabel winnerLabel = new JLabel(letter + " WINS!");
    winnerPanel.add(winnerLabel);
    gameWindow.add(winnerPanel, BorderLayout.NORTH);
} else if(count == 9 && win == false){
        JLabel winnerLabel1 = new JLabel("Tie Game!");
        winnerPanel.add(winnerLabel1);
        gameWindow.add(winnerPanel, BorderLayout.NORTH);
}

но, win, инициализируется как false и считается до 0. Эта часть кода выполняется только один раз, во время построения, поэтому она никогда не изменится

Я думаю, что в конструкторе, вы всегда можете иметь

winnerPanel.add(winnerLabel);
gameWindow.add(winnerPanel, BorderLayout.NORTH);

и поместите ваше состояние в слушатель действия (что-то вроде):

public void actionPerformed(ActionEvent e) {
    count++;
    ...//your code here
    if(win == true) {
        winnerLabel.setText(letter + " WINS!");
    } else if(count == 9 && win == false){
        winnerLabel.setText("TIE GAME");
    }
}
0 голосов
/ 16 июля 2010

1- Почему Game3 расширяется JFrame, если у вас уже есть gameWindow?

2 - замените JLabel winnerLabel = new JLabel(letter + " WINS!"); на winnerLabel = new JLabel(letter + " WINS!"); и JLabel winnerLabel1 = new JLabel("Tie Game!"); на winnerLabel1 = new JLabel("Tie Game!");, так как вы не хотите создавать новые локальные переменные, но назначаете новые объекты переменным-членам класса Game3. Также по той же причине, что и выше, замените JPanel winnerPanel = new JPanel(); на winnerPanel = new JPanel();.

Примените эти изменения и дайте мне знать, что будет дальше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...