Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
163 views
in Technique[技术] by (71.8m points)

java - paintComponent() Is Never Called

In the process of refining my program, I inevitably broke something. Before, my mazes were painting beautifully, but now paintComponent() is never called at all (according to a sys-out debug text). I've gotten other elements to change visibility just fine, but when the mazep's are set to visible, they never paint. Any help would be appreciated - I've likely just been staring at it too long to see the problem.

GUI.java

package com.whatever;

import javax.swing.*;

import com.whatever.models.Maze;

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

public class GUI extends JFrame {
    private static final long serialVersionUID = 1L;
    
    public GUI() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(1000, 500);
        
        JPanel startp = new JPanel();
        
        MazePanel mazep1 = new MazePanel();
        mazep1.setMaze(Maze.Maze1);
        add(mazep1);
        mazep1.setVisible(true);
        
        MazePanel mazep2 = new MazePanel();
        mazep2.setMaze(Maze.Maze2);
        add(mazep2, BorderLayout.CENTER);
        mazep2.setVisible(false);
        
        MazePanel mazep3 = new MazePanel();
        mazep3.setMaze(Maze.Maze3);
        add(mazep3, BorderLayout.CENTER);
        mazep3.setVisible(false);
        
        JMenuBar menuBar = new JMenuBar();  
        JMenuItem reset = new JMenuItem("Reset");
        JMenuItem back = new JMenuItem("Return");
        
        menuBar.add(reset);
        reset.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                System.out.println("Reset has been pushed!");
                mazep1.setMaze(Maze.Maze1);
                mazep2.setMaze(Maze.Maze2);
                mazep3.setMaze(Maze.Maze3);
            }
        });
        menuBar.add(Box.createHorizontalGlue());
        menuBar.add(back);
        back.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                System.out.println("Back to the main screen!");
                menuBar.setVisible(false);
                startp.setVisible(true);
                mazep1.setVisible(false);
                mazep2.setVisible(false);
                mazep3.setVisible(false);
            }
        });
        setJMenuBar(menuBar);
        menuBar.setVisible(false);

        startp.setLayout(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        Label title = new Label("Heaven & Earth");
        title.setAlignment(Label.CENTER);
        c.gridx = 0;
        c.gridy = 0;
        startp.add(title, c);
        JButton easy = new JButton("Easy");
        c.gridy = 1;
        startp.add(easy, c);
        easy.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                System.out.println("To the easy maze!");
                menuBar.setVisible(true);
                mazep1.setVisible(true);
                startp.setVisible(false);
                mazep2.setVisible(false);
                mazep3.setVisible(false);
            }
        });
        JButton medium = new JButton("Medium");
        c.gridy = 2;
        startp.add(medium, c);
        medium.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                System.out.println("To the medium maze!");
                menuBar.setVisible(true);
                mazep2.setVisible(true);
                startp.setVisible(false);
                mazep1.setVisible(false);
                mazep3.setVisible(false);
            }
        });
        JButton hard = new JButton("Hard");
        c.gridy = 3;
        startp.add(hard, c);
        hard.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                System.out.println("To the hard maze!");
                menuBar.setVisible(true);
                mazep3.setVisible(true);
                startp.setVisible(false);
                mazep1.setVisible(false);
                mazep2.setVisible(false);
            }
        });
        startp.setVisible(true);        
        add(startp);
        
        setVisible(true);
    }
}

class MazePanel extends JPanel {
    private static final long serialVersionUID = 1L;
    private static char[][] maze = null;
    private static int x1, y1, x2, y2 = 0;
    
    public void setMaze(char[][] maze) {
        String type = null;
        if (maze.equals(Maze.Maze1)) {
            type = "easy";
        } else if (maze.equals(Maze.Maze2)) {
            type = "medium";
        } else if (maze.equals(Maze.Maze3)) {
            type = "hard";
        }
        
        System.out.println("I've set the " + type + " maze!");
        this.maze = maze;
        boolean first = true;
        for(int i = 0; i < maze.length; i++) {
            for(int j = 0; j < maze[i].length; j++) {
                if(maze[i][j] == 's' && first) {
                    x1 = j;
                    y1 = i;
                    first = false;
                } else if(maze[i][j] == 's' && !first) {
                    x2 = j;
                    y2 = i;
                }
                if (maze[i][j] == 0) {
                }
                //System.out.print(maze[i][j] + " ");
            }
            //System.out.println();
        }
    }
    
    @Override
    public Dimension getPreferredSize() {
        return new Dimension(1000, 500);
    }
    
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        System.out.println("Painting now!");
        final int HOROFF = 250;
        final int VEROFF = 50; 
        for(int i = 0; i < maze.length; i++) {
            for(int j = 0; j < maze[i].length; j++) {
                if(maze[i][j] == 1) {
                    g.setColor(Color.BLACK);
                    g.fillRect(j * 25 + HOROFF, i * 25 + VEROFF, 25, 25);
                } else if((i == y1 && j == x1) || (i == y2 && j == x2)) {
                    g.setColor(Color.BLUE);
                    g.fillRect(j * 25 + HOROFF, i * 25 + VEROFF, 25, 25);
                } else if(maze[i][j] == 'e') {
                    g.setColor(Color.WHITE);
                    g.fillRect(j * 25 + HOROFF, i * 25 + VEROFF, 25, 25);
                }
            }
        }
        g.setColor(Color.BLACK);
        g.drawRect(HOROFF, VEROFF, maze[0].length * 25, maze.length * 25);
    }
}

Maze.java


import java.awt.Panel;

public class Maze extends Panel {
    
    private static final long serialVersionUID = 1L;
    
    public static char[][] Maze1 = {
            {0,0,0,0,0,0,0,'e',1,0,1,0,0,0,0,0,'e'},
            {0,1,0,1,1,1,1,0,1,0,1,0,1,1,1,1,1},
            {0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0},
            {0,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,0},
            {0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0},
            {0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1},
            {0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0},
            {0,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0},
            {0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0},
            {0,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,0},
            {0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0},
            {1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0},
            {'s',0,0,0,0,0,0,0,1,'s',0,0,0,0,0,0,0}
    };
    
    public static char[][] Maze2 = {
            {0,0,0,0,0,0,0,0,1,'e',1,0,0,0,0,0,0,0,0,0,'e'},
            {0,0,0,1,0,0,0,1,0,0,1,0,1,1,0,0,0,1,0,1,0},
            {0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0},
            {0,1,0,0,0,1,0,1,0,1,1,1,0,0,0,0,0,1,0,1,0},
            {0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0},
            {0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0},
            {0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0},
            {1,0,1,0,0,0,0,0,1,0,1,0,0,0,0,1,0,1,0,0,0},
            {0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0},
            {0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0},
            {'s',0,0,0,0,0,0,0,0,1,1,'s',0,0,1,0,0,0,0,0,0}
    };

    public static char[][] Maze3 = {
            {0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0},
            {0,1,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,1,0,0},
            {0,0,0,0,1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0},
            {0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,1,0,1,0},
            {1,0,0,0,0,1,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0},
            {1,0,0,1,0,0,0,1,0,'s',1,'s',1,0,0,0,0,1,1,0,1,0},
            {0,0,0,0,0,1,0,0,0,1,'e',0,'e',1,0,0,0,0,0,0,0,1},
            {0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0,0},
            {0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0},
            {1,0,0,1,0,0,0,1,0,0,0,0,1,0,1,0,0,1,0,0,0,0},
            {0,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,1,0},
            {1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0}
    };
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

JFrame is using a BorderLayout by default, this will only manage/layout the last component added to each available position - so, this means, the only component actually been laid out is the startp panel, all the other components are been left at the original size of 0x0 and Swing is smart enough not to paint components with no size.

A better solution would be to use a CardLayout is designed to do exactly what you're trying to do.

For example...

import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Label;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;

public class GUI extends JFrame {

    private static final long serialVersionUID = 1L;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new GUI();
                frame.pack();
                frame.setLocationByPlatform(true);
                frame.setVisible(true);
            }
        });
    }

    private CardLayout cardLayout = new CardLayout();

    public GUI() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(1000, 500);


        setLayout(cardLayout);

        JPanel startp = new JPanel();

        MazePanel mazep1 = new MazePanel();
        mazep1.setMaze(Maze.Maze1);
        add(mazep1, "easyMaze");

        MazePanel mazep2 = new MazePanel();
        mazep2.setMaze(Maze.Maze2);
        add(mazep2, "medMaze");

        MazePanel mazep3 = new MazePanel();
        mazep3.setMaze(Maze.Maze3);
        add(mazep3, "hardMaze");

        JMenuBar menuBar = new JMenuBar();
        JMenuItem reset = new JMenuItem("Reset");
        JMenuItem back = new JMenuItem("Return");

        menuBar.add(reset);
        reset.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                System.out.println("Reset has been pushed!");
                mazep1.setMaze(Maze.Maze1);
                mazep2.setMaze(Maze.Maze2);
                mazep3.setMaze(Maze.Maze3);
            }
        });
        menuBar.add(Box.createHorizontalGlue());
        menuBar.add(back);
        back.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                System.out.println("Back to the main screen!");
                cardLayout.show(getContentPane(), "startup");
                menuBar.setVisible(false);
            }
        });
        setJMenuBar(menuBar);
        menuBar.setVisible(false);

        startp.setLayout(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        Label title = new Label("Heaven & Earth");
        title.setAlignment(Label.CENTER);
        c.gridx = 0;
        c.gridy = 0;
        startp.add(title, c);
        JButton easy = new JButton("Easy");
        c.gridy = 1;
        startp.add(easy, c);
        easy.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                System.out.println("To the easy maze!");
                menuBar.setVisible(true);
                cardLayout.show(getContentPane(), "easyMaze");
            }
        });
        JButton medium = new JButton("Medium");
        c.gridy = 2;
        startp.add(medium, c);
        medium.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                System.out.println("To the medium maze!");
                cardLayout.show(getContentPane(), "medMaze");
                menuBar.setVisible(true);
            }
        });
        JButton hard = new JButton("Hard");
        c.gridy = 3;
        startp.add(hard, c);
        hard.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                System.out.println("To the hard maze!");
                cardLayout.show(getContentPane(), "hardMaze");
                menuBar.setVisible(true);
            }
        });
        add(startp, "startup");

        cardLayout.show(getContentPane(), "startup");

        //setVisible(true);
    }

    static class MazePanel extends JPanel {

        private final long serialVersionUID = 1L;
        private char[][] maze = null;
        private int x1, y1, x2, y2 = 0;

        public void setMaze(char[][] maze) {
            String type = null;
            if (maze.equals(Maze.Maze1)) {
                type = "easy";
            } else if (maze.equals(Maze.Maze2)) {
                type = "medium";
            } else if (maze.equals(Maze.Maze3)) {
                type = "hard";
            }

            System.out.println("I've set the " + type + " maze!");
            this.maze = maze;
            boolean first = true;
            for (int i = 0; i < maze.length; i++) {
                for (int j = 0; j < maze[i].length; j++) {
                    if (maze[i][j] == 's' && first) {
                        x1 = j;
                        y1 = i;
                        first = false;
                    } else if (maze[i][j] == 's' && !first) {
                        x2 = j;
                        y2 = i;
                    }
                    if (maze[i][j] == 0) {
                    }
                    //System.out.print(maze[i][j] + " ");
                }
                //System.out.println();
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(1000, 500);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            System.out.println("Painting now!");
            final int HOROFF = 250;
            final int VEROFF = 50;
            for (int i = 0; i < maze.length; i++) {
                for (int j = 0; j < maze[i].length; j++) {
                    if (maze[i][j] == 1) {
                        g.setColor(Color.BLACK);
                        g.fillRect(j * 25 + HOROFF, i * 25 + VEROFF, 25, 25);
                    } else if ((i == y1 && j == x1) || (i == y2 && j == x2)) {
                        g.setColor(Color.BLUE);
                        g.fillRect(j * 25 + HOROFF, i * 25 + VEROFF, 25, 25);
                    } else if (maze[i][j] == 'e') {
                        g.setColor(Color.WHITE);
                        g.fillRect(j * 25 + HOROFF, i * 25 + VEROFF, 25, 25);
                    }
                }
            }
            g.setColor(Color.BLACK);
            g.drawRect(HOROFF, VEROFF, maze[0].length * 25, maze.length * 25);
        }
    }

    public static class Maze {

        private static final long serialVersionUID = 1L;

        public static char[][] Maze1 = {
            {0, 0, 0, 0, 0, 0, 0, 'e', 1, 0, 1, 0, 0, 0, 0, 0, 'e'},
            {0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1},
            {0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
            {0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0},
            {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
            {0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1},
            {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
            {0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
            {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0},
            {0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0},
            {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
            {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
            {'s', 0, 0, 0, 0, 0, 0, 0, 1, 's', 0, 0, 0, 0, 0, 0, 0}
        };

        public static char[][] Maze2 = {
            {0, 0, 0, 0, 0, 0, 0, 0, 1, 'e', 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'e'},
            {0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0},
            {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
            {0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0},
            {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0},
            {0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0},
            {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0},
            {1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0},
            {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0},
            {0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
            {'s', 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 's', 0, 0, 1, 0, 0, 0, 0, 0, 0}
        };

        public static char[][] Maze3 = {
            {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
            {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0},
            {0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0},
            {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0},
            {1, 0, 0, 1, 0, 0, 0, 1, 0, 's', 1, 's', 1, 0, 0, 0, 0, 1, 1, 0, 1, 0},
            {0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 'e', 0, 'e', 1, 0, 0, 0, 0, 0, 0, 0, 1},
            {0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0},
            {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0},
            {1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0},
            {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0},
            {1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
        };
    }
}

Also, the use of static in the MazePanel is unadvisable, as it will mean that EVERY instance of MazePanel will have the same data


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
...