Tom Tresansky
Tom Tresansky

Reputation: 19892

CardLayouts: How can I tell which card is visible?

I've been looking through the documentation for the Swing CardLayout and there doesn't appear to be any way to determine which card is currently showing baked in to the class. Yet there must be a way to ask the layout which card it is currently showing, right?

Due to project constraints, I can't simply extend it and add this functionality to a sub-class, so if there isn't such a function does that mean I'm stuck tracking the component's state external to the component (yuck!), or is there some other option buried somewhere deep in Swing?

Upvotes: 7

Views: 3628

Answers (4)

TheRealKernel
TheRealKernel

Reputation: 351

The selected answer here gives the first component added to the CardLayout and I don't think that's what the user is asking. There is a simple way to find the visible panel by iterating the CardLayout's components via:

for(Component comp : cardPanel.getComponents()) {
    if (comp.isVisible()) {
        return (JPanel)comp;
    }
}

Putting this in a method returning a Component

Component getVisibleCard() { ... }

Would allow you to get the Component that is currently showing.

Upvotes: 0

mKorbel
mKorbel

Reputation: 109813

basic tutorial descibed how to switch betweens cards in CardLayout, lots of examples about CardLayout the best are here or here

from link that I posted here How to get the top card in Java's CardLayout

or better way

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;

public class CardlayoutTest extends JFrame {

    private static final long serialVersionUID = 1L;
    public CardLayout card = new CardLayout();

    public CardlayoutTest() {
        EventHandler eventHandle = new EventHandler();
        JPanel pnlA = new JPanel(new BorderLayout());
        pnlA.add(new JButton("A"), BorderLayout.CENTER);
        JPanel pnlB = new JPanel(new BorderLayout());
        pnlB.add(new JButton("B"), BorderLayout.CENTER);
        pnlA.addAncestorListener(eventHandle);
        pnlA.addHierarchyListener(eventHandle);
        pnlB.addAncestorListener(eventHandle);
        pnlB.addHierarchyListener(eventHandle);
        setLayout(card);
        add(pnlA, "A");
        add(pnlB, "B");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    class EventHandler implements AncestorListener, HierarchyListener {

        @Override
        public void ancestorAdded(AncestorEvent event) {
            System.out.println("CardlayoutTest.EventHandler.ancestorAdded()");
        }

        @Override
        public void ancestorMoved(AncestorEvent event) {
            System.out.println("CardlayoutTest.EventHandler.ancestorMoved()");
        }

        @Override
        public void ancestorRemoved(AncestorEvent event) {
            System.out.println("CardlayoutTest.EventHandler.ancestorRemoved()");
        }

        @Override
        public void hierarchyChanged(HierarchyEvent e) {
            System.out.println("CardlayoutTest.EventHandler.hierarchyChanged()");
        }
    }

    public static void main(String[] args) {
        CardlayoutTest t = new CardlayoutTest();
        t.setSize(500, 500);
        System.out.println("CardlayoutTest.main()------------------------ FIRST");
        t.card.show(t.getContentPane(), "A");
        t.setVisible(true);
        System.out.print("\n");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
        }
        System.out.println("CardlayoutTest.main()------------------------ SECOND");
        t.card.show(t.getContentPane(), "B");
        System.out.print("\n");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
        }
        System.out.println("CardlayoutTest.main()------------------------ THIRD");
        t.card.show(t.getContentPane(), "B");
        System.out.print("\n");
    }
}

Upvotes: 2

mre
mre

Reputation: 44240

According to the How to Use CardLayout tutorial,

Conceptually, each component that a CardLayout manages is like a playing card or trading card in a stack, where only the top card is visible at any time. You can choose the card that is showing in any of the following ways:

  • By asking for either the first or last card, in the order it was added to the container
  • By flipping through the deck backwards or forwards
  • By specifying a card with a specific name

Try,

Component visibleComponent = foo.getComponent(0);

where foo is the JPanel instance using CardLayout.

Reference:

Upvotes: 5

toto2
toto2

Reputation: 5326

It does seem that there is no direct way to know which card is active. My guess is that it's a design decision, not a mistake. You are responsible of keeping track of the active card.

However, I don't quite see why you would need to keep track of it. Swing is event based and you pretty much know which card is active when you get some event.

Upvotes: 3

Related Questions