简体   繁体   中英

Java OverlayLayout items arrangement issue

I have an issue with placing objects inside JPanel which has OverlayLayout as layout. I am creating card game and what I want is to have a story of dropped cards on the table. For instance, I would like to have 10 or 12 cards on board, displayed in the order in which they were placed and with overlapping effect. Here is the following example of what I want to achieve:

在此处输入图像描述

With the current code of adding cards to board, when I am adding max 10 cards it looks like:

在此处输入图像描述

You can see figures of cards are obscured which makes it difficult to read card figure. The card images I am adding to board are object of custom class which extends JPanels with BufferedImage object inside:

@SuppressWarnings("serial")
class CardImage extends JPanel
{
    private BufferedImage cardImage;
    private Card card;
    private int index;
    private boolean empty;

    public CardImage(Card _card, boolean clickableCard, Color areaColor, String imagePath)
    {
        if (!imagePath.isEmpty()) {
            try {
                cardImage = ImageIO.read(new File("<path>" + imagePath));
            } catch (IOException e) {
                e.printStackTrace();
            }
            empty = false;
        } else {
            empty = true;
        }
        setSize(71, 96);
        setPreferredSize(new Dimension(71, 96));
        setBorder(null);
        if (clickableCard) {
            setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
        }
        setBackground(areaColor);
        card = _card;
        index = 0;
    }

    public void setIndex(int cardIndex)
    {
        index = cardIndex;
    }

    public int getIndex()
    {
        return index;
    }

    public Card getCard()
    {
        return card;
    }

    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        if (!empty) {
            g.drawImage(cardImage, 0, 0, cardImage.getWidth(), cardImage.getHeight(), this);
        }
    }
}

Note: I know this looks ugly I will correct that later.

I need to add empty black cards as initial to fill history card stack because when I am adding cards one by one, when no previous cards was added it puts cards in wrong place. I am using setAlignmentX () function to adjust cards position in X-axis. For adding 10 cards I am setting alignment X to every 0.1 First card has 0.0, second 0.1, third 0.2, ... When adding cards to empty panel card container it moves cards already placed. When adding first card (alignment X set to 0.0) and no other cards was added initially it looks like:

在此处输入图像描述

And after that when adding new card (with alignment 0.1) it moves all cards to the right:

在此处输入图像描述

After adding third card (with alignment 0.3) it moves all cards to the right again:

在此处输入图像描述

So this is why I need to initially add 10 or 5 black cards to make it looking like cards are added on center of card containing panel instead from left. The code for adding initial cards is following:

boardCardPanel.setMaximumSize(boardCardPanel.getSize());
for (int i = 0; i < 6; i++) {
    CardImage ci;
    ci = new CardImage(Card.CARD_10_CLUB, false, Color.black, "");
    ci.setMaximumSize(ci.getSize());
    ci.setAlignmentX(alignmentX);
    ci.setAlignmentY(0.5f);
    boardCardPanel.add(ci);
    alignmentX += 0.1;
}
boardCardPanel.repaint();
boardCardPanel.setVisible(true);


setVisible(true);
alignmentX = 0f;

and the code for adding one card is:

private void putCard()
{
    alignmentX = 0.0f;
    try {
        CardImage ci = new CardImage(Card.CARD_10_CLUB, false, Color.BLACK, "\\c"+(cardIndex+2)+".gif");
        ci.setMaximumSize(ci.getSize());
        boardCardPanel.add(ci, 0);
        for (int i = 0; i < boardCardPanel.getComponentCount(); i++) {
            ((CardImage)boardCardPanel.getComponent(i)).setAlignmentX(alignmentX);
            ((CardImage)boardCardPanel.getComponent(i)).setAlignmentY(0.5f);
            alignmentX += 0.2f;
        }
        if (boardCardPanel.getComponentCount() > 6) {
            boardCardPanel.remove(boardCardPanel.getComponentCount()-1);
        }
        System.out.println(boardCardPanel.getComponentCount());
        cardIndex = (cardIndex + 1) % 9;
        boardCardPanel.repaint();
        boardCardPanel.setVisible(true);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

So the question is how to make card history with overlapping images and adjust the overlapping indent in panel and make card history in center?

how to make card history with overlapping images and adjust the overlapping indent in panel and make card history in center?

That is two different questions, so you need two solutions.

make card history in center

The way to approach this is to nest panels, each with different layout managers to achieve the centering effect.

The easiest way to do this is to have the wrapper panel with a GridBagLayout :

JPanel cardPanel = new CardPanel( some layout manager );
cardPanel.add(...);

JPanel wrapper = new JPanel( new GridBagLayout() );
wrapper.add(cardPanel, new GridBagConstraints());

frame.add(wrapper, BorderLayout.CENTER);

Now the components added to the cardPanel will be dynamically centered in the frame as the frame size changes.

make card history with overlapping images and adjust the overlapping indent

The default layout managers of the JDK don't support overlapping easily. The OverlayLayout does not give you very much control over component placement.

Instead check out the Overlap Layout which was specifically designed for this type of layout.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM