gpt4 book ai didi

swing - 使用 JComponents 时的命令模式有用性

转载 作者:行者123 更新时间:2023-12-05 00:26:56 25 4
gpt4 key购买 nike

所以,我正在使用 Swing 库开发一个程序,我显然有按钮和菜单项。其中一些应该做同样的事情,我认为使用命令模式应该是这样做的方式,例如我有一个“保存”按钮和一个“保存”菜单项,它们必须实现相同的保存算法。
命令模式似乎没问题,但我不知道谁是接收者。一个命令不是应该在一个实现某种“接收器接口(interface)”的对象上工作,这样你就可以在不同的接收器上使用不同的命令来任意耦合它们吗?看起来我的模式实现中没有“接收器”。
我的另一个疑问是命令是否应该作为单例实现,因为您可能会从同一项目的不同部分调用它的函数,并且只实例化一次并使其静态调用会很方便吗?

谢谢你。

最佳答案

" I obviously have buttons and menu items. Some of these are supposed to do the same stuff,"



正如@nIcEcOw 所说,这就是 Action s 是为了。 This Answer正是表明了这一点。

How to use Actions 中所述:

An Action can be used to separate functionality and state from a component. For example, if you have two or more components that perform the same function, consider using an Action object to implement the function. An Action object is an action listener that provides not only action-event handling, but also centralized handling of the state of action-event-firing components such as tool bar buttons, menu items, common buttons, and text fields. The state that an action can handle includes text, icon, mnemonic, enabled, and selected status.



enter image description here

安只有三个 Actions .打开、保存和新建。每个 Action有一个 ActionCommand , 和 icon ,以及要执行的操作。 JMenuItemJToolBar按钮共享相同 Action并做同样的事情。这是您可以运行的代码。
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Box;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;

public class ActionTest {

public ActionTest() {
ImageIcon openIcon = new ImageIcon(
ActionTest.class.getResource("/resources/image/open.gif"));
ImageIcon saveIcon = new ImageIcon(
ActionTest.class.getResource("/resources/image/save.gif"));
ImageIcon newIcon = new ImageIcon(
ActionTest.class.getResource("/resources/image/new.gif"));

Action openAction = new AbstractAction("Open", openIcon) {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Open File");
}
};
Action saveAction = new AbstractAction("Save", saveIcon) {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Save File");
}
};
Action newAction = new AbstractAction("New", newIcon) {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("New File");
}
};

JMenuItem openMenuItem = new JMenuItem(openAction);
JMenuItem saveMenuItem = new JMenuItem(saveAction);
JMenuItem newMenuItem = new JMenuItem(newAction);

JMenuBar menuBar = new JMenuBar();
JMenu fileMenu = new JMenu("File");
fileMenu.add(openMenuItem);
fileMenu.add(saveMenuItem);
fileMenu.add(newMenuItem);
menuBar.add(fileMenu);

JToolBar toolBar = new JToolBar();
toolBar.add(Box.createHorizontalGlue());
toolBar.setBorder(new LineBorder(Color.LIGHT_GRAY, 1));
toolBar.add(newAction);
toolBar.add(openAction);
toolBar.add(saveAction);

JFrame frame = new JFrame("Toolbar and Menu Test");
frame.setJMenuBar(menuBar);
frame.add(toolBar, BorderLayout.PAGE_START);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
frame.setVisible(true);

}

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new ActionTest();
}
});
}
}

正如上述教程中的引文所述,您可以做的不仅仅是将图像和操作命令添加到 Action。 .您可以使用它来设置助记符和加速器。这是一个自定义 Action上课
  • Action 命令字符串
  • 一个图标
  • 工具提示的描述
  • 助记符
  • 和一个关键的加速器。
    private class MyAction extends AbstractAction {

    String name;

    public MyAction(String name, Icon icon) {
    super(name, icon);
    this.name = name;
    }

    public MyAction(String name, Icon icon, String desc,
    Integer mnemonic, KeyStroke accelorator) {
    super(name, icon);
    putValue(Action.SHORT_DESCRIPTION, desc);
    putValue(Action.MNEMONIC_KEY, mnemonic);
    putValue(Action.ACCELERATOR_KEY, accelorator);
    this.name = name;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
    switch (name) {
    case "Open":
    System.out.println("Open");
    break;
    case "New":
    System.out.println("New");
    break;
    case "Save":
    System.out.println("Save");
    break;
    }
    }
    }

  • 这是 Action 的实例化
    Action newAction = new MyAction("New", newIcon,
    "Creates a new file",
    new Integer(KeyEvent.VK_N),
    KeyStroke.getKeyStroke(KeyEvent.VK_N, ActionEvent.CTRL_MASK));

    这是新的结果。您将看到 actionCommand在菜单中,以及关键的助记符和加速键、工具提示,您将看到 jtoolbar 按钮具有相同的特征。您还将在最终代码中看到,一旦创建了组件,就永远不会。您只需添加 ActionJToolBarJMenu让他们发挥他们的魔力。

    enter image description here
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;

    public class ActionInterfaceDemo extends JFrame {

    public ActionInterfaceDemo() {
    ImageIcon openIcon = new ImageIcon(ActionInterfaceDemo.class.getResource("/resources/image/open.gif"));
    ImageIcon saveIcon = new ImageIcon(ActionInterfaceDemo.class.getResource("/resources/image/save.gif"));
    ImageIcon newIcon = new ImageIcon(ActionInterfaceDemo.class.getResource("/resources/image/new.gif"));

    Action openAction = new MyAction("Open", openIcon,
    "Opens a file",
    new Integer(KeyEvent.VK_O),
    KeyStroke.getKeyStroke(KeyEvent.VK_O, ActionEvent.CTRL_MASK));
    Action saveAction = new MyAction("Save", saveIcon,
    "Saves a file",
    new Integer(KeyEvent.VK_S),
    KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK));
    Action newAction = new MyAction("New", newIcon,
    "Creates a new file",
    new Integer(KeyEvent.VK_N),
    KeyStroke.getKeyStroke(KeyEvent.VK_N, ActionEvent.CTRL_MASK));

    JMenuBar menuBar = new JMenuBar();
    JMenu fileMenu = new JMenu("File");
    setJMenuBar(menuBar);
    menuBar.add(fileMenu);

    fileMenu.add(newAction);
    fileMenu.add(openAction);
    fileMenu.add(saveAction);


    JToolBar toolBar = new JToolBar("Alignment");
    toolBar.setBorder(BorderFactory.createLineBorder(Color.BLUE));
    toolBar.add(Box.createHorizontalGlue());
    toolBar.add(newAction);
    toolBar.add(openAction);
    toolBar.add(saveAction);

    add(toolBar, BorderLayout.PAGE_START);
    add(new JScrollPane(new TextArea(10, 40)), BorderLayout.CENTER);

    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setTitle("Action Interface Demo");
    pack();
    setLocationByPlatform(true);
    setVisible(true);
    }

    private class MyAction extends AbstractAction {

    String name;

    public MyAction(String name, Icon icon) {
    super(name, icon);
    this.name = name;
    }

    public MyAction(String name, Icon icon, String desc,
    Integer mnemonic, KeyStroke accelorator) {
    super(name, icon);
    putValue(Action.SHORT_DESCRIPTION, desc);
    putValue(Action.MNEMONIC_KEY, mnemonic);
    putValue(Action.ACCELERATOR_KEY, accelorator);
    this.name = name;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
    switch (name) {
    case "Open":
    System.out.println("Open");
    break;
    case "New":
    System.out.println("New");
    break;
    case "Save":
    System.out.println("Save");
    break;
    }
    }
    }

    public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable(){
    public void run() {
    new ActionInterfaceDemo();
    }
    });
    }
    }

    更新

    更好的解释 Action的关系和 命令模式

    Command Pattern 中所述

    The command pattern is a commonly used pattern which encapsulates a method call or action-like code into a single class. The advantages of being able to package a method (or methods) into a class become evident when you have multiple invokers for a single action (for example a button and a menu item may perform the same action).

    In Swing and Borland Delphi programming, an Action is a command object. In addition to the ability to perform the desired command, an Action may have an associated icon, keyboard shortcut, tooltip text, and so on. A toolbar button or menu item component may be completely initialized using only the Action object.



    所以基本上 Swing 使用 的概念。命令模式通过使用 Actions
    至于OP的问题

    "Command Pattern seems to be ok but I can't get who's the receiver in all that."



    至于 接收器 ,wiki 以文本编辑器为例,定义了 接收器像这样

    Receiver, Target Object: the object that is about to be copied, pasted, moved, etc. The receiver object owns the method that is called by the command's execute method. The receiver is typically also the target object. For example, if the receiver object is a cursor and the method is called moveUp, then one would expect that the cursor is the target of the moveUp action. On the other hand, if the code is defined by the command object itself, the target object will be a different object entirely.



    的主要更多组件命令模式 声明如下

    与命令模式相关的四个术语是 命令、接收者、调用者和客户端。

    Client, Source, Invoker: the button, toolbar button, or menu item clicked, the shortcut key pressed by the user.



    所以把它们放在一起:
  • MenuItem ( 客户端 ) 调用它
  • 调用它的操作( 命令对象 )actionPerformed反过来
  • 调用 上的方法接收器 .

  • wiki article用一个 Java 例子很好读

    关于swing - 使用 JComponents 时的命令模式有用性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21512639/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com