Отправка информации между панелями и основной рамой

1

Мое промежуточное задание для моего класса comp sci - это то, что я должен создать игру тиктакто. У меня есть 9 отдельных объектов JPanel, которые представляют фрагменты, все с индексом int "turn", который определяет, какой графический объект будет помещен в панель. Моя проблема в том, что мне нужно сделать так, чтобы при нажатии кнопки внутри панели она меняет значение поворотов для всех объектов CellPanel внутри фрейма, а не только из этого экземпляра, так что в следующий раз панели, он ставит новую графику, вместо той же графики, что и раньше.

Мой класс Mid1 с основным методом:

import java.awt.*;
import javax.swing.*;

public class Mid1 extends JFrame {
  public Mid1() {
    setLayout(new GridLayout(3, 3));

    CellPanel panel1 = new CellPanel();
    add(panel1);
    CellPanel panel2 = new CellPanel();
    add(panel2);
    CellPanel panel3 = new CellPanel();
    add(panel3);
    CellPanel panel4 = new CellPanel();
    add(panel4);
    CellPanel panel5 = new CellPanel();
    add(panel5);
    CellPanel panel6 = new CellPanel();
    add(panel6);
    CellPanel panel7 = new CellPanel();
    add(panel7);
    CellPanel panel8 = new CellPanel();
    add(panel8);
    CellPanel panel9 = new CellPanel();
    add(panel9);
  }

  public static void main(String[] args) {
    Mid1 frame = new Mid1();
    frame.setTitle("mid1");
    frame.setSize(400, 400);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLocationRelativeTo(null); // Center the frame
    frame.setVisible(true);

  }
}

Мой класс CellPanel:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;

class CellPanel extends JPanel implements ActionListener{
  Image cross = new ImageIcon("image/x.gif").getImage();
  Image not = new ImageIcon("image/o.gif").getImage();
  JButton button;
  int turn = 0;
  int draw;

  public CellPanel(){
      BorderLayout layout = new BorderLayout();
      setLayout(layout);
      button = new JButton("Take");
      button.setPreferredSize(new Dimension(0,20));
      button.addActionListener(this);
      this.add(button, layout.SOUTH);
  }

  public void setTurn(int t){
      turn = t;
  }

  public int getTurn(){
      return turn;
  }

  @Override
  protected void paintComponent(Graphics g) {
    super.paintComponent(g);

    if (draw == 1)
        g.drawImage(cross, 0, 0, getWidth(), getHeight(), this);
    if (draw == 2)
        g.drawImage(not, 0, 0, getWidth(), getHeight(), this);

      System.out.println(turn);

    /*int mode = (int)(Math.random() * 3);

    if (mode == 0) {
      g.drawImage(cross, 0, 0, getWidth(), getHeight(), this);
    }
    else if (mode == 1) {
      g.drawImage(not, 0, 0, getWidth(), getHeight(), this);
    }*/
  }

    @Override
    public void actionPerformed(ActionEvent e) {
        switch(turn) {
            case 0:
                draw = 1;
                this.repaint();
                turn = 1;
                break;
            case 1: 
                draw = 2;
                this.repaint();
                turn = 0;
                break;
            default: turn = 0;
                break;
        }
        this.remove(button);
    }
}
  • 0
    Разделите ваши проблемы. Я бы удалил поле поворота из панели (панели не должны знать, кто из игроков будет играть дальше, панели нужно только знать, что отображать). Когда игрок помечает квадрат, передайте значение на панель, чтобы он знал, какой игрок только что играл, и может отобразить соответствующий символ.
  • 0
    Я не уверен, как мне передать значение, так как кнопки и их списки действий существуют внутри панелей. Должен ли я сделать их отдельными и поместить их в саму рамку? Я не уверен, как бы я работал макет их в этом случае.
Теги:
swing
jpanel
jframe

2 ответа

1

Пусть каждый CellPanel знает, когда изменяется состояние игры с использованием шаблона наблюдателя; несколько реализаций предложены здесь. Хотя CellPanel может с пользой расширить JPanel чтобы установить предпочтительный размер, он все равно может реализовать Observer. Ваша игровая модель, которая должна уведомить прослушивающие ячейки, чтобы перерисовать себя, может расширить Observable.

0

Есть несколько способов сделать это.

Предполагая, что у вас есть только одна настольная доска для tic tac, самая простая вещь - объявить turn как static.

static int turn = 0;

Затем вы можете сделать get и set static, и вам нужно только изменить его для одной из CellPanels, чтобы все они узнали, что поворот изменился.

CellPanel.setTurn(1); 
//sets turn for static int turn to 1. All CellPanels share the same turn value and recognize this as such

Это, как говорится, я не уверен, какова цель вашего предмета turn. Это означает, что игрок 1, игрок 2? Какое это физическое явление? Что-то другое?

  • 0
    Это, конечно, исправляет мою первую проблему, но теперь моя проблема заключается в том, что мне нужно запускать проверку каждый раз, когда активируется ActionListener, чтобы увидеть, есть ли где-нибудь на доске «три в ряд». Статика здесь не будет работать, так как каждая панель (очевидно) будет иметь разные значения для графики. Любой совет?
  • 0
    @GraysonErickson Это должно быть то, что концептуальная доска, которая содержит все ваши CellPanels, должна проверить. CellPanels не должны проверять соседей, чтобы определить, выстраиваются ли они в линию (на самом деле, это было бы очень сложно). Если вам нужно связаться с доской из CellPanel, вы всегда можете назначить ей родительский элемент JPanel, чтобы они могли вызвать parent.checkForWin ();

Ещё вопросы

Сообщество Overcoder
Наверх
Меню