java - JPanel 上的元素未出现

标签 java swing

我对使用 swing 进行 GUI 编程还很陌生,并且遇到了我确信是菜鸟的问题。

我创建了一个 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();
    }
}

但是,正如我所说,我知道迷宫类工作正常,因为它在我运行时完美地输出到控制台。此外,MazeFrame 类中的 println 语句显示每个单元格都在注册其各自的状态。

最佳答案

查看代码中的注释:

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
    }
}

注意:通常您甚至不需要设置组件的首选大小,因为每个组件都有一个首选大小。但在这种情况下,您没有向标签添加文本或图标,因此它没有首选大小。

关于java - JPanel 上的元素未出现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14785692/

相关文章:

java - for each loops as streams in Java8 - k-means

java - 将 Maven 依赖项转移到 Ant

java - 如何在java中实现可访问性

java - 在 Netbeans GUI 中覆盖 paintComponent

java - 如何修复 SOAPUI 中不受支持的 major.minor 版本 52.0

java - 使用 Google App Engine 进行全文搜索

java - 当我们在 Eclips 中单击 "Run on Server"选项时,tomcat 在浏览器中打开主页(Ex :Index. jsp)的步骤是什么

java - 从 JTextField 创建 'BufferedReader'

java - JPanel画线时如何添加背景网格?

java - 将输入格式化程序和密码特征与 swing 一起使用