innere klassen auslagern

Colt45

Aktives Mitglied
Moin,
ich steh vor einem kleinen Problem. Ich habe eine große Controllerklasse mit etlichen inneren klassen, die die ActionEvents von verschiedenen Buttons handlen. Nun möchte ich diese inneren klassen auslagern, das Problem dabei ist, dass diese auf Instanzvariablen und Methoden der Controllerklasse zugreifen (ich will weder public instanzvariablen noch jedes mal den Controller instanziieren), und das sind in manchen inneren klassen ziemlich viele, also fällt die Option, sie als Parameter dem Konstruktor zu übergeben schonmal weg.
Hat jemand eine Idee, wie ich an dieses Problem rangehen kann, ohne massiv in die grundarchitektur einzugreifen?
Danke schonmal im Vorraus.
-Colt
 
Nun möchte ich diese inneren klassen auslagern,
Das macht auch Sinn. Zu viele innere Klassen sollen sich recht unperformant auswirken.

(ich will weder public instanzvariablen noch jedes mal den Controller instanziieren)
Macht man beides nicht. Instanzvariablen sollten immer
Code:
private
deklariert werden. Der Zugriff von außen bzw. die Manipulation von Daten einer Klasse sollte immer über Methoden laufen.
Man erzeugt auch nicht jedes mal ein Controller-Objekt. Man übergibt einfach
Code:
this
. 😉

Hat jemand eine Idee, wie ich an dieses Problem rangehen kann, ohne massiv in die grundarchitektur einzugreifen?

Von [JAPI]AbstractAction[/JAPI] erben und
Code:
actionPerformed()
überscheiben?
 
Von [JAPI]AbstractAction[/JAPI] erben und
Code:
actionPerformed()
überscheiben?

Könntest du mir das genauer erklären, wie das mit AbstractAction funktioniert, ich hab damit noch nicht wirklich gearbeitet bzw. mich damit befasst?

Hier mal ein Beispiel, wie ich es bis jetzt gelöst habe:

Java:
private class UnitFormListener implements ActionListener
	{
		public void actionPerformed(ActionEvent e)
		{
			Object src = e.getSource();

                        //unitForm erbt von JFrame und ist Instanzvariable im Controller
			if(src == unitForm.getAdditionalUnitButton())
			{
                                //createUnit ist eine Methode im Controller, die wiederum           
                                //auf Instanzvariablen zugreift
				createUnit();
				unitForm.getUnitNameTextField().setText("");
				unitForm.getUnitDescriptionTextField().setText("");
			}
			else if(src == unitForm.getCancelButton())
			{
				unitForm.dispose();
			}
			else if(src == unitForm.getFinishButton())
			{
                                //viewState ist eine Hilfsvariable um zu unterscheiden, ob unitForm grad
                                //im "Neu"-Modus oder im "Bearbeiten"-Modus steht
				if(unitForm.getViewState() == 1)
				{
					unitForm.dispose();
					createUnit();
				}
				else if(unitForm.getViewState() == 2)
				{
					unitForm.dispose();
					updateUnit();
				}

			}
		}
	}
 
Zuletzt bearbeitet:
Schau dir die Konstruktoren von [JAPI]AbstractAction[/JAPI] an. Mit dem super()-Aufruf kannst du der Basisklasse Werte zu deren Initialisierung übergeben. Auch ein Icon ist möglich.

Hier mal ein frei aus der Luft gegriffenes Beispiel zum setzen der Hintergrundfarbe einer Component.
Java:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class ChooseColorAction extends AbstractAction {
   private MainPanel panel;

   public ChooseColorAction(MainPanel panel, String name) {
      super(name);
      this.panel = panel;
   }

   public void actionPerformed(ActionEvent e) {
      panel.setBackground(JColorChooser.showDialog(panel, "Hintergrundfarbe auswählen", Color.WHITE));
   }
}

In deinem Controller müsste in diesem Fall dann eine setBackground()-Methode implementiert sein, die die Hintergrundfarbe der entsprechenden Component setzt.
Der Code zum Einsetzen der Action in den Button sähe dann so aus:
Java:
  chooseColorBtn = new JButton(new ChooseColorAction(this, "Hintergrundfarbe setzen"));
 
Also grundsätzlich isses so gelöst, dass ich verschiedene Klassen habe, die von JFrame erben und die einzelnen Fenster repräsentieren, in diesen sind die JButtons instanziiert und deklariert. Was beim Klicken passieren soll, wird im Controller geregelt. Da hol ich mir mittels eines getters in der JFrame-Klasse den Button und rufe dann eine Methode im Controller auf. Ich wollte es auch vom Design her so handlen, dass ich nicht für jeden Button eine eigene AbstractAction-Klasse verwende, sondern pro Fenster, also pro JFrame einen
Java:
MyJFrameListener implements Action Listener
.
 
Na dann musst du für jeden JFrame Klassen schreiben, die das Interface ActionListener implementieren.
Innerhalb der Klasse verarbeitest du dann die Events der Komponenten, auf die dein Listener lauscht.

BTW: Eine Anwendung sollte nur einen JFrame haben. Die anderen Fenster sollten vom Typ JDialog und JOptionPane etc. sein.
 
[OT](Zumindest so halb: ) Inwiefern haben innere Klassen Einfluß auf die Performance?[/OT]

Die inneren Objekte halten eine Referenz auf das äußere. Das ist erstmal ein kleiner Overhead. Außerdem steigt die Gefahr von Speicherlecks, was sicherlich schlimmer ist. Wer keine inner class braucht, kann ja genauso gut eine static nested class verwenden (Findbugs findet übrigens automatisch solche Kandidaten).
 
OK, ich bin bei "innere Klasse" jetzt davon ausgegangen, dass es in erster Linie um statische geht. Nicht-statische können IMHO (nicht pauschal, aber in manchen Fällen) etwas "unschöne" Strukturen hervorbringen...
 
Bei nicht-statischen innere Klassen gibt es pro Instanz der äusseren Klassen (also Objekt der äusseren Klasse) eine eigene innere Klasse.
 

Neue Themen


Zurück
Oben