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 ブロックを自由に追加してください (つまり、 avoid NullPointerException) 。

View というインターフェイスに メソッドonShow()とメソッドを追加して、 のすべてのインスタンスをに変更することも検討できます。これにより、ビュー スイッチを処理するための将来の拡張が可能になります。これは提供できない可能性があります。onHide()ContainerViewCardLayout

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      
    }    
}  

必要に応じて簡単に適応でき、切り替えは非常に効率的です。私のアプリケーションの 1 つで、各ビューをマップにロードして動的に登録する代わりに、各ビューに定数フィールドを使用しています。この例は、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 に答える