我怎样才能让我的cardLayout工作?

时间:2012-07-20 12:51:59

标签: java swing layout

我正在尝试开发一个LARP角色管理器,我在我的框架内,一个面板包含我想通过CardLayout交换的所有窗口。这是我的ContainerPane代码。

public class ContainerPane extends JPanel {
    private static final long serialVersionUID = -4799973935806714569L;
    private JPanel deckOfPanes = null;
    private PlayerManagerPane myPlayerManagerPane = null;
    private GameManagerPane myGameManagerPane= null;
    private CharacterManagerPane myCharacterManagerPane = null;

    final static String CHANGETOCHARACTERMANAGERPANE = "Character Manager";
    final static String CHANGETOPLAYERMANAGERPANE = "Player Manager";
    final static String CHANGETOGAMEMANAGERPANE = "Game Manager";

    public ContainerPane(EventListener myEventListener) {
        myPlayerManagerPane = new PlayerManagerPane(myEventListener);
        myGameManagerPane = new GameManagerPane(myEventListener);
        myCharacterManagerPane = new CharacterManagerPane(myEventListener);
        deckOfPanes= new JPanel(new CardLayout());
        deckOfPanes.add(myCharacterManagerPane,CHANGETOCHARACTERMANAGERPANE);
        deckOfPanes.add(myPlayerManagerPane,CHANGETOPLAYERMANAGERPANE);
        deckOfPanes.add(myGameManagerPane,CHANGETOGAMEMANAGERPANE);

        CardLayout cardLayout = (CardLayout) ((ContainerPane) this).getDeckOfPanes().getLayout();
        cardLayout.show(deckOfPanes,CHANGETOCHARACTERMANAGERPANE);
    }

public JPanel getDeckOfPanes() {
    return deckOfPanes;
}

首先,我想象构造函数的最后一行将确保在调用它时显示顶部的某张卡。

在我的代码的其他地方,我想使用菜单栏交换卡片。以下是我的EventHandler类的代码:

public void swapView(String key) {
    CardLayout cardLayout = (CardLayout) ((ContainerPane) myContainerPane).getDeckOfPanes().getLayout();
    cardLayout.show(myContainerPane.getDeckOfPanes(),key);
}

这也不起作用。我刚刚开始使用Java,我真的很感激任何帮助,我已经检查了教程和网络上的其他地方(包括堆栈溢出),从我看到的,它应该工作。请,任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:5)

您尚未将deckOfPanes添加到ContainerPane。添加:

    deckOfPanes = new JPanel(cardLayout);
    add(deckOfPanes); 
    // etc. 

答案 1 :(得分:1)

来源(我的新博客):http://goo.gl/SDHvX

我在SO上遇到过许多答案,建议开发人员使用CardLayout在视图或面板之间切换。我知道它有效并且不难实现,但我不相信CardLayout是最合适的方法。我为一个我正在调用ViewSwitcher的类编写了一个起点,它负责在JFrame内切换视图。如果你拿出评论,你会发现它实际上是一个非常小的类,它很容易使用。当请求的视图尚未注册时,可以随意添加try / catch块(即避免NullPointerException

您还可以考虑将onShow()onHide()方法添加到名为View的界面,并将Container的所有实例更改为View。这将允许将来扩展处理视图切换 - CardLayout可能无法提供的。

import java.awt.BorderLayout;  
import java.awt.Container;  
import java.util.HashMap;  
import javax.swing.JFrame;  

/**  
 * Used to switch views within a JFrame.  
 *  
 * @author FHMP  
 */    
public class ViewSwitcher {    

    /**  
     * Map to keep track of views according to their specified names  
     */    
    private HashMap<String, Container> views = new HashMap<>();    
    /**  
     * The host container that contains the views to be switched between  
     */    
    private Container host;    
    /**  
     * Used to keep track of the current view  
     */    
    private Container current;    

    /**  
     * Registers a view bound to a specified name  
     *   
     * @param name the name of the view  
     * @param view the view  
     */    
    public void registerView(Container view, String name) {    
        views.put(name, view);    
    }    

    /**  
     * Sets the host container that will contain the view 
     *   
     * @param host the host container  
     */    
    public void setHost(Container host) {    
        this.host = host;    
    }    

    /**  
     * Switches to the view bound to the specified name  
     *   
     * @param name the name of the view to switch to  
     */    
    public void switchTo(String name) {    
        Container view = views.get(name);    

        if(current != null){
           if(current == view) return;
           host.remove(current);   
        }  
        current = view;  

        host.add(view, BorderLayout.CENTER);    
        host.validate();    
        host.repaint(); // just to make sure      
    }    
}  

如果您需要,它很容易适应,并且切换非常有效。在我的一个应用程序中,我为每个视图使用常量字段,而不是通过将它们加载到地图中来动态注册每个视图。此示例仅用于演示删除/添加组件而不是使用CardLayout的想法。 您可以像这样使用它:

// JPanels a, b, c already initialised  
// JFrame frame is the main window  

ViewSwitcher switcher = new ViewSwitcher();  

switcher.setHost(frame);  

switcher.registerView(a, "menu");  
switcher.registerView(b, "main");  
switcher.registerView(c, "help");  

switcher.switchTo("help");  
switcher.switchTo("main");