Panel in a panel display in java

161 Views Asked by At

MASSIVE EDIT: I added more descritpion and code.

I recently encounter a problem where a panel that I added to another panel won't display properly (only display a black dot instead of the image). The flow of the code is: the Menu class has a button panel. When the button start is press, the Menu remove the button panel, create a Board object(that implement panel) and add it to Menu. In Board constructor, an image is loaded (a .png), then a PlayerPanel (that implement panel) is added to the board panel. In PlayerPanl constructor, an image is loaded. The plan is to make the menu repaint() method able to call Board paintcomponent. Board will then ask PlayerPanel to paintComponent. PlayerPanel paint his image, Board paint his image and that's it, both image should display.

public class Menu extends JFrame implements ActionListener
    {
        Board theBoard;
        JPanel pnlButton = new JPanel();
        JButton btnStart = new Jbutton("Start");

        public Menu(String s) 
            { 
        pnlButton.add(btnStart);
        super.add(pnlButton);
        super.setLocation(0,0);
                super.setSize(600, 500); 
                super.setResizable(false);
                super.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }
        @Override
        public void actionPerformed(ActionEvent evt) 
        { 
                if(evt.getSource() == btnStart)
                { 
                    theBoard = new Board ("TestBoard");
                    super.remove(pnlButton);  
                    super.add(theBoard);
                    super.repaint();
                }
        }
}

public class Board extends JPanel
{
    BufferedImage boardImage;
    PlayerPanel playerPanel;
    public Board (String boardName)
        {
            boardImage = Tools.loadImage(boardName);
                playerPanel = new PlayerPanel();
                this.add(playerPanel);
    }

    @Override 
        public void paintComponent(Graphics g) 
        {
                g.drawImage(boardImage, 0, 200, null);
        }
}

public class PlayerPanel extends JPanel
{
        BufferedImage playerImage;

    public PlayerPanel()
        {
                playerImage = Tools.loadImage("TestPlayer");
        }

        @Override 
        public void paintComponent(Graphics g) 
        {
                g.drawImage(playerImage, 0, 0, null);
        }
}

Both image load successfully as tested, but when the repaint() is call from the JFrame holding the Board panel, only the image in Board is painted, and the image in PlayerPanel is replace with a black dot.

Any help? Thanks!

1

There are 1 best solutions below

0
On

Your problem seems to be due to the size of your PlayerPanel JPanel. Sometimes it helps to debug things by testing to see what size things are when they're rendered. For instance, if you change your Board paintComponent method to this:

@Override
public void paintComponent(Graphics g) {
  super.paintComponent(g);
  if (boardImage != null) {
     g.drawImage(boardImage, 0, 200, null);
  }

  System.out.printf("Board size: [%d, %d]%n", getWidth(), getHeight());
  System.out.printf("Player size: [%d, %d]%n", playerPanel.getWidth(), playerPanel.getHeight());
}

it will tell you exactly what the sizes are of itself and its constituent playerPanel.

To solve the issue, you could give Board a layout manager that expands its constituent components such as a BorderLayout. Another possible solution is to give PlayerPanel its own getPreferredSize() method override, especially if you want it to size itself to its image. e.g.,

@Override
public void paintComponent(Graphics g) {
   super.paintComponent(g);
   if (playerImage != null) {
      g.drawImage(playerImage, 0, 0, null);
   }
}

Alternatively, you could use a JLabel that holds an ImageIcon rather than draw in the JPanel.

Note, you should swap views with a CardLayout rather than calling remove(...), add(...), revalidate(), repaint()