【发布时间】:2017-12-19 10:15:01
【问题描述】:
我一直在查看 Swing CardLayout 的文档,但似乎没有任何方法可以确定当前显示哪个卡已嵌入到课程中。然而,必须有一种方法可以询问布局它当前显示的是哪张卡片,对吧?
由于项目限制,我不能简单地扩展它并将此功能添加到子类中,所以如果没有这样的功能,是否意味着我无法跟踪组件外部的组件状态(哎呀!),或者在 Swing 的某个地方深处还有其他选择吗?
【问题讨论】:
我一直在查看 Swing CardLayout 的文档,但似乎没有任何方法可以确定当前显示哪个卡已嵌入到课程中。然而,必须有一种方法可以询问布局它当前显示的是哪张卡片,对吧?
由于项目限制,我不能简单地扩展它并将此功能添加到子类中,所以如果没有这样的功能,是否意味着我无法跟踪组件外部的组件状态(哎呀!),或者在 Swing 的某个地方深处还有其他选择吗?
【问题讨论】:
从概念上讲,CardLayout 管理的每个组件就像一个 扑克牌或交易牌堆叠,只有最上面的牌是 随时可见。您可以选择显示在任何 有以下几种方式:
按顺序询问第一张或最后一张卡片 它被添加到容器中通过向后或向前翻转甲板通过指定具有特定名称的卡
试试,
Component visibleComponent = foo.getComponent(0);
其中foo 是使用CardLayout 的JPanel 实例。
参考:
【讨论】:
似乎没有直接的方法可以知道哪张卡处于活动状态。我的猜测是这是一个设计决定,而不是一个错误。您有责任跟踪活动卡。
但是,我不太明白您为什么需要跟踪它。 Swing 是基于事件的,当您获得某些事件时,您几乎可以知道哪张卡处于活动状态。
【讨论】:
基本教程描述了如何在cards in CardLayout之间切换,很多关于CardLayout的例子the best are here或here
来自我在这里发布的链接How to get the top card in Java's CardLayout
或者更好的方法
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");
}
}
【讨论】:
此处选择的答案给出了添加到 CardLayout 的第一个组件,我认为这不是用户要问的。有一种简单的方法可以通过以下方式迭代 CardLayout 的组件来找到可见面板:
for(Component comp : cardPanel.getComponents()) {
if (comp.isVisible()) {
return (JPanel)comp;
}
}
将其放入返回组件的方法中
Component getVisibleCard() { ... }
将允许您获取当前显示的组件。
【讨论】: