2013-05-19 3 views
0

Я здесь ошарашен. У меня есть JPanel (defBoardPanel), что я добавление к родителю JPanel (GamePanel) следующим образом:JPanel не появляется при добавлении в родительский JPanel

public GamePanel(SetupBoard sb) { 
    this.setLayout(new BorderLayout()); 
    // this.setBackground(Color.yellow); 
    JPanel defBoardPanel = new JPanel(); 
    defBoardPanel.setBackground(Color.yellow); 

    for (int r = 0; r < sb.boardSize; r++){ 
     for (int c = 0; c < sb.boardSize; c++){ 
      Cell c = new Cell(r, c);  
      c.label.setOpaque(true); 
      if (sb.getCell(r, c).status == sb.getCell(r,c).status.occupied){ 
       c.label.setBackground(Color.black); 
       System.out.println("LABEL IS OCCUPIED"); 
      } 
      else { 
       c.label.setBackground(Color.white); 
      } 
      defBoardPanel.add(c.label); 
     } 
    } 

    defBoardPanel.revalidate(); 
    defBoardPanel.setVisible(true); 
    this.add(defBoardPanel, BorderLayout.WEST); 
    this.revalidate(); 
    this.setVisible(true); 

Эта панель должна быть добавлена ​​к JFrame (MainFrame), которая показана ниже. Когда приложение запускается, JFrame отображает другой тип Panel (SetupBoard), с помощью которого пользователь устанавливает свою игровую панель. Когда они нажимают «принять», вызывается метод StartGame() MainFrame, который должен показывать JPanels выше.

public MainFrame() { 
    this.setLayout(new BorderLayout()); 
    this.setSize(500, 500); 

    SetupBoard sb = new SetupBoard(10, this); 
    this.setContentPane(sb); 

} 

    void startGame(SetupBoard sb){ 
     GamePanel gp = new GamePanel(sb); 
     this.setContentPane(gp); 
     this.revalidate(); 

} 

Моя проблема заключается в том, что дочерняя панель (defBoardPanel) не отображается. Сам экран GamePanel (который я проверил с использованием метода setBackground(Color.yellow), который вы видите в комментариях), но не панель, которую я добавил на нее.

Какую тупую ошибку я пропускаю здесь?

РЕДАКТИРОВАТЬ: StartGame() вызывается из класса SetupBoard:

void startGame(){ 
    mf.startGame(this); 
} 

, где М.Ф. является ссылкой на MainFrame, который создал SetupBoard экземпляр. Тот факт, что GamePanel отображается вообще, подтверждает, что это правильно называется.

+1

Вы на самом деле называете 'startGame'? Для лучшей помощи скорее опубликуйте [SSCCE] (http://sscce.org/) – Reimeus

+0

@Reimeus да, см. Править. Кроме того, я попытался создать SSCCE, но не смог воспроизвести поведение. – drewmoore

+0

Кажется, что у вас нет компонентов внутри defBoardPanel, и вы не задали ему определенный размер. Возможно, defBoardPanel имеет нулевой размер, поэтому вы его не видите. Попробуйте установить размер панели, а затем вызовите пакет() на свой объект JFrame, чтобы переместить все, основываясь на размерах панелей и компонентов. – Bobulous

ответ

1

Кажется, что нормально работать, если я обрезаю код, которого у меня нет. Скорее всего, проблема исходит из того, что вы не показываете нам. Поэтому получение SSCCE принесет вам большую пользу. В то же время, вы всегда можете воспользоваться (найти различия с вашим кодом) в следующей один, который высоко возникла из вашей (я заполнил некоторые пробелы, как я мог):

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.GridLayout; 

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

public class GamePanel extends JPanel { 
    private static final int COLS = 10; 
    private static final int ROWS = 10; 

    public GamePanel() { 
     this.setLayout(new BorderLayout()); 
     // this.setBackground(Color.yellow); 
     JPanel defBoardPanel = new JPanel(new GridLayout(ROWS, COLS)); 
     defBoardPanel.setBackground(Color.yellow); 
     for (int r = 0; r < ROWS; r++) { 
      for (int c = 0; c < COLS; c++) { 
       JLabel label = new JLabel((r + 1) + " " + (c + 1)); 
       label.setOpaque(true); 
       if (Math.random() > 0.5) { 
        label.setBackground(Color.black); 
        label.setForeground(Color.WHITE); 
        System.out.println("LABEL IS OCCUPIED"); 
       } else { 
        label.setBackground(Color.white); 
       } 
       defBoardPanel.add(label); 
      } 
     } 
     this.add(defBoardPanel, BorderLayout.WEST); 
    } 

    public static class MainFrame extends JFrame { 
     public MainFrame() { 
      this.setLayout(new BorderLayout()); 
      this.setSize(500, 500); 
     } 

     void startGame() { 
      GamePanel gp = new GamePanel(); 
      this.setContentPane(gp); 
      pack(); 
      setVisible(true); 
     } 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       MainFrame mainFrame = new MainFrame(); 
       mainFrame.startGame(); 
      } 
     }); 
    } 
} 
1

Эта кодовая последовательность заменяет GamePanel после того как оно было добавлено к MainFrame

public MainFrame() { 
    this.setLayout(new BorderLayout()); 
    this.setSize(500, 500); 

    SetupBoard sb = new SetupBoard(10, this); // invokes startGame 
    this.setContentPane(sb); <----- GamePanel replaced here 
} 

void startGame(SetupBoard sb) { 
    GamePanel gp = new GamePanel(sb); 
    this.setContentPane(gp); 
    this.revalidate(); 
} 
+0

+1 вызов 'setContentPane' в конструкторе' MainFrame' переопределит вызов, сделанный 'startGame' (если' startGame' вызывается в конструкторе 'SetupBoard'). Как я уже говорил, «скорее всего, проблема связана с тем, что вы не показываете нам». _ ;-) –

+0

Этот вызов, созданный в конструкторе, не вызывается после вызова 'startGame()'. startGame() вызывается в экземпляре MainFrame, который уже существует. Кроме того, не будет ли это снова отображаться SetupBoard? Это не так, GamePanel отображается, просто не панель, которую я добавил к ней. – drewmoore

+0

@GuillaumePolet: 'startGame()' не вызывается в конструкторе SetupBoard, его вызывается отдельным методом, который вызывается в 'ActionListener' на кнопке на SetupBoard. – drewmoore

Смежные вопросы