Search code examples
javaswingjlayeredpane

JLayeredPane display problems


I am working on a little card game and I have been having some trouble: when I try to add dynamic components to my JLayeredPane it does not display them.

I have a custom component that represents a card and I want to display 2 of them in a layered fashion. For that I have the following class:

public class PairView extends JPanel {

private JLayeredPane layeredPane;
private CardView attackCard;
private CardView defenceCard;
private static Point origin = new Point(0, 0);
private static int offset = 10;

public PairView() {
}

public PairView(Card attackCard) {

    setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));

    layeredPane = new JLayeredPane();
    layeredPane.setPreferredSize(new Dimension(120, 170));
    this.defenceCard = null;
    this.attackCard = new CardView(attackCard);


    this.attackCard.setOpaque(true);
    this.attackCard.setForeground(Color.black);
    this.attackCard.setBorder(BorderFactory.createLineBorder(Color.black));
    this.attackCard.setBounds(origin.x, origin.y, 100, 150);


    layeredPane.add(this.attackCard, 0);
    this.origin.x += offset;
    this.origin.y += offset;
}
public void addDefenceCard(Card defenceCard) throws DurakException {
    if (this.defenceCard == null) {
        this.defenceCard = new CardView(defenceCard);

        this.defenceCard.setOpaque(true);
        this.defenceCard.setForeground(Color.black);
        this.defenceCard.setBorder(BorderFactory.createLineBorder(Color.black));
        this.defenceCard.setBounds(origin.x, origin.y, 100, 150);
        layeredPane.add(this.defenceCard, 1);
    } else {
        throw new DurakException("A defence Card is already present");
    }

} 

I tested this via the drag and drop interface in NetBeans and I have the following problem:

  1. From what I understand, the default constructor is always called, so when I create 2 random CardView components and add them to the layered pane in the default constructor the parent JFrame display them just fine.
  2. If I use the overwritten constructor or try to add another component (like the addDefenceCard method) it does not display the added component.
  3. calling revalidate() or repaint() isn't doing anything.

How to get the components to show?


Solution

  • Your class extend JPanel, but you never add any components to the panel so there is nothing to display.

    You need to add the JLayeredPane to the panel:

    layeredPane = new JLayeredPane();
    this.add( layeredPane );
    

    I don't know if you need the set the layout to a BoxLayout. The default FlowLayout of the panel will respect the preferredSize of any component added to it.

    this.attackCard.setOpaque(true);
    this.attackCard.setForeground(Color.black);
    this.attackCard.setBorder(BorderFactory.createLineBorder(Color.black));
    

    You may want to consider setting these properties in the constructor of the CardView class. That way the default properties are set in one place and can easily be changed.

    Instead of using a layered pane you may want to consider using the Overlap Layout. It was designed to support the requirement of overlapping components.