繁体   English   中英

从JPanel内部切换JFrame中的JPanel

[英]Switching JPanel in JFrame from inside the JPanel

我正在尝试基于按钮创建动态应用程序,这些按钮可从创建的面板内部切换JFrame的主面板(这是应用程序的顶部内容)。

该问题与设计问题有关,而不是开发问题。 我不确定我的设计,但是我会尽力解释。

我有一个JFrame代表我的应用程序,其中包含一个JTabbedPane(和其中的多个Tabs)。 每个选项卡都包含一个默认的JPanel,并且在该JPanel中,我正在调用呈现我的View的控制器(我正在尝试使用MVC模式)。

但是从所谓的View中,我有一些按钮,这些按钮必须切换JPanel的内容(包含在JTabbedPane中的Jpanel)。 而且我正在寻找切换视图的最佳方法,同时又不违反OOP的标准规则。

示意图:

JFrame
    JTabbedPane
        JPanel
            View1
                Button (pointing somehow to View2)
        JPanel
            View3
                 Button (pointing somehow to View4)

当我从视图1中单击按钮时,我想要这样:

JFrame
    JTabbedPane
        JPanel
            View2
                ...
        JPanel
            View3
                 Button (pointing somehow to View4)

并且,一旦加载了View 2,如果我通过JTabbedPane转到View3并单击View3.button,我想拥有以下内容:

JFrame
    JTabbedPane
        JPanel
            View2
                ...
        JPanel
            View4
                 ...

正如我所说的,这更多是设计问题。 我的“设计”是否足够好,不必为每个组件提供JFrame的引用? 我该如何执行呢?

我希望我的文字没有太多错误,英语不是我的母语。 此外,欢迎对我的英语写作技能进行任何更正。

谢谢。

我想说您的JTabbedPane是对面板感兴趣的类-因为它是JTabbedPane,它将切换其内容。

因此,我想将JTabbedPane扩展到?TabbedPane(其中?代表“我的”或项目中的任何命名约定),并使其扩展ActionListener,如下所示:

public class MyTabbedPane extends JTabbedPane implements ActionListener {
    ...
    public void actionPerformed(ActionEvent aev) {
        // replace panels
        revalidate();
        repaint();
    }
}

然后在需要的地方(可能是按钮)将选项卡式窗格注册为操作侦听器。

如果要切换到多个面板,则需要更多代码来传递状态。 您可以编写自己的侦听器:

public class PanelSwitchActionListener {
    public void panelSwitchRequested(...);
}

然后,传递Enum表示要切换到哪个面板,或者甚至将面板本身放在panelSwitchRequested()方法的(...)部分中。 然后在按钮上添加一个Action(Listener),并使它们针对已注册的PanelSwitchActionListener(希望是您的JTabbedPane)触发panelSwitchRequested()。

我会尝试回到模型上。 该模型将维护一个视图列表,以及一个给定视图引用的方法,它可以返回下一个视图(即model.getNextView(view) )。

该模型可以传递给您的控制器(在此我要说一个自定义的JTabbedPane,如pafau所述),它可以根据需要构造所有选项卡。 这样,您就可以将导航机制与视图分离,并将逻辑委托给模型。

就个人而言,我将重新考虑同时使用选项卡式窗格和视图之间切换的设计。 通常是/或者带有选项卡式窗格是首选。

但是,如果仍然需要这种方式,请尝试以不同的方式考虑您的观点。 我认为JPanels实际上是Views。 如果将控制器附加到每个视图,将模型附加到每个控制器,则可以在它们之间切换而无需在视图或控制器中添加过多的逻辑,但仍可以将视图与模型分离。 我把使用CardLayoutNull Object的一个粗略示例放在一起,但否则相当简单。 当然,所有类都应重命名为适合您的项目的名称。

View.java

public class View extends JPanel {

    private CardLayout layout;


    public View(Controller controller, JComponent... subviews) {
        layout = new CardLayout();
        setLayout(layout);

        for (int index = 0; index < subviews.length; ++index) {
            JButton changeButton = new JButton("Change");
            changeButton.addActionListener(controller);
            subviews[index].add(changeButton);
            add(subviews[index], "View" + index);
        }
    }

    public void setSubview(int index) {
        layout.show(this, "View" + index);
    }

}

NullView.java

public class NullView extends View {

    public NullView() {
        super(null);
    }

    @Override
    public void setSubview(int index) {
        // do nothing
    }

}

Controller.java

public class Controller implements ActionListener {

    private Model model;

    private View view;

    public Controller(Model model) {
        this.model = model;
        this.view = new NullView();
    }

    public void setView(View view) {
        this.view = view;
    }

    public void actionPerformed(ActionEvent e) {
        model.nextIndex();
        view.setSubview(model.getCurIndex());
    }

}

Model.java

public class Model {

    private int nViews;

    private int curIndex;

    public Model(int nViews) {
        if (nViews <= 0) nViews = 1;
        this.nViews = nViews;
    }

    public void nextIndex() {
        curIndex = (curIndex + 1) % nViews;
    }

    public int getCurIndex() {
        return curIndex;
    }

 }

在内容窗格中:

 Controller controller1 = new Controller(new Model(2));

 View view1 = new View(controller1, subview1, subview2);
 controller1.setView(view1);

 Controller controller2 = new Controller(new Model(3));

 View view2 = new View(controller2, subview3, subview4, subview5);
 controller2.setView(view2);

 JTabbedPane tabbedPane = new JTabbedPane();
 tabbedPane.addTab("Tab1", view1);
 tabbedPane.addTab("Tab2", view2);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM