2

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

该问题更多地与设计问题而不是开发问题相关。我不确定我的设计,但我会试着解释一下。

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

但是从所谓的视图中,我有一些按钮,它们必须切换 JPanel 的内容(Jpanel 包含在 JTabbedPane 中)。而且我正在寻找切换视图的最佳方式,而不会违反 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 的参考?我该怎么做?

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

谢谢你。

4

3 回答 3

1

我会说你的 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 触发 panelSwitchRequested() (希望是您的 JTabbedPane)。

于 2012-07-24T19:37:19.637 回答
0

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

但是,如果您仍然需要这种方式,请尝试以不同的方式思考您的观点。我认为 JPanels 实际上是 Views。如果您将控制器附加到每个视图并将模型附加到每个控制器,您将能够在它们之间切换,而无需在视图或控制器中放置太多逻辑,但仍将视图与模型解耦。我将一个粗略的例子放在一起,它使用CardLayoutNull Object,但在其他方面相当简单。当然,所有的类都应该重命名为适合你项目的东西。

查看.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);
    }

}

空视图.java

public class NullView extends View {

    public NullView() {
        super(null);
    }

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

}

控制器.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());
    }

}

模型.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);
于 2012-07-26T10:13:12.447 回答
0

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

这个模型可以传递给你的控制器(在这里我会说一个自定义的 JTabbedPane,正如 pafau 提到的),它可以根据需要构建所有选项卡。通过这种方式,您可以将导航机制与视图分离,并将逻辑委托给模型。

于 2012-07-24T22:51:45.797 回答