java对象间通信

2024-04-23

还在学习Java。

Swing 又让我问了这个问题,但这确实是一个普遍的面向对象问题。如果我有一个主类(包含 main()),它会创建一个执行某些操作的新对象“A”,主类现在具有对该对象的引用,对象“B”如何访问该对象的属性?

我能想到的唯一方法是让主类创建一个新对象“B”,将对象“A”作为参数传递给构造函数,我认为这是可以的。但这不会使事件处理变得困难吗?

例如,也许这是一个糟糕的设计导致了问题。我有一个带有程序逻辑的大师班,它创建一个标准的 Swing 框架,带有一个菜单,菜单项具有动作侦听器。但动作监听器需要与外部对象交互。

所以一些代码(忽略细节):

主类,包含程序逻辑以及保存和加载方法等:

public final class TheProgramme implements WindowListener }
    private static final TheProgramme TP = new TheProgramme();
    // Declare Class variables, instance variables etc.

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

    private static void createAndShewGUI() {
        TP.populateAndShew();
    }

    private void populateAndShew() {
        final StandardFrame sF = new StandardFrame("TheProgramme");
        theFrame = sF.getMainFrame();
        theFrame.addWindowListener(this);
        theFrame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
        theFrame.pack(); theFrame.setVisible(true);
    }
...
}

因此,我们创建了一个标准框架对象,它创建了一个菜单、空面板和状态栏,但在菜单项上具有事件侦听器:

public class StandardFrame {
    // Declare instance variables that must be visible to the ActionListener inner class

    public StandardFrame(String theTitle) {
        mainFrame = new JFrame(theTitle);
        mainFrame.setJMenuBar(createMenuBar()); // ... the menu bar and ...
        mainFrame.setContentPane(createBlankPanel()); // ... a blank panel
        java.net.URL imageURL = TheProgramme.class.getResource("images/icon.png");
        if (imageURL != null) {
            ImageIcon icon = new ImageIcon(imageURL);
            mainFrame.setIconImage(icon.getImage());
        }
    }

    public JMenuBar createMenuBar() {
        ActionListener menuEvents = new MenuListener();
        JMenuBar aMenuBar = new JMenuBar();
        JMenu fileMenu = new JMenu("File"); fileMenu.setMnemonic(KeyEvent.VK_F);
        ...
        aMenuBar.add(fileMenu);
        ...
        JMenuItem newItem = new JMenuItem("New", KeyEvent.VK_N); newItem.addActionListener(menuEvents);
        newItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, ActionEvent.CTRL_MASK));
        ...
        fileMenu.add(newItem);
        ...
        return aMenuBar;
    }
}

class MenuListener implements ActionListener {

    public void actionPerformed(ActionEvent ae) {
        String actionCommand = ae.getActionCommand();
        switch (actionCommand) {
            case "New":
                // !!! here we need to call a method in an object to create a new document object !!!
                break;
             case "Reformat":
                // !!! here we need to call a method in the object created above
         }
     }
}

第一个问题是菜单项上的动作监听器调用一个方法来创建对象,但它不是对静态方法的调用。 第二个问题是它需要能够稍后由于另一个菜单选择而调用该新对象中的方法。


执行此操作的经典方法是模型-视图-控制器 http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller就是在运行时将对象绑定在一起。控制器(您的操作侦听器)采用参数来指示要操作的视图和模型。

正如 Aqua 提到的,这种参数的使用也称为“依赖注入”。

   public static void main( String[] args )
   {
      Model model = new Model();
      View view = new View();
      ActionListener listener = new MyActionListener( model, view );
      view.addActionListener( listener );
   }

   private static class MyActionListener implements ActionListener
   {
      private Model model;
      private View view;

      public MyActionListener( Model model, View view )
      {
         this.model = model;
         this.view = view;
      }
   }

在 Java 中,您可以作一点欺骗,因为 ActionEvent 有一个指向事件源的指针(通常是生成事件的视图/JComponent)。

private static class MyActionListener implements ActionListener
{
  private Model model;

  public MyActionListener( Model model )
  {
     this.model = model;
  }

  @Override
  public void actionPerformed( ActionEvent e )
  {
     JComponent source = (JComponent) e.getSource();
     // source == "view"...
  }
}

要设置新文档,您可以创建一个“文档持有者”类。 “新建”菜单项将新文档放入 Holder 类中。所有其他菜单项从持有者类“获取”文档。这是一个相当严格的 OO 范例,它不使用静态方法或字段,尽管它有点乏味。

Set up:

   public static void main( String[] args )
   {
      ModelDocumentHolder model = new ModelDocumentHolder();
      View view = new View();
      ActionListener listener = new NewDocument( model );
      view.addActionListener( listener );
      View view2 = new View();
      view2.addActionListener( new RegularListener( model ) );
   }

新文档监听器:

   private static class NewDocument implements ActionListener
   {
      private ModelDocumentHolder model;

      public NewDocument( ModelDocumentHolder model )
      {
         this.model = model;
      }

      @Override
      public void actionPerformed( ActionEvent e )
      {
         model.setDoc( new Document() );
      }
   }

大多数其他菜单项:

   private static class RegularListener implements ActionListener
   {
      private ModelDocumentHolder model;

      public RegularListener( ModelDocumentHolder model )
      {
         this.model = model;
      }

      @Override
      public void actionPerformed( ActionEvent e )
      {
         JComponent source = (JComponent) e.getSource();
         Document doc = model.getDoc();
         // do stuff...
      }
   }

持有者类别:

   private static class ModelDocumentHolder
   {
      private Document doc;

      public Document getDoc()
      {
         return doc;
      }

      public void setDoc( Document doc )
      {
         this.doc = doc;
      }

   }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java对象间通信 的相关文章

随机推荐

  • 你能强制 Vim 在文件末尾显示一个空行吗?

    当我在记事本中打开文本文件时 如果包含文本的最后一行末尾有回车符 则会显示一个空行 然而 在 Vim 中它不显示这个空行 我注意到的另一件事是 Vim 编辑器默认在最后一行添加回车符 即使它没有显示 我可以这么说 因为如果我在记事本中打开在
  • Java流合并或减少重复对象

    我需要通过将所有重复条目合并到一个对象中来从可以具有重复项的列表中生成一个唯一的朋友列表 Example 从不同的社交源中获取好友并放入 1 个大列表中1 朋友 姓名 约翰尼 德普 出生日期 1970 11 10 来源 FB fbAttri
  • 重新排序/重置自动增量主键

    我有一个带有自动增量主键的 MySQL 表 我删除了表格中间的一些行 例如 现在我在 ID 列中有这样的内容 12 13 14 19 20 我删除了 15 16 17 和 18 行 我想重新分配 重置 重新排序主键 以便具有连续性 即将 1
  • 如何在 mongodb 聚合期间有条件地投影字段

    我有一个用户文档 例如 id s0m3Id skills skill1 skill2 现在我想通过以下方式展开此文档 skills字段并为每项技能添加分数 所以我的汇总看起来像 unwind path skills preserveNull
  • Rest 服务器(Play Framework)在负载测试期间出现“Read Timed out”异常

    我们正在使用 Play Framework 在 REST 服务器上运行重负载测试 jmeter 350 个线程 35M 总请求 并在大约 2 小时后遇到以下错误 我们删除了其他组件 以便 request 只是接受请求而不执行任何操作 任何人
  • JSON 行 Mime 类型

    我想知道为 JSON 行设置什么 Content Type http jsonlines org http jsonlines org 我尝试搜索 它并不是真正的 application json 因为整个内容都不是 JSON 每一行都是
  • 如何从Python使用OpenCV的C++函数?

    我正在使用 OpenCV 的 Python 绑定 它真的很棒 但是 C 版本中的某些函数在 Python 绑定 BackgroundSubstractorMOG2 和许多特征检测算法中缺失 从 Python 调用它们的最简单方法是什么 我希
  • 在java中设置按钮点击延迟?

    我有一个保存按钮JFrame 单击 保存 时 保存 文本将设置为 正在保存 我需要在延迟 10 秒后将该文本设置为 已保存 在 java 中这怎么可能 请帮忙 try Thread sleep 4000 catch InterruptedE
  • 使用 Retrofit 2.0.x 进行 HTTP 缓存

    我正在尝试使用 Retrofit 2 0 在我的应用程序中缓存一些响应 但我遗漏了一些内容 我安装了一个缓存文件 如下 private static File httpCacheDir private static Cache cache
  • EF7(Core) 中同一个表的多个关系

    我有这样的模型 public class Question public string Id get set Guid NewGuid ToString public Answer Answer get set public List
  • 在 Scala 中的 List[Either] 上使用 flatMap

    Either从 Scala 2 12 开始是右偏的 这使得它可以在 for yield 块中使用 而无需投影 就像Option 但显然这还不足以表现得像Option当与flatMap object Main def main args Ar
  • 如何使用routing.yml中的参数进行重定向?

    在routing yml中你可以执行以下操作 redirect old url to new pattern old pattern defaults controller FrameworkBundle Redirect urlRedir
  • 是否有可用的 SQL Server 2008 数据库更改管理 (MIgrations) 工具?

    我们正在奔跑塔伦蒂诺 http code google com p tarantino wiki DatabaseChangeManagement在 Nant 构建脚本中 但我们正在获得一些新硬件并利用升级到 SQL Server 2008
  • 斯卡拉。浮点数的奇怪结果

    为什么减法时会得到奇怪的结果2 99999 from 3 scala gt math sqrt 3 res0 Double 1 7320508075688772 scala gt math pow res0 2 res1 Double 2
  • Qunit qunit-fixture div 被删除,使用 Resharper 8 运行单元测试

    我遇到一个问题 当我在 ReSharper 8 下运行 Qunit 进行测试时尝试在 div id qunit fixture 中附加或设置 HTML 代码时 由于某种原因 div id qunit fixture 被删除 我需要测试文档就
  • Istio 的 `DestinationRule` 与 Kubernetes `Service` 之间的区别?

    我刚刚阅读了 istio 1 0 0 的文档 特别是它的概念 我想了解一件事 尤其是DestinationRule https istio io docs concepts traffic management rule configura
  • 时钟中的时间显示与r中的xy散点图

    我想创建以下类型的情节 但不知道是否有任何包已经存在 因为我找不到 数据 myd lt data frame X 1 5 Y c 0 8 0 6 0 7 0 75 0 1 clockd c 12 05 12 25 12 45 1 30 2
  • 如何从嵌套 Jar 中提取 .class 文件?

    我有一个名为 的 Jar 文件外部Jar jar 其中包含另一个名为 的罐子内Jar jar 此 InnerJar 包含 2 个名为 的文件测试1 类 测试2 类 现在我想提取这两个文件 我尝试了一些代码 但它不起作用 class Nest
  • XSLT 如何用 div 包装每 3 个元素?

    我有一些 XML 文档
  • java对象间通信

    还在学习Java Swing 又让我问了这个问题 但这确实是一个普遍的面向对象问题 如果我有一个主类 包含 main 它会创建一个执行某些操作的新对象 A 主类现在具有对该对象的引用 对象 B 如何访问该对象的属性 我能想到的唯一方法是让主