实时切换内容窗格 [英] Switching contentpane in real time

查看:105
本文介绍了实时切换内容窗格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试制作带有简介的Java小项目,并在播放完整视频或按键后跳到菜单.我为游戏"状态做了枚举.我如何切换JPanels并停止旧版本正在做的所有事情,因为简介也在Thread中播放音乐.

I try to make java small project with intro and after full video or keypressed skip to menu. I made enums for state of "game". How i can switch JPanels and stop everything that old one is doing, because intro is also playing music in Thread.

contentPane.addMouseListener(new MouseAdapter() {
                public void mousePressed(MouseEvent e) {
                    System.out.println("Clicked");
                    State = GameState.MainMenu;
                }
            });
            if (State == GameState.Intro) {
                contentPane.removeAll();
                contentPane.add(intro);
                contentPane.revalidate();
                contentPane.repaint();
                intro.music.interrupt();
                System.out.println(State);
            } else if (State == GameState.MainMenu) {
                contentPane.removeAll();
                contentPane.add(menu);
                contentPane.revalidate();
                contentPane.repaint();
                System.out.println(State);
            }
        }

推荐答案

我建议的第一件事是利用CardLayout-请参见

The first thing I would recommend is, making use of a CardLayout - See How to use CardLayout for more details.

这将使视图之间的切换更加简单.

It will make switching between the views much simpler.

接下来,我建议您设计一种独立于视图本身的导航"系统.这个想法是,任何一个视图实际上都应该知道或关心哪个视图是下一个(或上一个),并且应该仅向导航系统发出简单"请求,例如显示下一个视图".由导航系统决定到底是什么意思(以及如何驱动).

Next, I would recommend devising some kind of "navigation" system which is independent of the views themselves. The idea is, any one view really should know or care which view is next (or previous) and should only be making "simple" requests to the navigation system, like "show next view". It's up to the navigation system to decide exactly what that means (and how to drive it).

这使您可以更好地控制定义和管理整个导航过程.

This allows you more control over defining and managing the overall navigation process.

然后,我将其与可选的生命周期"概念相结合,这将允许导航系统在导航状态发生变化时通知那些实现.

I would then couple that with a optional "life cycle" concept, which would allow the navigation system to notify those implementations when the navigation state was changing.

您实际上是如何做到的,将在很大程度上取决于您的总体设计和意图,但是可能看起来像...

"How" you actually do this, will depend on a lot on your overall design and intentions, but it might look something like...

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();
        }
    }
}

如您所见,我喜欢在interface上工作,这隐藏了系统其他部分的实现细节,并为我提供了更好的定制点.例如,组件并不关心NavigationController的实现方式",只是它遵循特定且可定义的工作流程.

As you can see, I like working to interfaces, this hides the implementation details from other parts of the system and provides me with a better point of customisation. For example, components don't care "how" the NavigationController is implemented, only that it follows a specific and definable work flow.

好的,但是这怎么工作?让我们从支持LifeCycle的组件的基本实现开始,它看起来可能类似于...

Okay, but how might this work? Let's start with a basic implementation of a component that support LifeCycle, it might look something like...

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

您可能会使用...来设置它.

And you might set it up using something like...

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());

等等,"您说,这是线性导航,我需要更动态的东西!"

"But wait" you say, "this is a linear navigation, I need something more dynamic!"

重点.在那种情况下,我会创建另一个interface!这将从(线性)NavigationController扩展而来,并提供了一种显示"任意命名视图的方法.

Far point. In that case I would create, yes, another interface!! This would extend from the (linear) NavigationController and provide a means to "show" arbitrary named views.

为什么要这样?由于并非所有视图都有权决定应显示哪个视图,因此有些视图只想显示下一个(或上一个)视图,例如,MenuPane可能是唯一实际需要非线性导航控制器的视图,所有其他人只需要能够前进或后退

Why do it this way? Because not all the views need the power to decide which view should be shown, some just want to show the next (or previous) view, for example, MenuPane might be the only view which actually needs a non-linear navigation controller, all the others just need to be able to move back or forward

但是如何停止Thread

这是一个复杂的问题,并不总是容易回答. 基本"的答案是,您需要定义一种控制机制,该机制可以与Thread的可中断"支持一起使用,并退出线程上下文.

That's a complicated question, which isn't always easily answered. The "basic" answer is, you need to define a controlling mechanism which can work together with the "interruptable" support of the Thread and exit the thread context.

也许如何杀死Java线程将是一个起点

这篇关于实时切换内容窗格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆