【问题标题】:How to show a jPanel in a jFrame when pressing a menuItem按下menuItem时如何在jFrame中显示jPanel
【发布时间】:2017-11-04 22:56:44
【问题描述】:

我正在使用 JAVA Netbeans。我已经有了我的菜单,这是第一张照片:

当我按下其中一个 menuItems 时,它会打开一个新的 jDialog,其中包含以下内容:

我希望当我按下菜单项时,我在 jDialog 上的所有组件都在 jFrame 中打开......这样它们就可以调整到主框架。我希望这发生在我拥有的每个 menuItem 上,所以当我按下另一个 menuItem 时,它会替换我目前在 jFrame 上的所有信息,或者如果可能的话打开某种选项卡?

【问题讨论】:

  • 首先,我不关心对话框,我只是将面板直接添加到框架中开始,这对我来说似乎是一个不必要的步骤。其次,我会看看How to use Actions,它将有助于简化流程。第三,根据整个应用程序的复杂性,我可能会考虑使用CardLayout。看看How to use CardLayout
  • 另一种选择可能是使用JTabbedPane

标签: java netbeans jframe jpanel jdialog


【解决方案1】:

任何解决方案都需要某种形式的模型-视图-控制器。这将有助于在解耦 API 的同时简化功能。

首先,我先看看How to use Actions。这些是独立的工作单元,可以轻松应用于按钮和键绑定,并为可重用的 sn-ps 代码提供基础。

例如,我们可以定义一个非常简单的Action,它简单地管理视图与控制器的交互,以方便视图的切换:

public abstract class AbstractManagerAction extends AbstractAction {

    private Controller controller;
    private JPanel panel;

    public AbstractManagerAction(Controller manager, JPanel panel) {
        this.controller = manager;
        this.panel = panel;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        controller.show(panel);
    }

}

Action 并不关心Controller“如何”工作,只是当它将视图传递给它时,视图将显示在屏幕上,因此控制器的底层实现发生了变化,但是,由于API建立的契约,Action不需要更改。

现在,您可以拥有一个处理创建 JDialogController 和一个管理 JFrameController,并根据需要将它们链接在一起。

好的,但是我听到你问这实际上如何让你的生活变得更简单?

好吧,假设您有这样的视图...

public class SomeOptionsPane extends JPanel {

    public SomeOptionsPane() {
        setLayout(new GridBagLayout());
        add(new JLabel("Some options"));
    }

}

为了在屏幕上呈现它,我们需要先定义它自己的Action...

public class SomeOptionsAction extends AbstractManagerAction {
    public SomeOptionsAction(Controller controller) {
        super(controller, new SomeOptionsPane());
        putValue(NAME, "Some options");
    }
}

这使我们可以抽象出通用功能(如上所示),但允许对视图本身进行自定义(在这种情况下,我只定义了将要显示的文本)。您还可以定义一堆其他属性,但为简洁起见,我跳过了这一步。

现在,当我想将选项添加到JMenuBar/JMenu 时,我只需要创建一个Action 的实例...

JMenu options = new JMenu("Options");
options.add(new SomeOptionsAction(controller));

简单。现在,当Action 被触发时,它将调用Controllers show 方法并将视图实例传递给它!魔法!

总体而言,您还可以考虑使用CardLayoutJTabbedPane 来进一步改善用户体验,具体取决于用户界面的总体复杂程度。请参阅How to use CardLayoutHow to Use Tabbed Panes 了解更多详情。

而且,因为我知道在你看到它运行之前你不会满意,所以我用来测试这个想法的基本代码..

import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                Controller manager = new Controller() {
                    @Override
                    public void show(JPanel pane) {
                        frame.getContentPane().removeAll();
                        frame.getContentPane().add(pane);
                        frame.getContentPane().revalidate();
                        frame.getContentPane().repaint();
                    }
                };

                JMenuBar menuBar = new JMenuBar();
                JMenu options = new JMenu("Options");
                menuBar.add(options);
                options.add(new SomeOptionsAction(manager));
                options.add(new SomeOtherOptionsAction(manager));
                frame.setJMenuBar(menuBar);

                frame.setSize(200, 200);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public interface Controller {

        public void show(JPanel pane);
    }

    public abstract class AbstractManagerAction extends AbstractAction {

        private Controller controller;
        private JPanel panel;

        public AbstractManagerAction(Controller controller, JPanel panel) {
            this.controller = controller;
            this.panel = panel;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            controller.show(panel);
        }

    }

    public class SomeOptionsAction extends AbstractManagerAction {

        public SomeOptionsAction(Controller controller) {
            super(controller, new SomeOptionsPane());
            putValue(NAME, "Some options");
        }
    }

    public class SomeOptionsPane extends JPanel {

        public SomeOptionsPane() {
            setLayout(new GridBagLayout());
            add(new JLabel("Some options"));
        }

    }

    public class SomeOtherOptionsAction extends AbstractManagerAction {

        public SomeOtherOptionsAction(Controller manager) {
            super(manager, new SomeOtherOptionsPane());
            putValue(NAME, "Some other options");
        }
    }

    public class SomeOtherOptionsPane extends JPanel {

        public SomeOtherOptionsPane() {
            setLayout(new GridBagLayout());
            add(new JLabel("Some other options"));
        }

    }
}

现在,在我被烤之前,我知道这不是一个“传统”的 MVC,但 Swing 也不是,所以我专注于提供一个解耦的解决方案

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-16
    • 2011-07-18
    • 2014-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-02
    相关资源
    最近更新 更多