2013-02-09 2 views
1

Я довольно новичок в программировании GUI с качелями, и у меня есть то, что я уверен, это проблема с noob.Элементы на JPanel не отображаются

Я создал JFrame с JPanel внутри него. Затем я пытаюсь добавить JLabel для каждого элемента массива. Проблема в том, что элементы не отображаются на панели. Я проверил, чтобы элементы массива регистрировались с помощью инструкции println, так что это не проблема. Я предполагаю, что я где-то пропустил заявление ... пожалуйста, советую.

Вот мой код:

public class MazeFrame extends javax.swing.JFrame { 
    Maze m; 
    /** 
    * Creates new form MazeFrame 
    */ 
    public MazeFrame(Maze m) { 
     this.m = m; 
     setSize(new Dimension(800, 600)); 
     JPanel pan = new JPanel(); 
     add(pan); 
     setVisible(true); 
     // pan.setBackground(Color.yellow); 
     pan.setLayout(new GridLayout(m.width, m.height)); 

     for (int curr = 0; curr < m.height; curr++){ 
      for (Cell c: m.maze[curr]){ 
       JLabel lab = new JLabel(); 
       switch (c.state){ 
        case border: 
         lab.setBackground(Color.black); 
         System.out.println("addedborder"); 
         break; 
        case wall: 
         lab.setBackground(Color.DARK_GRAY); 
         System.out.println("addedwall"); 
         break; 
        case open: 
         lab.setBackground(Color.LIGHT_GRAY); 
         System.out.println("addedopen"); 
         break; 
        case travelled: 
         lab.setBackground(Color.RED);    
       } 
       lab.setSize(new Dimension(50, 50)); 
       lab.setVisible(true);    
       pan.add(lab); 
       // System.out.println("added"); 
      } 
     } 
     pan.revalidate(); 
     pan.repaint(); 
    } 
} 

Вот класс лабиринта:

package robots; 

import java.util.Random; 


public class Maze { 
    public Cell[][] maze; 
    final int width; 
    final int height; 

    public Maze(){ 
     width = 20; 
     height = 20; 
     maze = new Cell[width][height]; 
     for (int row = 0; row < height; row++){ 
      for (int col = 0; col < width; col++){ 
       maze[row][col] = new Cell(row, col); 
      } 
     } 

     // set borders 
     for (int curr = 0; curr < height; curr++) { 
      maze[0][curr].setState("border"); 
      maze[curr][0].setState("border"); 
      maze[height - 1][curr].setState("border"); 
      maze[curr][width - 1].setState("border"); 
     } 

     // initially mark all cells as walls 
     for (int row = 1; row < height - 1; row++) { 
      for (int col = 1; col < width - 1; col++) { 
       maze[row][col].setState("wall"); 
      } 
     } 

    } 

    private boolean isValidTurn(int row, int col) { 
     if (row >= 0 && col < width && col > 0 && 
        row < 20 && (!this.maze[row][col].getState().matches("open"))) { 
      return true; 
     } 
     return false; 
    } 

    public void makeRoute() { 
     Random r = new Random(); 
     int row = 0; 
     int col = r.nextInt(width); 
     maze[row][col].setState("open"); 
     row = row+1; 
     maze[row][col].setState("open"); 

     // System.out.println(this); 
     while (row < (this.height - 1)) { 
      // Assuming the mouse moves in only 3 directions left right or down 
      // in the maze. 0 indicates left turn 1 indicates right turn and 
      // 2 indicates down movement in the maze. 
      int nextDir = r.nextInt(3); 
      switch (nextDir) { 
       case 0: // left turn 
        if (this.isValidTurn(row, (col - 1))) { 
         --col; 
         this.maze[row][col].setState("open"); 
        } 
        break; 
       case 1: // right turn 
        if (this.isValidTurn(row, (col + 1))) { 
         ++col; 
         this.maze[row][col].setState("open"); 
        } 
        break; 
       case 2: // down movement 
        ++row; 
        this.maze[row][col].setState("open"); 
        break; 
      } 
      System.out.println("turn : " + nextDir); 
      // System.out.println(this); 
     } 
     System.out.println(this); 
    } 
} 

class Cell { 
    int row; 
    int col; 
    int above, below, toLeft, toRight; 
    enum state {border, wall, open, travelled}; 
    state state; 

    public Cell(int row, int col){ 
     this.row = row; 
     this.col = col; 
     above = row + 1; 
     below = row -1; 
     toLeft = col -1; 
     toRight = col +1; 
    } 

    @Override 
    public String toString(){ 
     String out = new String(); 
     if (state == state.border) { 
      out = "0"; 
     } 
     if (state == state.wall) { 
      out = "#"; 
     } 
     if (state == state.open) { 
      out = "."; 
     } 
     if (state == state.open) { 
      out = "-"; 
     }  
     return out; 
    } 

    public void setState(String toSet){ 
     switch (toSet){ 
      case "border": 
       state = state.border; 
       break; 
      case "wall": 
       state = state.wall; 
       break; 
      case "open": 
       state = state.open; 
       break; 
      case "travelled": 
       state = state.travelled; 
       break; 
     } 
    } 

    public String getState() { 
     return state.toString(); 
    } 
} 

Но, как я уже сказал, я знаю, что класс лабиринта работает отлично, потому что он выводит на консоль прекрасно, когда Я запускаю его. Кроме того, инструкции println в классе MazeFrame показывают, что каждая ячейка регистрируется в соответствующем состоянии.

+0

Попробуйте переместить 'SetVisible (истина)', так что появляется в конце конструктора – MadProgrammer

+0

просто попыталась это, по-прежнему имеют те же проблемы ... – drewmoore

+0

Пожалуйста, ваши классы Maze и класс Cell тоже –

ответ

2

Смотрите комментарии в коде:

public class MazeFrame extends javax.swing.JFrame { 
    Maze m; 
    /** 
    * Creates new form MazeFrame 
    */ 
    public MazeFrame(Maze m) { 
     this.m = m; 
// Don't manually set the size of a frame. Let the preferred size of you components determine the size. 
// This is done by invoking pack() after all components have been added to the frame. 
//  setSize(new Dimension(800, 600)); 
     JPanel pan = new JPanel(); 
     add(pan); 
//  setVisible(true); // do after all components added. 
     // pan.setBackground(Color.yellow); 
     pan.setLayout(new GridLayout(m.width, m.height)); 

     for (int curr = 0; curr < m.height; curr++){ 
      for (Cell c: m.maze[curr]){ 
       JLabel lab = new JLabel(); 
       lab.setOpaque(true); // as suggested by MadProgrammer 
       switch (c.state){ 
        case border: 
         lab.setBackground(Color.black); 
         System.out.println("addedborder"); 
         break; 
        case wall: 
         lab.setBackground(Color.DARK_GRAY); 
         System.out.println("addedwall"); 
         break; 
        case open: 
         lab.setBackground(Color.LIGHT_GRAY); 
         System.out.println("addedopen"); 
         break; 
        case travelled: 
         lab.setBackground(Color.RED);    
       } 
// Set the preferred size so layout managers can do there job 
//    lab.setSize(new Dimension(50, 50)); 
       lab.setPreferredSize(new Dimension(50, 50)); 
// Not required. This is the default for all components except top level containers like JFrame, JDialog 
//    lab.setVisible(true);    
       pan.add(lab); 
       // System.out.println("added"); 
      } 
     } 
// No neeed to revalidate or repaint because the frame is not visible yet 
//  pan.revalidate(); 
//  pan.repaint(); 
     pack(); // let the layout manager determine the size of the frame 
     setVisible(); // show the frame 
    } 
} 

Примечание: Обычно вам не нужно устанавливать предпочтительный размер компонента, потому что каждый компонент имеет предпочтительный размер. Но в этом случае вы не добавляли текст или значок на ярлык, чтобы у него не было предпочтительного размера.

2

Как я знаю, что вы должны позвонить перепроверить/перекрашивать при добавлении компонентов в любой видимый контейнер, так что вы можете переместить SetVisible & добавление панели в кадр с последним утверждением:

// update panel 
pan.revalidate(); 
pan.repaint(); 

// adding panel to frame 
this.add(pan); 
this.pack(); 
this.setVisible(true); 

другой вещи вы не» т нужно вызвать JLabel.setVisible (истина), потому что его значение по умолчанию, а также изменить фон JLabel вам нужно добавить (потому что его прозрачны по умолчанию):

lab.setOpaque(true); 
+0

Я сделал все эти вещи (переместил revalidate/repaint на дно, добавил setOpaque (true), и все же у меня есть тот же результат – drewmoore

+0

убедитесь, что вы вызываете пакет() до setvisible. –

3

Я был в состоянии получить что-то работает (что если это правильно, другое материя)

enter image description here

В основном все, что я сделал (кроме перемещения setVisible до конца конструктора) был сделать lab непрозрачным ...

public TestMaze(Maze m) { 
    this.m = m; 
    setSize(new Dimension(800, 600)); 
    JPanel pan = new JPanel(); 
    add(pan); 
    pan.setLayout(new GridLayout(m.width, m.height)); 

    for (int curr = 0; curr < m.height; curr++) { 
     for (Cell c : m.maze[curr]) { 
      JLabel lab = new JLabel(); 
      lab.setOpaque(true); // <-- Add me... 
      switch (c.state) { 
       case border: 
        lab.setBackground(Color.black); 
        break; 
       case wall: 
        lab.setBackground(Color.DARK_GRAY); 
        break; 
       case open: 
        lab.setBackground(Color.LIGHT_GRAY); 
        break; 
       case travelled: 
        lab.setBackground(Color.RED); 
      } 
      lab.setSize(new Dimension(50, 50)); 
      lab.setVisible(true); 
      pan.add(lab); 
      // System.out.println("added"); 
     } 
    } 
    setVisible(true); 
} 
+0

+1 для setOpaque(). Я думаю, что все компоненты Swing (кроме JLabel и JComponent) по умолчанию непрозрачны, поэтому это исключение. – camickr

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