首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在按menuItem时在jFrame中显示menuItem

如何在按menuItem时在jFrame中显示menuItem
EN

Stack Overflow用户
提问于 2017-11-05 06:56:44
回答 1查看 449关注 0票数 1

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

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

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

EN

回答 1

Stack Overflow用户

发布于 2017-11-05 07:26:54

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

首先,我先来看一下How to use Actions。这些是自包含的工作单元,可以很容易地应用于按钮和键绑定,并为可重用的代码片段提供基础。

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

代码语言:javascript
复制
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“如何工作”,只关心当它将视图传递给它时,视图将显示在屏幕上,因此控制器的底层实现会发生变化,但是,由于Action所建立的契约,因此不需要进行更改。

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

好吧,但我听到你在问,这怎么会让你的生活变得更简单呢?

好吧,让我们假设你有一个这样的视图...

代码语言:javascript
复制
public class SomeOptionsPane extends JPanel {

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

}

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

代码语言:javascript
复制
public class SomeOptionsAction extends AbstractManagerAction {
    public SomeOptionsAction(Controller controller) {
        super(controller, new SomeOptionsPane());
        putValue(NAME, "Some options");
    }
}

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

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

代码语言:javascript
复制
JMenu options = new JMenu("Options");
options.add(new SomeOptionsAction(controller));

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

总而言之,您还可以考虑使用CardLayoutJTabbedPane来进一步改善用户体验,这取决于UI通常有多复杂。有关更多详细信息,请参阅How to use CardLayoutHow to Use Tabbed Panes

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

代码语言:javascript
复制
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也不是,所以我专注于提供一个解耦的解决方案

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47116441

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档