我正在尝试开发一个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,我真的很感激任何帮助,我已经检查了教程和网络上的其他地方(包括堆栈溢出),从我看到的,它应该工作。请,任何帮助将不胜感激。
答案 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");