我建议的第一件事是使用CardLayout - 有关详细信息,请参阅How to use CardLayout。
这将使视图之间的切换变得更加简单。
接下来,我建议设计一种独立于视图本身的“导航”系统。这个想法是,任何一个视图都应该知道或关心下一个(或上一个)视图,并且应该只向导航系统发出“简单”请求,例如“显示下一个视图”。由导航系统决定这意味着什么(以及如何驾驶它)。
这使您可以更好地控制整个导航过程的定义和管理。
然后我会将它与可选的“生命周期”概念结合起来,这将允许导航系统在导航状态发生变化时通知这些实现。
“如何”实际执行此操作在很大程度上取决于您的整体设计和意图,但它可能看起来像......
LifeCycle
public interface LifeCycle {
public void willShow();
public void didShow();
public void willHide();
public void didHide();
}
NavigationController
public interface NavigationController {
public void next();
}
public interface View {
public String getName();
public JComponent getView();
}
默认实现...
public class DefaultView implements View {
private String name;
private JComponent view;
public DefaultView(String name, JComponent view) {
this.name = name;
this.view = view;
}
@Override
public String getName() {
return name;
}
@Override
public JComponent getView() {
return view;
}
}
public class DefaultNavigationController implements NavigationController {
private List<View> views;
private Container parent;
private CardLayout layout;
private View currentView;
public DefaultNavigationController(Container parent, CardLayout layout) {
this.parent = parent;
this.layout = layout;
}
protected Container getParent() {
return parent;
}
protected CardLayout getLayout() {
return layout;
}
public void add(String name, JComponent comp) {
getParent().add(comp, name);
views.add(new DefaultView(name, comp));
}
protected List<View> getViews() {
return views;
}
@Override
public void next() {
List<View> views = getViews();
if (views.isEmpty()) {
return;
}
int index = (currentView == null ? -1 : views.indexOf(currentView)) + 1;
if (index >= views.size()) {
// This is the last view
return;
}
View previousView = currentView;
View nextView = views.get(index);
willHide(previousView);
willShow(nextView);
getLayout().show(getParent(), nextView.getName());
didHide(previousView);
didShow(nextView);
currentView = nextView;
}
protected void willHide(View view) {
if (view != null && view.getView() instanceof LifeCycle) {
LifeCycle cycle = (LifeCycle)view.getView();
cycle.willHide();
}
}
protected void willShow(View view) {
if (view != null && view.getView() instanceof LifeCycle) {
LifeCycle cycle = (LifeCycle)view.getView();
cycle.willShow();
}
}
protected void didHide(View view) {
if (view != null && view.getView() instanceof LifeCycle) {
LifeCycle cycle = (LifeCycle)view.getView();
cycle.didHide();
}
}
protected void didShow(View view) {
if (view != null && view.getView() instanceof LifeCycle) {
LifeCycle cycle = (LifeCycle)view.getView();
cycle.didShow();
}
}
}
如您所见,我喜欢使用interfaces,这对系统的其他部分隐藏了实现细节,并为我提供了更好的定制点。例如,组件不关心NavigationController“如何”实现,只关心它遵循特定且可定义的工作流程。
好的,但是这如何工作?让我们从支持LifeCycle 的组件的基本实现开始,它可能看起来像...
public class IntroPane extends JPanel implements LifeCycle {
private NavigationController navigationController;
protected NavigationController getNavigationController() {
return navigationController;
}
protected void next() {
getNavigationController().next();
}
@Override
public void willShow() {
// Prepare any resources
// Lazy load resources
// Do other preparation work which doesn't need to be done in the
// constructor or which needs to be recreated because of actions
// in will/didHide
}
@Override
public void didShow() {
// Start animation loops and other "UI" related stuff
}
@Override
public void willHide() {
// Pause the animation loop and other "UI" related stuff
}
@Override
public void didHide() {
// Dispose of system intensive resources which can be recreated
// in willShow
}
}
您可以使用类似...的方式进行设置
CardLayout cardLayout = new CardLayout();
JPanel contentPane = new JPanel(cardLayout);
DefaultNavigationController navigationController = new DefaultNavigationController(contentPane, cardLayout);
navigationController.add("intro", new IntroPane());
navigationController.add("menu", new MenuPane());
navigationController.add("game", new GamePane());
“但是等等”你说,“这是一个线性导航,我需要一些更动态的东西!”
远点。在那种情况下,我会创建另一个interface!!这将从(线性)NavigationController 扩展,并提供一种“显示”任意命名视图的方法。
为什么要这样?因为并非所有视图都需要决定显示哪个视图的能力,所以有些视图只想显示下一个(或上一个)视图,例如,MenuPane 可能是唯一需要非线性导航控制器的视图,所有其他人只需要能够后退或前进
但是我该如何停止Thread
这是一个复杂的问题,并不总是很容易回答。 “基本”答案是,您需要定义一个控制机制,该机制可以与Thread 的“可中断”支持一起工作并退出线程上下文。
也许How to Kill a Java Thread 会是一个起点