2012-07-20 31 views
1

我正在嘗試開發一個LARP角色管理器,並且在我的框架內部有一個面板來包含我想要使用CardLayout交換的所有窗口。這是我的ContainerPane代碼。如何讓我的cardLayout工作?

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,我非常感謝這方面的幫助,我已經檢查了教程和Web上的其他地方(包括堆棧溢出),並且從我可以看到的情況來看,它應該可行。請,任何幫助,將不勝感激。

回答

5

您尚未將deckOfPanes添加到您的ContainerPane。地址:

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

第一個窗格現在可以工作,但我仍然無法獲取菜單來更改窗格。這是一個單獨的問題? – Pureferret 2012-07-20 16:20:28

+0

@ Pureferret:爲此你必須顯示你用於'MenuItem'的代碼...... – 2012-07-20 16:37:25

+1

這是一個單獨的問題。您尚未發佈任何與您的菜單調用交換相關的代碼。 – Reimeus 2012-07-20 16:38:20

1

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

我遇到很多答案的SO這表明開發人員應該使用CardLayout到的意見或面板之間切換。我知道它的工作原理並不難實現,但我不認爲CardLayout是最合適的方法。我寫了一個我叫ViewSwitcher的課程的起點,該課程負責在JFrame內切換視圖。如果你拿出評論,你會發現它實際上是一個非常小的班級,它很容易使用。隨意添加try/catch塊當一個請求的視圖還沒有被註冊(即避免NullPointerException

您也可以考慮加入onShow()onHide()方法的接口稱爲查看和更改的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");