Kann Zugabe einer Action kurz sein? Kann ich Argumente für die actionPerformed hinzufügen?

StackOverflow https://stackoverflow.com/questions/2515552

  •  22-09-2019
  •  | 
  •  

Frage

Ich habe eine große Tabelle auf eine Schaltfläche in jeder Zelle enthält. Diese Tasten sind sehr ähnlich und tun fast das gleiche. Wenn ich eine Aktion Hörer auf diese Weise zu jeder Taste hinzufügen:

tmp.addActionListener(new ActionListener(){
   @Override
   public void actionPerformed(ActionEvent evt) {
      proposition = proposition + action;
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            updatePropositionPanel();
         }
      });
   }
});

Eigentlich unterscheiden sich jede Aktion Hörer von allen anderen durch den Wert des action. proposition und updatePropositionPanel ist ein Feld und eine Methode der Klasse.

  1. Zuerst dachte ich, dass ich es kürzer machen, wenn ich nicht innere Klassen verwenden. Also entschied ich eine neue Action Klasse zu programmieren. Aber als ich erkennen, dass in diesem Fall „Satz“ nicht auf die Instanzen dieser Klasse sichtbar sein.

  2. Dann habe ich beschlossen, die Methode actionPerformed auf die aktuelle Klasse hinzuzufügen, und das tun: addActionListener(this). Aber als ich merkte, dass ich nicht weiß, wie gibt Argumente an die Methode actionPerformed.

Also, wie funktioniert es. Kann ich eine Aktion Hörer in einer kurzen und elegent Art und Weise hinzufügen?

ADDED:

Ich mochte die Idee, eine innere Klasse mit einem Konstruktor zu programmieren, das einige Argumente und actioPerformed Methode nehmen, die Argumente gegeben im Konstruktor verwenden kann. Ich fing an, dies zu tun und dann erkennen, dass es einen Konflikt mit anderen inneren anonymen Klassen erstellt (verwendet wie in dem oben angegebenen Code). Also, ich glaube ich eine andere Klasse schaffen (nicht innere).

War es hilfreich?

Lösung

Sie können Ihre eigene Klasse erstellen und die Daten in das Konstruktor übergeben. Zum Beispiel

public class MyActionListener
{
    private int proposition;
    private MyOtherClass moc;

    public MyActionListener(int proposition, MyOtherClass moc) {
        this.proposition = proposition;
        this.moc = moc;
    }

    public void actionPerformed(ActionEvent evt) {
        proposition += moc.action;
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                moc.updatePropositionPanel();
            }
        });
    }
}

Dann können Sie es als normal hinzufügen, vorbei an was auch immer Argumente, die Sie wie an den Konstruktor:

tmp.addActionListener( new MyActionListener(proposition, this) );

Andere Tipps

Bearbeiten :. Ich habe die Klasse zu zeigen Konstruktion mit MyOuterClass geändert

Hier ist ein Code skizziert. Hoffentlich werden Sie 1, das ist, wie ich es umsetzen würde.

public class MyOuterClass {
    // member variables for MyOuterClass

    public MyOuterClass() {
        // ...constructor stuff here
    }
    // ...outer class stuff here - methods, etc.

    // The code each place you want to add the listener, somewhere in MyOuterClass
    tmp.addActionListener(new MyActionListener(poposition, action));


    // below outer class stuff, although it can really be most places, I usually put
    // it here - personal style preference.  Swing's classes often put inner
    // classes first

    /**
     * An inner class.
     */
    private MyActionListener implements ActionListener {
        /**
      * Object used here as a filler, replace with appropriate
      * class types
      */
        private Object proposition;
        private Object action;

        private MyActionListener(Object proposition, Object action) {
            this.proposition = proposition;
            this.action = action;
        }
        public void actionPerformed(ActionEvent evt) {
          proposition = proposition + action;
          SwingUtilities.invokeLater(new Runnable() {
             public void run() {
                updatePropositionPanel();
             }
        }
        /**
         * Setters provided in case you need to change proposition and action.  If not,
         * feel free not to have them and to have final members
         */
        private void setProposition(Object proposition) {
            this.proposition = proposition;
        }
        private void setAction(Object action) {
            this.action = action;
        }
    }
}

Bearbeiten :. Ein andere Klasse zu erstellen, wie Sie in Ihrem bearbeiten gefragt, tut wie oben, aber eine nicht-private andere Klasse in einer anderen .java-Datei und den Code entfernt erstellen

Als einzige andere im Wert von action ist, können Sie den Code innerhalb einer Methode platzieren. (Auch die @Override ist unnötig und += ist nützlich, hier.)

public void setup(
    final AbstractButton button,
    final int action
) { 
    button.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent evt) {
            proposition += action;
            EventQueue.invokeLater(new Runnable() {
                public void run() {
                   updatePropositionPanel();
                }
           });
        }
    });
}

Die invokeLater ist wahrscheinlich sinnlos, da man sowieso auf dem AWT Event Dispatch Thread (EDT) sein wird.

Wenn Sie viele allgemeine Zwecke Aktionen hinzufügen, dann könnte man es vereinfachen, indem sie über eine Schnittstelle, die keine sinnlose Ereignisobjekt mit ihm verbunden.

Wenn Sie sein hackish wollen Sie den Hörer in einer Unterklasse Konstruktor hinzufügen könnten.

    new ActionHandler(button) { public void action() {
        proposition += action;
        updatePropositionPanel();
    }});

Wir hoffen, JDK7 wird die Java-Syntax für diese Art der Sache weniger ausführlich machen. Java wird jedoch immer ein wenig umfangreich sein.

Option 1 funktioniert, wenn Sie proposition wandelbar (z StringBuilder statt String) machen. Option 2 funktioniert, wenn Sie erklären, sie final. Auf diese Weise sind sie zugänglich / sichtbar in der inneren Klasse.

Sie können eine separate MyActionListener Klasse erstellen und übergeben Sie die beiden Werte Proposition und Aktion mit dem Konstruktor. Es declutters den Quellcode.

Sie können Ihre eigene Listener-Klasse, dass Geräte Action erstellen. Diese Klasse könnte Membervariablen auf die Parameter enthalten entsprechende Sie sprechen; Sie würden sie mit dem Konstruktor festgelegt.

Der Anruf die Hörer hinzufügen würde dann wie folgt aussehen:

tmp.addActionListener(new MyActionListenerSubClass(proposition, action));

Ich gehe davon aus, dass Ihre Aussage und Wirkung Variablen sind Strings zum Zwecke dieses Beispiels. Definieren Sie eine Schnittstelle PropositionUpdater, eine Schnittstelle PropositionPanelUpdater und einen Kollaborateur Satz Inhaber:

public interface PropositionUpdater() {
    public void updateProposition(PropositionHolder holder, String action);
}

public interface PropositionHolder() {
    public String getProposition();

    public void setProposition(String proposition);
}

public interface PropositionPanelUpdater() {
    public void updatePropositionPanel();
}

Die Standardimplementierung eines Satzes Updater ist einfach:

public class DefaultPropositionUpdater implements PropositionUpdater {
    public void updateProposition(final PropositionHolder holder, final String action) {
        holder.setProposition(holder.getProposition() + action);
    }
}

Ich werde den Ausfall eines PropositionHolder und PropositionPanelUpdater Ihre Phantasie überlassen;)

Nun, hier ist Ihre Aktion Hörer:

public class PropositionUpdaterActionListener implements ActionListener {
    private PropositionHolder holder;

    private PropositionUpdater updater;

    private PropositionPanelUpdater panelUpdater;

    public PropositionUpdaterActionListener(final PropositionHolder holder, final PropositionUpdater updater, final PropositionPanelUpdater panelUpdater) {
        super();
        this.holder = holder;
        this.updater = updater;
        this.panelUpdater = panelUpdater;
    }

    public void actionPerformed(final ActionEvent evt) {
        //Not sure how you *got* the action, but whatever...
        updater.updateProposition(holder, action);
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                panelUpdater.updatePropositionPanel();
            }
        });
    }
}

Du hast nicht sagen, wie viele Tasten Sie sprechen.

Wenn es eine kleine Zahl wie ein Schachbrett oder weniger @ juskt Ansatz ist gut.

Wenn Sie jedoch auf etwas größer ist, suchen würde ich diesen Ansatz:

public class MyActionListener {
      public void actionPerformed(ActionEvent evt) {
          JComponent c = (JComponent)evt.getSoource();
          int prop = (Integer)c.getclientProperty("PROPOSITION");
          int act = (Integer)c.getclientProperty("ACTION");
          SomeClass obj = c.getclientProperty("UPDATE");
          prop += act;
          // If necessary, clientPut("PROPOSITION", prop);
          SwingUtilities.invokeLater(new    Runnable() {
              public void run() {
                  obj.updatePropositionPanel();
              }
          });
      }
}

Diese Aktion Hörer halten keinen Staat. Als Ergebnis kann eine einzelne Instanz für alle Tasten verwendet werden. Für so etwas wie ein Go-Brett (19x19), funktioniert dies auf 1 Objekt aus statt 361.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top