简体   繁体   English

如何删除内部类ActionListener?

[英]How to remove an inner class ActionListener?

I am making a text based game, but I am having a rather large problem. 我正在制作一个基于文本的游戏,但是我遇到了一个很大的问题。 This problem is that when I assign a new ActionListener to a button that already has an ActionListener assigned to it, it does both of the actions. 问题是,当我将一个新的ActionListener分配给一个已经为其分配了ActionListener的按钮时,它将同时执行两个操作。 Here's my code: 这是我的代码:

       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!");
       }

Thanks for helping, 感谢您的帮助,

billofbong 乒乓球

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

Anonymous inner class listeners look nice in quick and dirty example code, but, in practice, they are a horrible idea. 匿名内部类侦听器在快速而肮脏的示例代码中看起来不错,但是在实践中,它们是一个可怕的想法。 You are learning one of the reasons. 您正在学习原因之一。 Other reasons are that they can't readily be subclassed or modified via Dependency Injection types of things, can't readily be shared (say a button, a toolbar icon, and a menu do the same thing), can't readily be enabled / disabled, (say, "Save As" should be disabled cause nothing is open) etc... 其他原因是它们不能轻易通过Dependency Injection类型的事物进行子类化或修改,不能轻易共享(例如按钮,工具栏图标和菜单执行相同的事情),不能轻易启用/禁用,(例如,应禁用“另存为”,因为没有打开任何内容)等。

For this use case, break them out into some series of actual Listeners, perhaps organized in a class, array, or some Enums, so they can get swapped in and out. 对于此用例,将它们分成一些实际的侦听器系列,可能以类,数组或某些Enum的形式组织,以便可以将它们交换进出。

You are mixing data with code in a bad way by hard-coding the logic of your program in the program itself, and this is the main source of your current and future problems. 通过在程序本身中对程序的逻辑进行硬编码,正在以一种不好的方式将数据与代码混合,这是当前和将来问题的主要根源。 This won't work, at least not without a lot of kludges. 这是行不通的,至少没有很多麻烦就行了。

I suggest you try to separate your data out of your code and make your program more MVC-ish, which stands Model-View-Controller (or one of its many variants). 我建议您尝试将数据与代码分离,使程序更具MVC风格,即Model-View-Controller(或其众多变体之一)。 For instance the logic of the program is held by the Model and this includes the non-visualized map of the land being explored, the position of the player in this map, his companions, and your inventory of items that you've collected. 例如,程序的逻辑由模型掌握,其中包括所探索土地的非可视化地图,玩家在该地图中的位置,他的同伴以及您所收集物品的清单。 So you will likely have several non-GUI classes such as Player, Map, Item (this may be an interface), Room, etc... The Map itself, the possible items, there locations, will be specified in a data file, perhaps a text file for a simple program or a database for a more complex one, and you will need classes to read and parse this file(s). 因此,您可能会有几种非GUI类,例如Player,Map,Item(可能是接口),Room等。Map本身,可能的项目以及那里的位置将在数据文件中指定,可能是一个简单程序的文本文件,或者一个更复杂程序的数据库,您将需要类来读取和解析此文件。

The View of your program is your GUI, and it should be as dumb as possible. 程序的视图就是您的GUI,它应该尽可能的简单。 Here is where you'll have your buttons, your text display, and if fancy, a graphical display of your game. 在这里,您将有自己的按钮,文本显示,以及花哨的游戏图形显示。 No program logic goes in here. 这里没有程序逻辑。 None. 没有。

The Control will be the Action Listeners that you add to your JButtons and any other code that has to deal with handling user input. 控件将是您添加到JButton中的动作侦听器,以及其他必须处理用户输入的代码。 But this code could be relatively simple, and it's main task is to pass user interactions to the model. 但是这段代码可能相对简单,它的主要任务是将用户交互传递给模型。 So for instance if the left button is pressed, it may be simply something like 因此,例如,如果按下左按钮,则可能只是类似

model.leftButtonPress();

Then the model will decide what to do with a left button press, if anything. 然后,模型将决定用左键按下(如果有)该怎么做。 The model will know where you are in the game for instance, if there's a door to your left or if it's a wall, and based on the state of the model your game will perform the requisite action. 例如,模型会知道您在游戏中的位置,左边是否有一扇门,或者它是否是墙,并且模型根据模型状态执行必要的操作。

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

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