Zugriff auf Variablen eines Objektes ohne sie auf static zu setzen

  • Themenstarter Themenstarter Mchicken
  • Beginndatum Beginndatum
M

Mchicken

Gast
Hallo,
Ich habe eine Klasse Main in deren main-Methode ich über new Frame(); die Klasse "Frame" starte.
In "Frame" ist die GUI angelegt. Desweiteren habe ich eine Klasse "OK_Action", welche als ActionListener eines OK-Buttons aus der Klasse Frame fungiert. In "OK_Action" möchte ich nun auf Variablen/Werte aus dem aktuellen "Frame"-Objekt zugreifen, also z.B JTextFields invisible setzten oder so etwas in der Richtung.
Ich habe momentan alle Variablen/JButtons/JLabels in "Frame" auf static gesetzt, was natürlich nicht sehr schön ist.

Ich bin momentan damit überfordert, wie ich sonst auf die Elemente im aktuellen "Frame"-Objekt zugreifen soll, da dieses Objekt nur in der Klasse Main existent ist.

Hoffe ihr versteht was ich meine 🙁.

Gruß Mchicken
 
Der Klasse "OK_Action" eine Referenz von Frame mit übergeben, dann kannst du auch auf Methoden (public) in Frame zugreifen.
 
Ich glaube ich steh grad total auf dem Schlauch,
also den ActionListener weise ich so zu
Java:
ok_button.addActionListener(new OK_Action());
.
Ich soll also dem Konstruktor von OK_Action die Referenz übergeben, ja?
Aber wie lege ich die Referenz an? Bzw. wie sieht sie aus?

Sorry, kenn mich leier noch nicht so gut aus 🙁

Gruß Mchicken
 
bspw. so... deine static-Variablen am besten gleich in private ändern und dann entsprechende getter-Methoden bereitstellst.

Java:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;

public class MyJFrame extends JFrame {
	public static void main(String[] args) {
		new MyJFrame();
	}

	private JButton buttonOK = new JButton("OK");
	private OK_Action listener = new OK_Action(this);

	public MyJFrame() {
		setSize(300, 300);
		setLocationRelativeTo(null);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		add(buttonOK, BorderLayout.SOUTH);
		buttonOK.addActionListener(listener);
		setVisible(true);
	}

	public JButton getButtonOK() {
		return buttonOK;
	}
}

class OK_Action implements ActionListener {
	MyJFrame f;
	int i = 1;

	public OK_Action(MyJFrame f) {
		this.f = f;
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		f.getButtonOK().setText("OK wurde " + i + "x gedrückt");
		i++;
	}
}
 
Ah vielen vielen Dank. Ich wusste nicht, dass man die Referenz des Objektes mit "this" übergeben kann 🙂

Noch zwei kleine grundlegende Fragen, so initialisiere ich die GUI-Elemente

Java:
public class Frame {
	
	public JTextArea gamefield;
	public JTextField name1_tf;
	public JTextField name2_tf;
	public JLabel name1_l;
	public JLabel name2_l;
	public JButton ok_button;
	public JButton[] throw_buttons;
	
	
	public Frame(){

1. Der Sinn die Elemente außerhalb einer Methode zu initialisieren liegt doch darin, dass diese dann in jeder Klasse zugänglich sind, oder?

2. Sollte ich die Elemente dann immer über "this." (also this.gamefield) ansprechen, und falls ja wieso?

Gruß Mchicken
 
Die GUI-Elemente würde ich von public auf private ändern, dann sind sie in der Klasse (auch in Methoden) erreichbar. Wenn du von ausserhalb auf die Elemente zugreifen möchtest, dann mit einer public-Methode in der Klasse.

Zu 2.) Innerhalb der Klasse kannst aber musst du nicht die Elemente mit this. ansprechen.
 
1. Der Sinn die Elemente außerhalb einer Methode zu initialisieren liegt doch darin, dass diese dann in jeder Klasse zugänglich sind, oder?

2. Sollte ich die Elemente dann immer über "this." (also this.gamefield) ansprechen, und falls ja wieso?

Gruß Mchicken


Zu 1.: Nein, denn ein direkter Zugriff auf Klassenelemente ausserhalb der Klasse spricht für ein schlechtes Design. Der Sinn liegt darin, dass diese Felder, selbst bei privatem Zugriff, für alle Methoden INNERHALB der Klasse zugänglich sind.
Zu 2.: This ist nur dann wirklich nötig, wenn ein Klassenfeld die gleiche Bezeichnung wie eine lokale Variable hat und Du auf das Klassenfeld zugreifen willst. Ich benutze this immer bei Klassenfeldern, denn m.E. erhöht es die Lesbarkeit.
 
Ergänzend ein Beispiel mit Inner Class:
Java:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;

public class MyJFrame extends JFrame {
	public static void main(String[] args) {
		new MyJFrame();
	}

	private JButton buttonOK = new JButton("OK");

	public MyJFrame() {
		setSize(300, 300);
		setLocationRelativeTo(null);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		add(buttonOK, BorderLayout.SOUTH);
		buttonOK.addActionListener(new OK_Action());
		setVisible(true);
	}

	private class OK_Action implements ActionListener {
		private int i = 0;

		@Override
		public void actionPerformed(ActionEvent e) {
			buttonOK.setText("OK wurde " + ++i + "x gedrückt");
		}
	}
}

Statt "initialisieren" meinst du wohl "deklarieren".

Mit "außerhalb einer Methode" ist dann wohl gemeint, die Variablen als Instance Members zu deklarieren? Ja, dann sind sie (je nach Access Level Modifier) nach außen, aber auch innerhalb der Klasse für andere Methoden sichtbar.

Das "this" kannst du meistens weglassen. Normalerweise spricht man diese Variablen indirekt über Getter und Setter an (und hat die Variablen an sich private oder protected).
 
Noch zwei kleine grundlegende Fragen, so initialisiere ich die GUI-Elemente

<KorinthenkackMode>
So deklarierst Du Deine Variablen. In Java werden Objekt-Variablen automatisch mit NULL initialisiert.
Richtiges initialisieren geht über einen Konstruktor-Aufruf, also new...
</KorinthenkackMode>
 
1. Der Sinn die Elemente außerhalb einer Methode zu initialisieren liegt doch darin, dass diese dann in jeder Klasse zugänglich sind, oder?
2. Sollte ich die Elemente dann immer über "this." (also this.gamefield) ansprechen, und falls ja wieso?

meine 5 Cent auch noch dazu 😉

zu 1.) Nein, sondern nur das sie innerhalb der gesamten Klasse sichtbar sind.
zu 2.) Auch nein 🙂

zum Unterschied zwischen deklarieren...und initialisieren ist ja schon was gesagt worden 🙂
 

Zurück
Oben