Layout-Manager

philbo

Mitglied
Hallo...
ich habe zur Zeit meine Applikation komplett basierend auf dem Null-Layout, d.h. ich muss eben für jeden Button, jedes Label usw. mit setBounds angeben, wo sich das genau befinden soll.
Ich habe bei mir einen "Startbildschirm" auf dem 3 Buttons zu sehen sind. (Datensatz anlegen, Datensatz suchen, Beenden), je nachdem welchen Button man klickt, werden die vorhandenen Objekte (Buttons etc) entfernt und die gewünschten geadded.
Was gibt es denn für eine Möglichkeit, das etwas bequemer zu lösen? Das Problem ist eben auch, dass sich insgesamt mein Quelltext so sehr aufgebläht hat, dass es schon nicht mehr feierlich ist :)
Habe für die wenigen Funktionen, die mein Programm bietet bereits 500 Zeilen Quelltext - das kanns ja wohl eigentlich nicht sein, oder?!
Wie würdet ihr sowas aufbauen?

Gruß
Philipp

P.S.: @Snape keine Angst kriegen, das soll nicht wieder so ein Mammut-Thread werden, wie der letzte ;)
 
Original geschrieben von philbo
Hallo...
ich habe zur Zeit meine Applikation komplett basierend auf dem Null-Layout, d.h. ich muss eben für jeden Button, jedes Label usw. mit setBounds angeben, wo sich das genau befinden soll.
Ich habe bei mir einen "Startbildschirm" auf dem 3 Buttons zu sehen sind. (Datensatz anlegen, Datensatz suchen, Beenden), je nachdem welchen Button man klickt, werden die vorhandenen Objekte (Buttons etc) entfernt und die gewünschten geadded.
Was gibt es denn für eine Möglichkeit, das etwas bequemer zu lösen? Das Problem ist eben auch, dass sich insgesamt mein Quelltext so sehr aufgebläht hat, dass es schon nicht mehr feierlich ist :)
Habe für die wenigen Funktionen, die mein Programm bietet bereits 500 Zeilen Quelltext - das kanns ja wohl eigentlich nicht sein, oder?!
Wie würdet ihr sowas aufbauen?

Gruß
Philipp

P.S.: @Snape keine Angst kriegen, das soll nicht wieder so ein Mammut-Thread werden, wie der letzte ;)

NullLayout... omg.... also wenn Du etwas anständiges nehmen willst, was man IMMER verwenden kann: GridBagLayout. Das ist vor allem am Anfang etwas schwierig zu durchschauen, aber wenn Du das einmal begriffen und öfter benutzt hast, wirst Du es zu schätzen wissen.
Ansonsten schaue Dir GridLayout und BorderLayout mal näher an, die kann man auch recht gut und oft einsetzen und sind einfacher von der Benutzung.

Ob das wieder ein Mammutthread wird, werden wir ja sehen... :)
 
Ok...ich schau es mir mal an...aber die Frage vorweg:
Kann ich da verschiedene Pane anlegen und die dann auf Buttonklick einfach nur anzeigen lassen, oder ist es besser, einen Pane zu verwenden und den zu leeren bzw zu füllen?
 
Okay...einfach ist es echt nicht...bekomme gerade so einige Fehler angezeigt...
Also, ich habe jetzt die globalen Variablen Container c; GridBagLayout gbl;
Dann eine Methode
Code:
static void addComponent( Container cont,
        GridBagLayout gbl,
        Component c,
        int x, int y,
        int width, int height,
        double weightx, double weighty )
{
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = x; gbc.gridy = y;
gbc.gridwidth = width; gbc.gridheight = height;
gbc.weightx = weightx; gbc.weighty = weighty;
gbl.setConstraints( c, gbc );
cont.add( c );
}

Meine main Methode sieht so aus...
Code:
public static void main(String[] args) {
	Schulungsunterlagenverwaltung wnd = new Schulungsunterlagenverwaltung();
   	Container c = wnd.getContentPane();
    GridBagLayout gbl = new GridBagLayout();
    c.setLayout( gbl );
	fenster(800,100); }
Die Methode Fenster, die aufgerufen wird:
Code:
static void fenster(int x,int y){
    WindowListener l = new WindowAdapter() {
    	public void windowClosing(WindowEvent e) {
    		int response = JOptionPane.showConfirmDialog(null,"Programm" +
    			" wirklich beenden ?","Programm beenden",
				JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
    		if (response == 0){
    			wnd.setVisible(false);
    			wnd.dispose();
    			System.exit(0);
    		}
    	}
    };
    Color farbe = new Color(204,204,204);
   	wnd.addWindowListener(l);
	wnd.setBackground(farbe);
    wnd.setLayout(null);
    wnd.setResizable(false);
    wnd.setSize(x,y);
    Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
    wnd.setLocation((d.width - wnd.getSize().width ) /2,(200));
    wnd.setVisible(true);
}

Wenn ich dann jetzt aus einer anderen Methode eine neue Komponente (z.b. einen JButton) adden will, mit dem Aufruf addComponent(c, gbl, b_eingeben, 0, 0, 2, 2, 1.0, 1.0 );

dann bekomme ich die Fehlermeldungen
java.lang.ExceptionInInitializerError
Caused by: java.lang.NullPointerException
at Schulungsunterlagenverwaltung.addComponent(Schulungsunterlagenverwaltung.java:96)
at Schulungsunterlagenverwaltung.hauptfenster(Schulungsunterlagenverwaltung.java:81)
at Schulungsunterlagenverwaltung.<init>(Schulungsunterlagenverwaltung.java:40)
at Schulungsunterlagenverwaltung.<clinit>(Schulungsunterlagenverwaltung.java:34)
Exception in thread "main"

Hat da vielleicht jemand ne Idee, wo die Fehler/Probleme liegen
 
Original geschrieben von philbo
Okay...einfach ist es echt nicht...bekomme gerade so einige Fehler angezeigt...
Also, ich habe jetzt die globalen Variablen Container c; GridBagLayout gbl;
Dann eine Methode
Code:
static void addComponent( Container cont,
        GridBagLayout gbl,
        Component c,
        int x, int y,
        int width, int height,
        double weightx, double weighty )
{
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = x; gbc.gridy = y;
gbc.gridwidth = width; gbc.gridheight = height;
gbc.weightx = weightx; gbc.weighty = weighty;
gbl.setConstraints( c, gbc );
cont.add( c );
}


Wenn ich dann jetzt aus einer anderen Methode eine neue Komponente (z.b. einen JButton) adden will, mit dem Aufruf addComponent(c, gbl, b_eingeben, 0, 0, 2, 2, 1.0, 1.0 );

dann bekomme ich die Fehlermeldungen

Hat da vielleicht jemand ne Idee, wo die Fehler/Probleme liegen

Naja, was mag eine NullPointerException wohl bedeuten... ;)
gbc wird nicht NULL sein, weil gerade erst erzeugt, kann also höchstens sein, dass gbl und/oder cont NULL sind.

Übrigens gewöhn Dir mal an, nicht alle Funktionalität in die public static void main() zu legen oder generell in statischen Kontext.
Vor allem problematisch ist es, eine statische Variable genauso zu nennen wie einen Übergabeparameter (gbl).
Noch ein Tip: Benutze eine IDE wie Eclipse, sie zeigt die Stelle an, wo es kracht.
 
Also ich benutze ja Eclipse.
gbc wird nicht NULL sein, weil gerade erst erzeugt, kann also höchstens sein, dass gbl und/oder cont NULL sind
ja...aber warum ist mir nicht klar.
Die Fehler zeigen auf :
gbl.setConstraints( c, gbc );
und auf:
addComponent(c, gblayout, b_eingeben, 0, 0, 2, 2, 1.0, 1.0 );

Übrigens gewöhn Dir mal an, nicht alle Funktionalität in die public static void main() zu legen oder generell in statischen Kontext.
Hehe, ich bin immer froh wenn ich meine Vorstellungen irgendwie umgesetzt bekomme. Was MUSS denn unbedingt in der public static void main liegen?

Vor allem problematisch ist es, eine statische Variable genauso zu nennen wie einen Übergabeparameter (gbl).
Ok, die hab ich schonmal umbenannt.
 
Original geschrieben von philbo
Also ich benutze ja Eclipse.

ja...aber warum ist mir nicht klar.
Die Fehler zeigen auf :
gbl.setConstraints( c, gbc );
und auf:
addComponent(c, gblayout, b_eingeben, 0, 0, 2, 2, 1.0, 1.0 );

Na dann dürfte wohl klar sein, dass gbl NULL ist. Aber auch das zeigt Dir Eclipse an. Lass Dir doch vor der Ausführung der Zeile
gbl.setConstraints( c, gbc );
den Wert für gbl ausgeben.

Hehe, ich bin immer froh wenn ich meine Vorstellungen irgendwie umgesetzt bekomme. Was MUSS denn unbedingt in der public static void main liegen?

Es reicht

MyClass myClass = new MyClass();

und ab dem Konstruktor von MyClass kann alles weitere geschehen, nicht-statisch ist dort wesentlich einfacher zu benutzen.
Oder wenn MyClass ein Frame ist dann eben noch ein

myClass.show();

Aber mehr muss es normalerweise nicht sein.
 
Na dann dürfte wohl klar sein, dass gbl NULL ist. Aber auch das zeigt Dir Eclipse an. Lass Dir doch vor der Ausführung der Zeile
gbl.setConstraints( c, gbc );
den Wert für gbl ausgeben.
Stimmt, ist null

Wenn ich jetzt das
Code:
Container c = wnd.getContentPane();
	GridBagLayout gbl = new GridBagLayout();
	c.setLayout( gbl );
aus der main entferne und in meine Methode hinzufüge, wo der Button geadded werden soll, gibts nen Nullpointer-Fehler bei der ersten Zeile davon, obwohl wnd (ist die Instanz meiner Klasse, oder wie das heisst) public static ist.
Hab es dann mit Container c = this.getContentPane probiert, aber dann bekomme ich nen Fehler bei setLayout :
java.lang.Error: Do not use Schulungsunterlagenverwaltung.setLayout() use Schulungsunterlagenverwaltung.getContentPane().setLayout() instead
Obwohl ich das doch so gesehen mache, oder?!
 
Original geschrieben von philbo
Stimmt, ist null

Wenn ich jetzt das
Code:
Container c = wnd.getContentPane();
	GridBagLayout gbl = new GridBagLayout();
	c.setLayout( gbl );
aus der main entferne und in meine Methode hinzufüge, wo der Button geadded werden soll, gibts nen Nullpointer-Fehler bei der ersten Zeile davon, obwohl wnd (ist die Instanz meiner Klasse, oder wie das heisst) public static ist.

Du begehst einen riesen Denkfehler. Zuallererst: Entferne überall in Deinem Code das Wort static, ausser bei der main-Methode.
Diese reduzierst Du auf
Code:
	public static void main(String[] args)
	{
		Schulungsunterlagenverwaltung wnd = new Schulungsunterlagenverwaltung();
		wnd.show();
	}

WICHTIG: wnd ist NUR in der main-Methode sichtbar (=vorhanden, benutzbar) (!) (!)
Das heisst, dass eigentlich die Methode static void fenster(int x, int y) mit all den Zugriffen auf wnd gar nicht funktionieren kann - es sei denn, Du definierst sie noch an anderer Stelle als Instanzvariable.

Falls Du noch immer, also auch nach Änderungen anhand dieser Hinweise, Probleme haben sollteste, poste bitte den relevanten Teil, also main(), Konstruktor und Instanzvariablendeklarationen sowie die addComponent().
 

Neue Beiträge

Zurück