1

我正在尝试开发一个 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,非常感谢您对此提供的任何帮助,我已经检查了教程和网络上的其他地方(包括堆栈溢出),据我所知,它应该可以工作。请,任何帮助将不胜感激。

4

2 回答 2

5

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

    deckOfPanes = new JPanel(cardLayout);
    add(deckOfPanes); 
    // etc. 
于 2012-07-20T13:25:40.083 回答
1

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

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

您还可以考虑向名为 View 的接口添加onShow()onHide()方法,并将所有实例更改为Containerto 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");  
于 2012-07-21T01:04:20.660 回答