【问题标题】:How to get the top card in Java's CardLayout如何在 Java 的 CardLayout 中获得最上面的卡片
【发布时间】:2011-05-23 17:33:08
【问题描述】:

是否可以在 Java 的 CardLayout 中获得最上面的卡片? 我尝试遍历每个组件以使用 isVisible() 检查可见性,但似乎它们都是“可见的”。

编辑:“顶部卡片”是指当前位于“顶部”、正在显示的卡片,而不是第一张或最后一张卡片。另外,我不知道它是否有帮助,但我正在寻找 JPanel(或其子类)

编辑:代码 sn -p

for (Component component : getComponents()) {
 if (component instanceof JPanel && component.isVisible()) {
  currentPanel = (JPanel) component;
  System.out.println(currentPanel.getClass().getName());
 }
}  

上面的代码总是打印出每个组件类的名字,不管它们是不是可见卡片。

编辑:我将其用作学校作业的一部分。我不是想在这里获得免费赠品,任务并不围绕这个布局。它似乎是在面板之间切换的最方便的布局。我的老师已经指定项目中没有第三方代码。我之前已经从 camickr 的链接中看到了实现,但我不能使用它。我可以松散地实现类似的功能,也许在文档中给出参考,但我不能简单地下载和使用它。

编辑:我试图获得顶部卡片的原因是因为我有一个带有“添加”按钮的工具栏。我不想为我的两个可能的事情中的每一个都设置一个添加按钮,而是希望它通过查看当前正在查看的面板来知道要添加哪个。如果有其他更合适的方法可以做到这一点,请告诉我。

编辑:感谢大家的帮助。我弄清楚了问题所在。我想这是我的错,因为我没有提供足够的细节。我的两张卡片是JScrollPanes,我还需要查看其中的内容,以确定其中一个面板是否是我所看到的。我没有在滚动窗格本身上检查isVisible(),我一直在查看它始终可见的主张,我需要验证滚动窗格的可见性。

public JPanel getCurrentPanel() {
        JPanel currentPanel = null;

        for (Component component : getComponents()) {
            if (component.isVisible()) {
                if (component instanceof JPanel) 
                    currentPanel = (JPanel) component;
                else if (component instanceof JScrollPane)
                    currentPanel = (JPanel) ((JScrollPane) component).getViewport().getComponent(0);
            }
        }

        return currentPanel;
    }

【问题讨论】:

    标签: java layout user-interface awt cardlayout


    【解决方案1】:

    如果您修改添加到问题中的代码 sn-p,您可以轻松判断哪张卡可见。在我的测试框架中,当按下按钮时,它会打印出当前可见卡片的名称,然后再翻转到下一张卡片。修改您的代码,要记住的重要一点是您需要在实际具有 CardLayout 的组件上调用 getComponents()。这样,只有一个子节点可见。我猜在您的代码中,您在包含您的 JPanel 和 CardLayout 的框架上调用 getComponents。

    class TestFrame
            extends JFrame
            implements ActionListener
    {
        public TestFrame()
        {
            cards = new JPanel(new CardLayout() );
            card_list = new JPanel[5];
    
            for (int i = 0; i < card_list.length; i++) {
                String text = "Card " + i;
                JPanel card = createCard(text);
                card_list[i] = card;
                cards.add(card, text);
            }
    
            add(cards);
        }
    
    public JPanel getCurrentCard()
    {
        JPanel card = null;
    
        for (Component comp : cards.getComponents() ) {
            if (comp.isVisible() == true) {
                card = (JPanel)comp;
                System.out.println(card.getName() );
            }
        }
        System.out.println();
    
        return card;
    }
    
    public void actionPerformed(ActionEvent evt)
    {
        JPanel card = getCurrentCard();
    
        CardLayout cl = (CardLayout)(cards.getLayout() );
        cl.next(cards);
    }
    
        public JPanel createCard(String text)
        {
            JPanel card = new JPanel();
            card.setName(text);
    
            JButton btn = new JButton(text);
            btn.addActionListener(this);
    
            card.add(btn);
            return card;
        }
    
        JPanel cards;
        JPanel[] card_list;
    }
    

    在 actionPerformed() 方法中,我打印了卡片的名称,但您有对当前可见卡片的引用。

    【讨论】:

    • @RD,代码 sn-p 来自尝试使用 CardLayout 的 JPanel 中的 getCurrentPanel() 方法。由于其他原因,我扩展了 JPanel,所以我可以访问它。
    • 好吧,没有看到你所有的代码,我无法告诉你出了什么问题,但我可以告诉你,我的 TestFrame 代码一次只能正确找到一张可见的卡片。
    • @alexcoco,已编辑将相关代码放入 getCurrentCard() 方法中。
    • @RD,是的,当然,它确实有效,我相信我已经找到了问题所在。正在测试,即将更新。
    • @RD,更新了我遇到的问题。感谢您的示例代码,它运行良好(只需要打包和 setVisible)。
    【解决方案2】:

    我扩展了 CardLayout 以提供这种类型的功能。见Card Layout Focus

    编辑:

    然后遍历组件以查找 ZOrder 为 0 的组件。这是在顶部绘制的组件。实际上,您甚至不必遍历所有组件,只需获取位置 0 的组件即可。查看我关于重叠布局的博客,了解有关 ZOrder 工作原理的更详细说明。

    Component visibleComponent = panelWithCardLayout.getComponent(0);
    

    编辑2:

    上面的编辑是错误的。 ZOrder 与 CardLayout 一起使用时没有任何意义。所以你不能简单地获取组件 0。

    【讨论】:

    • 是的,我以前见过这个。但我不能那样做。我会在一秒钟内用解释更新问题。
    • hmm,getComponent(0) 似乎给了我添加到布局中的第一个,而不是顶部。当组件发生变化时,我认为面板不会像在 OverlapLayout 中那样管理 ZOrder。
    • 是的,你是对的。 ZOrder 在使用 CardLayout 时没有任何意义。您需要循环查找可见面板,如 RD1 发布的已接受答案所示。
    【解决方案3】:

    CardLayout.first() 的实现中,应该设置顶部卡片可见,您有以下内容:

    int ncomponents = parent.getComponentCount();
    for (int i = 0 ; i < ncomponents ; i++) {
        Component comp = parent.getComponent(i);
        if (comp.isVisible()) {
            comp.setVisible(false);     // hide previously visible components
            break;
        }
    }
    
    if (ncomponents > 0) {
        currentCard = 0;
        parent.getComponent(0).setVisible(true);   // set visibility of component 0
        parent.validate();
    }
    

    所以我想你可以通过yourContainer.getComponent(0) 获得“顶牌”。

    【讨论】:

    • 啊。我的错。看起来您应该能够遍历组件并查找 isVisible 一个...您确定这不起作用吗??
    • 是的,循环遍历它们并打印值总是让我留下最后一张卡片,即使可见卡片已经改变。稍后我会用 sn-p 更新。
    【解决方案4】:

    您可以设置根据卡片可见性而变化的变量

    例如

    int cardShow;
    

    然后你设置你的卡可见

    cards.show(card1, "card1");
    cardShow = 1;
    

    当您尝试获取可见的卡片时,只需使用

    if (cardShow == 1)
    //code in case of card1 is visible
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-01
      • 2011-07-14
      • 1970-01-01
      • 2016-09-03
      • 1970-01-01
      • 2011-09-24
      • 2014-05-19
      • 1970-01-01
      相关资源
      最近更新 更多