Java WindowBuilder Einstieg

semmelkuh

VerwirrterBenutzer
ID: 188086
L
28 April 2006
558
30
Hey,

ich habe vor ein Java Programm mit einer komplexeren GUI zu erstellen. Deshalb habe ich mir den WindowBuilder runtergeladen und damit eine GUI gebaut.
Bloß bin ich mir nun unsicher ob mein weiteres Vorgehen, was auf dem vom WindowBuilder generierten Code basiert, so richtig ist. (Ich hätte es per Hand nämlich anders geschrieben, aber das Ganze wieder umzubasteln widerstrebt dem Nutzen eines GUI Editors dann doch. :ugly:)

Dazu hier direkt ein ganz kleines Beispielprogramm: 1 JLabel, 1 JButton.
Der JButton bekommt einen ActionListener und damit soll der Text vom JLabel geändert werden.
Das Ganze habe ich (bzw. der WindowBuilder) wie im folgenden Code zu sehen erstellt. Kursiv ist was ich hinzufügte und fett ist was Eclipse anschließend verlangte, damit es auch funktioniert.
Und genau das ist meine eigentliche Frage: Ist es richtig/sinnvoll, dass das JLabel final ist bzw. sein muss? Oder sollte man das alles irgendwie anders gestalten?

Code:
package gui;

import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JLabel;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class GUI extends JFrame {

	private JPanel contentPane;

	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					GUI frame = new GUI();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	public GUI() {
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 450, 300);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);
		
		[B]final[/B] JLabel lblNewLabel = new JLabel("New label");
		lblNewLabel.setBounds(97, 103, 70, 14);
		contentPane.add(lblNewLabel);
		
		JButton btnNewButton = new JButton("New button");
		btnNewButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				[I]lblNewLabel.setText("Neuer Text");[/I]
			}
		});
		btnNewButton.setBounds(92, 128, 89, 23);
		contentPane.add(btnNewButton);
	}

}

Das Programm funktioniert so ersteinmal. Aber können durch das final nicht später Probleme auftreten? Oder ist das so normal?

Danke
semmelkuh
 
Dass dir deine IDE das final-Keyword abverlangt, ist korrekt. Verwendest du eine Variable innerhalb einer inneren Klasse, so kannst du dort nur zugreifen, wenn sich der Inhalt der Variable nicht ändert, d.h. final setzen.

Du kannst wegen dem final-Keyword später nur nicht hergehen und dieser Variable einen anderen Wert (= ein anderes JLabel) zuordnen. Das liegt aber in deiner Hand und da es nicht sinnvoll ist, wird du es auch nicht tun. In Java gilt bei Objekten CallByReference, d.h. wenn DU deine Referenz lblNewLabel auf ein anderes Objekt umbiegst, kriegt das niemand sonst mit. Das JPanel, was das Label schon eingebunden hat, wird deshalb auch nix anderes zeigen.

Ich weiß nicht, wie sich der Eclipse-Debugger verhält - ich kenn es nur von IntelliJ (für Java eigentlich ein Muss, wenn man mehr programmiert - kostd was, aber es lohnt sich echt!), dass dir dort im Debugger eine Nummer am Objekt angezeigt wird, damit du weißt, ob es dasselbe (==) Objekt ist.

z.B. angenommen, du schreibst:
PHP:
JLabel lblNewLabel = new JLabel("New label"); // final weg
// lblNewLabel = JLabel@2345
contentPane.add(lblNewLabel); // contentPane hält Referenz zu JLabel@2345

lblNewLabel = new JLabel("Foobar"); // Referenz umbiegen auf neues Objekt
// lblNewLabel = JLabel@6789
// contentPane hält immer noch Referenz zu JLabel@2345

lblNewLabel = (JLabel) contentPane.getComponent(0); // Referenz wieder auf das alte JLabel biegen
// lblNewLabel = JLabel@2345
// Garbage Collector kann JLabel@6789 wegräumen; letzte Referenz darauf wurde entfernt