Komponente zur Laufzeit erstellen

Kiloui

Mitglied
Hi,
wie erreiche ich es Komponenten (Buttons, CheckBoxes etc) zur Laufzeit zu erstellen ?

Ganz simpel...angenommen der Benutzer wir nach einer Anzahl gefragt und anschließend werden entsprechend viele CheckBoxes erstellt ?
Ich weiß nicht wie das mit den namen der CheckBoxes objekte funktioniert.
Werden den Komponenten dann zufällige namen zugeteilt ?
Wie kann ich dann die Namen herausfinden um mit den Komponenten arbeiten zu können ?


Was ich vorhabe ist es ein Verzeichnis zu durchsuchen und dann für jede Datei die gefunden wird ein Bild + CheckBox zu erstellen.
 
Hallo Kiloui
Aus meiner Sciht ist das eigetnlich nicht so schwer.
Alles was Du machen musst ist die Komponenten z.B. Buttons zur Laufzeit in Deinen Kontainer z.B. JPanel einzufügen. Nehmen wiri mal an, Du weit den Buttons die Du so dynamisch erzeugst und in Deinen Kontainer hinzufügst (add-Methode) den selben Listener zu, so kannst Du problemlos mit Abfragen der Source (s. EventObject) im Listener auf den entsprechendne Button schließen. Du kannst natürlich Deinen Komponenten auch Namen geben, wenn Du der Meinung bist Du müsstest das. Diese könnte man dann einfach machschinell mit einem Statischen String und einer laufenden Nummer versehen. Ich bin jetzt mal davon ausgegangen, dass Du Swing verwendest, jedoch nehme ich an dass dies im SWT sicher ähnlich gehandhabt wird, auch wenn ich SWT nicht kenne.
viele Grüß e

Takidoso
 
Danke für deine Antwort.

Habe grad mal versucht ein Objekt zu erstellen dessen Name durch einen vorher definierten String repräsentiert wird....und das funktioniert echt :D
War mir eigentlich sicher dass würde nicht gehen...aber so ist es ja echt easy :)

Danke
kiloui
 
Wozu der Name?
Wäre es nicht sinnvoller ein Array von der Länge der Eingabe zu erstellen und da der Reihe nach die JComponents reinschreiben? Und eben dann im Listener übern Source per Schleife das Objekt herausfinden?

Namen sind afaik nur dafür gut, in einer Debug-Ansicht Threads auseinanderhalten zu können. Sonst habe ich in ihnen keine Verwendung erkannt.
 
Wäre es nicht sinnvoller ein Array von der Länge der Eingabe zu erstellen und da der Reihe nach die JComponents reinschreiben? Und eben dann im Listener übern Source per Schleife das Objekt herausfinden?

Was genau meinst du mit den Listenern ? Hab grad erst angefangen mit Java und damit noch nie gearbeitet....

Den Namen brauche ich aber um mit dem Obkekt arbeiten zu können....also um über "name.eigenschaft" die eigenschaften der Komponente zu bestimmen
 
Hier ein kleines Beispiel.
Habs auf 3 Klassen aufgeteilt, damit du dich besser auskennst.
Natürlich ginge es besser (da man keine Schleife braucht) über eine anonymoume Klasse, aber ich denke für einem Anfänger ist das noch zu schwer.
Wenn du irgendetwas nicht verstehst dann frag.

Java:
package app;

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

public final class Kiloui extends JFrame
{
	private static final long serialVersionUID = 1L;
	private final int numbersOfButtons = 5;
	
	public Kiloui()
	{
		super();
		
		this.setSize(800, 600);
		this.setTitle("Ne menge Buttons");
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setResizable(false);
		this.setLayout(null);
		
		JButton[] buttonArray = new JButton[this.numbersOfButtons];
		BuildForm.run(this.numbersOfButtons, buttonArray, this);
		
		this.setVisible(true);
	}
	public final static void main(String[] args)
	{
		new Kiloui();
	}
}
//////////////////////////////
package app;

import javax.swing.JButton;

public final class BuildForm extends Object
{
	public BuildForm()
	{
		super();
	}
	public final static void run(int i, JButton[] buttonArray, Kiloui kiloui)
	{
		Listener l = new Listener(buttonArray);
		
		for(int j = 0; j < i; j++)
		{
			buttonArray[j] = new JButton();
			buttonArray[j].setText("Button ".concat(String.valueOf(j)));
			buttonArray[j].setLocation(20, 30 * j + 10);
			buttonArray[j].setSize(100, 20);
			buttonArray[j].addActionListener(l);
			
			kiloui.add(buttonArray[j]);			
		}
	}
}
//////////////////////////////
package app;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;

public final class Listener implements ActionListener
{
	private JButton[] buttonArray;
	
	public Listener(JButton[] buttonArray)
	{
		super();
		this.buttonArray = buttonArray;
	}
	public final void actionPerformed(ActionEvent arg0)
	{
		JButton source = (JButton)arg0.getSource();
		
		for(JButton button:this.buttonArray)
			if(button.equals(source))
				System.out.println(button.getText().concat(" gedrückt"));
	}
}
 
Ok danke, das funktioniert soweit alles und macht auch alles sinn.

Aber 3 Fragen hab ich doch noch ;)

1) Hat zwar nicht direkt was mit dem Thema zu tun aber was erreichst du durch das "this.".
Z.b. in der Klasse "Kiloui" schreibst du:

this.setSize(800, 600);
this.setTitle("Ne menge Buttons");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(false);
this.setLayout(null);

oder

BuildForm.run(this.numbersOfButtons, buttonArray, this);

Hätte vorallem beim zweiten nich einfach "numersOfButtons" gereicht anstatt "this.NumbersOfButtons" ?

2)
Kann man auch einfach direkt einen ActionListener erstellen und den Namen herausbekommen können ohne selbst eine Klasse "Listener" zu schreiben und die Klasse "ActionListener" zu extenden/implementieren ?

3)
Die Methode "actionPerformed(ActionEvent arg0)" rufst du nirgends auf, oder ?
Sprich "actionPerformed" kann man beliebig mit Code füllen und wird ohne dass man sie nochmal speziell aufruft ausgeführt sobald dass Programm merkt dass mit der jeweiligen Komponente etwas gemacht wird ?
 
1)
Hätte es. "this." ist ein Pointer, der direkt auf die Klasse verweißt. Im ersten Zitat verweißt es immer auf Methoden der Klasse. Kiloui erbt von JFrame (extends JFrame), d. H. es bekommt alle public und protected (event. auch die ohne Modifizierer, solche hatte ich aber noch nie) Methoden und Variablen der jeweiligen Klasse.
Ich verwende es grundsätzlich immer, ist aber nur nötig wenn es eine Klassen- und eine Methodenvariable gibt, da sonst die Methodenvariable bevorzugt wird. z. B.:
Java:
String aString;
public void setAString(String aString)
{
	this.aString = aString;
}
Hier ist es notwendig, da er sonst die Methodenvariable, die im Konstruktor steht in sich selbst schreiben würde.
Aber ich verwende es nur um schnell zwischen Klassen- und Methoden-Variablen zu unterscheiden. Zudem öffnet sich bei "this" automatisch in Eclipse das Autoverfollständigkeitsfenster, sonst müsste ich Controll + Space drücken.

2)
Ja. Das meine ich mit Anonyme Klasse.
Java:
for(int j = 0; j < i; j++)
{
	buttonArray[j] = new JButton();
	buttonArray[j].setText("Button ".concat(String.valueOf(j)));
	buttonArray[j].setLocation(20, 30 * j + 10);
	buttonArray[j].setSize(100, 20);
	buttonArray[j].addActionListener(new ActionListener() {
		public void actionPerformed(ActionEvent e)
		{
			JButton source = (JButton)e.getSource();
			System.out.println(source.getText());
		}				
	});
	
	kiloui.add(buttonArray[j]);			
}

In diesen Fall bekommt jeder Button seinen eigenen ActionListener. Hier brauchst du keine Schleife, da der Source immer der gleich ist, da der Listener ja nur an einen Button hängt. Wichtig ist nur dass anonyme Klassen keinen Konstruktor haben, d. H. du kannst ihnen auch keine Objekte übergeben.

3)
Nein, das machen die Buttons selbst. Einfach mit addActionListener() eine Klasse die ActionListener implementiert (könntest z. B. auch in der "BuildForm" den ActionListener implementieren und ihm per "this" übergeben), oder eben eine anonyme Klasse schreiben. Ich glaube zumindest dass es auch "Klasse" heißt, obwohl es in Wirklichkein ein Interface ist.
 
Ach noch eine Sache...damit ich keinen neuen Thread aufmachen muss :)

Wenn ich jetzt mehrere Komponenten erstelle und diese nicht in das fenster paßen sind sie nicht mehr sichtbar....wie bekomme ich sobald nötig eine Scrollleiste an meinem Fenster hin ?
 

Neue Beiträge

Zurück