繁体   English   中英

如何删除内部类ActionListener?

[英]How to remove an inner class ActionListener?

我正在制作一个基于文本的游戏,但是我遇到了一个很大的问题。 问题是,当我将一个新的ActionListener分配给一个已经为其分配了ActionListener的按钮时,它将同时执行两个操作。 这是我的代码:

       while(shouldLoop) {
       if(Player.loc == 1) {
       left.setText("Do nothing");
       left.addActionListener(new ActionListener() {
           @Override
           public void actionPerformed(ActionEvent e) {
           nar1.setText("You are still in a dungeon."); //Here's my first assignment
       }
       });
       right.setText("Pick the lock");
       right.addActionListener(new ActionListener() {
           @Override
           public void actionPerformed(ActionEvent e) {
               Player.loc = 2;
           }
       });
       } if(Player.loc == 2) {
               nar1.setText("You are now outside");
               nar2.setText("the door. What now?");
               forward.addActionListener(new ActionListener() {
                   @Override
                   public void actionPerformed(ActionEvent e) {
                       nar1.setText("You hear a guard.");
                       nar2.setText("What do you do now?");
                       Player.loc = 3;
       }
               });
               left.addActionListener(new ActionListener() {   //Here's another
                   @Override                                   //assignment to
                   public void actionPerformed(ActionEvent e) {//the same button
                       nar1.setText("You hear a guard.");      //so when I press
                       nar2.setText("What do you do now?");    //it here, it
                       Player.loc = 3;                         //performs the
                   }                                           //original assignment
               });
               right.addActionListener(new ActionListener() {
                   @Override
                   public void actionPerformed(ActionEvent e) {
                       nar1.setText("You hear a guard.");
                       nar2.setText("What do you do now?");
                       Player.loc = 3;
                   }
               });
               right.setText(rgt);
               forward.setText(fwd);
               back.setText(bck);
               left.setText(lft);
               forward.setVisible(true);
       } if(Player.loc == 3) {
           forward.setVisible(false);
           right.setText("Sneak around him!");
           left.setText("Fight him!");
       }

感谢您的帮助,

乒乓球

您为什么不只将addActionListener代码提升到while循环之外?

匿名内部类侦听器在快速而肮脏的示例代码中看起来不错,但是在实践中,它们是一个可怕的想法。 您正在学习原因之一。 其他原因是它们不能轻易通过Dependency Injection类型的事物进行子类化或修改,不能轻易共享(例如按钮,工具栏图标和菜单执行相同的事情),不能轻易启用/禁用,(例如,应禁用“另存为”,因为没有打开任何内容)等。

对于此用例,将它们分成一些实际的侦听器系列,可能以类,数组或某些Enum的形式组织,以便可以将它们交换进出。

通过在程序本身中对程序的逻辑进行硬编码,正在以一种不好的方式将数据与代码混合,这是当前和将来问题的主要根源。 这是行不通的,至少没有很多麻烦就行了。

我建议您尝试将数据与代码分离,使程序更具MVC风格,即Model-View-Controller(或其众多变体之一)。 例如,程序的逻辑由模型掌握,其中包括所探索土地的非可视化地图,玩家在该地图中的位置,他的同伴以及您所收集物品的清单。 因此,您可能会有几种非GUI类,例如Player,Map,Item(可能是接口),Room等。Map本身,可能的项目以及那里的位置将在数据文件中指定,可能是一个简单程序的文本文件,或者一个更复杂程序的数据库,您将需要类来读取和解析此文件。

程序的视图就是您的GUI,它应该尽可能的简单。 在这里,您将有自己的按钮,文本显示,以及花哨的游戏图形显示。 这里没有程序逻辑。 没有。

控件将是您添加到JButton中的动作侦听器,以及其他必须处理用户输入的代码。 但是这段代码可能相对简单,它的主要任务是将用户交互传递给模型。 因此,例如,如果按下左按钮,则可能只是类似

model.leftButtonPress();

然后,模型将决定用左键按下(如果有)该怎么做。 例如,模型会知道您在游戏中的位置,左边是否有一扇门,或者它是否是墙,并且模型根据模型状态执行必要的操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM