Java 实时切换contentpane

Java 实时切换contentpane,java,multithreading,swing,jpanel,Java,Multithreading,Swing,Jpanel,我试着用简介制作java小项目,在完整视频或按键后跳到菜单。我做了游戏状态的枚举。我如何切换JPanels并停止旧版本所做的一切,因为intro也在线程中播放音乐 contentPane.addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { System.out.println("Clicked");

我试着用简介制作java小项目,在完整视频或按键后跳到菜单。我做了游戏状态的枚举。我如何切换JPanels并停止旧版本所做的一切,因为intro也在线程中播放音乐

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

我建议的第一件事是,使用卡片布局-有关更多详细信息,请参阅

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

接下来,我建议设计一种独立于视图本身的导航系统。其思想是,任何一个视图都应该知道或关心下一个或上一个视图,并且应该只向导航系统发出简单的请求,如show next view(显示下一个视图)。这完全取决于导航系统来决定这意味着什么以及如何驾驶它

这使您能够更好地控制定义和管理整个导航过程

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

你如何做到这一点,将在很大程度上取决于你的总体设计和意图,但它可能看起来像

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());
生命周期 导航控制器 默认实现。。。 你可以用类似于

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());
但是等一下你说,这是一个线性导航,我需要一些更动态的

远点。在这种情况下,我会创建,是的,另一个接口!!这将从线性导航控制器扩展而来,并提供一种显示任意命名视图的方法

为什么要这样做?因为并非所有视图都需要决定应该显示哪个视图的权限,有些视图只想显示下一个或上一个视图,例如,MenuPane可能是唯一实际需要非线性导航控制器的视图,所有其他视图只需要能够向后或向前移动

但是我如何停止线程

这是一个复杂的问题,并不总是容易回答。基本答案是,您需要定义一个控制机制,它可以与线程的可中断支持一起工作,并退出线程上下文


也许是一个开始点:

首先,我会认真考虑使用CARDFLASH;其次,您需要定义某种类型的生命周期,这样当控制器检测到导航事件时,它可以指示当前视图在切换到新视图时停止或处置或准备撤销。如何做有些复杂,因为您需要在适合您的总体需求的情况下进行
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());