Search code examples
javaswingjframejpaneljlabel

JLabel not going where I want it to go


I am making a game and have trouble with getting a JLabel to show in a particular placeenter image description here

I want the JLabel to be above the level panel. When I try to do what I think would work, it will show me a blank screen with the label but no level panel. Also, why won't my game redraw correctly when I drag the window?

Game

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.Timer;


public class Game {

    private Level l;
    private Player p;
    private ArrayList<Monster> m;
    private static JLabel status = new JLabel();
    private JLabel score = new JLabel();
    private static LevelPanel lp;
    private Timer timer;
    public Game()
    {
        l = new Level(this,4,11);
        p = new Player(this,1,1);
        m = new ArrayList<Monster>();
        Monster monster = new SimpleMonster(this,0,0,0,1);
        Monster m1 = new SimpleMonster(this);
        m.add(monster);
        m.add(m1);
        lp = new LevelPanel(this);
        status = new JLabel("null");
        lp.add(status);
        timer = new Timer(10, new TimerListener());
        timer.start();
    }


    public void win()
    {
        timer.stop();
        status.setText("Congrats you won!");
        System.out.println("You win!");
    }

    public void lose()
    {
        timer.stop();
        status.setText("Sorry you lose.");
//      System.out.println("Sorry");
    }

    public static void main(String[] args)
    {
        JFrame jframe = new JFrame();

        jframe.add(new LevelPanel(new Game()));
//      jframe.add(lp);
        jframe.getContentPane().add(lp);
//      jframe.getContentPane().add(status);
//      jframe.add(status);
        jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jframe.setPreferredSize(new Dimension(500, 500));   
        jframe.pack();
        jframe.setVisible(true);

    }

    private class TimerListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent ae) {
            // TODO Auto-generated method stub
//          panel.repaint();

            //update score and remainder
            for (Monster m : getMonsters())
            {
                m.update();
            }
            //call update() of all monsters
        }
    }
    public Level getLevel()
    {
        return l;
    }

    public Player getPlayer()
    {
        return p;
    }

    public ArrayList<Monster> getMonsters()
    {
        return m;
    }
}

My Level Panel

import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JPanel;


public class LevelPanel extends JPanel implements KeyListener{

    private Game game;
    public LevelPanel(Game game)
    {
        this.game = game;
        setFocusable(true);
        addKeyListener(this);

    }

    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        game.getLevel().draw(g);
        repaint();
    }
    @Override
    public void keyPressed(KeyEvent arg0) {

        if (arg0.getKeyCode() == KeyEvent.VK_UP)
        {
            game.getPlayer().move(-1, 0);
        }
        if (arg0.getKeyCode() == KeyEvent.VK_DOWN)
        {
            game.getPlayer().move(1, 0);
        }
        if (arg0.getKeyCode() == KeyEvent.VK_LEFT)
        {
            game.getPlayer().move(0, -1);
        }
        if (arg0.getKeyCode() == KeyEvent.VK_RIGHT)
        {
            game.getPlayer().move(0, 1);
        }
//      System.out.print(game.getLevel().getItemsLeft());
//      repaint();
    }
    @Override
    public void keyReleased(KeyEvent arg0) {
        // TODO Auto-generated method stub

    }
    @Override
    public void keyTyped(KeyEvent arg0) {
        // TODO Auto-generated method stub

    }

}

Solution

  • The problem is that you had simply added the JPanel and JLabel using add() so they will just go wherever the default is. If you want to position them in a certain alignment you need to use a layout manager. The simplest one to use is BorderLayout, but if you want full control you should use GridBagLayout. Using GridBag you can set constaints for each individual Component. To understand GridBagLayout and save you time in the long run I suggest you look up Constraints and Insets as well as GridBagLayout.