Jlennon321
Jlennon321

Reputation: 228

JPanel appears in two locations

I am designing a grid-based game which uses the Java swing framework. I have a JFrame with two JPanel within it, but one of them appears in two places. Here is a screenshot: enter image description here

The panel that says "Turn 1" and has the buttons is only supposed to appear to the right of the grid, but it strangely also appears in the upper-left hand corner. Here is my code:

public class ArenaPanel extends JPanel {

    private final GridPanel gp;
    private final InfoPanel ip;
    private GameManager gm;
    private int w, h;
    private int cw, ch;
    private double tw, th;
    private Point p2;
    private Point p1;
    private int shotWidth;
    private Color shotColor;

    public ArenaPanel(int w, int h) {
        Images.load();
        setLayout(new GridBagLayout());
        this.w = w;
        this.h = h;
        GridBagConstraints c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 1;
        c.weightx = 0;
        c.weighty = 1;
        gp = new GridPanel();
        gp.setPreferredSize(new Dimension(700, 700));
        this.add(gp, c);
        c.gridx = 1;
        c.weightx = c.weighty = 0;
        ip = new InfoPanel();
        add(ip, c);
    }

    public void setGameManager(GameManager g) {
        gm = g;
    }

    public void start() {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                gm.start();
            }
        });
        t.start();
    }

    public void step() {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                gm.doTurn();
            }
        });
        t.start();
    }

    public void paint(Graphics g) {
        g.setColor(Color.black);
        int val = Math.min(getWidth() - 200, getHeight());
        gp.setPreferredSize(new Dimension(val, val));
        gp.revalidate();
        g.fillRect(0, 0, getWidth(), getHeight());
        paintComponents(g);
    }

    private class GridPanel extends JPanel {

        public void paint(Graphics g) {
            cw = getWidth();
            ch = getHeight();
            g.setColor(Color.gray);
            g.fillRect(0, 0, cw, ch);
            tw = (double) cw / w;
            th = (double) ch / h;
            g.setColor(Color.black);
            for (int i = 0; i < w; i++) {
                g.drawLine((int) (i * tw), 0, (int) (i * tw), ch);
            }
            for (int i = 0; i < h; i++) {
                g.drawLine(0, (int) (i * th), cw, (int) (i * th));
            }
            for (int i = 0; i < w; i++) {
                for (int j = 0; j < h; j++) {
                    Robot t = gm.getGrid()[i][j];
                    if (t != null) {
                        Point p = expand(i, j);
                        g.drawImage(t.getImage(), p.x + t.getOffsetX(),
                                p.y + t.getOffsetY(), (int) tw, (int) th, null);
                    }
                }
            }
            if (p1 != null) {
                Graphics2D g2 = (Graphics2D) g;
                g2.setColor(shotColor);
                g2.setStroke(new BasicStroke(shotWidth));
                g2.drawLine(p1.x, p1.y, p2.x, p2.y);
                p1 = null;
                p2 = null;
            }
        }
    }

    private class InfoPanel extends JPanel implements ActionListener {

        private JButton start, stop, step;
        private JLabel turns;
        private int numTurns = 0;
        private GridBagConstraints gbc;
        private ArrayList<TeamPanel> tpanels;

        public InfoPanel() {
            JPanel buttons = new JPanel();
            setLayout(new GridBagLayout());
            buttons.setLayout(new GridBagLayout());
            gbc = new GridBagConstraints();
            start = new JButton("Start");
            gbc.gridy = 0;
            gbc.gridx = 1;
            turns = new JLabel("Turn 1");
            buttons.add(turns, gbc);
            start.addActionListener(this);
            gbc.gridy = 1;
            gbc.gridx = 0;
            buttons.add(start, gbc);
            step = new JButton("Step");
            step.addActionListener(this);
            gbc.gridx++;
            buttons.add(step, gbc);
            stop = new JButton("Stop");
            stop.addActionListener(this);
            gbc.gridx++;
            buttons.add(stop, gbc);
            gbc.gridx = 0;
            gbc.gridy = 0;
            add(buttons, gbc);
            tpanels = new ArrayList<TeamPanel>();
        }

        @Override
        public void actionPerformed(ActionEvent actionEvent) {
            if (actionEvent.getSource() == start) {
                start();
            } else if (actionEvent.getSource() == stop) {
                gm.stop();
            } else if (actionEvent.getSource() == step) {
                step();
            }
        }

        public void incrementTurn() {
            numTurns++;
            turns.setText("Turn " + numTurns);
        }

        public void initializeTeams(Map<String, TeamInfo> m) {
            Set<String> k = m.keySet();
            for (TeamPanel tp : tpanels) {
                this.remove(tp);
            }
            tpanels.clear();
            gbc.gridy = 1;
            for (String s : k) {
                TeamPanel tp = new TeamPanel(m.get(s));
                add(tp, gbc);
                gbc.gridy++;
                tpanels.add(tp);
            }
            this.revalidate();
        }
    }

    private class TeamPanel extends JPanel {
        private Color col;
        private int score;
        private JLabel scoreLabel;
        private TeamInfo inf;

        public TeamPanel(TeamInfo inf) {
            this.inf = inf;
            col = getColor(inf.c);
            super.setLayout(new FlowLayout());
            BufferedImage ico = new BufferedImage(20, 20, BufferedImage.TYPE_3BYTE_BGR);
            Graphics g = ico.getGraphics();
            g.setColor(col);
            g.fillRect(0, 0, 20, 20);
            add(new JLabel(new ImageIcon(ico)));
            this.add(new JLabel(inf.team));
            scoreLabel = new JLabel("" + inf.score);
            add(scoreLabel);
        }

        public void paint(Graphics g) {
            //g.setColor(col);
            //g.fillRect(-5, 0, 10, 10);
            scoreLabel.setText("Score: " + inf.score);
            this.paintComponents(g);
        }
    }

    public void initializeTeams(Map<String, TeamInfo> m) {
        ip.initializeTeams(m);
    }
}

I have looked on google and StackOverflow for a similar problem, but I was unable to find one. Any help would be greatly appreciated.

Thanks!

Upvotes: 1

Views: 73

Answers (1)

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285403

  • Don't override the paint(...) method
  • Override the JPanel's paintComponent(...) method instead.
  • Don't forget to call the super paintComponent(...) method within your override.
  • And never call the super's paintComponents(...) (note the trailing "s") from within either the paint or paintComponent method. This smells like it could be the cause of your problem.

Upvotes: 5

Related Questions